add compute functions

- fix Device and PaginatedCollection
- improve DeviceToNodeMetadata
This commit is contained in:
Andrea Turli 2017-01-24 22:33:48 +01:00
parent 49f1d0760e
commit 3696412213
7 changed files with 356 additions and 6 deletions

View File

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.packet.compute.functions;
import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata.Status;
import org.jclouds.packet.domain.Device;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.ImmutableMap;
/**
* Transforms an {@link Device.State} to the jclouds portable model.
*/
@Singleton
public class DeviceStateToStatus implements Function<Device.State, Status> {
private static final Function<Device.State, Status> toPortableStatus = Functions.forMap(
ImmutableMap.<Device.State, Status> builder()
.put(Device.State.PROVISIONING, Status.PENDING)
.put(Device.State.ACTIVE, Status.RUNNING)
.build(),
Status.UNRECOGNIZED);
@Override
public Status apply(final Device.State input) {
return toPortableStatus.apply(input);
}
}

View File

@ -0,0 +1,110 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.packet.compute.functions;
import java.util.List;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.packet.domain.Device;
import org.jclouds.packet.domain.IpAddress;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import static com.google.common.collect.FluentIterable.from;
/**
* Transforms an {@link Device} to the jclouds portable model.
*/
@Singleton
public class DeviceToNodeMetadata implements Function<Device, NodeMetadata> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final PlanToHardware planToHardware;
private final OperatingSystemToImage operatingSystemToImage;
private final FacilityToLocation facilityToLocation;
private final Function<Device.State, NodeMetadata.Status> toPortableStatus;
private final GroupNamingConvention groupNamingConvention;
@Inject
DeviceToNodeMetadata(PlanToHardware planToHardware, OperatingSystemToImage operatingSystemToImage, FacilityToLocation facilityToLocation,
Function<Device.State, NodeMetadata.Status> toPortableStatus,
GroupNamingConvention.Factory groupNamingConvention) {
this.planToHardware = planToHardware;
this.operatingSystemToImage = operatingSystemToImage;
this.facilityToLocation = facilityToLocation;
this.toPortableStatus = toPortableStatus;
this.groupNamingConvention = groupNamingConvention.createWithoutPrefix();
}
@Override
public NodeMetadata apply(Device input) {
return new NodeMetadataBuilder()
.ids(input.id())
.name(input.hostname())
.hostname(input.hostname())
.group(groupNamingConvention.extractGroup(input.hostname()))
.location(facilityToLocation.apply(input.facility()))
.hardware(planToHardware.apply(input.plan()))
.imageId(input.operatingSystem().slug())
.operatingSystem(operatingSystemToImage.apply(input.operatingSystem()).getOperatingSystem())
.status(toPortableStatus.apply(input.state()))
.publicAddresses(getPublicIpAddresses(input.ipAddresses()))
.privateAddresses(getPrivateIpAddresses(input.ipAddresses()))
.tags(input.tags())
.build();
}
private Iterable<String> getPublicIpAddresses(List<IpAddress> input) {
return filterAndTransformIpAddresses(input, new IsPublicIpAddress());
}
private Iterable<String> getPrivateIpAddresses(List<IpAddress> input) {
return filterAndTransformIpAddresses(input, Predicates.not(new IsPublicIpAddress()));
}
private Iterable<String> filterAndTransformIpAddresses(List<IpAddress> input, Predicate<IpAddress> filter) {
return from(input).filter(filter).transform(new IpAddressToIp());
}
private static class IpAddressToIp implements Function<IpAddress, String> {
@Override
public String apply(final IpAddress input) {
return input.address();
}
}
private static class IsPublicIpAddress implements Predicate<IpAddress> {
@Override
public boolean apply(IpAddress input) {
return input.publicAddress();
}
}
}

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.packet.compute.functions;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.jclouds.location.suppliers.all.JustProvider;
import org.jclouds.packet.domain.Facility;
import com.google.common.base.Function;
import static com.google.common.collect.Iterables.getOnlyElement;
/**
* Transforms an {@link Facility} to the jclouds portable model.
*/
@Singleton
public class FacilityToLocation implements Function<Facility, Location> {
private final JustProvider justProvider;
// allow us to lazy discover the provider of a resource
@Inject
FacilityToLocation(JustProvider justProvider) {
this.justProvider = justProvider;
}
@Override
public Location apply(final Facility facility) {
final LocationBuilder builder = new LocationBuilder();
builder.id(facility.code());
builder.description(facility.name());
builder.parent(getOnlyElement(justProvider.get()));
builder.scope(LocationScope.REGION);
return builder.build();
}
}

View File

@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.packet.compute.functions;
import javax.inject.Singleton;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.packet.domain.Distribution;
import org.jclouds.packet.domain.OperatingSystem;
import com.google.common.base.Function;
import static org.jclouds.compute.domain.OperatingSystem.builder;
/**
* Transforms an {@link OperatingSystem} to the jclouds portable model.
*/
@Singleton
public class OperatingSystemToImage implements Function<OperatingSystem, Image> {
@Override
public Image apply(final OperatingSystem input) {
ImageBuilder builder = new ImageBuilder();
builder.ids(input.slug());
builder.name(input.name());
builder.description(input.name());
builder.status(Image.Status.AVAILABLE);
builder.operatingSystem(builder()
.name(input.name())
.family(Distribution.fromValue(input.distribution()).osFamily())
.description(input.name())
.version(input.version())
.is64Bit(true)
.build());
return builder.build();
}
}

View File

@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.packet.compute.functions;
import javax.inject.Singleton;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.packet.domain.Plan;
import org.jclouds.packet.domain.Specs;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* Transforms an {@link Plan} to the jclouds portable model.
*/
@Singleton
public class PlanToHardware implements Function<Plan, Hardware> {
@Override
public Hardware apply(Plan plan) {
HardwareBuilder builder = new HardwareBuilder()
.ids(plan.slug())
.name(plan.name())
.hypervisor("none")
.processors(getProcessors(plan))
.ram(getMemory(plan))
.volumes(getVolumes(plan));
return builder.build();
}
private Integer getMemory(Plan plan) {
if (plan.specs() == null || plan.specs().drives() == null) return 0;
String total = plan.specs().memory().total();
if (total.endsWith("GB")) {
return Integer.valueOf(total.substring(0, total.length() - 2)) * 1024;
} else {
throw new IllegalArgumentException("Cannot parse memory: " + plan.specs().memory());
}
}
private Iterable<Volume> getVolumes(Plan plan) {
if (plan.specs() == null || plan.specs().drives() == null) return Lists.newArrayList();
return Iterables.transform(plan.specs().drives(), new Function<Specs.Drive, Volume>() {
@Override
public Volume apply(Specs.Drive drive) {
return new VolumeImpl(
drive.type(),
Volume.Type.LOCAL,
Float.parseFloat(drive.size().substring(0, drive.size().length() - 2)), null, true, false);
}
});
}
private Iterable<Processor> getProcessors(Plan plan) {
if (plan.specs() == null || plan.specs().cpus() == null) return Lists.newArrayList();
return Iterables.transform(plan.specs().cpus(), new Function<Specs.CPU, Processor>() {
@Override
public Processor apply(Specs.CPU input) {
// No cpu speed from Packet API, so assume more cores == faster
return new Processor(input.count(), input.count());
}
});
}
}

View File

@ -70,7 +70,7 @@ public abstract class Device {
public abstract List<IpAddress> ipAddresses();
public abstract List<ProvisioningEvent> provisioningEvents();
public abstract Plan plan();
public abstract String rootPassword();
@Nullable public abstract String rootPassword();
public abstract String userdata();
public abstract String href();

View File

@ -16,8 +16,6 @@
*/
package org.jclouds.packet.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Iterator;
import java.util.List;
@ -30,6 +28,8 @@ import com.google.auto.value.AutoValue;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Base class for all collections that return paginated results.
*/
@ -57,7 +57,7 @@ public abstract class PaginatedCollection<T> extends IterableWithMarker<T> {
protected PaginatedCollection(List<T> items, Meta meta) {
this.items = ImmutableList.copyOf(checkNotNull(items, "items cannot be null"));
this.meta = checkNotNull(meta, "meta cannot be null");
this.meta = meta;
}
public List<T> items() {
@ -66,7 +66,7 @@ public abstract class PaginatedCollection<T> extends IterableWithMarker<T> {
public Meta meta() {
return meta;
}
}
@Override
public Iterator<T> iterator() {
@ -75,7 +75,7 @@ public abstract class PaginatedCollection<T> extends IterableWithMarker<T> {
@Override
public Optional<Object> nextMarker() {
if (meta.next() == null) {
if (meta == null || meta.next() == null) {
return Optional.absent();
}
return Optional.fromNullable((Object) meta.next());