You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2017/12/22 08:04:25 UTC
jclouds-labs git commit: Implement
GetOrCreateNetworkDomainThenCreateNodes Strategy.
Repository: jclouds-labs
Updated Branches:
refs/heads/master 9c74d22bb -> 5a3b59916
Implement GetOrCreateNetworkDomainThenCreateNodes Strategy.
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/5a3b5991
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/5a3b5991
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/5a3b5991
Branch: refs/heads/master
Commit: 5a3b59916865eef4076f8b708bc57b30e21cebf5
Parents: 9c74d22
Author: Trevor Flanagan <tr...@itaas.dimensiondata.com>
Authored: Wed Dec 20 17:22:58 2017 +0000
Committer: Ignasi Barrera <na...@apache.org>
Committed: Fri Dec 22 08:34:32 2017 +0100
----------------------------------------------------------------------
...imensionDataCloudControlTemplateOptions.java | 153 ++++++++++++++++
...GetOrCreateNetworkDomainThenCreateNodes.java | 177 ++++++++++++++++++
.../strategy/TemplateWithNetworkIds.java | 64 +++++++
...sionDataCloudControlTemplateOptionsTest.java | 57 ++++++
...rCreateNetworkDomainThenCreateNodesTest.java | 178 +++++++++++++++++++
5 files changed, 629 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5a3b5991/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/options/DimensionDataCloudControlTemplateOptions.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/options/DimensionDataCloudControlTemplateOptions.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/options/DimensionDataCloudControlTemplateOptions.java
new file mode 100644
index 0000000..0d40b38
--- /dev/null
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/options/DimensionDataCloudControlTemplateOptions.java
@@ -0,0 +1,153 @@
+/*
+ * 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.dimensiondata.cloudcontrol.compute.options;
+
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.javax.annotation.Nullable;
+
+public class DimensionDataCloudControlTemplateOptions extends TemplateOptions implements Cloneable {
+
+ public static final String DEFAULT_NETWORK_DOMAIN_NAME = "JCLOUDS_NETWORK_DOMAIN";
+ public static final String DEFAULT_VLAN_NAME = "JCLOUDS_VLAN";
+ public static final String DEFAULT_PRIVATE_IPV4_BASE_ADDRESS = "10.0.0.0";
+ public static final Integer DEFAULT_PRIVATE_IPV4_PREFIX_SIZE = 24;
+
+ private String networkDomainName;
+ private String defaultPrivateIPv4BaseAddress;
+ private Integer defaultPrivateIPv4PrefixSize;
+
+ public String getNetworkDomainName() {
+ return networkDomainName;
+ }
+
+ public String getDefaultPrivateIPv4BaseAddress() {
+ return defaultPrivateIPv4BaseAddress;
+ }
+
+ public Integer getDefaultPrivateIPv4PrefixSize() {
+ return defaultPrivateIPv4PrefixSize;
+ }
+
+ public DimensionDataCloudControlTemplateOptions networkDomainName(@Nullable String networkDomainName) {
+ this.networkDomainName = networkDomainName;
+ return this;
+ }
+
+ public DimensionDataCloudControlTemplateOptions defaultPrivateIPv4BaseAddress(
+ @Nullable String defaultPrivateIPv4BaseAddress) {
+ this.defaultPrivateIPv4BaseAddress = defaultPrivateIPv4BaseAddress;
+ return this;
+ }
+
+ public DimensionDataCloudControlTemplateOptions defaultPrivateIPv4PrefixSize(
+ @Nullable Integer defaultPrivateIPv4PrefixSize) {
+ this.defaultPrivateIPv4PrefixSize = defaultPrivateIPv4PrefixSize;
+ return this;
+ }
+
+ @Override
+ public DimensionDataCloudControlTemplateOptions clone() {
+ final DimensionDataCloudControlTemplateOptions options = new DimensionDataCloudControlTemplateOptions();
+ copyTo(options);
+ return options;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof DimensionDataCloudControlTemplateOptions)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ DimensionDataCloudControlTemplateOptions that = (DimensionDataCloudControlTemplateOptions) o;
+
+ if (networkDomainName != null ?
+ !networkDomainName.equals(that.networkDomainName) :
+ that.networkDomainName != null) {
+ return false;
+ }
+
+ if (defaultPrivateIPv4BaseAddress != null ?
+ !defaultPrivateIPv4BaseAddress.equals(that.defaultPrivateIPv4BaseAddress) :
+ that.defaultPrivateIPv4BaseAddress != null) {
+ return false;
+ }
+ return defaultPrivateIPv4PrefixSize != null ?
+ defaultPrivateIPv4PrefixSize.equals(that.defaultPrivateIPv4PrefixSize) :
+ that.defaultPrivateIPv4PrefixSize == null;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (networkDomainName != null ? networkDomainName.hashCode() : 0);
+ result = 31 * result + (defaultPrivateIPv4BaseAddress != null ? defaultPrivateIPv4BaseAddress.hashCode() : 0);
+ result = 31 * result + (defaultPrivateIPv4PrefixSize != null ? defaultPrivateIPv4PrefixSize.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "DimensionDataCloudControlTemplateOptions{ networkDomainName='" + networkDomainName
+ + "', defaultPrivateIPv4BaseAddress='" + defaultPrivateIPv4BaseAddress + "', defaultPrivateIPv4PrefixSize='"
+ + defaultPrivateIPv4PrefixSize + "'}";
+ }
+
+ public static class Builder {
+
+ /**
+ * @see #networkDomainName
+ */
+ public static DimensionDataCloudControlTemplateOptions networkDomainName(final String networkDomainName) {
+ final DimensionDataCloudControlTemplateOptions options = new DimensionDataCloudControlTemplateOptions();
+ return options.networkDomainName(networkDomainName);
+ }
+
+ /**
+ * @see #defaultPrivateIPv4BaseAddress
+ */
+ public static DimensionDataCloudControlTemplateOptions defaultPrivateIPv4BaseAddress(
+ final String defaultPrivateIPv4BaseAddress) {
+ final DimensionDataCloudControlTemplateOptions options = new DimensionDataCloudControlTemplateOptions();
+ return options.defaultPrivateIPv4BaseAddress(defaultPrivateIPv4BaseAddress);
+ }
+
+ /**
+ * @see #defaultPrivateIPv4PrefixSize
+ */
+ public static DimensionDataCloudControlTemplateOptions defaultPrivateIPv4PrefixSize(
+ final Integer defaultPrivateIPv4PrefixSize) {
+ final DimensionDataCloudControlTemplateOptions options = new DimensionDataCloudControlTemplateOptions();
+ return options.defaultPrivateIPv4PrefixSize(defaultPrivateIPv4PrefixSize);
+ }
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public DimensionDataCloudControlTemplateOptions nodeNames(Iterable<String> nodeNames) {
+ return DimensionDataCloudControlTemplateOptions.class.cast(super.nodeNames(nodeNames));
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5a3b5991/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/GetOrCreateNetworkDomainThenCreateNodes.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/GetOrCreateNetworkDomainThenCreateNodes.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/GetOrCreateNetworkDomainThenCreateNodes.java
new file mode 100644
index 0000000..a427ed4
--- /dev/null
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/GetOrCreateNetworkDomainThenCreateNodes.java
@@ -0,0 +1,177 @@
+/*
+ * 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.dimensiondata.cloudcontrol.compute.strategy;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.inject.Inject;
+import org.jclouds.compute.config.CustomizationResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
+import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
+import org.jclouds.compute.strategy.ListNodesStrategy;
+import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
+import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlApi;
+import org.jclouds.dimensiondata.cloudcontrol.compute.options.DimensionDataCloudControlTemplateOptions;
+import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomain;
+import org.jclouds.dimensiondata.cloudcontrol.domain.Vlan;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.MoreObjects.firstNonNull;
+import static java.lang.String.format;
+import static org.jclouds.dimensiondata.cloudcontrol.compute.options.DimensionDataCloudControlTemplateOptions.DEFAULT_NETWORK_DOMAIN_NAME;
+import static org.jclouds.dimensiondata.cloudcontrol.compute.options.DimensionDataCloudControlTemplateOptions.DEFAULT_VLAN_NAME;
+import static org.jclouds.dimensiondata.cloudcontrol.config.DimensionDataCloudControlComputeServiceContextModule.NETWORK_DOMAIN_NORMAL_PREDICATE;
+import static org.jclouds.dimensiondata.cloudcontrol.config.DimensionDataCloudControlComputeServiceContextModule.VLAN_NORMAL_PREDICATE;
+
+@Singleton
+public class GetOrCreateNetworkDomainThenCreateNodes extends CreateNodesWithGroupEncodedIntoNameThenAddToSet {
+
+ private final DimensionDataCloudControlApi api;
+ private final ComputeServiceConstants.Timeouts timeouts;
+ private final Predicate<String> networkDomainNormalPredicate;
+ private final Predicate<String> vlanNormalPredicate;
+
+ @Inject
+ protected GetOrCreateNetworkDomainThenCreateNodes(final CreateNodeWithGroupEncodedIntoName addNodeWithGroupStrategy,
+ final ListNodesStrategy listNodesStrategy, final GroupNamingConvention.Factory namingConvention,
+ final ListeningExecutorService userExecutor,
+ final CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
+ final DimensionDataCloudControlApi api, final ComputeServiceConstants.Timeouts timeouts,
+ @Named(NETWORK_DOMAIN_NORMAL_PREDICATE) final Predicate<String> networkDomainNormalPredicate,
+ @Named(VLAN_NORMAL_PREDICATE) final Predicate<String> vlanNormalPredicate) {
+ super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
+ customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
+ this.api = api;
+ this.timeouts = timeouts;
+ this.networkDomainNormalPredicate = networkDomainNormalPredicate;
+ this.vlanNormalPredicate = vlanNormalPredicate;
+ }
+
+ @Override
+ public Map<?, ListenableFuture<Void>> execute(final String group, final int count, final Template template,
+ final Set<NodeMetadata> goodNodes, final Map<NodeMetadata, Exception> badNodes,
+ final Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
+
+ final DimensionDataCloudControlTemplateOptions templateOptions = template.getOptions()
+ .as(DimensionDataCloudControlTemplateOptions.class);
+
+ String networkDomainName = firstNonNull(templateOptions.getNetworkDomainName(), DEFAULT_NETWORK_DOMAIN_NAME);
+ String vlanName = firstNonNull(
+ templateOptions.getNetworks().isEmpty() ? null : templateOptions.getNetworks().iterator().next(),
+ DEFAULT_VLAN_NAME);
+ templateOptions.networkDomainName(networkDomainName);
+ String networkDomainId = tryCreateOrGetExistingNetworkDomainId(template.getLocation().getId(), networkDomainName);
+ String vlanId = tryCreateOrGetExistingVlanId(networkDomainId, vlanName, templateOptions);
+ templateOptions.networks(vlanName);
+ return super
+ .execute(group, count, new TemplateWithNetworkIds(template, networkDomainId, vlanId), goodNodes, badNodes,
+ customizationResponses);
+ }
+
+ private String tryCreateOrGetExistingNetworkDomainId(final String datacenterId, final String networkDomainName) {
+ String networkDomainId = getExistingNetworkDomainId(datacenterId, networkDomainName).orNull();
+ if (networkDomainId != null) {
+ logger.debug("Found a suitable existing network domain %s", networkDomainId);
+ } else {
+ networkDomainId = deployNeworkDomain(datacenterId, networkDomainName);
+ }
+ return networkDomainId;
+ }
+
+ private String deployNeworkDomain(final String datacenter, final String networkDomainName) {
+ logger.debug("Creating a network domain '%s' in Datacenter '%s' ...", networkDomainName, datacenter);
+ String networkDomainId = api.getNetworkApi()
+ .deployNetworkDomain(datacenter, networkDomainName, "network domain created by jclouds",
+ NetworkDomain.Type.ESSENTIALS.name());
+ String message = format("networkDomain(%s) is not ready within %d ms.", networkDomainId, timeouts.nodeRunning);
+
+ if (!networkDomainNormalPredicate.apply(networkDomainId)) {
+ throw new IllegalStateException(message);
+ }
+ return networkDomainId;
+ }
+
+ private Optional<String> getExistingNetworkDomainId(final String datacenterId, final String networkDomainName) {
+ Optional<NetworkDomain> networkDomainOptional = api.getNetworkApi()
+ .listNetworkDomainsWithDatacenterIdAndName(datacenterId, networkDomainName).concat().first();
+ if (networkDomainOptional.isPresent()) {
+ return Optional.of(networkDomainOptional.get().id());
+ } else {
+ return Optional.<String>absent();
+ }
+ }
+
+ private String tryCreateOrGetExistingVlanId(final String networkDomainId, final String vlanName,
+ final DimensionDataCloudControlTemplateOptions templateOptions) {
+
+ String vlanId = getExistingVlan(networkDomainId, vlanName).orNull();
+ if (vlanId != null) {
+ logger.debug("Found a suitable existing vlan %s", vlanId);
+ } else {
+ vlanId = deployVlan(networkDomainId, vlanName, templateOptions);
+ }
+ return vlanId;
+
+ }
+
+ private String deployVlan(final String networkDomainId, final String vlanName,
+ final DimensionDataCloudControlTemplateOptions templateOptions) {
+ logger.debug("Creating a vlan %s in network domain '%s' ...", vlanName, networkDomainId);
+ String defaultPrivateIPv4BaseAddress = firstNonNull(templateOptions.getDefaultPrivateIPv4BaseAddress(),
+ DimensionDataCloudControlTemplateOptions.DEFAULT_PRIVATE_IPV4_BASE_ADDRESS);
+ Integer defaultPrivateIPv4PrefixSize = firstNonNull(templateOptions.getDefaultPrivateIPv4PrefixSize(),
+ DimensionDataCloudControlTemplateOptions.DEFAULT_PRIVATE_IPV4_PREFIX_SIZE);
+
+ String vlanId = api.getNetworkApi()
+ .deployVlan(networkDomainId, vlanName, "vlan created by jclouds", defaultPrivateIPv4BaseAddress,
+ defaultPrivateIPv4PrefixSize);
+ if (!vlanNormalPredicate.apply(vlanId)) {
+ String message = format("vlan(%s) is not ready within %d ms.", vlanId, timeouts.nodeRunning);
+ throw new IllegalStateException(message);
+ }
+ return vlanId;
+ }
+
+ private Optional<String> getExistingVlan(final String networkDomainId, final String vlanName) {
+ FluentIterable<Vlan> vlans = api.getNetworkApi().listVlans(networkDomainId).concat();
+ final Optional<Vlan> vlan = vlans.firstMatch(new Predicate<Vlan>() {
+ @Override
+ public boolean apply(final Vlan input) {
+ return input.name().equals(vlanName);
+ }
+ });
+
+ if (vlan.isPresent()) {
+ return Optional.of(vlan.get().id());
+ } else {
+ return Optional.absent();
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5a3b5991/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/TemplateWithNetworkIds.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/TemplateWithNetworkIds.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/TemplateWithNetworkIds.java
new file mode 100644
index 0000000..496a652
--- /dev/null
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/TemplateWithNetworkIds.java
@@ -0,0 +1,64 @@
+/*
+ * 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.dimensiondata.cloudcontrol.compute.strategy;
+
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.Location;
+
+/**
+ * Extend the default {@link Template} object with extra identifier information about where the nodes must be created.
+ */
+public class TemplateWithNetworkIds implements Template {
+
+ private final Template delegate;
+ private final String networkDomainId;
+ private final String vlanId;
+
+ public TemplateWithNetworkIds(Template template, String networkDomainId, String vlanId) {
+ this.delegate = template;
+ this.networkDomainId = networkDomainId;
+ this.vlanId = vlanId;
+ }
+
+ @Override
+ public Image getImage() {
+ return delegate.getImage();
+ }
+
+ @Override
+ public Hardware getHardware() {
+ return delegate.getHardware();
+ }
+
+ @Override
+ public Location getLocation() {
+ return delegate.getLocation();
+ }
+
+ @Override
+ public TemplateOptions getOptions() {
+ return delegate.getOptions();
+ }
+
+ @Override
+ public Template clone() {
+ return new TemplateWithNetworkIds(delegate.clone(), networkDomainId, vlanId);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5a3b5991/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/options/DimensionDataCloudControlTemplateOptionsTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/options/DimensionDataCloudControlTemplateOptionsTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/options/DimensionDataCloudControlTemplateOptionsTest.java
new file mode 100644
index 0000000..02cfbc5
--- /dev/null
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/options/DimensionDataCloudControlTemplateOptionsTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.dimensiondata.cloudcontrol.compute.options;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+@Test(groups = "unit", testName = "DimensionDataCloudControlTemplateOptionsTest")
+public class DimensionDataCloudControlTemplateOptionsTest {
+
+ private DimensionDataCloudControlTemplateOptions templateOptions;
+ private String networkDomainName;
+ private String defaultPrivateIPv4BaseAddress;
+ private int defaultPrivateIPv4PrefixSize;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ networkDomainName = "networkDomainName";
+ defaultPrivateIPv4BaseAddress = "defaultPrivateIPv4BaseAddress";
+ defaultPrivateIPv4PrefixSize = 100;
+ templateOptions = DimensionDataCloudControlTemplateOptions.Builder.networkDomainName(networkDomainName)
+ .defaultPrivateIPv4BaseAddress(defaultPrivateIPv4BaseAddress)
+ .defaultPrivateIPv4PrefixSize(defaultPrivateIPv4PrefixSize);
+ }
+
+ @Test
+ public void testBuilder() throws Exception {
+ assertEquals(networkDomainName, templateOptions.getNetworkDomainName());
+ assertEquals(defaultPrivateIPv4BaseAddress, templateOptions.getDefaultPrivateIPv4BaseAddress());
+ assertEquals(defaultPrivateIPv4PrefixSize, templateOptions.getDefaultPrivateIPv4PrefixSize().intValue());
+ }
+
+ @Test
+ public void testEquals() throws Exception {
+ assertTrue(templateOptions.equals(
+ DimensionDataCloudControlTemplateOptions.Builder.networkDomainName(networkDomainName)
+ .defaultPrivateIPv4BaseAddress(defaultPrivateIPv4BaseAddress)
+ .defaultPrivateIPv4PrefixSize(defaultPrivateIPv4PrefixSize)));
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5a3b5991/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/GetOrCreateNetworkDomainThenCreateNodesTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/GetOrCreateNetworkDomainThenCreateNodesTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/GetOrCreateNetworkDomainThenCreateNodesTest.java
new file mode 100644
index 0000000..0fef94d
--- /dev/null
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/strategy/GetOrCreateNetworkDomainThenCreateNodesTest.java
@@ -0,0 +1,178 @@
+/*
+ * 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.dimensiondata.cloudcontrol.compute.strategy;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import org.easymock.EasyMock;
+import org.jclouds.collect.IterableWithMarkers;
+import org.jclouds.collect.PagedIterables;
+import org.jclouds.compute.config.CustomizationResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
+import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
+import org.jclouds.compute.strategy.ListNodesStrategy;
+import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlApi;
+import org.jclouds.dimensiondata.cloudcontrol.compute.options.DimensionDataCloudControlTemplateOptions;
+import org.jclouds.dimensiondata.cloudcontrol.domain.IpRange;
+import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomain;
+import org.jclouds.dimensiondata.cloudcontrol.domain.State;
+import org.jclouds.dimensiondata.cloudcontrol.domain.Vlan;
+import org.jclouds.dimensiondata.cloudcontrol.features.NetworkApi;
+import org.jclouds.domain.Location;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Date;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMockSupport.injectMocks;
+import static org.jclouds.dimensiondata.cloudcontrol.compute.options.DimensionDataCloudControlTemplateOptions.DEFAULT_NETWORK_DOMAIN_NAME;
+import static org.jclouds.dimensiondata.cloudcontrol.compute.options.DimensionDataCloudControlTemplateOptions.DEFAULT_PRIVATE_IPV4_BASE_ADDRESS;
+import static org.jclouds.dimensiondata.cloudcontrol.compute.options.DimensionDataCloudControlTemplateOptions.DEFAULT_PRIVATE_IPV4_PREFIX_SIZE;
+import static org.jclouds.dimensiondata.cloudcontrol.compute.options.DimensionDataCloudControlTemplateOptions.DEFAULT_VLAN_NAME;
+import static org.testng.AssertJUnit.assertEquals;
+
+@Test(groups = "unit", testName = "GetOrCreateNetworkDomainThenCreateNodesTest")
+public class GetOrCreateNetworkDomainThenCreateNodesTest {
+
+ private GetOrCreateNetworkDomainThenCreateNodes getOrCreateNetworkDomainThenCreateNodes;
+ private NetworkApi networkApi;
+ private DimensionDataCloudControlApi api;
+ private Template template;
+ private DimensionDataCloudControlTemplateOptions templateOptions;
+ private CreateNodeWithGroupEncodedIntoName addNodeWithGroupStrategy;
+ private ListNodesStrategy listNodesStrategy;
+ private GroupNamingConvention.Factory namingConvention;
+ private ListeningExecutorService userExecutor;
+ private CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory;
+ private org.jclouds.compute.reference.ComputeServiceConstants.Timeouts timeouts;
+ private Location location;
+ private String datacenterId;
+ private NetworkDomain networkDomain;
+ private Vlan vlan;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ networkApi = EasyMock.createMock(NetworkApi.class);
+ api = EasyMock.createMock(DimensionDataCloudControlApi.class);
+ template = EasyMock.createNiceMock(Template.class);
+ addNodeWithGroupStrategy = EasyMock.createNiceMock(CreateNodeWithGroupEncodedIntoName.class);
+ listNodesStrategy = EasyMock.createNiceMock(ListNodesStrategy.class);
+ namingConvention = EasyMock.createNiceMock(GroupNamingConvention.Factory.class);
+ userExecutor = EasyMock.createNiceMock(ListeningExecutorService.class);
+ customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory = EasyMock
+ .createNiceMock(CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory.class);
+ location = createNiceMock(Location.class);
+ templateOptions = new DimensionDataCloudControlTemplateOptions();
+ templateOptions.nodeNames(Sets.newHashSet("node1"));
+ datacenterId = "datacenterId";
+
+ timeouts = new ComputeServiceConstants.Timeouts();
+
+ final Predicate<String> alwaysTrue = new Predicate<String>() {
+ @Override
+ public boolean apply(final String input) {
+ return true;
+ }
+ };
+
+ getOrCreateNetworkDomainThenCreateNodes = new GetOrCreateNetworkDomainThenCreateNodes(addNodeWithGroupStrategy,
+ listNodesStrategy, namingConvention, userExecutor,
+ customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory, api, timeouts, alwaysTrue, alwaysTrue);
+
+ networkDomain = NetworkDomain.builder().id("690de302-bb80-49c6-b401-8c02bbefb945")
+ .name(DEFAULT_NETWORK_DOMAIN_NAME).build();
+ vlan = Vlan.builder().networkDomain(networkDomain).id("vlanId").name(DEFAULT_VLAN_NAME).description("")
+ .privateIpv4Range(IpRange.create("10.0.0.0", 24))
+ .ipv6Range(IpRange.create("2607:f480:111:1575:0:0:0:0", 64)).ipv4GatewayAddress("10.0.0.1")
+ .ipv6GatewayAddress("2607:f480:111:1575:0:0:0:1").createTime(new Date()).state(State.NORMAL)
+ .datacenterId("NA9").build();
+
+ injectMocks(api);
+ injectMocks(template);
+ injectMocks(networkApi);
+ expect(template.getOptions()).andReturn(templateOptions).anyTimes();
+ expect(template.getLocation()).andReturn(location);
+ expect(location.getId()).andReturn(datacenterId);
+
+ expect(api.getNetworkApi()).andReturn(networkApi).anyTimes();
+ }
+
+ @Test
+ public void testExecute() throws Exception {
+ expect(networkApi.listNetworkDomainsWithDatacenterIdAndName(datacenterId, DEFAULT_NETWORK_DOMAIN_NAME))
+ .andReturn(PagedIterables.onlyPage(IterableWithMarkers.from(Lists.newArrayList(networkDomain))));
+
+ expect(networkApi.listVlans(networkDomain.id()))
+ .andReturn(PagedIterables.onlyPage(IterableWithMarkers.from(Lists.newArrayList(vlan))));
+
+ replay(networkApi, api, template, location);
+
+ executeAndAssert();
+ }
+
+ @Test(dependsOnMethods = "testExecute")
+ public void testExecute_deployNetworkDomain_deployVlan() throws Exception {
+ expect(networkApi.listNetworkDomainsWithDatacenterIdAndName(datacenterId, DEFAULT_NETWORK_DOMAIN_NAME))
+ .andReturn(PagedIterables.onlyPage(IterableWithMarkers.from(Lists.<NetworkDomain>newArrayList())));
+
+ final String deployedNetworkDomainId = "deployedNetworkDomainId";
+ final String networkDomainDescription = "network domain created by jclouds";
+
+ final NetworkDomain deployedNetworkDomain = NetworkDomain.builder().id(deployedNetworkDomainId)
+ .description(networkDomainDescription).name(DEFAULT_NETWORK_DOMAIN_NAME).state(State.NORMAL).build();
+ expect(networkApi.deployNetworkDomain(datacenterId, DEFAULT_NETWORK_DOMAIN_NAME, networkDomainDescription,
+ NetworkDomain.Type.ESSENTIALS.name())).andReturn(deployedNetworkDomainId);
+ expect(networkApi.getNetworkDomain(deployedNetworkDomainId)).andReturn(deployedNetworkDomain);
+
+ final String deployedVlanId = "deployedVlanId";
+ final String deployedVlanDescription = "vlan created by jclouds";
+ Vlan deployedVlan = Vlan.builder().networkDomain(deployedNetworkDomain).id("deployedVlanId")
+ .name(DEFAULT_VLAN_NAME).description("").privateIpv4Range(IpRange.create("10.0.0.0", 24))
+ .ipv6Range(IpRange.create("2607:f480:111:1575:0:0:0:0", 64)).ipv4GatewayAddress("10.0.0.1")
+ .ipv6GatewayAddress("2607:f480:111:1575:0:0:0:1").createTime(new Date()).state(State.NORMAL)
+ .datacenterId(datacenterId).build();
+ expect(networkApi.listVlans(deployedNetworkDomain.id()))
+ .andReturn(PagedIterables.onlyPage(IterableWithMarkers.from(Lists.<Vlan>newArrayList())));
+ expect(networkApi.deployVlan(deployedNetworkDomainId, DEFAULT_VLAN_NAME, deployedVlanDescription,
+ DEFAULT_PRIVATE_IPV4_BASE_ADDRESS, DEFAULT_PRIVATE_IPV4_PREFIX_SIZE)).andReturn(deployedVlanId);
+ expect(networkApi.getVlan(deployedVlanId)).andReturn(deployedVlan);
+
+ replay(networkApi, api, template, location);
+
+ executeAndAssert();
+ }
+
+ private void executeAndAssert() {
+ getOrCreateNetworkDomainThenCreateNodes.execute("group", 0, template, Collections.<NodeMetadata>emptySet(),
+ Collections.<NodeMetadata, Exception>emptyMap(),
+ ArrayListMultimap.<NodeMetadata, CustomizationResponse>create());
+
+ assertEquals(DEFAULT_NETWORK_DOMAIN_NAME, templateOptions.getNetworkDomainName());
+ assertEquals(DEFAULT_VLAN_NAME, templateOptions.getNetworks().iterator().next());
+ }
+}