You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by an...@apache.org on 2018/07/31 20:09:50 UTC
[1/2] jclouds-labs git commit: [JCLOUDS-1430] - add more features
Repository: jclouds-labs
Updated Branches:
refs/heads/master d74d7f62d -> a5dbf0065
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/functions/ArrayToCommaSeparatedString.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/functions/ArrayToCommaSeparatedString.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/functions/ArrayToCommaSeparatedString.java
new file mode 100644
index 0000000..3bb22b4
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/functions/ArrayToCommaSeparatedString.java
@@ -0,0 +1,49 @@
+/*
+ * 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.aliyun.ecs.functions;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+
+import javax.inject.Singleton;
+import java.util.Arrays;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Takes an array of string and return a "["s1", "s2", … "sN"]"
+ */
+@Singleton
+public class ArrayToCommaSeparatedString implements Function<Object, String> {
+ @Override
+ public String apply(Object input) {
+ checkArgument(checkNotNull(input, "input") instanceof String[], "This function is only valid for array of Strings!");
+ String[] names = (String[]) input;
+
+ String arrayToCommaSeparatedString = Joiner.on(",")
+ .join(Iterables.transform(Arrays.asList(names), new Function<String, String>() {
+ @Override
+ public String apply(String s) {
+ return new StringBuilder(s.length() + 1).append('"').append(s).append('"').toString();
+ }
+ }));
+ return String.format("[%s]", arrayToCommaSeparatedString);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/functions/BaseToPagedIterable.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/functions/BaseToPagedIterable.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/functions/BaseToPagedIterable.java
deleted file mode 100644
index 9f2ddcf..0000000
--- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/functions/BaseToPagedIterable.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.aliyun.ecs.functions;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import org.jclouds.aliyun.ecs.ECSComputeServiceApi;
-import org.jclouds.aliyun.ecs.domain.options.ListImagesOptions;
-import org.jclouds.collect.IterableWithMarker;
-import org.jclouds.collect.internal.Arg0ToPagedIterable;
-
-/**
- * Base class to implement the functions that build the
- * <code>PagedIterable</code>. Subclasses just need to override the
- * {@link #fetchPageUsingOptions(ListImagesOptions, Optional)} to invoke the right API
- * method with the given options parameter to get the next page.
- */
-public abstract class BaseToPagedIterable<T, O extends ListImagesOptions> extends
- Arg0ToPagedIterable<T, BaseToPagedIterable<T, O>> {
- private final Function<Integer, O> pageNumberToOptions;
- protected final ECSComputeServiceApi api;
-
- protected BaseToPagedIterable(ECSComputeServiceApi api, Function<Integer, O> pageNumberToOptions) {
- this.api = api;
- this.pageNumberToOptions = pageNumberToOptions;
- }
-
- protected abstract IterableWithMarker<T> fetchPageUsingOptions(O options, Optional<Object> arg0);
-
- @Override
- protected Function<Object, IterableWithMarker<T>> markerToNextForArg0(final Optional<Object> arg0) {
- return new Function<Object, IterableWithMarker<T>>() {
- @Override
- public IterableWithMarker<T> apply(Object input) {
- O nextOptions = pageNumberToOptions.apply(Integer.class.cast(input));
- return fetchPageUsingOptions(nextOptions, arg0);
- }
- };
- }
-
-}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/ImageApiLiveTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/ImageApiLiveTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/ImageApiLiveTest.java
index 957d9cc..5fe5c3f 100644
--- a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/ImageApiLiveTest.java
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/ImageApiLiveTest.java
@@ -20,12 +20,14 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.jclouds.aliyun.ecs.compute.internal.BaseECSComputeServiceApiLiveTest;
import org.jclouds.aliyun.ecs.domain.Image;
-import org.jclouds.aliyun.ecs.domain.Regions;
+import org.jclouds.aliyun.ecs.domain.internal.Regions;
import org.jclouds.aliyun.ecs.features.ImageApi;
import org.testng.annotations.Test;
import java.util.concurrent.atomic.AtomicInteger;
+import static org.jclouds.aliyun.ecs.domain.options.ListImagesOptions.Builder.imageIds;
+import static org.jclouds.aliyun.ecs.domain.options.PaginationOptions.Builder.pageNumber;
import static org.testng.Assert.assertTrue;
import static org.testng.util.Strings.isNullOrEmpty;
@@ -38,12 +40,27 @@ public class ImageApiLiveTest extends BaseECSComputeServiceApiLiveTest {
@Override
public boolean apply(Image input) {
found.incrementAndGet();
- return !isNullOrEmpty(input.imageId());
+ return !isNullOrEmpty(input.id());
}
}), "All images must have the 'id' field populated");
assertTrue(found.get() > 0, "Expected some image to be returned");
}
+ public void testListWithOptions() {
+ final AtomicInteger found = new AtomicInteger(0);
+ assertTrue(api().list(Regions.EU_CENTRAL_1.getName(),
+ imageIds("debian_8_09_64_20G_alibase_20170824.vhd")
+ .paginationOptions(pageNumber(3)))
+ .firstMatch(new Predicate<Image>() {
+ @Override
+ public boolean apply(Image input) {
+ found.incrementAndGet();
+ return !isNullOrEmpty(input.id());
+ }
+ }).isPresent(), "All images must have the 'id' field populated");
+ assertTrue(found.get() > 0, "Expected some image to be returned");
+ }
+
private ImageApi api() {
return api.imageApi();
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/ImageApiMockTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/ImageApiMockTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/ImageApiMockTest.java
index b333e6d..e61b910 100644
--- a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/ImageApiMockTest.java
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/ImageApiMockTest.java
@@ -19,8 +19,7 @@ package org.jclouds.aliyun.ecs.compute.features;
import com.google.common.collect.ImmutableMap;
import org.jclouds.aliyun.ecs.compute.internal.BaseECSComputeServiceApiMockTest;
import org.jclouds.aliyun.ecs.domain.Image;
-import org.jclouds.aliyun.ecs.domain.Regions;
-import org.jclouds.collect.IterableWithMarker;
+import org.jclouds.aliyun.ecs.domain.internal.Regions;
import org.testng.annotations.Test;
import static com.google.common.collect.Iterables.isEmpty;
@@ -54,15 +53,15 @@ public class ImageApiMockTest extends BaseECSComputeServiceApiMockTest {
public void testListImagesWithOptions() throws InterruptedException {
server.enqueue(jsonResponse("/images-first.json"));
- IterableWithMarker<Image> images = api.imageApi().list(Regions.EU_CENTRAL_1.getName(), paginationOptions(pageNumber(1)));
+ Iterable<Image> images = api.imageApi().list(Regions.EU_CENTRAL_1.getName(), paginationOptions(pageNumber(1)));
assertEquals(size(images), 10);
assertEquals(server.getRequestCount(), 1);
- assertSent(server, "GET", "DescribeImages", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()), 1);
+ assertSent(server, "GET", "DescribeImages", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()));
}
public void testListImagesWithOptionsReturns404() throws InterruptedException {
server.enqueue(response404());
- IterableWithMarker<Image> images = api.imageApi().list(Regions.EU_CENTRAL_1.getName(), paginationOptions(pageNumber(2)));
+ Iterable<Image> images = api.imageApi().list(Regions.EU_CENTRAL_1.getName(), paginationOptions(pageNumber(2)));
assertTrue(isEmpty(images));
assertEquals(server.getRequestCount(), 1);
assertSent(server, "GET", "DescribeImages", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()), 2);
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/RegionAndZoneApiLiveTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/RegionAndZoneApiLiveTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/RegionAndZoneApiLiveTest.java
index 91239a1..f32399b 100644
--- a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/RegionAndZoneApiLiveTest.java
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/RegionAndZoneApiLiveTest.java
@@ -38,7 +38,7 @@ public class RegionAndZoneApiLiveTest extends BaseECSComputeServiceApiLiveTest {
@Override
public boolean apply(Region input) {
found.incrementAndGet();
- return !isNullOrEmpty(input.regionId());
+ return !isNullOrEmpty(input.id());
}
}), "All regions must have the 'id' field populated");
assertTrue(found.get() > 0, "Expected some region to be returned");
@@ -50,7 +50,7 @@ public class RegionAndZoneApiLiveTest extends BaseECSComputeServiceApiLiveTest {
@Override
public boolean apply(Zone input) {
found.incrementAndGet();
- return !isNullOrEmpty(input.zoneId());
+ return !isNullOrEmpty(input.id());
}
}), "All zones must have the 'id' field populated");
assertTrue(found.get() > 0, "Expected some zone to be returned");
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/RegionAndZoneApiMockTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/RegionAndZoneApiMockTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/RegionAndZoneApiMockTest.java
index 291d1b0..e116845 100644
--- a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/RegionAndZoneApiMockTest.java
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/RegionAndZoneApiMockTest.java
@@ -19,7 +19,7 @@ package org.jclouds.aliyun.ecs.compute.features;
import com.google.common.collect.ImmutableMap;
import org.jclouds.aliyun.ecs.compute.internal.BaseECSComputeServiceApiMockTest;
import org.jclouds.aliyun.ecs.domain.Region;
-import org.jclouds.aliyun.ecs.domain.Regions;
+import org.jclouds.aliyun.ecs.domain.internal.Regions;
import org.jclouds.aliyun.ecs.domain.Zone;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SecurityGroupApiLiveTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SecurityGroupApiLiveTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SecurityGroupApiLiveTest.java
new file mode 100644
index 0000000..5c76fc5
--- /dev/null
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SecurityGroupApiLiveTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.aliyun.ecs.compute.features;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.jclouds.aliyun.ecs.compute.internal.BaseECSComputeServiceApiLiveTest;
+import org.jclouds.aliyun.ecs.domain.IpProtocol;
+import org.jclouds.aliyun.ecs.domain.Permission;
+import org.jclouds.aliyun.ecs.domain.internal.Regions;
+import org.jclouds.aliyun.ecs.domain.SecurityGroup;
+import org.jclouds.aliyun.ecs.domain.SecurityGroupRequest;
+import org.jclouds.aliyun.ecs.domain.options.CreateSecurityGroupOptions;
+import org.jclouds.aliyun.ecs.features.SecurityGroupApi;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.util.Strings.isNullOrEmpty;
+
+@Test(groups = "live", testName = "SecurityGroupApiLiveTest")
+public class SecurityGroupApiLiveTest extends BaseECSComputeServiceApiLiveTest {
+
+ public static final String TEST_PORT_RANGE = "8081/8085";
+ public static final String INTERNET = "0.0.0.0/0";
+
+ private String securityGroupId;
+
+ @BeforeClass
+ public void setUp() {
+ SecurityGroupRequest request = api().create(Regions.EU_CENTRAL_1.getName(),
+ CreateSecurityGroupOptions.Builder
+ .securityGroupName("jclouds-test")
+ );
+ securityGroupId = request.getSecurityGroupId();
+ }
+
+ @AfterClass
+ public void tearDown() {
+ if (securityGroupId != null) {
+ api().delete(Regions.EU_CENTRAL_1.getName(), securityGroupId);
+ }
+ }
+
+ public void testAddRules() {
+ api().addInboundRule(Regions.EU_CENTRAL_1.getName(), securityGroupId, IpProtocol.TCP, TEST_PORT_RANGE, INTERNET);
+ }
+
+ @Test(groups = "live", dependsOnMethods = "testAddRules")
+ public void testGet() {
+ Permission permission = Iterables.getOnlyElement(api().get(Regions.EU_CENTRAL_1.getName(), securityGroupId));
+ checkPermission(permission);
+ }
+
+ @Test(groups = "live", dependsOnMethods = "testGet")
+ public void testList() {
+ final AtomicInteger found = new AtomicInteger(0);
+ assertTrue(Iterables.all(api().list(Regions.EU_CENTRAL_1.getName()).concat(), new Predicate<SecurityGroup>() {
+ @Override
+ public boolean apply(SecurityGroup input) {
+ found.incrementAndGet();
+ return !isNullOrEmpty(input.id());
+ }
+ }), "All security groups must have the 'id' field populated");
+ assertTrue(found.get() > 0, "Expected some security group to be returned");
+ }
+
+ private SecurityGroupApi api() {
+ return api.securityGroupApi();
+ }
+
+ private void checkPermission(Permission permission) {
+ assertNotNull(permission.ipProtocol());
+ assertNotNull(permission.portRange());
+ assertNotNull(permission.sourceCidrIp());
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SecurityGroupApiMockTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SecurityGroupApiMockTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SecurityGroupApiMockTest.java
new file mode 100644
index 0000000..46aa76b
--- /dev/null
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SecurityGroupApiMockTest.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.aliyun.ecs.compute.features;
+
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.aliyun.ecs.compute.internal.BaseECSComputeServiceApiMockTest;
+import org.jclouds.aliyun.ecs.domain.internal.Regions;
+import org.jclouds.aliyun.ecs.domain.SecurityGroup;
+import org.testng.annotations.Test;
+
+import static com.google.common.collect.Iterables.isEmpty;
+import static com.google.common.collect.Iterables.size;
+import static org.jclouds.aliyun.ecs.domain.options.ListSecurityGroupsOptions.Builder.paginationOptions;
+import static org.jclouds.aliyun.ecs.domain.options.PaginationOptions.Builder.pageNumber;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test(groups = "unit", testName = "SecurityGroupApiMockTest", singleThreaded = true)
+public class SecurityGroupApiMockTest extends BaseECSComputeServiceApiMockTest {
+
+ public void testListSecurityGroups() throws InterruptedException {
+ server.enqueue(jsonResponse("/securitygroups-first.json"));
+ server.enqueue(jsonResponse("/securitygroups-last.json"));
+ Iterable<SecurityGroup> securitygroups = api.securityGroupApi().list(Regions.EU_CENTRAL_1.getName()).concat();
+ assertEquals(size(securitygroups), 7); // Force the PagedIterable to advance
+ assertEquals(server.getRequestCount(), 2);
+ assertSent(server, "GET", "DescribeSecurityGroups", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()));
+ assertSent(server, "GET", "DescribeSecurityGroups", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()), 2);
+ }
+
+ public void testListSecurityGroupsReturns404() throws InterruptedException {
+ server.enqueue(response404());
+ Iterable<SecurityGroup> securitygroups = api.securityGroupApi().list(Regions.EU_CENTRAL_1.getName()).concat();
+ assertTrue(isEmpty(securitygroups));
+ assertEquals(server.getRequestCount(), 1);
+ assertSent(server, "GET", "DescribeSecurityGroups", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()));
+ }
+
+ public void testListSecurityGroupsWithOptions() throws InterruptedException {
+ server.enqueue(jsonResponse("/securitygroups-first.json"));
+ Iterable<SecurityGroup> securitygroups = api.securityGroupApi().list(Regions.EU_CENTRAL_1.getName(), paginationOptions(pageNumber(1).pageSize(5)));
+ assertEquals(size(securitygroups), 5);
+ assertEquals(server.getRequestCount(), 1);
+ assertSent(server, "GET", "DescribeSecurityGroups", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()), 1);
+ }
+
+ public void testListSecurityGroupsWithOptionsReturns404() throws InterruptedException {
+ server.enqueue(response404());
+ Iterable<SecurityGroup> securitygroups = api.securityGroupApi().list(Regions.EU_CENTRAL_1.getName(), paginationOptions(pageNumber(2)));
+ assertTrue(isEmpty(securitygroups));
+ assertEquals(server.getRequestCount(), 1);
+ assertSent(server, "GET", "DescribeSecurityGroups", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()), 2);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SshKeyPairApiLiveTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SshKeyPairApiLiveTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SshKeyPairApiLiveTest.java
new file mode 100644
index 0000000..85ceee5
--- /dev/null
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SshKeyPairApiLiveTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.aliyun.ecs.compute.features;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.jclouds.aliyun.ecs.compute.internal.BaseECSComputeServiceApiLiveTest;
+import org.jclouds.aliyun.ecs.domain.KeyPair;
+import org.jclouds.aliyun.ecs.domain.KeyPairRequest;
+import org.jclouds.aliyun.ecs.domain.internal.Regions;
+import org.jclouds.aliyun.ecs.features.SshKeyPairApi;
+import org.jclouds.ssh.SshKeys;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.util.Strings.isNullOrEmpty;
+
+@Test(groups = "live", testName = "SecurityGroupApiLiveTest")
+public class SshKeyPairApiLiveTest extends BaseECSComputeServiceApiLiveTest {
+
+ private String keyPairName = "jclouds-test";
+
+ @BeforeClass
+ public void setUp() {
+ KeyPairRequest request = api().create(Regions.EU_CENTRAL_1.getName(), keyPairName);
+ assertNotNull(request.getRequestId());
+ }
+
+ @AfterClass
+ public void tearDown() {
+ if (keyPairName != null) {
+ api().delete(Regions.EU_CENTRAL_1.getName(), keyPairName);
+ }
+ }
+
+ public void testImport() {
+ String importedKeyPairName = keyPairName + new Random().nextInt(1024);
+ KeyPair imported = api().importKeyPair(
+ Regions.EU_CENTRAL_1.getName(),
+ SshKeys.generate().get("public"),
+ importedKeyPairName);
+ assertEquals(imported.name(), importedKeyPairName);
+ assertNotNull(imported.privateKeyBody());
+ assertNotNull(imported.keyPairFingerPrint());
+ }
+
+ public void testList() {
+ final AtomicInteger found = new AtomicInteger(0);
+ assertTrue(Iterables.all(api().list(Regions.EU_CENTRAL_1.getName()).concat(), new Predicate<KeyPair>() {
+ @Override
+ public boolean apply(KeyPair input) {
+ found.incrementAndGet();
+ return !isNullOrEmpty(input.name());
+ }
+ }), "All key pairs must have the 'name' field populated");
+ assertTrue(found.get() > 0, "Expected some key pair to be returned");
+ }
+
+ private SshKeyPairApi api() {
+ return api.sshKeyPairApi();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SshKeyPairApiMockTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SshKeyPairApiMockTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SshKeyPairApiMockTest.java
new file mode 100644
index 0000000..23c21ad
--- /dev/null
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/SshKeyPairApiMockTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.aliyun.ecs.compute.features;
+
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.aliyun.ecs.compute.internal.BaseECSComputeServiceApiMockTest;
+import org.jclouds.aliyun.ecs.domain.KeyPair;
+import org.jclouds.aliyun.ecs.domain.KeyPairRequest;
+import org.jclouds.aliyun.ecs.domain.internal.Regions;
+import org.jclouds.aliyun.ecs.domain.Request;
+import org.jclouds.aliyun.ecs.domain.options.ListKeyPairsOptions;
+import org.jclouds.aliyun.ecs.domain.options.PaginationOptions;
+import org.jclouds.collect.IterableWithMarker;
+import org.testng.annotations.Test;
+
+import static com.google.common.collect.Iterables.isEmpty;
+import static com.google.common.collect.Iterables.size;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test(groups = "unit", testName = "SshKeyPairApiMockTest", singleThreaded = true)
+public class SshKeyPairApiMockTest extends BaseECSComputeServiceApiMockTest {
+
+ public void testCreateSshKey() throws InterruptedException {
+ server.enqueue(jsonResponse("/keypair-create-res.json"));
+ KeyPairRequest keyPairRequest = api.sshKeyPairApi().create(Regions.EU_CENTRAL_1.getName(), "jclouds");
+ assertEquals(keyPairRequest, objectFromResource("/keypair-create-res.json", KeyPairRequest.class));
+ assertEquals(server.getRequestCount(), 1);
+ assertSent(server, "POST", "CreateKeyPair", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()));
+ }
+
+ public void testDeleteSshKey() throws InterruptedException {
+ server.enqueue(jsonResponse("/keypair-delete-res.json"));
+ Request delete = api.sshKeyPairApi().delete(Regions.EU_CENTRAL_1.getName());
+ assertEquals(delete, objectFromResource("/keypair-delete-res.json", Request.class));
+ assertEquals(server.getRequestCount(), 1);
+ assertSent(server, "POST", "DeleteKeyPairs", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()));
+ }
+
+ public void testImportSshKey() throws InterruptedException {
+ server.enqueue(jsonResponse("/keypair-import-res.json"));
+ KeyPair keyPair = api.sshKeyPairApi().importKeyPair(
+ Regions.EU_CENTRAL_1.getName(),
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCdgcoNzH4hCc0j3b4MuG503L/J54uyFvwCAOu8vSsYuLpJ4AEyEOv+T0SfdF605fK6GYXA16Rxk3lrPt7mfKGNtXR0Ripbv7Zc6PvCRorwgj/cjh/45miozjrkXAiHD1GFZycfbi4YsoWAqZj7W4mwtctmhrYM0FPdya2XoRpVy89N+A5Xo4Xtd6EZn6JGEKQM5+kF2aL3ggy0od/DqjuEVYwZoyTe1RgUTXZSU/Woh7WMhsRHbqd3eYz4s6ac8n8IJPGKtUaQeqUtH7OK6NRYXVypUrkqNlwdNYZAwrjXg/x5T3D+bo11LENASRt9OJ2OkmRSTqRxBeDkhnVauWK/",
+ "jclouds"
+ );
+ assertEquals(keyPair, objectFromResource("/keypair-import-res.json", KeyPair.class));
+ assertEquals(server.getRequestCount(), 1);
+ assertSent(server, "POST", "ImportKeyPair", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()));
+ }
+
+ public void testListImages() throws InterruptedException {
+ server.enqueue(jsonResponse("/keypairs-first.json"));
+ server.enqueue(jsonResponse("/keypairs-last.json"));
+
+ Iterable<KeyPair> keypairs = api.sshKeyPairApi().list(Regions.EU_CENTRAL_1.getName()).concat();
+ assertEquals(size(keypairs), 12);
+ assertEquals(server.getRequestCount(), 2);
+ assertSent(server, "GET", "DescribeKeyPairs");
+ assertSent(server, "GET", "DescribeKeyPairs", 2);
+ }
+
+ public void testListKeyPairsReturns404() {
+ server.enqueue(response404());
+ Iterable<KeyPair> keypairs = api.sshKeyPairApi().list(Regions.EU_CENTRAL_1.getName()).concat();
+ assertTrue(isEmpty(keypairs));
+ assertEquals(server.getRequestCount(), 1);
+ }
+
+ public void testListKeyPairsWithOptions() throws InterruptedException {
+ server.enqueue(jsonResponse("/keypairs-first.json"));
+
+ IterableWithMarker<KeyPair> keypairs = api.sshKeyPairApi().list(Regions.EU_CENTRAL_1.getName(), ListKeyPairsOptions.Builder
+ .paginationOptions(PaginationOptions.Builder.pageNumber(1)));
+
+ assertEquals(size(keypairs), 10);
+ assertEquals(server.getRequestCount(), 1);
+
+ assertSent(server, "GET", "DescribeKeyPairs", 1);
+ }
+
+ public void testListKeyPairsWithOptionsReturns404() throws InterruptedException {
+ server.enqueue(response404());
+
+ IterableWithMarker<KeyPair> keypairs = api.sshKeyPairApi().list(Regions.EU_CENTRAL_1.getName(), ListKeyPairsOptions.Builder
+ .paginationOptions(PaginationOptions.Builder.pageNumber(2)));
+
+ assertTrue(isEmpty(keypairs));
+
+ assertEquals(server.getRequestCount(), 1);
+ assertSent(server, "GET", "DescribeKeyPairs", 2);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/TagApiLiveTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/TagApiLiveTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/TagApiLiveTest.java
new file mode 100644
index 0000000..854b494
--- /dev/null
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/TagApiLiveTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.aliyun.ecs.compute.features;
+
+import com.google.common.base.Predicate;
+import org.jclouds.aliyun.ecs.compute.internal.BaseECSComputeServiceApiLiveTest;
+import org.jclouds.aliyun.ecs.domain.internal.Regions;
+import org.jclouds.aliyun.ecs.domain.Request;
+import org.jclouds.aliyun.ecs.domain.SecurityGroupRequest;
+import org.jclouds.aliyun.ecs.domain.Tag;
+import org.jclouds.aliyun.ecs.domain.options.CreateSecurityGroupOptions;
+import org.jclouds.aliyun.ecs.domain.options.ListTagsOptions;
+import org.jclouds.aliyun.ecs.domain.options.TagOptions;
+import org.jclouds.aliyun.ecs.features.TagApi;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.util.Strings.isNullOrEmpty;
+
+@Test(groups = "live", testName = "TagApiLiveTest")
+public class TagApiLiveTest extends BaseECSComputeServiceApiLiveTest {
+
+ public static final String RESOURCE_TYPE = "securitygroup";
+
+ private String securityGroupName = "pre-test-security";
+ private String securityGroupId;
+
+ @BeforeClass
+ public void setUp() {
+ SecurityGroupRequest preRequisite = api.securityGroupApi().create(Regions.EU_CENTRAL_1.getName(),
+ CreateSecurityGroupOptions.Builder.securityGroupName(securityGroupName)
+ );
+ securityGroupId = preRequisite.getSecurityGroupId();
+ Request request = api().add(Regions.EU_CENTRAL_1.getName(), securityGroupId, RESOURCE_TYPE,
+ TagOptions.Builder.tag(1, "owner"));
+ assertNotNull(request.getRequestId());
+ }
+
+ @AfterClass
+ public void tearDown() {
+ api().remove(Regions.EU_CENTRAL_1.getName(), securityGroupId, RESOURCE_TYPE);
+ if (securityGroupId != null) {
+ api.securityGroupApi().delete(Regions.EU_CENTRAL_1.getName(), securityGroupId);
+ }
+ }
+
+ public void testList() {
+ final AtomicInteger found = new AtomicInteger(0);
+ assertFalse(api().list(Regions.EU_CENTRAL_1.getName(), ListTagsOptions.Builder.resourceId(securityGroupId))
+ .filter(new Predicate<Tag>() {
+ @Override
+ public boolean apply(Tag input) {
+ found.incrementAndGet();
+ return !isNullOrEmpty(input.tagKey());
+ }
+ }).isEmpty(), "All tags must have the 'key' field populated");
+ assertTrue(found.get() > 0, "Expected some tags to be returned");
+ }
+
+ private TagApi api() {
+ return api.tagApi();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/TagApiMockTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/TagApiMockTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/TagApiMockTest.java
new file mode 100644
index 0000000..deb492d
--- /dev/null
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/features/TagApiMockTest.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.aliyun.ecs.compute.features;
+
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.aliyun.ecs.compute.internal.BaseECSComputeServiceApiMockTest;
+import org.jclouds.aliyun.ecs.domain.internal.Regions;
+import org.jclouds.aliyun.ecs.domain.Tag;
+import org.testng.annotations.Test;
+
+import static com.google.common.collect.Iterables.isEmpty;
+import static com.google.common.collect.Iterables.size;
+import static org.jclouds.aliyun.ecs.domain.options.ListTagsOptions.Builder.paginationOptions;
+import static org.jclouds.aliyun.ecs.domain.options.PaginationOptions.Builder.pageNumber;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test(groups = "unit", testName = "TagApiMockTest", singleThreaded = true)
+public class TagApiMockTest extends BaseECSComputeServiceApiMockTest {
+
+ public void testListTags() throws InterruptedException {
+ server.enqueue(jsonResponse("/tags-first.json"));
+ server.enqueue(jsonResponse("/tags-last.json"));
+ Iterable<Tag> tags = api.tagApi().list(Regions.EU_CENTRAL_1.getName()).concat();
+ assertEquals(size(tags), 10); // Force the PagedIterable to advance
+ assertEquals(server.getRequestCount(), 2);
+ assertSent(server, "GET", "DescribeTags", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()));
+ assertSent(server, "GET", "DescribeTags", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()), 2);
+ }
+
+ public void testListTagsReturns404() throws InterruptedException {
+ server.enqueue(response404());
+ Iterable<Tag> tags = api.tagApi().list(Regions.EU_CENTRAL_1.getName()).concat();
+ assertTrue(isEmpty(tags));
+ assertEquals(server.getRequestCount(), 1);
+ assertSent(server, "GET", "DescribeTags", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()));
+ }
+
+ public void testListTagsWithOptions() throws InterruptedException {
+ server.enqueue(jsonResponse("/tags-first.json"));
+ Iterable<Tag> tags = api.tagApi().list(Regions.EU_CENTRAL_1.getName(), paginationOptions(pageNumber(1).pageSize(5)));
+ assertEquals(size(tags), 8);
+ assertEquals(server.getRequestCount(), 1);
+ assertSent(server, "GET", "DescribeTags", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()), 1);
+ }
+
+ public void testListTagsWithOptionsReturns404() throws InterruptedException {
+ server.enqueue(response404());
+ Iterable<Tag> tags = api.tagApi().list(Regions.EU_CENTRAL_1.getName(), paginationOptions(pageNumber(2)));
+ assertTrue(isEmpty(tags));
+ assertEquals(server.getRequestCount(), 1);
+ assertSent(server, "GET", "DescribeTags", ImmutableMap.of("RegionId", Regions.EU_CENTRAL_1.getName()), 2);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/internal/BaseECSComputeServiceApiMockTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/internal/BaseECSComputeServiceApiMockTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/internal/BaseECSComputeServiceApiMockTest.java
index 1b27556..dd3938d 100644
--- a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/internal/BaseECSComputeServiceApiMockTest.java
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/compute/internal/BaseECSComputeServiceApiMockTest.java
@@ -89,6 +89,10 @@ public class BaseECSComputeServiceApiMockTest {
return new MockResponse().setStatus("HTTP/1.1 404 Not Found");
}
+ protected MockResponse response204() {
+ return new MockResponse().setStatus("HTTP/1.1 204 No Content");
+ }
+
protected String stringFromResource(String resourceName) {
try {
return Resources.toString(getClass().getResource(resourceName), Charsets.UTF_8)
@@ -98,10 +102,19 @@ public class BaseECSComputeServiceApiMockTest {
}
}
+ protected <T> T objectFromResource(String resourceName, Class<T> type) {
+ String text = stringFromResource(resourceName);
+ return json.fromJson(text, type);
+ }
+
protected RecordedRequest assertSent(MockWebServer server, String method, String action) throws InterruptedException {
return assertSent(server, method, action, ImmutableMap.<String, String>of(), null);
}
+ protected RecordedRequest assertSent(MockWebServer server, String method, String action, Integer page) throws InterruptedException {
+ return assertSent(server, method, action, ImmutableMap.<String, String>of(), page);
+ }
+
protected RecordedRequest assertSent(MockWebServer server, String method, String action, Map<String, String> queryParameters) throws InterruptedException {
return assertSent(server, method, action, queryParameters, null);
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/functions/ArrayToCommaSeparatedStringTest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/functions/ArrayToCommaSeparatedStringTest.java b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/functions/ArrayToCommaSeparatedStringTest.java
new file mode 100644
index 0000000..625606f
--- /dev/null
+++ b/aliyun-ecs/src/test/java/org/jclouds/aliyun/ecs/functions/ArrayToCommaSeparatedStringTest.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.aliyun.ecs.functions;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+@Test(groups = "unit")
+public class ArrayToCommaSeparatedStringTest {
+
+ public void testArrayOfString() {
+ String[] input = {"Cheese", "Pepperoni", "Black Olives"};
+ String actual = new ArrayToCommaSeparatedString().apply(input);
+ assertNotNull(actual);
+ assertEquals(actual, "[\"Cheese\",\"Pepperoni\",\"Black Olives\"]");
+ }
+
+ public void testSingleArrayOfString() {
+ String[] input = {"Sun"};
+ String actual = new ArrayToCommaSeparatedString().apply(input);
+ assertNotNull(actual);
+ assertEquals(actual, "[\"Sun\"]");
+ }
+
+ public void testEmptyArrayOfString() {
+ String[] input = {};
+ String actual = new ArrayToCommaSeparatedString().apply(input);
+ assertNotNull(actual);
+ assertEquals(actual, "[]");
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void testNullInput() {
+ new ArrayToCommaSeparatedString().apply(null);
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "This function is only valid for array of Strings!")
+ public void testWrongInputType() {
+ new ArrayToCommaSeparatedString().apply("wrong");
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/resources/keypair-create-res.json
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/resources/keypair-create-res.json b/aliyun-ecs/src/test/resources/keypair-create-res.json
new file mode 100644
index 0000000..f302b9d
--- /dev/null
+++ b/aliyun-ecs/src/test/resources/keypair-create-res.json
@@ -0,0 +1,6 @@
+{
+ "RequestId": "022B3F72-4403-494D-A015-219236A5432E",
+ "KeyPairFingerPrint": "e70b8c018d46a81dd881adddc34e8ff5",
+ "PrivateKeyBody": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAlU7ybrJx19O/DBP5iZE+n2ffCnDeaiI0A5DoinINPEyfyQdG\nie4Jki9iQQ/3WY05QyKlgpjFZt9ZJ0FbLF0yoExBuePVdCskN2jv0rZWE/6WR3ku\nOEuu1w3wfkcGJiN32cxrM7D455XAYd0c/KrRgajybloidQxFwPx/FmxZ7QNH66ww\nRoJndr0FUGldbusXmX4UO5d1i8vC0V6lOI+Jmq+7n92SV5lZb7rsjLwh3pnKIGi4\nF9Drt/HZzbdr0nLGyArO5KQs+xRzgj6a8VUOYyHpzkAd5gASwPZI8K5vSjMqRgee\nc6pBAGWzmQJ53n40gSs71FGHUmfAFOJdMZiE9QIDAQABAoIBADEIy1+FZRPfa4e4\n66O9Opa5Uyuno7OxZemh5mzJRgV+mJ85r3XO4f/LZfY+Gxqi4aJlt3trVrEROsNE\nmH+6X8z7Hj7BTzGmlW9JHDHURfKtEoeIiaBdYp8n6cpe4usVjN/PXYmNXkEYEiVR\nq5pjMwjlBjEtktFj5Wiaw9YGYYYPoInJdGizSjCgsnLErvCIdFgiO9QTCLRNIQsn\n4TUlIfZQGbv6w4IbtR5z6qGEbM6aYrbOyJtpmDA9972dUk1vNlR+ChUmOBVJ3ZPP\nUwyasRqTgGX3vjiKLGNzoHPT4HDewzyVoK/bzA+qyew/QZ5dE0sMHvf3E6lNuVd0\nP/ZL5uUCgYEA+W3+p9J2fNR39eKC7ckqpo+xyeluXoZ0wGE86oV4Q4SxSwE+nHYF\nC5TxhYzjCLKC6TUUlUBobxOdI873k03tTH3wMC7TVGs3TxNG70Yf8lv7Be5Tlcgf\nfgeLnUuUtzY1UASFpDjgpJxgkN/tb1vnaDfd6JNIQeHDOSaURBRV+xcCgYEAmT3L\nPhauJMAK3FyatXnef/J
Y+dpHrDTcAcfLFlUlZBb+BedG6dV03WqWe2ef7kHmsPKK\n5G4R/Bc9SpVFOpm/G6+kDRxE8WcsmPcfRKpXnkFCkYBdJO1bHcxRBAaU88Q25WiY\nBrNv5LzoWDL47LUnuL4cTw3qB4y4bi1EJklgl9MCgYEApHstb9uwuPafOK0rK8T5\ndCbT1dMyLfE6clZtBjYHrXaGN3DVqfWFtDJ+5lOWr3iQLVsMfLOhaoYjnKZxylic\nAFIYHp3yS/v72BBdOZIjpP2U1j9oLSBv6/rrzUk3A24iz+Z7fmTndoWMhFy2RTX0\nrlwQ4Lqm7pMC2uAe65oBbPcCgYBzw5fXZsDVqHJL+HUzZUZt98G5tmlwsVoGyk0k\nqNwfWbM6+HW8znGDlzLpNOY/0m8Y+5Frca+Kdm/p+QwccetKWgyfjtySVXP+dqmb\ncOfR+ND2JDe5Xsn3n9MQLHy4DmG+Op6maUW9UexgPNmJ0GyahpvSKNvEKk1lhjK2\njbY32wKBgHq90kddHF11d6efjgLmeKE6SETLYG8zwciHWc+J/LK0WizO5MRGzWKN\nExUAenjdmaVtedeYWxlMZAcNZPuzjtVZGs+VW1pRDvdJlPZx1Rl3REo5aVx1LX7I\noK2+klsagwU7TCvGHYC/1vyQrbiym8L5dfjG6J3QeAi2ZbTzYUOw\n-----END RSA PRIVATE KEY-----\n",
+ "KeyPairName": "jclouds-test"
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/resources/keypair-delete-res.json
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/resources/keypair-delete-res.json b/aliyun-ecs/src/test/resources/keypair-delete-res.json
new file mode 100644
index 0000000..a4fb26b
--- /dev/null
+++ b/aliyun-ecs/src/test/resources/keypair-delete-res.json
@@ -0,0 +1,3 @@
+{
+ "RequestId": "A2B4BEF6-5607-4A6E-B5B4-87A4E148E4F0"
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/resources/keypair-import-res.json
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/resources/keypair-import-res.json b/aliyun-ecs/src/test/resources/keypair-import-res.json
new file mode 100644
index 0000000..cf647db
--- /dev/null
+++ b/aliyun-ecs/src/test/resources/keypair-import-res.json
@@ -0,0 +1,6 @@
+{
+ "RequestId": "E5AE0C6B-A56E-4AD8-8110-D870FF46E96F",
+ "KeyPairFingerPrint": "9a1fc59d7d1c51a16d541ee475b7d7bb",
+ "PrivateKeyBody": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAkCMCNi52fH2ZEIbei35FtT4RXiLXQ9xBLA7pYVuk35G5YPSn\nzltQ52KlugU/FRI7jXLNfrw4Kt8LIt2LlaflqRWkJjOREozFHxIhjWCMM8hOV3NK\nF3vG85vhuOF6QGBSYHDCGFJ6y+KMlfVd4O2Qm/2PgqoOYOy80W8QF6ZsSAeS93Tz\nGNyb9pzcsxv2O3rRgfoqMCF5+/0T/mDLSfIiu6WRoWEeEXHRrqcOidR2gfBEkIKE\nKljcTtPaZ17u//QKVF0akhP464w+HV6tuEgAx7FOfjgqcWG4dKh77p6uCxHVxPK7\nA2bFlSLdxtBQ6SsSTOYhMx48FtQppZ1ZRstj8wIDAQABAoIBADiXxlKHw7X1ipfW\nnKKgnbYf/Km9fFAEtwIZiMDVPtMZYHQVG54GdKmlLfTwAmi/k+ph3RWZyWPr12+F\nFT1Zgu70tFLbhGaIJw2gDNR5yBK83yWu+rRlwSP9XI8+2MVWDIIZQ9xQ5i4Pcauf\nf5DFNjZJRIPFSYf869Y/iU3/5hwRZTr4HU+YQvF/tVtdstwGfMOwNrfYdouc6uVK\nQ7bbVZsdwSSZxM3kwsK9mtZTbWEi7KpbM1mO3tZuhdrvDs7Dh33sqK9PxoN83UdB\nCupi/12sBZFkNSLzhQUTSQAMPNfypUJBjAy8y6y0kmD/eztiMKMO6uk4dPZzK1jQ\nfPb6uMECgYEA2ZAY3RqTozIH51sgqan/xD+XGbj6qVD/0WQN/pBxGooDrXkRBgO9\nRb5NTcmKBBou0TNaPEWmGA0N/tbJgnUsg2jMG8LSWii+eHM0XNtimc3eGz6Bn4Ff\n09KPJQs30rhmqUy/7M+UVE8yCk5BaCWCuBPzy6TOuxVx7eJmGUusMTkCgYEAqZoB\nT6irt5s1bCPwfhh9tc7
46FoHq/nykfi0hphTGqyQniKNrq4kcXDDylel0ZbAFGaX\nDXePERZ2bKRkdYSCJGnfpMtFs2v6S35T/854qleCEO6DlIlUjBV2CmjIGztGPfhj\nsLtGcLN+TkMYZeP09Q03cC1gb06+Vy5st2kT+osCgYAlxzPKEPdZ+zIMJnLBg1d6\nSGCAgvJjvEDvpyQW9BXvuc9xq/gcx0Fyft0FiN2CYNmIUhZ1KNLykjG/8qQDFz2n\ng+cNWwMTzMdmOvr4tM+mTW0n5e60N87gBUv97ri+ym5pL36ULGdhTG8wAu6wmvLb\n6/sFfZS4P70Mxadc9RrtYQKBgFHnVpTCjtKnOKBVptEuQJ8pKZkDyUqq9RK7OWr6\nar+p8Fj9tNBTtrO10keIFkLl+zKe7HmLcGK/J0eGCCGccUDmhCNQKwPftEr64dPa\nQPl6Mwy8Mnzr6RGRV6TlPyWvdVd9+Z6igfzxIaDn1AN4l5Yz4L7imvyF2XO+rq/Q\nJd7LAoGBAMy9S/NT+gLRveAAp8tFKoZ1yYC+s+6j0ztCuEuzkDioeL+YX/9nMrD7\neWg68NuQwSxBC+yTSj4E1WJJMiHehT6Slh9cgg82Eg1jgoR/eOVns0xktCYEsOu0\nV1tVN4jMAUwClxTCwWt5znKW1XVz5I80v2A67Z+0iCvGtYChiXQw\n-----END RSA PRIVATE KEY-----\n",
+ "KeyPairName": "jclouds-test-12345"
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/resources/keypairs-first.json
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/resources/keypairs-first.json b/aliyun-ecs/src/test/resources/keypairs-first.json
new file mode 100644
index 0000000..f88c1a8
--- /dev/null
+++ b/aliyun-ecs/src/test/resources/keypairs-first.json
@@ -0,0 +1,50 @@
+{
+ "PageNumber": 1,
+ "TotalCount": 12,
+ "KeyPairs": {
+ "KeyPair": [
+ {
+ "KeyPairFingerPrint": "188a7d0fdbfbf42a632ed34b1f7f0b12",
+ "KeyPairName": "jclouds-jclouds-imported-831"
+ },
+ {
+ "KeyPairFingerPrint": "259eea89c50e16a54ccc9558a15ca8b3",
+ "KeyPairName": "jclouds-test1"
+ },
+ {
+ "KeyPairFingerPrint": "388a7d0fdbfbf42a632ed34b1f7f0b12",
+ "KeyPairName": "jclouds-jclouds-imported-832"
+ },
+ {
+ "KeyPairFingerPrint": "459eea89c50e16a54ccc9558a15ca8b3",
+ "KeyPairName": "jclouds-test2"
+ },
+ {
+ "KeyPairFingerPrint": "588a7d0fdbfbf42a632ed34b1f7f0b12",
+ "KeyPairName": "jclouds-jclouds-imported-833"
+ },
+ {
+ "KeyPairFingerPrint": "659eea89c50e16a54ccc9558a15ca8b3",
+ "KeyPairName": "jclouds-test2"
+ },
+ {
+ "KeyPairFingerPrint": "788a7d0fdbfbf42a632ed34b1f7f0b12",
+ "KeyPairName": "jclouds-jclouds-imported-834"
+ },
+ {
+ "KeyPairFingerPrint": "859eea89c50e16a54ccc9558a15ca8b3",
+ "KeyPairName": "jclouds-test3"
+ },
+ {
+ "KeyPairFingerPrint": "988a7d0fdbfbf42a632ed34b1f7f0b12",
+ "KeyPairName": "jclouds-jclouds-imported-835"
+ },
+ {
+ "KeyPairFingerPrint": "059eea89c50e16a54ccc9558a15ca8b3",
+ "KeyPairName": "jclouds-test4"
+ }
+ ]
+ },
+ "PageSize": 10,
+ "RequestId": "3E2D8822-5058-4E2F-9D51-7A0E4EC93E33"
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/resources/keypairs-last.json
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/resources/keypairs-last.json b/aliyun-ecs/src/test/resources/keypairs-last.json
new file mode 100644
index 0000000..56685b1
--- /dev/null
+++ b/aliyun-ecs/src/test/resources/keypairs-last.json
@@ -0,0 +1,18 @@
+{
+ "PageNumber": 2,
+ "TotalCount": 12,
+ "KeyPairs": {
+ "KeyPair": [
+ {
+ "KeyPairFingerPrint": "128a7d0fdbfbf42a632ed34b1f7f0b12",
+ "KeyPairName": "jclouds-jclouds-imported-836"
+ },
+ {
+ "KeyPairFingerPrint": "059eea89c50e16a54ccc9558a15ca8b3",
+ "KeyPairName": "jclouds-test5"
+ }
+ ]
+ },
+ "PageSize": 10,
+ "RequestId": "3E2D8822-5058-4E2F-9D51-7A0E4EC93E32"
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/resources/securitygroups-first.json
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/resources/securitygroups-first.json b/aliyun-ecs/src/test/resources/securitygroups-first.json
new file mode 100644
index 0000000..fa86c32
--- /dev/null
+++ b/aliyun-ecs/src/test/resources/securitygroups-first.json
@@ -0,0 +1,61 @@
+{
+ "PageNumber": 1,
+ "TotalCount": 7,
+ "PageSize": 5,
+ "RegionId": "eu-central-1",
+ "RequestId": "3F76B1CB-6930-4D5F-81E4-70F85FC239CA",
+ "SecurityGroups": {
+ "SecurityGroup": [
+ {
+ "CreationTime": "2018-07-05T12:14:19Z",
+ "Tags": {
+ "Tag": []
+ },
+ "SecurityGroupId": "sg-gw8e5qdwvppsinxlmeu9",
+ "Description": "",
+ "SecurityGroupName": "jclouds-test",
+ "VpcId": "vpc-gw8vbir5z9j9lncyrjjhx"
+ },
+ {
+ "CreationTime": "2018-09-05T12:14:21Z",
+ "Tags": {
+ "Tag": []
+ },
+ "SecurityGroupId": "sg-gw8e5qdwvppsinxlmeu2",
+ "Description": "",
+ "SecurityGroupName": "jclouds-test2",
+ "VpcId": "vpc-gw8vbir5z9j9lncyrjjhb"
+ },
+ {
+ "CreationTime": "2018-07-03T14:34:56Z",
+ "Tags": {
+ "Tag": []
+ },
+ "SecurityGroupId": "sg-gw8izkhfxvoemvocgdsj",
+ "Description": "",
+ "SecurityGroupName": "default",
+ "VpcId": "vpc-gw8vbir5z9j9lncyrjjhx"
+ },
+ {
+ "CreationTime": "2018-07-02T07:04:03Z",
+ "Tags": {
+ "Tag": []
+ },
+ "SecurityGroupId": "sg-gw838ply3g09998rmie1",
+ "Description": "",
+ "SecurityGroupName": "jclouds-aliyun-ecs",
+ "VpcId": "vpc-gw8vbir5z9j9lncyrjjhx"
+ },
+ {
+ "CreationTime": "2018-07-02T06:49:48Z",
+ "Tags": {
+ "Tag": []
+ },
+ "SecurityGroupId": "sg-gw838ply3g0993boacgo",
+ "Description": "",
+ "SecurityGroupName": "jclouds-aliyun-ecss",
+ "VpcId": "vpc-gw8vbir5z9j9lncyrjjhx"
+ }
+ ]
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/resources/securitygroups-last.json
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/resources/securitygroups-last.json b/aliyun-ecs/src/test/resources/securitygroups-last.json
new file mode 100644
index 0000000..5e6a125
--- /dev/null
+++ b/aliyun-ecs/src/test/resources/securitygroups-last.json
@@ -0,0 +1,31 @@
+{
+ "PageNumber": 2,
+ "TotalCount": 7,
+ "PageSize": 5,
+ "RegionId": "eu-central-1",
+ "RequestId": "3F76B1CB-6930-4D5F-81E4-70F85FC239CB",
+ "SecurityGroups": {
+ "SecurityGroup": [
+ {
+ "CreationTime": "2018-07-06T12:14:21Z",
+ "Tags": {
+ "Tag": []
+ },
+ "SecurityGroupId": "sg-gw8e5qdwvppsinxlmeu6",
+ "Description": "",
+ "SecurityGroupName": "jclouds-test6",
+ "VpcId": "vpc-gw8vbir5z9j9lncyrjjhx"
+ },
+ {
+ "CreationTime": "2018-08-07T12:14:21Z",
+ "Tags": {
+ "Tag": []
+ },
+ "SecurityGroupId": "sg-gw8e5qdwvppsinxlmeu7",
+ "Description": "",
+ "SecurityGroupName": "jclouds-test7",
+ "VpcId": "vpc-gw8vbir5z9j9lncyrjjha"
+ }
+ ]
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/resources/tags-first.json
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/resources/tags-first.json b/aliyun-ecs/src/test/resources/tags-first.json
new file mode 100644
index 0000000..d694c29
--- /dev/null
+++ b/aliyun-ecs/src/test/resources/tags-first.json
@@ -0,0 +1,66 @@
+{
+ "PageNumber": 1,
+ "Tags": {
+ "Tag": [
+ {
+ "ResourceTypeCount": {
+ "Securitygroup": 1
+ },
+ "TagValue": "val1",
+ "TagKey": "key1"
+ },
+ {
+ "ResourceTypeCount": {
+ "Securitygroup": 1
+ },
+ "TagValue": "val2",
+ "TagKey": "key2"
+ },
+ {
+ "ResourceTypeCount": {
+ "Securitygroup": 1
+ },
+ "TagValue": "val3",
+ "TagKey": "key3"
+ },
+ {
+ "ResourceTypeCount": {
+ "Securitygroup": 1
+ },
+ "TagValue": "val4",
+ "TagKey": "key4"
+ },
+ {
+ "ResourceTypeCount": {
+ "Securitygroup": 1
+ },
+ "TagValue": "val5",
+ "TagKey": "key5"
+ },
+ {
+ "ResourceTypeCount": {
+ "Securitygroup": 1
+ },
+ "TagValue": "val6",
+ "TagKey": "key6"
+ },
+ {
+ "ResourceTypeCount": {
+ "Securitygroup": 1
+ },
+ "TagValue": "val7",
+ "TagKey": "key7"
+ },
+ {
+ "ResourceTypeCount": {
+ "Securitygroup": 1
+ },
+ "TagValue": "val8",
+ "TagKey": "key8"
+ }
+ ]
+ },
+ "TotalCount": 10,
+ "PageSize": 8,
+ "RequestId": "3A4B8581-8AAE-4E09-A4BB-3F568AB4293B"
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/test/resources/tags-last.json
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/test/resources/tags-last.json b/aliyun-ecs/src/test/resources/tags-last.json
new file mode 100644
index 0000000..0e092c4
--- /dev/null
+++ b/aliyun-ecs/src/test/resources/tags-last.json
@@ -0,0 +1,24 @@
+{
+ "PageNumber": 2,
+ "Tags": {
+ "Tag": [
+ {
+ "ResourceTypeCount": {
+ "Securitygroup": 1
+ },
+ "TagValue": "jclouds",
+ "TagKey": "owner"
+ },
+ {
+ "ResourceTypeCount": {
+ "Securitygroup": 1
+ },
+ "TagValue": "test1",
+ "TagKey": "test1"
+ }
+ ]
+ },
+ "TotalCount": 10,
+ "PageSize": 8,
+ "RequestId": "56E7EF73-A13F-44D4-9839-0C451E999226"
+}
\ No newline at end of file
[2/2] jclouds-labs git commit: [JCLOUDS-1430] - add more features
Posted by an...@apache.org.
[JCLOUDS-1430] - add more features
- add securitygroup-api
- add keypair-api
- add tag-api
- refactor paginations
- refactor tagOptions
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/a5dbf006
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/a5dbf006
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/a5dbf006
Branch: refs/heads/master
Commit: a5dbf0065d8fa8cabcaf020b7c10fe2f7ccf8d6a
Parents: d74d7f6
Author: andreaturli <an...@gmail.com>
Authored: Thu Jul 5 15:28:48 2018 +0200
Committer: andreaturli <an...@gmail.com>
Committed: Tue Jul 31 21:30:18 2018 +0200
----------------------------------------------------------------------
.../aliyun/ecs/ECSComputeServiceApi.java | 12 ++
.../org/jclouds/aliyun/ecs/domain/Image.java | 12 +-
.../org/jclouds/aliyun/ecs/domain/Images.java | 33 ----
.../jclouds/aliyun/ecs/domain/IpProtocol.java | 41 +++++
.../org/jclouds/aliyun/ecs/domain/KeyPair.java | 40 +++++
.../aliyun/ecs/domain/KeyPairRequest.java | 76 +++++++++
.../jclouds/aliyun/ecs/domain/Permission.java | 110 +++++++++++++
.../org/jclouds/aliyun/ecs/domain/Region.java | 6 +-
.../org/jclouds/aliyun/ecs/domain/Regions.java | 81 ----------
.../org/jclouds/aliyun/ecs/domain/Request.java | 58 +++++++
.../aliyun/ecs/domain/SecurityGroup.java | 42 +++++
.../aliyun/ecs/domain/SecurityGroupRequest.java | 59 +++++++
.../org/jclouds/aliyun/ecs/domain/Zone.java | 6 +-
.../aliyun/ecs/domain/internal/Regions.java | 81 ++++++++++
.../ecs/domain/options/AddTagsOptions.java | 64 ++++++++
.../options/CreateSecurityGroupOptions.java | 78 +++++++++
.../domain/options/DeleteKeyPairOptions.java | 51 ++++++
.../ecs/domain/options/ListImagesOptions.java | 15 +-
.../ecs/domain/options/ListKeyPairsOptions.java | 64 ++++++++
.../options/ListSecurityGroupsOptions.java | 62 ++++++++
.../ecs/domain/options/ListTagsOptions.java | 75 +++++++++
.../aliyun/ecs/domain/options/TagOptions.java | 95 +++++++++++
.../jclouds/aliyun/ecs/features/ImageApi.java | 35 +++--
.../aliyun/ecs/features/SecurityGroupApi.java | 157 +++++++++++++++++++
.../aliyun/ecs/features/SshKeyPairApi.java | 142 +++++++++++++++++
.../org/jclouds/aliyun/ecs/features/TagApi.java | 143 +++++++++++++++++
.../functions/ArrayToCommaSeparatedString.java | 49 ++++++
.../ecs/functions/BaseToPagedIterable.java | 55 -------
.../ecs/compute/features/ImageApiLiveTest.java | 21 ++-
.../ecs/compute/features/ImageApiMockTest.java | 9 +-
.../features/RegionAndZoneApiLiveTest.java | 4 +-
.../features/RegionAndZoneApiMockTest.java | 2 +-
.../features/SecurityGroupApiLiveTest.java | 95 +++++++++++
.../features/SecurityGroupApiMockTest.java | 69 ++++++++
.../compute/features/SshKeyPairApiLiveTest.java | 83 ++++++++++
.../compute/features/SshKeyPairApiMockTest.java | 108 +++++++++++++
.../ecs/compute/features/TagApiLiveTest.java | 83 ++++++++++
.../ecs/compute/features/TagApiMockTest.java | 69 ++++++++
.../BaseECSComputeServiceApiMockTest.java | 13 ++
.../ArrayToCommaSeparatedStringTest.java | 57 +++++++
.../src/test/resources/keypair-create-res.json | 6 +
.../src/test/resources/keypair-delete-res.json | 3 +
.../src/test/resources/keypair-import-res.json | 6 +
.../src/test/resources/keypairs-first.json | 50 ++++++
.../src/test/resources/keypairs-last.json | 18 +++
.../test/resources/securitygroups-first.json | 61 +++++++
.../src/test/resources/securitygroups-last.json | 31 ++++
aliyun-ecs/src/test/resources/tags-first.json | 66 ++++++++
aliyun-ecs/src/test/resources/tags-last.json | 24 +++
49 files changed, 2407 insertions(+), 213 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/ECSComputeServiceApi.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/ECSComputeServiceApi.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/ECSComputeServiceApi.java
index 140b098..bb24cf0 100644
--- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/ECSComputeServiceApi.java
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/ECSComputeServiceApi.java
@@ -18,6 +18,9 @@ package org.jclouds.aliyun.ecs;
import org.jclouds.aliyun.ecs.features.ImageApi;
import org.jclouds.aliyun.ecs.features.RegionAndZoneApi;
+import org.jclouds.aliyun.ecs.features.SecurityGroupApi;
+import org.jclouds.aliyun.ecs.features.SshKeyPairApi;
+import org.jclouds.aliyun.ecs.features.TagApi;
import org.jclouds.rest.annotations.Delegate;
import java.io.Closeable;
@@ -30,4 +33,13 @@ public interface ECSComputeServiceApi extends Closeable {
@Delegate
RegionAndZoneApi regionAndZoneApi();
+ @Delegate
+ SecurityGroupApi securityGroupApi();
+
+ @Delegate
+ SshKeyPairApi sshKeyPairApi();
+
+ @Delegate
+ TagApi tagApi();
+
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Image.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Image.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Image.java
index a65bb8b..328d6fe 100644
--- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Image.java
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Image.java
@@ -33,21 +33,21 @@ public abstract class Image {
"ImageOwnerAlias", "Progress", "IsSupportCloudinit", "Usage", "CreationTime", "Tags",
"ImageVersion", "Status", "ImageName", "IsSupportIoOptimized", "IsSelfShared", "IsCopied",
"IsSubscribed", "Platform", "Size"})
- public static Image create(String imageId, String description, String productCode, String osType,
+ public static Image create(String id, String description, String productCode, String osType,
String architecture, String osName, Map<String, List<DiskDeviceMapping>> diskDeviceMappings,
String imageOwnerAlias, String progress, Boolean isSupportCloudinit, String usage, Date creationTime,
- Map<String, List<Tag>> tags, String imageVersion, String status, String imageName,
+ Map<String, List<Tag>> tags, String imageVersion, String status, String name,
Boolean isSupportIoOptimized, Boolean isSelfShared, Boolean isCopied, Boolean isSubscribed, String platform,
String size) {
- return new AutoValue_Image(imageId, description, productCode, osType, architecture, osName,
+ return new AutoValue_Image(id, description, productCode, osType, architecture, osName,
diskDeviceMappings == null ?
ImmutableMap.<String, List<DiskDeviceMapping>>of() :
ImmutableMap.copyOf(diskDeviceMappings), imageOwnerAlias, progress, isSupportCloudinit, usage,
creationTime, tags == null ? ImmutableMap.<String, List<Tag>>of() : ImmutableMap.copyOf(tags), imageVersion,
- status, imageName, isSupportIoOptimized, isSelfShared, isCopied, isSubscribed, platform, size);
+ status, name, isSupportIoOptimized, isSelfShared, isCopied, isSubscribed, platform, size);
}
- public abstract String imageId();
+ public abstract String id();
public abstract String description();
@@ -77,7 +77,7 @@ public abstract class Image {
public abstract String status();
- public abstract String imageName();
+ public abstract String name();
public abstract Boolean isSupportIoOptimizeds();
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Images.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Images.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Images.java
deleted file mode 100644
index b0e3af3..0000000
--- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Images.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.aliyun.ecs.domain;
-
-import org.jclouds.aliyun.ecs.domain.internal.PaginatedCollection;
-
-import java.beans.ConstructorProperties;
-import java.util.Map;
-
-/**
- * A collection of Image
- */
-public class Images extends PaginatedCollection<Image> {
-
- @ConstructorProperties({ "Images", "PageNumber", "TotalCount", "PageSize", "RegionId", "RequestId" })
- public Images(Map<String, Iterable<Image>> content, Integer pageNumber, Integer totalCount, Integer pageSize, String regionId, String requestId) {
- super(content, pageNumber, totalCount, pageSize, regionId, requestId);
- }
-}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/IpProtocol.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/IpProtocol.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/IpProtocol.java
new file mode 100644
index 0000000..ca02d9e
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/IpProtocol.java
@@ -0,0 +1,41 @@
+/*
+ * 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.aliyun.ecs.domain;
+
+import com.google.common.base.Enums;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * IP protocol. Not case sensitive. Optional values:
+ * icmp
+ * gre
+ * tcp
+ * udp
+ * all: Support four protocols at the same time
+ */
+public enum IpProtocol {
+ ICMP, GRE, TCP, UDP, ALL;
+
+ public static IpProtocol fromValue(String value) {
+ Optional<IpProtocol> ipProtocol = Enums.getIfPresent(IpProtocol.class, value.toUpperCase());
+ checkArgument(ipProtocol.isPresent(), "Expected one of %s but was %s", Joiner.on(',').join(IpProtocol.values()), value);
+ return ipProtocol.get();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/KeyPair.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/KeyPair.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/KeyPair.java
new file mode 100644
index 0000000..83e148f
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/KeyPair.java
@@ -0,0 +1,40 @@
+/*
+ * 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.aliyun.ecs.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+@AutoValue
+public abstract class KeyPair {
+
+ KeyPair() {}
+
+ @SerializedNames({ "KeyPairName", "KeyPairFingerPrint", "PrivateKeyBody" })
+ public static KeyPair create(String name, String keyPairFingerPrint, String privateKeyBody) {
+ return new AutoValue_KeyPair(name, keyPairFingerPrint, privateKeyBody);
+ }
+
+ public abstract String name();
+
+ public abstract String keyPairFingerPrint();
+
+ @Nullable
+ public abstract String privateKeyBody();
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/KeyPairRequest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/KeyPairRequest.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/KeyPairRequest.java
new file mode 100644
index 0000000..a55fe74
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/KeyPairRequest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.aliyun.ecs.domain;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+
+import java.beans.ConstructorProperties;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class KeyPairRequest extends Request {
+
+ private final String keyPairName;
+ private final String keyPairFingerPrint;
+ private final String privateKeyBody;
+
+ @ConstructorProperties({ "RequestId", "KeyPairName", "KeyPairFingerPrint", "PrivateKeyBody" })
+ public KeyPairRequest(String requestId, String keyPairName, String keyPairFingerPrint, String privateKeyBody) {
+ super(requestId);
+ this.keyPairName = checkNotNull(keyPairName, "name");
+ this.keyPairFingerPrint = checkNotNull(keyPairFingerPrint, "keyPairFingerPrint");
+ this.privateKeyBody = checkNotNull(privateKeyBody, "privateKeyBody");
+ }
+
+ public String getKeyPairName() {
+ return keyPairName;
+ }
+
+ public String getKeyPairFingerPrint() {
+ return keyPairFingerPrint;
+ }
+
+ public String getPrivateKeyBody() {
+ return privateKeyBody;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ if (!super.equals(o)) return false;
+ KeyPairRequest that = (KeyPairRequest) o;
+ return Objects.equal(keyPairName, that.keyPairName) &&
+ Objects.equal(keyPairFingerPrint, that.keyPairFingerPrint) &&
+ Objects.equal(privateKeyBody, that.privateKeyBody);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), keyPairName, keyPairFingerPrint, privateKeyBody);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("name", keyPairName)
+ .add("keyPairFingerPrint", keyPairFingerPrint)
+ .add("privateKeyBody", privateKeyBody)
+ .toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Permission.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Permission.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Permission.java
new file mode 100644
index 0000000..003ccf1
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Permission.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.aliyun.ecs.domain;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Enums;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import org.jclouds.json.SerializedNames;
+
+import java.util.Date;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+@AutoValue
+public abstract class Permission {
+
+ public enum NicType {
+ INTERNET, INTRANET;
+
+ public static NicType fromValue(String value) {
+ Optional<NicType> nicType = Enums.getIfPresent(NicType.class, value.toUpperCase());
+ checkArgument(nicType.isPresent(), "Expected one of %s but was %s", Joiner.on(',').join(NicType.values()), value);
+ return nicType.get();
+ }
+ }
+
+ public enum Policy {
+ ACCEPT, DROP;
+
+ public static Policy fromValue(String value) {
+ Optional<Policy> policy = Enums.getIfPresent(Policy.class, value.toUpperCase());
+ checkArgument(policy.isPresent(), "Expected one of %s but was %s", Joiner.on(',').join(Policy.values()), value);
+ return policy.get();
+ }
+ }
+
+ public enum Direction {
+ EGRESS, ALL;
+
+ public static Direction fromValue(String value) {
+ Optional<Direction> direction = Enums.getIfPresent(Direction.class, value.toUpperCase());
+ checkArgument(direction.isPresent(), "Expected one of %s but was %s", Joiner.on(',').join(Direction.values()), value);
+ return direction.get();
+ }
+ }
+
+ Permission() {}
+
+ @SerializedNames({"SourceCidrIp", "DestCidrIp", "Description", "NicType",
+ "DestGroupName", "PortRange", "DestGroupId", "Direction", "Priority",
+ "IpProtocol", "SourceGroupOwnerAccount", "Policy", "CreateTime",
+ "SourceGroupId", "DestGroupOwnerAccount", "SourceGroupName"})
+ public static Permission create(String sourceCidrIp, String destCidrIp, String description, NicType nicType,
+ String destGroupName, String portRange, String destGroupId, Direction direction,
+ String priority,
+ IpProtocol ipProtocol, String sourceGroupOwnerAccount, Policy policy,
+ Date createTime, String sourceGroupId, String destGroupOwnerAccount, String sourceGroupName) {
+ return new AutoValue_Permission(sourceCidrIp, destCidrIp, description, nicType, destGroupName, portRange,
+ destGroupId, direction, priority, ipProtocol, sourceGroupOwnerAccount, policy, createTime, sourceGroupId,
+ destGroupOwnerAccount, sourceGroupName);
+ }
+
+ public abstract String sourceCidrIp();
+
+ public abstract String destCidrIp();
+
+ public abstract String description();
+
+ public abstract NicType nicType();
+
+ public abstract String destGroupName();
+
+ public abstract String portRange();
+
+ public abstract String destGroupId();
+
+ public abstract Direction direction();
+
+ public abstract String priority();
+
+ public abstract IpProtocol ipProtocol();
+
+ public abstract String sourceGroupOwnerAccount();
+
+ public abstract Policy policy();
+
+ public abstract Date createTime();
+
+ public abstract String sourceGroupId();
+
+ public abstract String destGroupOwnerAccount();
+
+ public abstract String sourceGroupName();
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Region.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Region.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Region.java
index ce2f6b7..cacdf4b 100644
--- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Region.java
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Region.java
@@ -25,11 +25,11 @@ public abstract class Region {
Region() {}
@SerializedNames({ "RegionId", "LocalName" })
- public static Region create(String regionId, String localName) {
- return new AutoValue_Region(regionId, localName);
+ public static Region create(String id, String localName) {
+ return new AutoValue_Region(id, localName);
}
- public abstract String regionId();
+ public abstract String id();
public abstract String localName();
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Regions.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Regions.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Regions.java
deleted file mode 100644
index e0a89c1..0000000
--- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Regions.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.aliyun.ecs.domain;
-
-/**
- * Enumeration of region names
- */
-public enum Regions {
-
- US_EAST_1("us-east-1", "US (Virginia)"),
- US_WEST_1("us-west-1", "US West (Silicon Valley)"),
- EU_CENTRAL_1("eu-central-1", "Germany (Frankfurt)"),
- AP_NORTHEAST_1("ap-northeast-1", "Japan (Tokyo)"),
- AP_SOUTH_1("ap-south-1", "India (Mumbai)"),
- AP_SOUTHEAST_1("ap-southeast-1", "Singapore"),
- AP_SOUTHEAST_2("ap-southeast-2", "Australia (Sydney)"),
- AP_SOUTHEAST_3("ap-southeast-3", "Malaysia (Kuala Lumpur)"),
- AP_SOUTHEAST_5("ap-southeast-5", "Indonesia (Jakarta)"),
- CN_NORTH_1("cn-qingdao", "China (Qingdao)"),
- CN_NORTH_2("cn-beijing", "China (Beijing)"),
- CN_NORTH_3("cn-zhangjiakou", "China (Zhangjiakou)"),
- CN_NORTH_5("cn-huhehaote", "China (Huhehaote)"),
- CN_EAST_1("cn-hangzhou", "China (Hangzou)"),
- CN_EAST_2("cn-shanghai", "China (Shanghai)"),
- CN_SOUTH_1("cn-shenzhen", "China (Shenzhen)"),
- CN_SOUTH_2("cn-hongkong", "China (Hongkong)"),
- ME_EAST_1("me-east-1", "UAE (Dubai)");
-
- private final String name;
- private final String description;
-
- Regions(String name, String description) {
- this.name = name;
- this.description = description;
- }
-
- /**
- * The name of this region, used in the regions.xml file to identify it.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Descriptive readable name for this region.
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Returns a region enum corresponding to the given region name.
- *
- * @param regionName
- * The name of the region. Ex.: eu-west-1
- * @return Region enum representing the given region name.
- */
- public static Regions fromName(String regionName) {
- for (Regions region : Regions.values()) {
- if (region.getName().equals(regionName)) {
- return region;
- }
- }
- throw new IllegalArgumentException("Cannot create enum from " + regionName + " value!");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Request.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Request.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Request.java
new file mode 100644
index 0000000..9ab7535
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Request.java
@@ -0,0 +1,58 @@
+/*
+ * 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.aliyun.ecs.domain;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+
+import java.beans.ConstructorProperties;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class Request {
+
+ private final String requestId;
+
+ @ConstructorProperties({ "RequestId" })
+ public Request(String requestId) {
+ this.requestId = checkNotNull(requestId, "requestId");
+ }
+
+ public String getRequestId() {
+ return requestId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ Request request = (Request) o;
+ return Objects.equal(requestId, request.requestId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(requestId);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("requestId", requestId).toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroup.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroup.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroup.java
new file mode 100644
index 0000000..3fd0658
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroup.java
@@ -0,0 +1,42 @@
+/*
+ * 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.aliyun.ecs.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.json.SerializedNames;
+
+@AutoValue
+public abstract class SecurityGroup {
+
+ SecurityGroup() {
+ }
+
+ @SerializedNames({ "SecurityGroupId", "Description", "SecurityGroupName", "VpcId" })
+ public static SecurityGroup create(String id, String description, String name,
+ String vpcId) {
+ return new AutoValue_SecurityGroup(id, description, name, vpcId);
+ }
+
+ public abstract String id();
+
+ public abstract String description();
+
+ public abstract String name();
+
+ public abstract String vpcId();
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroupRequest.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroupRequest.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroupRequest.java
new file mode 100644
index 0000000..0a2606a
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/SecurityGroupRequest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.aliyun.ecs.domain;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+
+import java.beans.ConstructorProperties;
+
+public class SecurityGroupRequest extends Request {
+
+ private final String securityGroupId;
+
+ @ConstructorProperties({ "RequestId", "SecurityGroupId" })
+ public SecurityGroupRequest(String requestId, String securityGroupId) {
+ super(requestId);
+ this.securityGroupId = securityGroupId;
+ }
+
+ public String getSecurityGroupId() {
+ return securityGroupId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ if (!super.equals(o))
+ return false;
+ SecurityGroupRequest that = (SecurityGroupRequest) o;
+ return Objects.equal(securityGroupId, that.securityGroupId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), securityGroupId);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("id", securityGroupId).toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Zone.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Zone.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Zone.java
index 87709e2..9e66651 100644
--- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Zone.java
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/Zone.java
@@ -31,7 +31,7 @@ public abstract class Zone {
@SerializedNames({ "ZoneId", "LocalName", "DedicatedHostGenerations", "AvailableResourceCreation",
"AvailableDedicatedHostTypes", "AvailableResources", "AvailableInstanceTypes",
"AvailableVolumeCategories", "AvailableDiskCategories" })
- public static Zone create(String zoneId, String localName,
+ public static Zone create(String id, String localName,
Map<String, List<Object>> dedicatedHostGenerations, // FIXME neither doc nor example showed the type in the list
Map<String, List<String>> availableResourceCreation,
Map<String, List<String>> availableDedicatedHostTypes,
@@ -39,7 +39,7 @@ public abstract class Zone {
Map<String, List<String>> availableInstanceTypes,
Map<String, List<String>> availableVolumeCategories,
Map<String, List<String>> availableDiskCategories) {
- return new AutoValue_Zone(zoneId, localName,
+ return new AutoValue_Zone(id, localName,
dedicatedHostGenerations == null ? ImmutableMap.<String, List<Object>>of() : ImmutableMap.copyOf(dedicatedHostGenerations),
availableResourceCreation == null ? ImmutableMap.<String, List<String>>of() : ImmutableMap.copyOf(availableResourceCreation),
availableDedicatedHostTypes == null ? ImmutableMap.<String, List<String>>of() : ImmutableMap.copyOf(availableDedicatedHostTypes),
@@ -50,7 +50,7 @@ public abstract class Zone {
);
}
- public abstract String zoneId();
+ public abstract String id();
public abstract String localName();
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/internal/Regions.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/internal/Regions.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/internal/Regions.java
new file mode 100644
index 0000000..e353b47
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/internal/Regions.java
@@ -0,0 +1,81 @@
+/*
+ * 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.aliyun.ecs.domain.internal;
+
+/**
+ * Enumeration of region names
+ */
+public enum Regions {
+
+ US_EAST_1("us-east-1", "US (Virginia)"),
+ US_WEST_1("us-west-1", "US West (Silicon Valley)"),
+ EU_CENTRAL_1("eu-central-1", "Germany (Frankfurt)"),
+ AP_NORTHEAST_1("ap-northeast-1", "Japan (Tokyo)"),
+ AP_SOUTH_1("ap-south-1", "India (Mumbai)"),
+ AP_SOUTHEAST_1("ap-southeast-1", "Singapore"),
+ AP_SOUTHEAST_2("ap-southeast-2", "Australia (Sydney)"),
+ AP_SOUTHEAST_3("ap-southeast-3", "Malaysia (Kuala Lumpur)"),
+ AP_SOUTHEAST_5("ap-southeast-5", "Indonesia (Jakarta)"),
+ CN_NORTH_1("cn-qingdao", "China (Qingdao)"),
+ CN_NORTH_2("cn-beijing", "China (Beijing)"),
+ CN_NORTH_3("cn-zhangjiakou", "China (Zhangjiakou)"),
+ CN_NORTH_5("cn-huhehaote", "China (Huhehaote)"),
+ CN_EAST_1("cn-hangzhou", "China (Hangzou)"),
+ CN_EAST_2("cn-shanghai", "China (Shanghai)"),
+ CN_SOUTH_1("cn-shenzhen", "China (Shenzhen)"),
+ CN_SOUTH_2("cn-hongkong", "China (Hongkong)"),
+ ME_EAST_1("me-east-1", "UAE (Dubai)");
+
+ private final String name;
+ private final String description;
+
+ Regions(String name, String description) {
+ this.name = name;
+ this.description = description;
+ }
+
+ /**
+ * The name of this region, used in the regions.xml file to identify it.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Descriptive readable name for this region.
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Returns a region enum corresponding to the given region name.
+ *
+ * @param regionName
+ * The name of the region. Ex.: eu-west-1
+ * @return Region enum representing the given region name.
+ */
+ public static Regions fromName(String regionName) {
+ for (Regions region : Regions.values()) {
+ if (region.getName().equals(regionName)) {
+ return region;
+ }
+ }
+ throw new IllegalArgumentException("Cannot create enum from " + regionName + " value!");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/AddTagsOptions.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/AddTagsOptions.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/AddTagsOptions.java
new file mode 100644
index 0000000..700f41d
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/AddTagsOptions.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.aliyun.ecs.domain.options;
+
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+public class AddTagsOptions extends BaseHttpRequestOptions {
+ public static final String RESOURCE_ID_PARAM = "ResourceId";
+ public static final String RESOURCE_TYPE_PARAM = "ResourceType";
+
+ public AddTagsOptions resourceId(String resourceId) {
+ queryParameters.put(RESOURCE_ID_PARAM, resourceId);
+ return this;
+ }
+
+ public AddTagsOptions resourceType(String resourceType) {
+ queryParameters.put(RESOURCE_TYPE_PARAM, resourceType);
+ return this;
+ }
+
+ public AddTagsOptions tagOptions(final TagOptions tagOptions) {
+ this.queryParameters.putAll(tagOptions.buildQueryParameters());
+ return this;
+ }
+
+ public static final class Builder {
+
+ /**
+ * @see {@link AddTagsOptions#resourceId(String)}
+ */
+ public static AddTagsOptions resourceId(String resourceId) {
+ return new AddTagsOptions().resourceId(resourceId);
+ }
+
+ /**
+ * @see {@link AddTagsOptions#resourceType(String)}
+ */
+ public static AddTagsOptions resourceType(String resourceType) {
+ return new AddTagsOptions().resourceType(resourceType);
+ }
+
+ /**
+ * @see ListTagsOptions#paginationOptions(PaginationOptions)
+ */
+ public static ListTagsOptions paginationOptions(PaginationOptions paginationOptions) {
+ return new ListTagsOptions().paginationOptions(paginationOptions);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/CreateSecurityGroupOptions.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/CreateSecurityGroupOptions.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/CreateSecurityGroupOptions.java
new file mode 100644
index 0000000..b98be4f
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/CreateSecurityGroupOptions.java
@@ -0,0 +1,78 @@
+/*
+ * 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.aliyun.ecs.domain.options;
+
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+public class CreateSecurityGroupOptions extends BaseHttpRequestOptions {
+ public static final String SECURITY_GROUP_NAME_PARAM = "SecurityGroupName";
+ public static final String DESCRIPTION_PARAM = "Description";
+ public static final String VPC_ID_PARAM = "VpcId";
+ public static final String CLIENT_TOKEN_PARAM = "ClientToken";
+
+ public CreateSecurityGroupOptions securityGroupName(String securityGroupName) {
+ queryParameters.put(SECURITY_GROUP_NAME_PARAM, securityGroupName);
+ return this;
+ }
+
+ public CreateSecurityGroupOptions description(String description) {
+ queryParameters.put(DESCRIPTION_PARAM, description);
+ return this;
+ }
+
+ public CreateSecurityGroupOptions vpcId(String vpcId) {
+ queryParameters.put(VPC_ID_PARAM, vpcId);
+ return this;
+ }
+
+ public CreateSecurityGroupOptions clientToken(String clientToken) {
+ queryParameters.put(CLIENT_TOKEN_PARAM, clientToken);
+ return this;
+ }
+
+ public static final class Builder {
+
+ /**
+ * @see {@link CreateSecurityGroupOptions#securityGroupName(String)}
+ */
+ public static CreateSecurityGroupOptions securityGroupName(String securityGroupName) {
+ return new CreateSecurityGroupOptions().securityGroupName(securityGroupName);
+ }
+
+ /**
+ * @see {@link CreateSecurityGroupOptions#description(String)}
+ */
+ public static CreateSecurityGroupOptions description(String description) {
+ return new CreateSecurityGroupOptions().description(description);
+ }
+
+ /**
+ * @see {@link CreateSecurityGroupOptions#vpcId(String)}
+ */
+ public static CreateSecurityGroupOptions vpcId(String vpcId) {
+ return new CreateSecurityGroupOptions().vpcId(vpcId);
+ }
+
+ /**
+ * @see {@link CreateSecurityGroupOptions#clientToken(String)}
+ */
+ public static CreateSecurityGroupOptions clientToken(String clientToken) {
+ return new CreateSecurityGroupOptions().clientToken(clientToken);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/DeleteKeyPairOptions.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/DeleteKeyPairOptions.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/DeleteKeyPairOptions.java
new file mode 100644
index 0000000..c372032
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/DeleteKeyPairOptions.java
@@ -0,0 +1,51 @@
+/*
+ * 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.aliyun.ecs.domain.options;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+import java.util.Arrays;
+
+public class DeleteKeyPairOptions extends BaseHttpRequestOptions {
+
+ public static final String KEYPAIR_NAMES_PARAM = "KeyPairNames";
+
+ public DeleteKeyPairOptions keyPairNames(String... keyPairNames) {
+ String keyPairNamesAsString = Joiner.on(",")
+ .join(Iterables.transform(Arrays.asList(keyPairNames), new Function<String, String>() {
+ @Override
+ public String apply(String s) {
+ return new StringBuilder(s.length() + 1).append('"').append(s).append('"').toString();
+ }
+ }));
+ queryParameters.put(KEYPAIR_NAMES_PARAM, String.format("[%s]", keyPairNamesAsString));
+ return this;
+ }
+
+ public static final class Builder {
+
+ /**
+ * @see {@link DeleteKeyPairOptions#keyPairNames(String...)}
+ */
+ public static DeleteKeyPairOptions keyPairNames(String... keyPairNames) {
+ return new DeleteKeyPairOptions().keyPairNames(keyPairNames);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListImagesOptions.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListImagesOptions.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListImagesOptions.java
index d30c350..34972a4 100644
--- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListImagesOptions.java
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListImagesOptions.java
@@ -16,13 +16,9 @@
*/
package org.jclouds.aliyun.ecs.domain.options;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.collect.Iterables;
+import org.jclouds.aliyun.ecs.functions.ArrayToCommaSeparatedString;
import org.jclouds.http.options.BaseHttpRequestOptions;
-import java.util.Arrays;
-
public class ListImagesOptions extends BaseHttpRequestOptions {
public static final String IMAGE_ID_PARAM = "ImageId";
public static final String STATUS_PARAM = "Status";
@@ -32,14 +28,7 @@ public class ListImagesOptions extends BaseHttpRequestOptions {
public static final String USAGE_PARAM = "Usage";
public ListImagesOptions imageIds(String... instanceIds) {
- String instanceIdsAsString = Joiner.on(",")
- .join(Iterables.transform(Arrays.asList(instanceIds), new Function<String, String>() {
- @Override
- public String apply(String s) {
- return new StringBuilder(s.length() + 1).append('"').append(s).append('"').toString();
- }
- }));
- queryParameters.put(IMAGE_ID_PARAM, String.format("[%s]", instanceIdsAsString));
+ queryParameters.put(IMAGE_ID_PARAM, String.format("[%s]", new ArrayToCommaSeparatedString().apply(instanceIds)));
return this;
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListKeyPairsOptions.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListKeyPairsOptions.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListKeyPairsOptions.java
new file mode 100644
index 0000000..9a7eb09
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListKeyPairsOptions.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.aliyun.ecs.domain.options;
+
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+public class ListKeyPairsOptions extends BaseHttpRequestOptions {
+ public static final String KEY_PAIR_FINGERPRINT_PARAM = "KeyPairFingerPrint";
+ public static final String KEY_PAIR_NAME_PARAM = "KeyPairName";
+
+ public ListKeyPairsOptions keyPairFingerPrint(String keyPairFingerPrint) {
+ queryParameters.put(KEY_PAIR_FINGERPRINT_PARAM, keyPairFingerPrint);
+ return this;
+ }
+
+
+ public ListKeyPairsOptions keyPairName(String keyPairName) {
+ queryParameters.put(KEY_PAIR_NAME_PARAM, keyPairName);
+ return this;
+ }
+
+ public ListKeyPairsOptions paginationOptions(final PaginationOptions paginationOptions) {
+ this.queryParameters.putAll(paginationOptions.buildQueryParameters());
+ return this;
+ }
+
+ public static final class Builder {
+
+ /**
+ * @see {@link ListKeyPairsOptions#keyPairFingerPrint(String)}
+ */
+ public static ListKeyPairsOptions keyPairFingerPrint(String keyPairFingerPrint) {
+ return new ListKeyPairsOptions().keyPairFingerPrint(keyPairFingerPrint);
+ }
+
+ /**
+ * @see {@link ListKeyPairsOptions#keyPairName(String)}
+ */
+ public static ListKeyPairsOptions keyPairName(String keyPairName) {
+ return new ListKeyPairsOptions().keyPairName(keyPairName);
+ }
+
+ /**
+ * @see ListKeyPairsOptions#paginationOptions(PaginationOptions)
+ */
+ public static ListKeyPairsOptions paginationOptions(PaginationOptions paginationOptions) {
+ return new ListKeyPairsOptions().paginationOptions(paginationOptions);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListSecurityGroupsOptions.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListSecurityGroupsOptions.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListSecurityGroupsOptions.java
new file mode 100644
index 0000000..3f7d215
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListSecurityGroupsOptions.java
@@ -0,0 +1,62 @@
+/*
+ * 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.aliyun.ecs.domain.options;
+
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+public class ListSecurityGroupsOptions extends BaseHttpRequestOptions {
+ public static final String VPC_ID_PARAM = "VpcId";
+
+ public ListSecurityGroupsOptions vpcId(String vpcId) {
+ queryParameters.put(VPC_ID_PARAM, vpcId);
+ return this;
+ }
+
+ public ListSecurityGroupsOptions paginationOptions(final PaginationOptions paginationOptions) {
+ this.queryParameters.putAll(paginationOptions.buildQueryParameters());
+ return this;
+ }
+
+ public ListSecurityGroupsOptions tagOptions(final TagOptions tagOptions) {
+ this.queryParameters.putAll(tagOptions.buildQueryParameters());
+ return this;
+ }
+
+ public static final class Builder {
+
+ /**
+ * @see {@link ListSecurityGroupsOptions#vpcId(String)}
+ */
+ public static ListSecurityGroupsOptions vpcId(String vpcId) {
+ return new ListSecurityGroupsOptions().vpcId(vpcId);
+ }
+
+ /**
+ * @see ListSecurityGroupsOptions#paginationOptions(PaginationOptions)
+ */
+ public static ListSecurityGroupsOptions paginationOptions(PaginationOptions paginationOptions) {
+ return new ListSecurityGroupsOptions().paginationOptions(paginationOptions);
+ }
+
+ /**
+ * @see ListSecurityGroupsOptions#tagOptions(TagOptions)
+ */
+ public static ListSecurityGroupsOptions tagOptions(TagOptions tagOptions) {
+ return new ListSecurityGroupsOptions().tagOptions(tagOptions);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListTagsOptions.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListTagsOptions.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListTagsOptions.java
new file mode 100644
index 0000000..05a4621
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/ListTagsOptions.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.aliyun.ecs.domain.options;
+
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+public class ListTagsOptions extends BaseHttpRequestOptions {
+ public static final String RESOURCE_ID_PARAM = "ResourceId";
+ public static final String RESOURCE_TYPE_PARAM = "ResourceType";
+
+ public ListTagsOptions resourceId(String resourceId) {
+ queryParameters.put(RESOURCE_ID_PARAM, resourceId);
+ return this;
+ }
+
+ public ListTagsOptions resourceType(String resourceType) {
+ queryParameters.put(RESOURCE_TYPE_PARAM, resourceType);
+ return this;
+ }
+
+ public ListTagsOptions paginationOptions(final PaginationOptions paginationOptions) {
+ this.queryParameters.putAll(paginationOptions.buildQueryParameters());
+ return this;
+ }
+
+ public ListTagsOptions tagOptions(final TagOptions tagOptions) {
+ this.queryParameters.putAll(tagOptions.buildQueryParameters());
+ return this;
+ }
+
+ public static final class Builder {
+
+ /**
+ * @see {@link ListTagsOptions#resourceId(String)}
+ */
+ public static ListTagsOptions resourceId(String resourceId) {
+ return new ListTagsOptions().resourceId(resourceId);
+ }
+
+ /**
+ * @see {@link ListTagsOptions#resourceType(String)}
+ */
+ public static ListTagsOptions resourceType(String resourceType) {
+ return new ListTagsOptions().resourceType(resourceType);
+ }
+
+ /**
+ * @see ListTagsOptions#paginationOptions(PaginationOptions)
+ */
+ public static ListTagsOptions paginationOptions(PaginationOptions paginationOptions) {
+ return new ListTagsOptions().paginationOptions(paginationOptions);
+ }
+
+ /**
+ * @see ListTagsOptions#tagOptions(TagOptions)
+ */
+ public static ListTagsOptions tagOptions(TagOptions tagOptions) {
+ return new ListTagsOptions().tagOptions(tagOptions);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/TagOptions.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/TagOptions.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/TagOptions.java
new file mode 100644
index 0000000..4e3068e
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/domain/options/TagOptions.java
@@ -0,0 +1,95 @@
+/*
+ * 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.aliyun.ecs.domain.options;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+public class TagOptions extends BaseHttpRequestOptions {
+
+ private static final List<String> FORBIDDEN_PREFIX = ImmutableList.of("aliyun", "acs", "http://", "https://");
+ private static final String TAG_KEY_TEMPLATE = "Tag.%d.Key";
+ private static final String TAG_VALUE_TEMPLATE = "Tag.%d.Value";
+
+ /**
+ * Tag keys can be up to 64 characters in length.
+ * Cannot begin with aliyun, acs:, http://, or https://. Cannot be a null string.
+ *
+ * Tag values can be up to 128 characters in length.
+ * Cannot begin with aliyun, http://, or https://. Can be a null string.
+ */
+ public TagOptions tag(int pos, final String key, final String value) {
+ validateInput(key, 64);
+ validateInput(value, 128);
+ queryParameters.put(String.format(TAG_KEY_TEMPLATE, pos), key);
+ queryParameters.put(String.format(TAG_VALUE_TEMPLATE, pos), value);
+ return this;
+ }
+
+ public TagOptions tag(int pos, String key) {
+ validateInput(key, 64);
+ queryParameters.put(String.format(TAG_KEY_TEMPLATE, pos), key);
+ queryParameters.put(String.format(TAG_VALUE_TEMPLATE, pos), "");
+ return this;
+ }
+
+ public TagOptions keys(Set<String> keys) {
+ checkState(keys.size() <= 5, "keys must be <= 5");
+ int i = 1;
+ for (String key : keys) {
+ tag(i, key);
+ i++;
+ }
+ return this;
+ }
+
+ public static class Builder {
+
+ public static TagOptions tag(int pos, String key, String value) {
+ return new TagOptions().tag(pos, key, value);
+ }
+
+ public static TagOptions tag(int pos, String key) {
+ return new TagOptions().tag(pos, key);
+ }
+
+ public static TagOptions keys(Set<String> keys) {
+ return new TagOptions().keys(keys);
+ }
+ }
+
+ private void validateInput(final String input, int maxLength) {
+ checkNotNull(input);
+ checkState(input.length() <= maxLength, String.format("input must be <= %d chars", maxLength));
+ checkState(!Iterables.any(FORBIDDEN_PREFIX, new Predicate<String>() {
+ @Override
+ public boolean apply(@Nullable String input) {
+ return input.startsWith(input);
+ }
+ }), "Cannot starts with " + Iterables.toString(FORBIDDEN_PREFIX));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/ImageApi.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/ImageApi.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/ImageApi.java
index 68572ef..e45e8d4 100644
--- a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/ImageApi.java
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/ImageApi.java
@@ -17,19 +17,20 @@
package org.jclouds.aliyun.ecs.features;
import com.google.common.base.Function;
-import com.google.common.base.Optional;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
import com.google.inject.TypeLiteral;
import org.jclouds.Constants;
import org.jclouds.Fallbacks;
import org.jclouds.aliyun.ecs.ECSComputeServiceApi;
import org.jclouds.aliyun.ecs.domain.Image;
-import org.jclouds.aliyun.ecs.domain.Images;
+import org.jclouds.aliyun.ecs.domain.internal.PaginatedCollection;
import org.jclouds.aliyun.ecs.domain.options.ListImagesOptions;
import org.jclouds.aliyun.ecs.domain.options.PaginationOptions;
import org.jclouds.aliyun.ecs.filters.FormSign;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
-import org.jclouds.collect.internal.Arg0ToPagedIterable;
+import org.jclouds.collect.internal.ArgsToPagedIterable;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.json.Json;
import org.jclouds.rest.annotations.Fallback;
@@ -45,6 +46,9 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
+import java.beans.ConstructorProperties;
+import java.util.List;
+import java.util.Map;
/**
* https://www.alibabacloud.com/help/doc-detail/25534.htm?spm=a2c63.p38356.b99.330.79eb59abhmnMDE
@@ -71,14 +75,22 @@ public interface ImageApi {
PagedIterable<Image> list(@QueryParam("RegionId") String region);
@Singleton
- final class ParseImages extends ParseJson<Images> {
+ final class ParseImages extends ParseJson<ParseImages.Images> {
@Inject
ParseImages(final Json json) {
super(json, TypeLiteral.get(Images.class));
}
- static class ToPagedIterable extends Arg0ToPagedIterable<Image, ToPagedIterable> {
+ private static class Images extends PaginatedCollection<Image> {
+
+ @ConstructorProperties({ "Images", "PageNumber", "TotalCount", "PageSize", "RegionId", "RequestId" })
+ public Images(Map<String, Iterable<Image>> content, Integer pageNumber, Integer totalCount, Integer pageSize, String regionId, String requestId) {
+ super(content, pageNumber, totalCount, pageSize, regionId, requestId);
+ }
+ }
+
+ private static class ToPagedIterable extends ArgsToPagedIterable<Image, ToPagedIterable> {
private final ECSComputeServiceApi api;
@@ -88,13 +100,18 @@ public interface ImageApi {
}
@Override
- protected Function<Object, IterableWithMarker<Image>> markerToNextForArg0(final Optional<Object> arg0) {
+ protected Function<Object, IterableWithMarker<Image>> markerToNextForArgs(final List<Object> args) {
+ if (args == null || args.isEmpty()) throw new IllegalStateException("Can't advance the PagedIterable");
+ final String regionId = args.get(0).toString();
+ final ListImagesOptions original = (ListImagesOptions) Iterables.tryFind(args, Predicates.instanceOf(ListImagesOptions.class)).orNull();
+
return new Function<Object, IterableWithMarker<Image>>() {
@Override
public IterableWithMarker<Image> apply(Object input) {
- String regionId = arg0.get().toString();
- ListImagesOptions listImagesOptions = ListImagesOptions.Builder.paginationOptions(PaginationOptions.class.cast(input));
- return api.imageApi().list(regionId, listImagesOptions);
+ ListImagesOptions options = original == null ?
+ ListImagesOptions.Builder.paginationOptions(PaginationOptions.class.cast(input)) :
+ original.paginationOptions(PaginationOptions.class.cast(input));
+ return api.imageApi().list(regionId, options);
}
};
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/SecurityGroupApi.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/SecurityGroupApi.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/SecurityGroupApi.java
new file mode 100644
index 0000000..c70bcb6
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/SecurityGroupApi.java
@@ -0,0 +1,157 @@
+/*
+ * 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.aliyun.ecs.features;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import com.google.inject.TypeLiteral;
+import org.jclouds.Constants;
+import org.jclouds.Fallbacks;
+import org.jclouds.aliyun.ecs.ECSComputeServiceApi;
+import org.jclouds.aliyun.ecs.domain.IpProtocol;
+import org.jclouds.aliyun.ecs.domain.Permission;
+import org.jclouds.aliyun.ecs.domain.Request;
+import org.jclouds.aliyun.ecs.domain.SecurityGroup;
+import org.jclouds.aliyun.ecs.domain.SecurityGroupRequest;
+import org.jclouds.aliyun.ecs.domain.internal.PaginatedCollection;
+import org.jclouds.aliyun.ecs.domain.options.CreateSecurityGroupOptions;
+import org.jclouds.aliyun.ecs.domain.options.ListSecurityGroupsOptions;
+import org.jclouds.aliyun.ecs.domain.options.PaginationOptions;
+import org.jclouds.aliyun.ecs.filters.FormSign;
+import org.jclouds.collect.IterableWithMarker;
+import org.jclouds.collect.PagedIterable;
+import org.jclouds.collect.internal.ArgsToPagedIterable;
+import org.jclouds.http.functions.ParseJson;
+import org.jclouds.json.Json;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.SelectJson;
+import org.jclouds.rest.annotations.Transform;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import java.beans.ConstructorProperties;
+import java.util.List;
+import java.util.Map;
+
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestFilters(FormSign.class)
+@QueryParams(keys = {"Version", "Format", "SignatureVersion", "ServiceCode", "SignatureMethod"},
+ values = {"{" + Constants.PROPERTY_API_VERSION + "}", "JSON", "1.0", "ecs", "HMAC-SHA1"})
+public interface SecurityGroupApi {
+
+ @Named("securityGroup:list")
+ @GET
+ @QueryParams(keys = "Action", values = "DescribeSecurityGroups")
+ @ResponseParser(ParseSecurityGroups.class)
+ @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class)
+ IterableWithMarker<SecurityGroup> list(@QueryParam("RegionId") String region, ListSecurityGroupsOptions options);
+
+ @Named("securityGroup:list")
+ @GET
+ @QueryParams(keys = "Action", values = "DescribeSecurityGroups")
+ @ResponseParser(ParseSecurityGroups.class)
+ @Transform(ParseSecurityGroups.ToPagedIterable.class)
+ @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class)
+ PagedIterable<SecurityGroup> list(@QueryParam("RegionId") String region);
+
+ @Singleton
+ final class ParseSecurityGroups extends ParseJson<ParseSecurityGroups.SecurityGroups> {
+
+ @Inject
+ ParseSecurityGroups(final Json json) {
+ super(json, TypeLiteral.get(SecurityGroups.class));
+ }
+
+ private static class SecurityGroups extends PaginatedCollection<SecurityGroup> {
+
+ @ConstructorProperties({"SecurityGroups", "PageNumber", "TotalCount", "PageSize", "RegionId", "RequestId"})
+ public SecurityGroups(Map<String, Iterable<SecurityGroup>> content, Integer pageNumber, Integer totalCount, Integer pageSize, String regionId, String requestId) {
+ super(content, pageNumber, totalCount, pageSize, regionId, requestId);
+ }
+ }
+
+ private static class ToPagedIterable extends ArgsToPagedIterable<SecurityGroup, ToPagedIterable> {
+
+ private final ECSComputeServiceApi api;
+
+ @Inject
+ ToPagedIterable(ECSComputeServiceApi api) {
+ this.api = api;
+ }
+
+ @Override
+ protected Function<Object, IterableWithMarker<SecurityGroup>> markerToNextForArgs(List<Object> args) {
+ if (args == null || args.isEmpty()) throw new IllegalStateException("Can't advance the PagedIterable");
+ final String regionId = args.get(0).toString();
+ final ListSecurityGroupsOptions original = (ListSecurityGroupsOptions) Iterables.tryFind(args, Predicates.instanceOf(ListSecurityGroupsOptions.class)).orNull();
+
+ return new Function<Object, IterableWithMarker<SecurityGroup>>() {
+ @Override
+ public IterableWithMarker<SecurityGroup> apply(Object input) {
+ ListSecurityGroupsOptions options = original == null ?
+ ListSecurityGroupsOptions.Builder.paginationOptions(PaginationOptions.class.cast(input)) :
+ original.paginationOptions(PaginationOptions.class.cast(input));
+ return api.securityGroupApi().list(regionId, options);
+ }
+ };
+ }
+ }
+ }
+
+ @Named("securityGroup:get")
+ @GET
+ @QueryParams(keys = "Action", values = "DescribeSecurityGroupAttribute")
+ @SelectJson("Permission")
+ List<Permission> get(@QueryParam("RegionId") String region, @QueryParam("SecurityGroupId") String securityGroupId);
+
+ @Named("securityGroup:create")
+ @POST
+ @QueryParams(keys = "Action", values = "CreateSecurityGroup")
+ @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+ SecurityGroupRequest create(@QueryParam("RegionId") String region);
+
+ @Named("securityGroup:create")
+ @POST
+ @QueryParams(keys = "Action", values = "CreateSecurityGroup")
+ @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+ SecurityGroupRequest create(@QueryParam("RegionId") String region, CreateSecurityGroupOptions options);
+
+ @Named("securityGroup:addInbound")
+ @POST
+ @QueryParams(keys = "Action", values = "AuthorizeSecurityGroup")
+ @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+ Request addInboundRule(@QueryParam("RegionId") String region, @QueryParam("SecurityGroupId") String securityGroupId,
+ @QueryParam("IpProtocol") IpProtocol ipProtocol, @QueryParam("PortRange") String portRange,
+ @QueryParam("SourceCidrIp") String sourceCidrIp);
+
+ @Named("securityGroup:delete")
+ @POST
+ @QueryParams(keys = "Action", values = "DeleteSecurityGroup")
+ @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+ Request delete(@QueryParam("RegionId") String region, @QueryParam("SecurityGroupId") String securityGroupId);
+}
+
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/SshKeyPairApi.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/SshKeyPairApi.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/SshKeyPairApi.java
new file mode 100644
index 0000000..b207335
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/SshKeyPairApi.java
@@ -0,0 +1,142 @@
+/*
+ * 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.aliyun.ecs.features;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import com.google.inject.TypeLiteral;
+import org.jclouds.Constants;
+import org.jclouds.Fallbacks;
+import org.jclouds.aliyun.ecs.ECSComputeServiceApi;
+import org.jclouds.aliyun.ecs.domain.KeyPair;
+import org.jclouds.aliyun.ecs.domain.KeyPairRequest;
+import org.jclouds.aliyun.ecs.domain.Request;
+import org.jclouds.aliyun.ecs.domain.internal.PaginatedCollection;
+import org.jclouds.aliyun.ecs.domain.options.ListKeyPairsOptions;
+import org.jclouds.aliyun.ecs.domain.options.PaginationOptions;
+import org.jclouds.aliyun.ecs.filters.FormSign;
+import org.jclouds.aliyun.ecs.functions.ArrayToCommaSeparatedString;
+import org.jclouds.collect.IterableWithMarker;
+import org.jclouds.collect.PagedIterable;
+import org.jclouds.collect.internal.ArgsToPagedIterable;
+import org.jclouds.http.functions.ParseJson;
+import org.jclouds.json.Json;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.ParamParser;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.Transform;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import java.beans.ConstructorProperties;
+import java.util.List;
+import java.util.Map;
+
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestFilters(FormSign.class)
+@QueryParams(keys = { "Version", "Format", "SignatureVersion", "ServiceCode", "SignatureMethod" },
+ values = {"{" + Constants.PROPERTY_API_VERSION + "}", "JSON", "1.0", "ecs", "HMAC-SHA1"})
+public interface SshKeyPairApi {
+
+ @Named("sshKeyPair:list")
+ @GET
+ @QueryParams(keys = "Action", values = "DescribeKeyPairs")
+ @ResponseParser(ParseKeyPairs.class)
+ @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class)
+ IterableWithMarker<KeyPair> list(@QueryParam("RegionId") String region, ListKeyPairsOptions options);
+
+ @Named("sshKeyPair:list")
+ @GET
+ @QueryParams(keys = "Action", values = "DescribeKeyPairs")
+ @ResponseParser(ParseKeyPairs.class)
+ @Transform(ParseKeyPairs.ToPagedIterable.class)
+ @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class)
+ PagedIterable<KeyPair> list(@QueryParam("RegionId") String region);
+
+ @Singleton
+ final class ParseKeyPairs extends ParseJson<ParseKeyPairs.KeyPairs> {
+
+ @Inject
+ ParseKeyPairs(final Json json) {
+ super(json, TypeLiteral.get(KeyPairs.class));
+ }
+
+ private static class KeyPairs extends PaginatedCollection<KeyPair> {
+
+ @ConstructorProperties({ "KeyPairs", "PageNumber", "TotalCount", "PageSize", "RegionId", "RequestId" })
+ public KeyPairs(Map<String, Iterable<KeyPair>> content, Integer pageNumber, Integer totalCount, Integer pageSize, String regionId, String requestId) {
+ super(content, pageNumber, totalCount, pageSize, regionId, requestId);
+ }
+ }
+
+ private static class ToPagedIterable extends ArgsToPagedIterable<KeyPair, ToPagedIterable> {
+
+ private final ECSComputeServiceApi api;
+
+ @Inject
+ ToPagedIterable(ECSComputeServiceApi api) {
+ this.api = api;
+ }
+
+ @Override
+ protected Function<Object, IterableWithMarker<KeyPair>> markerToNextForArgs(List<Object> args) {
+ if (args == null || args.isEmpty()) throw new IllegalStateException("Can't advance the PagedIterable");
+ final String regionId = args.get(0).toString();
+ final ListKeyPairsOptions original = (ListKeyPairsOptions) Iterables.tryFind(args, Predicates.instanceOf(ListKeyPairsOptions.class)).orNull();
+
+ return new Function<Object, IterableWithMarker<KeyPair>>() {
+ @Override
+ public IterableWithMarker<KeyPair> apply(Object input) {
+ ListKeyPairsOptions options = original == null ?
+ ListKeyPairsOptions.Builder.paginationOptions(PaginationOptions.class.cast(input)) :
+ original.paginationOptions(PaginationOptions.class.cast(input));
+ return api.sshKeyPairApi().list(regionId, options);
+ }
+ };
+ }
+ }
+ }
+
+ @Named("sshKeyPair:create")
+ @POST
+ @QueryParams(keys = "Action", values = "CreateKeyPair")
+ KeyPairRequest create(@QueryParam("RegionId") String region, @QueryParam("KeyPairName") String keyPairName);
+
+ @Named("sshKeyPair:import")
+ @POST
+ @QueryParams(keys = "Action", values = "ImportKeyPair")
+ KeyPair importKeyPair(@QueryParam("RegionId") String region,
+ @QueryParam("PublicKeyBody") String publicKeyBody,
+ @QueryParam("KeyPairName") String keyPairName);
+
+ @Named("sshKeyPair:delete")
+ @POST
+ @QueryParams(keys = "Action", values = "DeleteKeyPairs")
+ Request delete(@QueryParam("RegionId") String region,
+ @ParamParser(ArrayToCommaSeparatedString.class) @QueryParam("KeyPairNames") String... keyPairNames);
+
+}
+
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a5dbf006/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/TagApi.java
----------------------------------------------------------------------
diff --git a/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/TagApi.java b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/TagApi.java
new file mode 100644
index 0000000..67c3b82
--- /dev/null
+++ b/aliyun-ecs/src/main/java/org/jclouds/aliyun/ecs/features/TagApi.java
@@ -0,0 +1,143 @@
+/*
+ * 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.aliyun.ecs.features;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import com.google.inject.TypeLiteral;
+import org.jclouds.Constants;
+import org.jclouds.Fallbacks;
+import org.jclouds.aliyun.ecs.ECSComputeServiceApi;
+import org.jclouds.aliyun.ecs.domain.Request;
+import org.jclouds.aliyun.ecs.domain.Tag;
+import org.jclouds.aliyun.ecs.domain.internal.PaginatedCollection;
+import org.jclouds.aliyun.ecs.domain.options.ListTagsOptions;
+import org.jclouds.aliyun.ecs.domain.options.PaginationOptions;
+import org.jclouds.aliyun.ecs.domain.options.TagOptions;
+import org.jclouds.aliyun.ecs.filters.FormSign;
+import org.jclouds.collect.IterableWithMarker;
+import org.jclouds.collect.PagedIterable;
+import org.jclouds.collect.internal.ArgsToPagedIterable;
+import org.jclouds.http.functions.ParseJson;
+import org.jclouds.json.Json;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.Transform;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import java.beans.ConstructorProperties;
+import java.util.List;
+import java.util.Map;
+
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestFilters(FormSign.class)
+@QueryParams(keys = { "Version", "Format", "SignatureVersion", "ServiceCode", "SignatureMethod" },
+ values = {"{" + Constants.PROPERTY_API_VERSION + "}", "JSON", "1.0", "ecs", "HMAC-SHA1"})
+public interface TagApi {
+
+ @Named("tag:list")
+ @GET
+ @QueryParams(keys = "Action", values = "DescribeTags")
+ @ResponseParser(ParseTags.class)
+ @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class)
+ IterableWithMarker<Tag> list(@QueryParam("RegionId") String region, ListTagsOptions options);
+
+ @Named("tag:list")
+ @GET
+ @QueryParams(keys = "Action", values = "DescribeTags")
+ @ResponseParser(ParseTags.class)
+ @Transform(ParseTags.ToPagedIterable.class)
+ @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class)
+ PagedIterable<Tag> list(@QueryParam("RegionId") String region);
+
+ @Singleton
+ final class ParseTags extends ParseJson<ParseTags.Tags> {
+
+ @Inject
+ ParseTags(final Json json) {
+ super(json, TypeLiteral.get(Tags.class));
+ }
+
+ private static class Tags extends PaginatedCollection<Tag> {
+
+ @ConstructorProperties({ "Tags", "PageNumber", "TotalCount", "PageSize", "RegionId", "RequestId" })
+ public Tags(Map<String, Iterable<Tag>> content, Integer pageNumber, Integer totalCount, Integer pageSize, String regionId, String requestId) {
+ super(content, pageNumber, totalCount, pageSize, regionId, requestId);
+ }
+ }
+
+ private static class ToPagedIterable extends ArgsToPagedIterable<Tag, ToPagedIterable> {
+
+ private final ECSComputeServiceApi api;
+
+ @Inject
+ ToPagedIterable(ECSComputeServiceApi api) {
+ this.api = api;
+ }
+
+ @Override
+ protected Function<Object, IterableWithMarker<Tag>> markerToNextForArgs(List<Object> args) {
+ if (args == null || args.isEmpty()) throw new IllegalStateException("Can't advance the PagedIterable");
+ final String regionId = args.get(0).toString();
+ final ListTagsOptions original = (ListTagsOptions) Iterables.tryFind(args, Predicates.instanceOf(ListTagsOptions.class)).orNull();
+
+ return new Function<Object, IterableWithMarker<Tag>>() {
+ @Override
+ public IterableWithMarker<Tag> apply(Object input) {
+ ListTagsOptions options = original == null ?
+ ListTagsOptions.Builder.paginationOptions(PaginationOptions.class.cast(input)) :
+ original.paginationOptions(PaginationOptions.class.cast(input));
+ return api.tagApi().list(regionId, options);
+ }
+ };
+ }
+ }
+ }
+
+ @Named("tag:add")
+ @POST
+ @QueryParams(keys = "Action", values = "AddTags")
+ Request add(@QueryParam("RegionId") String region, @QueryParam("ResourceId") String resourceId,
+ @QueryParam("ResourceType") String resourceType,
+ TagOptions tagOptions);
+
+ @Named("tag:remove")
+ @POST
+ @QueryParams(keys = "Action", values = "RemoveTags")
+ Request remove(@QueryParam("RegionId") String region,
+ @QueryParam("ResourceId") String resourceId,
+ @QueryParam("ResourceType") String resourceType);
+
+ @Named("tag:remove")
+ @POST
+ @QueryParams(keys = "Action", values = "RemoveTags")
+ Request remove(@QueryParam("RegionId") String region,
+ @QueryParam("ResourceId") String resourceId,
+ @QueryParam("ResourceType") String resourceType,
+ TagOptions options);
+}
+