You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by ni...@apache.org on 2014/03/18 03:52:12 UTC
[19/20] fixing https://issues.apache.org/jira/browse/STRATOS-520 -
adding Openstack-nova module to dependencies
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
new file mode 100644
index 0000000..311d4ab
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
@@ -0,0 +1,286 @@
+/*
+ * 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.openstack.nova.v2_0.compute.config;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.jclouds.openstack.nova.v2_0.config.NovaProperties.AUTO_ALLOCATE_FLOATING_IPS;
+import static org.jclouds.openstack.nova.v2_0.config.NovaProperties.AUTO_GENERATE_KEYPAIRS;
+import static org.jclouds.openstack.nova.v2_0.config.NovaProperties.TIMEOUT_SECURITYGROUP_PRESENT;
+import static org.jclouds.util.Predicates2.retry;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.functions.IdentityFunction;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.openstack.nova.v2_0.compute.NovaComputeService;
+import org.jclouds.openstack.nova.v2_0.compute.NovaComputeServiceAdapter;
+import org.jclouds.openstack.nova.v2_0.compute.extensions.NovaImageExtension;
+import org.jclouds.openstack.nova.v2_0.compute.extensions.NovaSecurityGroupExtension;
+import org.jclouds.openstack.nova.v2_0.compute.functions.CreateSecurityGroupIfNeeded;
+import org.jclouds.openstack.nova.v2_0.compute.functions.FlavorInZoneToHardware;
+import org.jclouds.openstack.nova.v2_0.compute.functions.ImageInZoneToImage;
+import org.jclouds.openstack.nova.v2_0.compute.functions.ImageToOperatingSystem;
+import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupInZoneToSecurityGroup;
+import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupToSecurityGroup;
+import org.jclouds.openstack.nova.v2_0.compute.functions.OrphanedGroupsByZoneId;
+import org.jclouds.openstack.nova.v2_0.compute.functions.SecurityGroupRuleToIpPermission;
+import org.jclouds.openstack.nova.v2_0.compute.functions.ServerInZoneToNodeMetadata;
+import org.jclouds.openstack.nova.v2_0.compute.loaders.CreateUniqueKeyPair;
+import org.jclouds.openstack.nova.v2_0.compute.loaders.FindSecurityGroupOrCreate;
+import org.jclouds.openstack.nova.v2_0.compute.loaders.LoadFloatingIpsForInstance;
+import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
+import org.jclouds.openstack.nova.v2_0.compute.strategy.ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet;
+import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
+import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
+import org.jclouds.openstack.nova.v2_0.domain.Server;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.FlavorInZone;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ImageInZone;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ServerInZone;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
+import org.jclouds.openstack.nova.v2_0.predicates.FindSecurityGroupWithNameAndReturnTrue;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Provides;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+
+/**
+ * Module for building a compute service context for Nova
+ *
+ * @author Matt Stephenson
+ */
+public class NovaComputeServiceContextModule extends
+ ComputeServiceAdapterContextModule<ServerInZone, FlavorInZone, ImageInZone, Location> {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void configure() {
+ super.configure();
+ bind(new TypeLiteral<ComputeServiceAdapter<ServerInZone, FlavorInZone, ImageInZone, Location>>() {
+ }).to(NovaComputeServiceAdapter.class);
+
+ bind(ComputeService.class).to(NovaComputeService.class);
+
+ bind(new TypeLiteral<Function<ServerInZone, NodeMetadata>>() {
+ }).to(ServerInZoneToNodeMetadata.class);
+
+ bind(new TypeLiteral<Function<SecurityGroupRule, IpPermission>>() {
+ }).to(SecurityGroupRuleToIpPermission.class);
+
+ bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup>>() {
+ }).to(NovaSecurityGroupToSecurityGroup.class);
+
+ bind(new TypeLiteral<Function<SecurityGroupInZone, SecurityGroup>>() {
+ }).to(NovaSecurityGroupInZoneToSecurityGroup.class);
+
+ bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, Multimap<String, String>>>() {
+ }).to(OrphanedGroupsByZoneId.class);
+
+ bind(new TypeLiteral<Function<ImageInZone, Image>>() {
+ }).to(ImageInZoneToImage.class);
+ bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v2_0.domain.Image, OperatingSystem>>() {
+ }).to(ImageToOperatingSystem.class);
+
+ bind(new TypeLiteral<Function<FlavorInZone, Hardware>>() {
+ }).to(FlavorInZoneToHardware.class);
+
+ // we aren't converting location from a provider-specific type
+ bind(new TypeLiteral<Function<Location, Location>>() {
+ }).to(Class.class.cast(IdentityFunction.class));
+
+ bind(TemplateOptions.class).to(NovaTemplateOptions.class);
+
+ bind(new TypeLiteral<CacheLoader<ZoneAndId, Iterable<? extends FloatingIP>>>() {
+ }).annotatedWith(Names.named("FLOATINGIP")).to(LoadFloatingIpsForInstance.class);
+
+ bind(new TypeLiteral<Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone>>() {
+ }).to(CreateSecurityGroupIfNeeded.class);
+
+ bind(new TypeLiteral<CacheLoader<ZoneAndName, SecurityGroupInZone>>() {
+ }).to(FindSecurityGroupOrCreate.class);
+
+ bind(CreateNodesWithGroupEncodedIntoNameThenAddToSet.class).to(
+ ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.class);
+
+ bind(new TypeLiteral<CacheLoader<ZoneAndName, KeyPair>>() {
+ }).to(CreateUniqueKeyPair.class);
+
+ bind(new TypeLiteral<ImageExtension>() {
+ }).to(NovaImageExtension.class);
+
+ bind(new TypeLiteral<SecurityGroupExtension>() {
+ }).to(NovaSecurityGroupExtension.class);
+ }
+
+ @Override
+ protected TemplateOptions provideTemplateOptions(Injector injector, TemplateOptions options) {
+ return options.as(NovaTemplateOptions.class)
+ .autoAssignFloatingIp(injector.getInstance(
+ Key.get(boolean.class, Names.named(AUTO_ALLOCATE_FLOATING_IPS))))
+ .generateKeyPair(injector.getInstance(
+ Key.get(boolean.class, Names.named(AUTO_GENERATE_KEYPAIRS))));
+ }
+
+ @Provides
+ @Singleton
+ @Named("FLOATINGIP")
+ protected LoadingCache<ZoneAndId, Iterable<? extends FloatingIP>> instanceToFloatingIps(
+ @Named("FLOATINGIP") CacheLoader<ZoneAndId, Iterable<? extends FloatingIP>> in) {
+ return CacheBuilder.newBuilder().build(in);
+ }
+
+ @Provides
+ @Singleton
+ protected LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupMap(
+ CacheLoader<ZoneAndName, SecurityGroupInZone> in) {
+ return CacheBuilder.newBuilder().build(in);
+ }
+
+ @Override
+ protected Map<OsFamily, LoginCredentials> osFamilyToCredentials(Injector injector) {
+ return ImmutableMap.of(OsFamily.WINDOWS, LoginCredentials.builder().user("Administrator").build(),
+ OsFamily.UBUNTU, LoginCredentials.builder().user("ubuntu").build());
+ }
+
+ @Provides
+ @Singleton
+ @Named("SECURITYGROUP_PRESENT")
+ protected Predicate<AtomicReference<ZoneAndName>> securityGroupEventualConsistencyDelay(
+ FindSecurityGroupWithNameAndReturnTrue in,
+ @Named(TIMEOUT_SECURITYGROUP_PRESENT) long msDelay) {
+ return retry(in, msDelay, 100l, MILLISECONDS);
+ }
+
+ @Provides
+ @Singleton
+ protected LoadingCache<ZoneAndName, KeyPair> keyPairMap(
+ CacheLoader<ZoneAndName, KeyPair> in) {
+ return CacheBuilder.newBuilder().build(in);
+ }
+
+ @Provides
+ @Singleton
+ protected Supplier<Map<String, Location>> createLocationIndexedById(
+ @Memoized Supplier<Set<? extends Location>> locations) {
+ return Suppliers.compose(new Function<Set<? extends Location>, Map<String, Location>>() {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Map<String, Location> apply(Set<? extends Location> arg0) {
+ // TODO: find a nice way to get rid of this cast.
+ Iterable<Location> locations = (Iterable<Location>) arg0;
+ return Maps.uniqueIndex(locations, new Function<Location, String>() {
+
+ @Override
+ public String apply(Location arg0) {
+ return arg0.getId();
+ }
+
+ });
+ }
+ }, locations);
+
+ }
+
+ @VisibleForTesting
+ public static final Map<Server.Status, NodeMetadata.Status> toPortableNodeStatus = ImmutableMap
+ .<Server.Status, NodeMetadata.Status> builder().put(Server.Status.ACTIVE, NodeMetadata.Status.RUNNING)//
+ .put(Server.Status.SUSPENDED, NodeMetadata.Status.SUSPENDED)//
+ .put(Server.Status.DELETED, NodeMetadata.Status.TERMINATED)//
+ .put(Server.Status.PAUSED, NodeMetadata.Status.SUSPENDED)//
+ .put(Server.Status.RESIZE, NodeMetadata.Status.PENDING)//
+ .put(Server.Status.VERIFY_RESIZE, NodeMetadata.Status.PENDING)//
+ .put(Server.Status.REVERT_RESIZE, NodeMetadata.Status.PENDING)//
+ .put(Server.Status.BUILD, NodeMetadata.Status.PENDING)//
+ .put(Server.Status.PASSWORD, NodeMetadata.Status.PENDING)//
+ .put(Server.Status.REBUILD, NodeMetadata.Status.PENDING)//
+ .put(Server.Status.ERROR, NodeMetadata.Status.ERROR)//
+ .put(Server.Status.REBOOT, NodeMetadata.Status.PENDING)//
+ .put(Server.Status.HARD_REBOOT, NodeMetadata.Status.PENDING)//
+ .put(Server.Status.UNKNOWN, NodeMetadata.Status.UNRECOGNIZED)//
+ .put(Server.Status.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).build();
+
+ @Singleton
+ @Provides
+ protected Map<Server.Status, NodeMetadata.Status> toPortableNodeStatus() {
+ return toPortableNodeStatus;
+ }
+
+ @VisibleForTesting
+ public static final Map<org.jclouds.openstack.nova.v2_0.domain.Image.Status, Image.Status> toPortableImageStatus = ImmutableMap
+ .<org.jclouds.openstack.nova.v2_0.domain.Image.Status, Image.Status> builder()
+ .put(org.jclouds.openstack.nova.v2_0.domain.Image.Status.ACTIVE, Image.Status.AVAILABLE)
+ .put(org.jclouds.openstack.nova.v2_0.domain.Image.Status.SAVING, Image.Status.PENDING)
+ .put(org.jclouds.openstack.nova.v2_0.domain.Image.Status.DELETED, Image.Status.DELETED)
+ .put(org.jclouds.openstack.nova.v2_0.domain.Image.Status.ERROR, Image.Status.ERROR)
+ .put(org.jclouds.openstack.nova.v2_0.domain.Image.Status.UNKNOWN, Image.Status.UNRECOGNIZED)
+ .put(org.jclouds.openstack.nova.v2_0.domain.Image.Status.UNRECOGNIZED, Image.Status.UNRECOGNIZED).build();
+
+ @Singleton
+ @Provides
+ protected Map<org.jclouds.openstack.nova.v2_0.domain.Image.Status, Image.Status> toPortableImageStatus() {
+ return toPortableImageStatus;
+ }
+
+ @Override
+ protected Optional<ImageExtension> provideImageExtension(Injector i) {
+ return Optional.of(i.getInstance(ImageExtension.class));
+ }
+
+ @Override
+ protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) {
+ return Optional.of(i.getInstance(SecurityGroupExtension.class));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java
new file mode 100644
index 0000000..f8fd4d9
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java
@@ -0,0 +1,140 @@
+/*
+ * 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.openstack.nova.v2_0.compute.extensions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.find;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
+import static org.jclouds.location.predicates.LocationPredicates.idEquals;
+
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.CloneImageTemplate;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.ImageTemplate;
+import org.jclouds.compute.domain.ImageTemplateBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.nova.v2_0.NovaApi;
+import org.jclouds.openstack.nova.v2_0.domain.Server;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.util.concurrent.Atomics;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+
+/**
+ * Nova implementation of {@link ImageExtension}
+ *
+ * @author David Alves
+ *
+ */
+@Singleton
+public class NovaImageExtension implements ImageExtension {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final NovaApi novaApi;
+ private final ListeningExecutorService userExecutor;
+ private final Supplier<Set<? extends Location>> locations;
+ private final Predicate<AtomicReference<Image>> imageAvailablePredicate;
+
+ @Inject
+ public NovaImageExtension(NovaApi novaApi, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
+ @Memoized Supplier<Set<? extends Location>> locations,
+ @Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<AtomicReference<Image>> imageAvailablePredicate) {
+ this.novaApi = checkNotNull(novaApi, "novaApi");
+ this.userExecutor = checkNotNull(userExecutor, "userExecutor");
+ this.locations = checkNotNull(locations, "locations");
+ this.imageAvailablePredicate = checkNotNull(imageAvailablePredicate, "imageAvailablePredicate");
+ }
+
+ @Override
+ public ImageTemplate buildImageTemplateFromNode(String name, final String id) {
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
+ Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).get(zoneAndId.getId());
+ if (server == null)
+ throw new NoSuchElementException("Cannot find server with id: " + zoneAndId);
+ CloneImageTemplate template = new ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(name).build();
+ return template;
+ }
+
+ @Override
+ public ListenableFuture<Image> createImage(ImageTemplate template) {
+ checkState(template instanceof CloneImageTemplate,
+ " openstack-nova only supports creating images through cloning.");
+ CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
+ ZoneAndId sourceImageZoneAndId = ZoneAndId.fromSlashEncoded(cloneTemplate.getSourceNodeId());
+
+ String newImageId = novaApi.getServerApiForZone(sourceImageZoneAndId.getZone()).createImageFromServer(
+ cloneTemplate.getName(), sourceImageZoneAndId.getId());
+
+ final ZoneAndId targetImageZoneAndId = ZoneAndId.fromZoneAndId(sourceImageZoneAndId.getZone(), newImageId);
+
+ logger.info(">> Registered new Image %s, waiting for it to become available.", newImageId);
+
+ final AtomicReference<Image> image = Atomics.newReference(new ImageBuilder()
+ .location(find(locations.get(), idEquals(targetImageZoneAndId.getZone())))
+ .id(targetImageZoneAndId.slashEncode())
+ .providerId(targetImageZoneAndId.getId())
+ .description(cloneTemplate.getName())
+ .operatingSystem(OperatingSystem.builder().description(cloneTemplate.getName()).build())
+ .status(Image.Status.PENDING).build());
+
+ return userExecutor.submit(new Callable<Image>() {
+ @Override
+ public Image call() throws Exception {
+ if (imageAvailablePredicate.apply(image))
+ return image.get();
+ // TODO: get rid of the expectation that the image will be available, as it is very brittle
+ throw new UncheckedTimeoutException("Image was not created within the time limit: " + image.get());
+ }
+ });
+ }
+
+ @Override
+ public boolean deleteImage(String id) {
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
+ try {
+ this.novaApi.getImageApiForZone(zoneAndId.getZone()).delete(zoneAndId.getId());
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
new file mode 100644
index 0000000..8b36fc9
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
@@ -0,0 +1,373 @@
+/*
+ * 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.openstack.nova.v2_0.compute.extensions;
+
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Predicates.and;
+import static com.google.common.base.Predicates.notNull;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.transform;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.nameIn;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleCidr;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleEndPort;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleGroup;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleProtocol;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.ruleStartPort;
+
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.Constants;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.domain.Location;
+import org.jclouds.location.Zone;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.jclouds.openstack.nova.v2_0.NovaApi;
+import org.jclouds.openstack.nova.v2_0.domain.Ingress;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
+import org.jclouds.openstack.nova.v2_0.domain.ServerWithSecurityGroups;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
+import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
+import org.jclouds.openstack.nova.v2_0.extensions.ServerWithSecurityGroupsApi;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Supplier;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+/**
+ * An extension to compute service to allow for the manipulation of {@link org.jclouds.compute.domain.SecurityGroup}s. Implementation
+ * is optional by providers.
+ *
+ * @author Andrew Bayer
+ */
+public class NovaSecurityGroupExtension implements SecurityGroupExtension {
+
+ protected final NovaApi api;
+ protected final ListeningExecutorService userExecutor;
+ protected final Supplier<Set<String>> zoneIds;
+ protected final Function<SecurityGroupInZone, SecurityGroup> groupConverter;
+ protected final LoadingCache<ZoneAndName, SecurityGroupInZone> groupCreator;
+ protected final GroupNamingConvention.Factory namingConvention;
+
+ @Inject
+ public NovaSecurityGroupExtension(NovaApi api,
+ @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
+ @Zone Supplier<Set<String>> zoneIds,
+ Function<SecurityGroupInZone, SecurityGroup> groupConverter,
+ LoadingCache<ZoneAndName, SecurityGroupInZone> groupCreator,
+ GroupNamingConvention.Factory namingConvention) {
+
+ this.api = checkNotNull(api, "api");
+ this.userExecutor = checkNotNull(userExecutor, "userExecutor");
+ this.zoneIds = checkNotNull(zoneIds, "zoneIds");
+ this.groupConverter = checkNotNull(groupConverter, "groupConverter");
+ this.groupCreator = checkNotNull(groupCreator, "groupCreator");
+ this.namingConvention = checkNotNull(namingConvention, "namingConvention");
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroups() {
+ Iterable<? extends SecurityGroupInZone> rawGroups = pollSecurityGroups();
+ Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
+ groupConverter);
+ return ImmutableSet.copyOf(groups);
+ }
+
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsInLocation(final Location location) {
+ String zone = location.getId();
+ if (zone == null) {
+ return ImmutableSet.of();
+ }
+ return listSecurityGroupsInLocation(zone);
+ }
+
+ public Set<SecurityGroup> listSecurityGroupsInLocation(String zone) {
+ Iterable<? extends SecurityGroupInZone> rawGroups = pollSecurityGroupsByZone(zone);
+ Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
+ groupConverter);
+ return ImmutableSet.copyOf(groups);
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(checkNotNull(id, "id"));
+ String zone = zoneAndId.getZone();
+ String instanceId = zoneAndId.getId();
+
+ Optional<? extends ServerWithSecurityGroupsApi> serverApi = api.getServerWithSecurityGroupsExtensionForZone(zone);
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!serverApi.isPresent() || !sgApi.isPresent()) {
+ return ImmutableSet.of();
+ }
+
+ ServerWithSecurityGroups instance = serverApi.get().get(instanceId);
+ if (instance == null) {
+ return ImmutableSet.of();
+ }
+
+ Set<String> groupNames = instance.getSecurityGroupNames();
+ Set<? extends SecurityGroupInZone> rawGroups =
+ sgApi.get().list().filter(nameIn(groupNames)).transform(groupToGroupInZone(zone)).toSet();
+
+ return ImmutableSet.copyOf(transform(filter(rawGroups, notNull()), groupConverter));
+ }
+
+ @Override
+ public SecurityGroup getSecurityGroupById(String id) {
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(checkNotNull(id, "id"));
+ String zone = zoneAndId.getZone();
+ String groupId = zoneAndId.getId();
+
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!sgApi.isPresent()) {
+ return null;
+ }
+
+ SecurityGroupInZone rawGroup = new SecurityGroupInZone(sgApi.get().get(groupId), zone);
+
+ return groupConverter.apply(rawGroup);
+ }
+
+ @Override
+ public SecurityGroup createSecurityGroup(String name, Location location) {
+ String zone = location.getId();
+ if (zone == null) {
+ return null;
+ }
+ return createSecurityGroup(name, zone);
+ }
+
+ public SecurityGroup createSecurityGroup(String name, String zone) {
+ String markerGroup = namingConvention.create().sharedNameForGroup(name);
+ ZoneSecurityGroupNameAndPorts zoneAndName = new ZoneSecurityGroupNameAndPorts(zone, markerGroup, ImmutableSet.<Integer> of());
+
+ SecurityGroupInZone rawGroup = groupCreator.apply(zoneAndName);
+ return groupConverter.apply(rawGroup);
+ }
+
+ @Override
+ public boolean removeSecurityGroup(String id) {
+ checkNotNull(id, "id");
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
+ String zone = zoneAndId.getZone();
+ String groupId = zoneAndId.getId();
+
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!sgApi.isPresent()) {
+ return false;
+ }
+
+ if (sgApi.get().get(groupId) == null) {
+ return false;
+ }
+
+ sgApi.get().delete(groupId);
+ // TODO: test this clear happens
+ groupCreator.invalidate(new ZoneSecurityGroupNameAndPorts(zone, groupId, ImmutableSet.<Integer> of()));
+ return true;
+ }
+
+ @Override
+ public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
+ String zone = group.getLocation().getId();
+ ZoneAndId groupZoneAndId = ZoneAndId.fromSlashEncoded(group.getId());
+ String id = groupZoneAndId.getId();
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!sgApi.isPresent()) {
+ return null;
+ }
+
+ if (ipPermission.getCidrBlocks().size() > 0) {
+ for (String cidr : ipPermission.getCidrBlocks()) {
+ sgApi.get().createRuleAllowingCidrBlock(id,
+ Ingress.builder()
+ .ipProtocol(ipPermission.getIpProtocol())
+ .fromPort(ipPermission.getFromPort())
+ .toPort(ipPermission.getToPort())
+ .build(),
+ cidr);
+ }
+ }
+
+ if (ipPermission.getGroupIds().size() > 0) {
+ for (String zoneAndGroupRaw : ipPermission.getGroupIds()) {
+ ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(zoneAndGroupRaw);
+ String groupId = zoneAndId.getId();
+ sgApi.get().createRuleAllowingSecurityGroupId(id,
+ Ingress.builder()
+ .ipProtocol(ipPermission.getIpProtocol())
+ .fromPort(ipPermission.getFromPort())
+ .toPort(ipPermission.getToPort())
+ .build(),
+ groupId);
+ }
+ }
+
+ return getSecurityGroupById(ZoneAndId.fromZoneAndId(zone, id).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
+ Multimap<String, String> tenantIdGroupNamePairs,
+ Iterable<String> ipRanges,
+ Iterable<String> groupIds, SecurityGroup group) {
+ IpPermission.Builder permBuilder = IpPermission.builder();
+ permBuilder.ipProtocol(protocol);
+ permBuilder.fromPort(startPort);
+ permBuilder.toPort(endPort);
+ permBuilder.tenantIdGroupNamePairs(tenantIdGroupNamePairs);
+ permBuilder.cidrBlocks(ipRanges);
+ permBuilder.groupIds(groupIds);
+
+ return addIpPermission(permBuilder.build(), group);
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
+ String zone = group.getLocation().getId();
+ ZoneAndId groupZoneAndId = ZoneAndId.fromSlashEncoded(group.getId());
+ String id = groupZoneAndId.getId();
+
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+
+ if (!sgApi.isPresent()) {
+ return null;
+ }
+
+ org.jclouds.openstack.nova.v2_0.domain.SecurityGroup securityGroup = sgApi.get().get(id);
+
+ if (ipPermission.getCidrBlocks().size() > 0) {
+ for (String cidr : ipPermission.getCidrBlocks()) {
+ for (SecurityGroupRule rule : filter(securityGroup.getRules(),
+ and(ruleCidr(cidr), ruleProtocol(ipPermission.getIpProtocol()),
+ ruleStartPort(ipPermission.getFromPort()),
+ ruleEndPort(ipPermission.getToPort())))) {
+ sgApi.get().deleteRule(rule.getId());
+ }
+ }
+ }
+
+ if (ipPermission.getGroupIds().size() > 0) {
+ for (String groupId : ipPermission.getGroupIds()) {
+ for (SecurityGroupRule rule : filter(securityGroup.getRules(),
+ and(ruleGroup(groupId), ruleProtocol(ipPermission.getIpProtocol()),
+ ruleStartPort(ipPermission.getFromPort()),
+ ruleEndPort(ipPermission.getToPort())))) {
+ sgApi.get().deleteRule(rule.getId());
+ }
+
+ }
+ }
+
+ return getSecurityGroupById(ZoneAndId.fromZoneAndId(zone, id).slashEncode());
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
+ Multimap<String, String> tenantIdGroupNamePairs,
+ Iterable<String> ipRanges,
+ Iterable<String> groupIds, SecurityGroup group) {
+ IpPermission.Builder permBuilder = IpPermission.builder();
+ permBuilder.ipProtocol(protocol);
+ permBuilder.fromPort(startPort);
+ permBuilder.toPort(endPort);
+ permBuilder.tenantIdGroupNamePairs(tenantIdGroupNamePairs);
+ permBuilder.cidrBlocks(ipRanges);
+ permBuilder.groupIds(groupIds);
+
+ return removeIpPermission(permBuilder.build(), group);
+ }
+
+ @Override
+ public boolean supportsTenantIdGroupNamePairs() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsTenantIdGroupIdPairs() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsGroupIds() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsPortRangesForGroups() {
+ return false;
+ }
+
+ protected Iterable<? extends SecurityGroupInZone> pollSecurityGroups() {
+ Iterable<? extends Set<? extends SecurityGroupInZone>> groups
+ = transform(zoneIds.get(), allSecurityGroupsInZone());
+
+ return concat(groups);
+ }
+
+
+ protected Iterable<? extends SecurityGroupInZone> pollSecurityGroupsByZone(String zone) {
+ return allSecurityGroupsInZone().apply(zone);
+ }
+
+ protected Function<String, Set<? extends SecurityGroupInZone>> allSecurityGroupsInZone() {
+ return new Function<String, Set<? extends SecurityGroupInZone>>() {
+
+ @Override
+ public Set<? extends SecurityGroupInZone> apply(final String from) {
+ Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(from);
+
+ if (!sgApi.isPresent()) {
+ return ImmutableSet.of();
+ }
+
+
+ return sgApi.get().list().transform(groupToGroupInZone(from)).toSet();
+ }
+
+ };
+ }
+
+ protected Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroupInZone> groupToGroupInZone(final String zone) {
+ return new Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroupInZone>() {
+ @Override
+ public SecurityGroupInZone apply(org.jclouds.openstack.nova.v2_0.domain.SecurityGroup group) {
+ return new SecurityGroupInZone(group, zone);
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
new file mode 100644
index 0000000..f7c18ee
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
@@ -0,0 +1,112 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.nova.v2_0.NovaApi;
+import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
+import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
+import org.jclouds.rest.InsufficientResourcesException;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+/**
+ * A function for adding and allocating an ip to a node
+ *
+ * @author Adrian Cole
+ */
+public class AllocateAndAddFloatingIpToNode implements
+ Function<AtomicReference<NodeMetadata>, AtomicReference<NodeMetadata>> {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final Predicate<AtomicReference<NodeMetadata>> nodeRunning;
+ private final NovaApi novaApi;
+ private final LoadingCache<ZoneAndId, Iterable<? extends FloatingIP>> floatingIpCache;
+
+ @Inject
+ public AllocateAndAddFloatingIpToNode(@Named(TIMEOUT_NODE_RUNNING) Predicate<AtomicReference<NodeMetadata>> nodeRunning,
+ NovaApi novaApi, @Named("FLOATINGIP") LoadingCache<ZoneAndId, Iterable<? extends FloatingIP>> floatingIpCache) {
+ this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning");
+ this.novaApi = checkNotNull(novaApi, "novaApi");
+ this.floatingIpCache = checkNotNull(floatingIpCache, "floatingIpCache");
+ }
+
+ @Override
+ public AtomicReference<NodeMetadata> apply(AtomicReference<NodeMetadata> input) {
+ checkState(nodeRunning.apply(input), "node never achieved state running %s", input.get());
+ NodeMetadata node = input.get();
+ // node's location is a host
+ String zoneId = node.getLocation().getParent().getId();
+ FloatingIPApi floatingIpApi = novaApi.getFloatingIPExtensionForZone(zoneId).get();
+
+ FloatingIP ip = null;
+ try {
+ logger.debug(">> allocating or reassigning floating ip for node(%s)", node.getId());
+ ip = floatingIpApi.create();
+ } catch (InsufficientResourcesException e) {
+ logger.trace("<< [%s] allocating a new floating ip for node(%s)", e.getMessage(), node.getId());
+ logger.trace(">> searching for existing, unassigned floating ip for node(%s)", node.getId());
+ ArrayList<FloatingIP> unassignedIps = Lists.newArrayList(Iterables.filter(floatingIpApi.list(),
+ new Predicate<FloatingIP>() {
+
+ @Override
+ public boolean apply(FloatingIP arg0) {
+ return arg0.getFixedIp() == null;
+ }
+
+ }));
+ // try to prevent multiple parallel launches from choosing the same ip.
+ Collections.shuffle(unassignedIps);
+ ip = Iterables.getLast(unassignedIps);
+ }
+ logger.debug(">> adding floatingIp(%s) to node(%s)", ip.getIp(), node.getId());
+
+ floatingIpApi.addToServer(ip.getIp(), node.getProviderId());
+ input.set(NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip.getIp())).build());
+ floatingIpCache.invalidate(ZoneAndId.fromSlashEncoded(node.getId()));
+ return input;
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper("AllocateAndAddFloatingIpToNode").toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
new file mode 100644
index 0000000..6b5d519
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
@@ -0,0 +1,93 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.find;
+import static org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates.nameEquals;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpProtocol;
+import org.jclouds.openstack.nova.v2_0.NovaApi;
+import org.jclouds.openstack.nova.v2_0.domain.Ingress;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
+import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+@Singleton
+public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+ protected final NovaApi novaApi;
+
+ @Inject
+ public CreateSecurityGroupIfNeeded(NovaApi novaApi) {
+ this.novaApi = checkNotNull(novaApi, "novaApi");
+ }
+
+ @Override
+ public SecurityGroupInZone apply(ZoneSecurityGroupNameAndPorts zoneSecurityGroupNameAndPorts) {
+ checkNotNull(zoneSecurityGroupNameAndPorts, "zoneSecurityGroupNameAndPorts");
+
+ String zoneId = zoneSecurityGroupNameAndPorts.getZone();
+ Optional<? extends SecurityGroupApi> api = novaApi.getSecurityGroupExtensionForZone(zoneId);
+ checkArgument(api.isPresent(), "Security groups are required, but the extension is not availablein zone %s!", zoneId);
+ logger.debug(">> creating securityGroup %s", zoneSecurityGroupNameAndPorts);
+ try {
+
+ SecurityGroup securityGroup = api.get().createWithDescription(
+ zoneSecurityGroupNameAndPorts.getName(), zoneSecurityGroupNameAndPorts.getName());
+
+ logger.debug("<< created securityGroup(%s)", securityGroup);
+ for (int port : zoneSecurityGroupNameAndPorts.getPorts()) {
+ authorizeGroupToItselfAndAllIPsToTCPPort(api.get(), securityGroup, port);
+ }
+ return new SecurityGroupInZone(api.get().get(securityGroup.getId()), zoneId);
+ } catch (IllegalStateException e) {
+ logger.trace("<< trying to find securityGroup(%s): %s", zoneSecurityGroupNameAndPorts, e.getMessage());
+ SecurityGroup group = find(api.get().list(), nameEquals(zoneSecurityGroupNameAndPorts
+ .getName()));
+ logger.debug("<< reused securityGroup(%s)", group.getId());
+ return new SecurityGroupInZone(group, zoneId);
+ }
+ }
+
+ private void authorizeGroupToItselfAndAllIPsToTCPPort(SecurityGroupApi securityGroupApi,
+ SecurityGroup securityGroup, int port) {
+ logger.debug(">> authorizing securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);
+ securityGroupApi.createRuleAllowingCidrBlock(securityGroup.getId(), Ingress.builder().ipProtocol(
+ IpProtocol.TCP).fromPort(port).toPort(port).build(), "0.0.0.0/0");
+ logger.debug("<< authorized securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port);
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInZoneToHardware.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInZoneToHardware.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInZoneToHardware.java
new file mode 100644
index 0000000..160944b
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInZoneToHardware.java
@@ -0,0 +1,60 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.internal.VolumeImpl;
+import org.jclouds.domain.Location;
+import org.jclouds.openstack.nova.v2_0.domain.Flavor;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.FlavorInZone;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+
+/**
+ * A function for transforming the nova specific FlavorInZone object to the generic Hardware object.
+ *
+ * @author Matt Stephenson
+ */
+public class FlavorInZoneToHardware implements Function<FlavorInZone, Hardware> {
+
+ private final Supplier<Map<String, Location>> locationIndex;
+
+ @Inject
+ public FlavorInZoneToHardware(Supplier<Map<String, Location>> locationIndex) {
+ this.locationIndex = checkNotNull(locationIndex, "locationIndex");
+ }
+
+ @Override
+ public Hardware apply(FlavorInZone flavorInZone) {
+ Location location = locationIndex.get().get(flavorInZone.getZone());
+ checkState(location != null, "location %s not in locationIndex: %s", flavorInZone.getZone(), locationIndex.get());
+ Flavor flavor = flavorInZone.getFlavor();
+ return new HardwareBuilder().id(flavorInZone.slashEncode()).providerId(flavor.getId()).name(flavor.getName())
+ .ram(flavor.getRam()).processor(new Processor(flavor.getVcpus(), 1.0)).volume(
+ new VolumeImpl(Float.valueOf(flavor.getDisk()), true, true)).location(location).build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageInZoneToImage.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageInZoneToImage.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageInZoneToImage.java
new file mode 100644
index 0000000..109da29
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageInZoneToImage.java
@@ -0,0 +1,70 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.domain.Location;
+import org.jclouds.openstack.nova.v2_0.domain.Image.Status;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ImageInZone;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Supplier;
+
+/**
+ * A function for transforming a nova-specific Image into a generic Image object.
+ *
+ * @author Matt Stephenson
+ */
+public class ImageInZoneToImage implements Function<ImageInZone, Image> {
+ private final Map<Status, org.jclouds.compute.domain.Image.Status> toPortableImageStatus;
+ private final Function<org.jclouds.openstack.nova.v2_0.domain.Image, OperatingSystem> imageToOs;
+ private final Supplier<Map<String, Location>> locationIndex;
+
+ @Inject
+ public ImageInZoneToImage(Map<org.jclouds.openstack.nova.v2_0.domain.Image.Status, Image.Status> toPortableImageStatus,
+ Function<org.jclouds.openstack.nova.v2_0.domain.Image, OperatingSystem> imageToOs,
+ Supplier<Map<String, Location>> locationIndex) {
+ this.toPortableImageStatus = checkNotNull(toPortableImageStatus, "toPortableImageStatus");
+ this.imageToOs = checkNotNull(imageToOs, "imageToOs");
+ this.locationIndex = checkNotNull(locationIndex, "locationIndex");
+ }
+
+ @Override
+ public Image apply(ImageInZone imageInZone) {
+ Location location = locationIndex.get().get(imageInZone.getZone());
+ checkState(location != null, "location %s not in locationIndex: %s", imageInZone.getZone(), locationIndex.get());
+ org.jclouds.openstack.nova.v2_0.domain.Image image = imageInZone.getImage();
+ return new ImageBuilder().id(imageInZone.slashEncode()).providerId(image.getId()).name(image.getName())
+ .userMetadata(image.getMetadata()).operatingSystem(imageToOs.apply(image)).description(image.getName())
+ .location(location).status(toPortableImageStatus.get(image.getStatus())).build();
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this).toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageToOperatingSystem.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageToOperatingSystem.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageToOperatingSystem.java
new file mode 100644
index 0000000..f26c4e0
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/ImageToOperatingSystem.java
@@ -0,0 +1,128 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.base.Predicates.containsPattern;
+import static com.google.common.base.Predicates.equalTo;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.collect.Iterables.any;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.find;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.util.ComputeServiceUtils;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.nova.v2_0.domain.Image;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+
+/**
+ * A function for transforming a nova specific Image into a generic OperatingSystem object.
+ *
+ * @author Matt Stephenson
+ */
+public class ImageToOperatingSystem implements Function<Image, OperatingSystem> {
+ public static final Pattern DEFAULT_PATTERN = Pattern.compile("(([^ ]*) ([0-9.]+) ?.*)");
+ // Windows Server 2008 R2 x64
+ public static final Pattern WINDOWS_PATTERN = Pattern.compile("Windows (.*) (x[86][64])");
+
+ @javax.annotation.Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final Map<OsFamily, Map<String, String>> osVersionMap;
+
+ @Inject
+ public ImageToOperatingSystem(Map<OsFamily, Map<String, String>> osVersionMap) {
+ this.osVersionMap = osVersionMap;
+ }
+
+ public OperatingSystem apply(final Image from) {
+ OsFamily osFamily = null;
+ String osVersion = null;
+
+ String imageName = Objects.firstNonNull(from.getName(), "unspecified");
+
+ boolean is64Bit = true;
+
+ if (imageName.indexOf("Windows") != -1) {
+ osFamily = OsFamily.WINDOWS;
+ Matcher matcher = WINDOWS_PATTERN.matcher(from.getName());
+ if (matcher.find()) {
+ osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(1), osVersionMap);
+ is64Bit = matcher.group(2).equals("x64");
+ }
+ } else {
+ if (imageName.contains("Red Hat EL")) {
+ osFamily = OsFamily.RHEL;
+ } else if (imageName.contains("Oracle EL")) {
+ osFamily = OsFamily.OEL;
+ } else {
+ final Iterable<String> imageNameParts = Splitter.on(CharMatcher.WHITESPACE).trimResults().split(
+ imageName.toLowerCase());
+
+ try {
+ osFamily = find(Arrays.asList(OsFamily.values()), new Predicate<OsFamily>() {
+ @Override
+ public boolean apply(OsFamily osFamily) {
+ return any(imageNameParts, equalTo(osFamily.name().toLowerCase()));
+ }
+ });
+ } catch (NoSuchElementException e) {
+ String ubuntuVersion = startsWithUbuntuVersion(imageNameParts);
+ if (ubuntuVersion != null) {
+ osFamily = OsFamily.UBUNTU;
+ osVersion = ubuntuVersion;
+ } else {
+ logger.trace("could not parse operating system family for image(%s): %s", from.getId(), imageNameParts);
+ osFamily = OsFamily.UNRECOGNIZED;
+ }
+ }
+ }
+ Matcher matcher = DEFAULT_PATTERN.matcher(imageName);
+ if (matcher.find() && matcher.groupCount() >= 3) {
+ osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(3), osVersionMap);
+ }
+ }
+ return new OperatingSystem(osFamily, imageName, osVersion, null, imageName, is64Bit);
+ }
+
+ String startsWithUbuntuVersion(final Iterable<String> imageNameParts) {
+ Map<String, String> ubuntuVersions = osVersionMap.get(OsFamily.UBUNTU);
+ for (String ubuntuKey : filter(ubuntuVersions.keySet(), not(equalTo("")))) {
+ if (any(imageNameParts, containsPattern("^" + ubuntuKey + ".*"))) {
+ return ubuntuVersions.get(ubuntuKey);
+ }
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroup.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroup.java
new file mode 100644
index 0000000..fc772df
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupInZoneToSecurityGroup.java
@@ -0,0 +1,75 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Map;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.inject.Inject;
+
+
+/**
+ * A function for transforming a Nova-specific SecurityGroup into a generic
+ * SecurityGroup object.
+ *
+ * @author Andrew Bayer
+ */
+@Singleton
+public class NovaSecurityGroupInZoneToSecurityGroup implements Function<SecurityGroupInZone, SecurityGroup> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ protected final Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup> baseConverter;
+ protected final Supplier<Map<String, Location>> locationIndex;
+
+ @Inject
+ public NovaSecurityGroupInZoneToSecurityGroup(Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup> baseConverter,
+ Supplier<Map<String, Location>> locationIndex) {
+ this.baseConverter = checkNotNull(baseConverter, "baseConverter");
+ this.locationIndex = checkNotNull(locationIndex, "locationIndex");
+ }
+
+ @Override
+ public SecurityGroup apply(SecurityGroupInZone group) {
+ SecurityGroupBuilder builder = SecurityGroupBuilder.fromSecurityGroup(baseConverter.apply(group.getSecurityGroup()));
+
+ Location zone = locationIndex.get().get(group.getZone());
+ checkState(zone != null, "location %s not in locationIndex: %s", group.getZone(), locationIndex.get());
+
+ builder.location(zone);
+
+ builder.id(group.getZone() + "/" + group.getSecurityGroup().getId());
+
+ return builder.build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java
new file mode 100644
index 0000000..d39f849
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/NovaSecurityGroupToSecurityGroup.java
@@ -0,0 +1,69 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.collect.Iterables.transform;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
+
+import com.google.common.base.Function;
+import com.google.inject.Inject;
+
+
+/**
+ * A function for transforming a Nova-specific SecurityGroup into a generic
+ * SecurityGroup object.
+ *
+ * @author Andrew Bayer
+ */
+@Singleton
+public class NovaSecurityGroupToSecurityGroup implements Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ protected Function<SecurityGroupRule,IpPermission> ruleToPermission;
+
+ @Inject
+ public NovaSecurityGroupToSecurityGroup(Function<SecurityGroupRule,IpPermission> ruleToPermission) {
+ this.ruleToPermission = ruleToPermission;
+ }
+
+ @Override
+ public SecurityGroup apply(org.jclouds.openstack.nova.v2_0.domain.SecurityGroup group) {
+ SecurityGroupBuilder builder = new SecurityGroupBuilder();
+
+ builder.id(group.getId());
+ builder.providerId(group.getId());
+ builder.ownerId(group.getTenantId());
+ builder.name(group.getName());
+ if (group.getRules() != null) {
+ builder.ipPermissions(transform(group.getRules(), ruleToPermission));
+ }
+
+ return builder.build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/OrphanedGroupsByZoneId.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/OrphanedGroupsByZoneId.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/OrphanedGroupsByZoneId.java
new file mode 100644
index 0000000..4993f0c
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/OrphanedGroupsByZoneId.java
@@ -0,0 +1,77 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Sets.filter;
+
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.predicates.NodePredicates;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.openstack.nova.v2_0.compute.predicates.AllNodesInGroupTerminated;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+public class OrphanedGroupsByZoneId implements Function<Set<? extends NodeMetadata>, Multimap<String, String>> {
+ private final Predicate<ZoneAndName> allNodesInGroupTerminated;
+
+ @Inject
+ protected OrphanedGroupsByZoneId(ComputeService computeService) {
+ this(new AllNodesInGroupTerminated(checkNotNull(computeService, "computeService")));
+ }
+
+ @VisibleForTesting
+ OrphanedGroupsByZoneId(Predicate<ZoneAndName> allNodesInGroupTerminated) {
+ this.allNodesInGroupTerminated = checkNotNull(allNodesInGroupTerminated, "allNodesInGroupTerminated");
+ }
+
+ public Multimap<String, String> apply(Set<? extends NodeMetadata> deadNodes) {
+ Iterable<? extends NodeMetadata> nodesWithGroup = filter(deadNodes, NodePredicates.hasGroup());
+ Set<ZoneAndName> zoneAndGroupNames = ImmutableSet.copyOf(filter(transform(nodesWithGroup,
+ new Function<NodeMetadata, ZoneAndName>() {
+
+ @Override
+ public ZoneAndName apply(NodeMetadata input) {
+ String zoneId = input.getLocation().getScope() == LocationScope.HOST ? input.getLocation()
+ .getParent().getId() : input.getLocation().getId();
+ return ZoneAndName.fromZoneAndName(zoneId, input.getGroup());
+ }
+
+ }), allNodesInGroupTerminated));
+ Multimap<String, String> zoneToZoneAndGroupNames = Multimaps.transformValues(Multimaps.index(zoneAndGroupNames,
+ ZoneAndName.ZONE_FUNCTION), ZoneAndName.NAME_FUNCTION);
+ return zoneToZoneAndGroupNames;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/RemoveFloatingIpFromNodeAndDeallocate.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/RemoveFloatingIpFromNodeAndDeallocate.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/RemoveFloatingIpFromNodeAndDeallocate.java
new file mode 100644
index 0000000..269a333
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/RemoveFloatingIpFromNodeAndDeallocate.java
@@ -0,0 +1,74 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.nova.v2_0.NovaApi;
+import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
+import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.cache.LoadingCache;
+
+/**
+ * A function for removing and deallocating an ip address from a node
+ *
+ * @author Adrian Cole
+ */
+public class RemoveFloatingIpFromNodeAndDeallocate implements Function<ZoneAndId, ZoneAndId> {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final NovaApi novaApi;
+ private final LoadingCache<ZoneAndId, Iterable<? extends FloatingIP>> floatingIpCache;
+
+ @Inject
+ public RemoveFloatingIpFromNodeAndDeallocate(NovaApi novaApi,
+ @Named("FLOATINGIP") LoadingCache<ZoneAndId, Iterable<? extends FloatingIP>> floatingIpCache) {
+ this.novaApi = checkNotNull(novaApi, "novaApi");
+ this.floatingIpCache = checkNotNull(floatingIpCache, "floatingIpCache");
+ }
+
+ @Override
+ public ZoneAndId apply(ZoneAndId id) {
+ FloatingIPApi floatingIpApi = novaApi.getFloatingIPExtensionForZone(id.getZone()).get();
+ for (FloatingIP ip : floatingIpCache.getUnchecked(id)) {
+ logger.debug(">> removing floatingIp(%s) from node(%s)", ip, id);
+ floatingIpApi.removeFromServer(ip.getIp(), id.getId());
+ logger.debug(">> deallocating floatingIp(%s)", ip);
+ floatingIpApi.delete(ip.getId());
+ }
+ floatingIpCache.invalidate(id);
+ return id;
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper("RemoveFloatingIpFromNodeAndDecreate").toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5857efca/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermission.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermission.java b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermission.java
new file mode 100644
index 0000000..a98a62b
--- /dev/null
+++ b/dependencies/jclouds/openstack-nova/1.7.1-stratos/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/SecurityGroupRuleToIpPermission.java
@@ -0,0 +1,99 @@
+/*
+ * 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.openstack.nova.v2_0.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getFirst;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
+import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.cache.LoadingCache;
+import com.google.common.util.concurrent.Atomics;
+
+
+/**
+ * A function for transforming a nova-specific SecurityGroupRule into a generic
+ * IpPermission object.
+ *
+ * @author Andrew Bayer
+ */
+public class SecurityGroupRuleToIpPermission implements Function<SecurityGroupRule, IpPermission> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+ protected final Predicate<AtomicReference<ZoneAndName>> returnSecurityGroupExistsInZone;
+ protected final Supplier<Map<String, Location>> locationIndex;
+ LoadingCache<ZoneAndName, SecurityGroupInZone> groupMap;
+
+ @Inject
+ public SecurityGroupRuleToIpPermission(@Named("SECURITYGROUP_PRESENT") Predicate<AtomicReference<ZoneAndName>> returnSecurityGroupExistsInZone,
+ Supplier<Map<String, Location>> locationIndex,
+ LoadingCache<ZoneAndName, SecurityGroupInZone> groupMap) {
+ this.returnSecurityGroupExistsInZone = checkNotNull(returnSecurityGroupExistsInZone,
+ "returnSecurityGroupExistsInZone");
+ this.locationIndex = checkNotNull(locationIndex, "locationIndex");
+ this.groupMap = checkNotNull(groupMap, "groupMap");
+ }
+
+ @Override
+ public IpPermission apply(SecurityGroupRule rule) {
+ IpPermission.Builder builder = IpPermission.builder();
+ builder.ipProtocol(rule.getIpProtocol());
+ builder.fromPort(rule.getFromPort());
+ builder.toPort(rule.getToPort());
+ if (rule.getGroup() != null) {
+ String zone = getFirst(filter(locationIndex.get().keySet(), isSecurityGroupInZone(rule.getGroup().getName())),
+ null);
+ if (zone != null) {
+ SecurityGroupInZone group = groupMap.getUnchecked(ZoneAndName.fromZoneAndName(zone, rule.getGroup().getName()));
+ builder.groupId(zone + "/" + group.getSecurityGroup().getId());
+ }
+ }
+ if (rule.getIpRange() != null)
+ builder.cidrBlock(rule.getIpRange());
+
+ return builder.build();
+ }
+
+ protected Predicate<String> isSecurityGroupInZone(final String groupName) {
+ return new Predicate<String>() {
+
+ @Override
+ public boolean apply(String zone) {
+ AtomicReference<ZoneAndName> securityGroupInZoneRef = Atomics.newReference(ZoneAndName.fromZoneAndName(zone, groupName));
+ return returnSecurityGroupExistsInZone.apply(securityGroupInZoneRef);
+ }
+ };
+ }
+}