Issue 997:support AWS IAM api

This commit is contained in:
Adrian Cole 2012-06-24 11:48:05 -07:00
parent 763572f8ee
commit 5687a6d8ea
35 changed files with 2428 additions and 0 deletions

108
labs/aws-iam/pom.xml Normal file
View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to jclouds, Inc. (jclouds) under one or more
contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. jclouds 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>1.5.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.labs</groupId>
<artifactId>aws-iam</artifactId>
<name>jclouds Amazon Identity and Access Management (IAM) provider</name>
<description>Identity and Access Management (IAM) to Amazon Web Services</description>
<packaging>bundle</packaging>
<properties>
<test.aws-iam.endpoint>https://iam.amazonaws.com</test.aws-iam.endpoint>
<test.aws-iam.api-version>2010-05-08</test.aws-iam.api-version>
<test.aws-iam.build-version></test.aws-iam.build-version>
<test.aws-iam.identity>${test.aws.identity}</test.aws-iam.identity>
<test.aws-iam.credential>${test.aws.credential}</test.aws-iam.credential>
<jclouds.osgi.export>org.jclouds.aws.iam*;version="${project.version}"</jclouds.osgi.export>
<jclouds.osgi.import>org.jclouds*;version="${project.version}",*</jclouds.osgi.import>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds.labs</groupId>
<artifactId>iam</artifactId>
<version>${project.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.jclouds.labs</groupId>
<artifactId>iam</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemPropertyVariables>
<test.aws-iam.endpoint>${test.aws-iam.endpoint}</test.aws-iam.endpoint>
<test.aws-iam.api-version>${test.aws-iam.api-version}</test.aws-iam.api-version>
<test.aws-iam.build-version>${test.aws-iam.build-version}</test.aws-iam.build-version>
<test.aws-iam.identity>${test.aws-iam.identity}</test.aws-iam.identity>
<test.aws-iam.credential>${test.aws-iam.credential}</test.aws-iam.credential>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,87 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.aws.iam;
import java.net.URI;
import java.util.Properties;
import org.jclouds.iam.IAMApiMetadata;
import org.jclouds.providers.ProviderMetadata;
import org.jclouds.providers.internal.BaseProviderMetadata;
/**
* Implementation of @ link org.jclouds.types.ProviderMetadata} for Amazon's IAM
* provider.
*
* @author Adrian Cole
*/
public class AWSIAMProviderMetadata extends BaseProviderMetadata {
/** The serialVersionUID */
private static final long serialVersionUID = 2394954723306943404L;
public static Builder builder() {
return new Builder();
}
@Override
public Builder toBuilder() {
return builder().fromProviderMetadata(this);
}
public AWSIAMProviderMetadata() {
super(builder());
}
public AWSIAMProviderMetadata(Builder builder) {
super(builder);
}
public static Properties defaultProperties() {
Properties properties = new Properties();
return properties;
}
public static class Builder extends BaseProviderMetadata.Builder {
protected Builder(){
id("aws-iam")
.name("Amazon IAM")
.endpoint("https://iam.amazonaws.com")
.homepage(URI.create("http://aws.amazon.com/iam"))
.console(URI.create("https://console.aws.amazon.com/iam/home"))
.linkedServices("aws-ec2","aws-elb", "aws-cloudwatch", "aws-s3", "aws-simpledb")
.iso3166Codes("US-VA", "US-CA", "BR-SP", "US-OR", "IE", "SG", "JP-13")
.apiMetadata(new IAMApiMetadata())
.defaultProperties(AWSIAMProviderMetadata.defaultProperties());
}
@Override
public AWSIAMProviderMetadata build() {
return new AWSIAMProviderMetadata(this);
}
@Override
public Builder fromProviderMetadata(ProviderMetadata in) {
super.fromProviderMetadata(in);
return this;
}
}
}

View File

@ -0,0 +1 @@
org.jclouds.aws.iam.AWSIAMProviderMetadata

View File

@ -0,0 +1,35 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.aws.iam;
import org.jclouds.iam.IAMClientLiveTest;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code IAMClient}
*
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true, testName = "AWSIAMClientLiveTest")
public class AWSIAMClientLiveTest extends IAMClientLiveTest {
public AWSIAMClientLiveTest() {
provider = "aws-iam";
}
}

View File

@ -0,0 +1,37 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.aws.iam;
import org.jclouds.aws.iam.AWSIAMProviderMetadata;
import org.jclouds.iam.IAMApiMetadata;
import org.jclouds.providers.internal.BaseProviderMetadataTest;
import org.testng.annotations.Test;
/**
* The AWSIAMProviderTest tests the org.jclouds.providers.AWSIAMProvider class.
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "AWSIAMProviderTest")
public class AWSIAMProviderTest extends BaseProviderMetadataTest {
public AWSIAMProviderTest() {
super(new AWSIAMProviderMetadata(), new IAMApiMetadata());
}
}

View File

@ -0,0 +1,32 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.aws.iam.features;
import org.jclouds.iam.features.UserClientLiveTest;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
@Test(groups = "live", testName = "AWSUserClientLiveTest")
public class AWSUserClientLiveTest extends UserClientLiveTest {
public AWSUserClientLiveTest() {
provider = "aws-iam";
}
}

108
labs/iam/pom.xml Normal file
View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to jclouds, Inc. (jclouds) under one or more
contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. jclouds 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>1.5.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.labs</groupId>
<artifactId>iam</artifactId>
<name>jcloud iam api</name>
<description>jclouds components to access an implementation of Identity and Access Management (IAM)</description>
<packaging>bundle</packaging>
<properties>
<test.iam.endpoint>https://iam.amazonaws.com</test.iam.endpoint>
<test.iam.api-version>2010-05-08</test.iam.api-version>
<test.iam.build-version></test.iam.build-version>
<test.iam.identity>${test.aws.identity}</test.iam.identity>
<test.iam.credential>${test.aws.credential}</test.iam.credential>
<jclouds.osgi.export>org.jclouds.iam*;version="${project.version}"</jclouds.osgi.export>
<jclouds.osgi.import>org.jclouds*;version="${project.version}",*</jclouds.osgi.import>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds.common</groupId>
<artifactId>aws-common</artifactId>
<version>${project.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemPropertyVariables>
<test.iam.endpoint>${test.iam.endpoint}</test.iam.endpoint>
<test.iam.api-version>${test.iam.api-version}</test.iam.api-version>
<test.iam.build-version>${test.iam.build-version}</test.iam.build-version>
<test.iam.identity>${test.iam.identity}</test.iam.identity>
<test.iam.credential>${test.iam.credential}</test.iam.credential>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,43 @@
package org.jclouds.iam;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.collect.PaginatedSets;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.features.UserClient;
import org.jclouds.iam.options.ListUsersOptions;
import com.google.common.base.Function;
/**
* Utilities for using IAM.
*
* @author Adrian Cole
*/
public class IAM {
/**
* List users based on the criteria in the {@link ListUsersOptions} passed in.
*
* @param userClient
* the {@link UserClient} to use for the request
* @param options
* the {@link ListUsersOptions} describing the ListUsers request
*
* @return iterable of users fitting the criteria
*/
public static Iterable<User> list(final UserClient userClient, final ListUsersOptions options) {
return PaginatedSets.lazyContinue(userClient.list(options), new Function<String, PaginatedSet<User>>() {
@Override
public PaginatedSet<User> apply(String input) {
return userClient.list(options.clone().marker(input));
}
@Override
public String toString() {
return "listUsers(" + options + ")";
}
});
}
}

View File

@ -0,0 +1,95 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import java.net.URI;
import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.iam.config.IAMRestClientModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.internal.BaseRestApiMetadata;
import com.google.common.reflect.TypeToken;
/**
* Implementation of {@link ApiMetadata} for Amazon's IAM api.
*
* @author Adrian Cole
*/
public class IAMApiMetadata extends BaseRestApiMetadata {
/** The serialVersionUID */
private static final long serialVersionUID = 3450830053589179249L;
public static final TypeToken<RestContext<? extends IAMClient, ? extends IAMAsyncClient>> CONTEXT_TOKEN = new TypeToken<RestContext<? extends IAMClient, ? extends IAMAsyncClient>>() {
private static final long serialVersionUID = -5070937833892503232L;
};
@Override
public Builder toBuilder() {
return new Builder(getApi(), getAsyncApi()).fromApiMetadata(this);
}
public IAMApiMetadata() {
this(new Builder(IAMClient.class, IAMAsyncClient.class));
}
protected IAMApiMetadata(Builder builder) {
super(Builder.class.cast(builder));
}
public static Properties defaultProperties() {
Properties properties = BaseRestApiMetadata.defaultProperties();
properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
properties.setProperty(PROPERTY_HEADER_TAG, "amz");
return properties;
}
public static class Builder extends BaseRestApiMetadata.Builder {
protected Builder(Class<?> client, Class<?> asyncClient) {
super(client, asyncClient);
id("iam")
.name("Amazon IAM Api")
.identityName("Access Key ID")
.credentialName("Secret Access Key")
.version("2010-05-08")
.documentation(URI.create("http://docs.amazonwebservices.com/IAM/latest/APIReference/"))
.defaultEndpoint("https://iam.amazonaws.com")
.defaultProperties(IAMApiMetadata.defaultProperties())
.defaultModule(IAMRestClientModule.class);
}
@Override
public IAMApiMetadata build() {
return new IAMApiMetadata(this);
}
@Override
public Builder fromApiMetadata(ApiMetadata in) {
super.fromApiMetadata(in);
return this;
}
}
}

View File

@ -0,0 +1,64 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.features.UserAsyncClient;
import org.jclouds.iam.xml.UserHandler;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to Amazon IAM via the Query API
* <p/>
*
* @see <a
* href="http://docs.amazonwebservices.com/IAM/latest/APIReference"
* />
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@VirtualHost
public interface IAMAsyncClient {
/**
* @see IAMClient#getCurrentUser()
*/
@POST
@Path("/")
@XMLResponseParser(UserHandler.class)
@FormParams(keys = "Action", values = "GetUser")
ListenableFuture<User> getCurrentUser();
/**
* Provides asynchronous access to User features.
*/
@Delegate
UserAsyncClient getUserClient();
}

View File

@ -0,0 +1,49 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.features.UserClient;
import org.jclouds.rest.annotations.Delegate;
/**
* Provides access to Amazon IAM via the Query API
* <p/>
*
* @see <a
* href="http://docs.amazonwebservices.com/IAM/latest/APIReference"
* />
* @author Adrian Cole
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface IAMClient {
/**
* Retrieves information about the current user, including the user's path, GUID, and ARN.
*/
User getCurrentUser();
/**
* Provides synchronous access to User features.
*/
@Delegate
UserClient getUserClient();
}

View File

@ -0,0 +1,48 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.config;
import java.util.Map;
import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.iam.IAMAsyncClient;
import org.jclouds.iam.IAMClient;
import org.jclouds.iam.features.UserAsyncClient;
import org.jclouds.iam.features.UserClient;
import org.jclouds.rest.ConfiguresRestClient;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
/**
* Configures the Monitoring connection.
*
* @author Adrian Cole
*/
@ConfiguresRestClient
public class IAMRestClientModule extends FormSigningRestClientModule<IAMClient, IAMAsyncClient> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(UserClient.class, UserAsyncClient.class)
.build();
public IAMRestClientModule() {
super(TypeToken.of(IAMClient.class), TypeToken.of(IAMAsyncClient.class), DELEGATE_MAP);
}
}

View File

@ -0,0 +1,209 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.domain;
import java.util.Date;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
/**
* @see <a href="http://docs.amazonwebservices.com/IAM/latest/APIReference/API_GetUser.html" />
*
* @author Adrian Cole
*/
public class User {
public static Builder<?> builder() {
return new ConcreteBuilder();
}
public Builder<?> toBuilder() {
return new ConcreteBuilder().fromUser(this);
}
public static abstract class Builder<T extends Builder<T>> {
protected abstract T self();
private Optional<String> path = Optional.absent();
private String id;
private Optional<String> name = Optional.absent();
private String arn;
private Date createDate;
/**
* @see User#getPath()
*/
public T path(String path) {
this.path = Optional.fromNullable(path);
return self();
}
/**
* @see User#getId()
*/
public T id(String id) {
this.id = id;
return self();
}
/**
* @see User#getName()
*/
public T name(String name) {
this.name = Optional.fromNullable(name);
return self();
}
/**
* @see User#getArn()
*/
public T arn(String arn) {
this.arn = arn;
return self();
}
/**
* @see User#getCreateDate()
*/
public T createDate(Date createDate) {
this.createDate = createDate;
return self();
}
public User build() {
return new User(path, name, id, arn, createDate);
}
public T fromUser(User in) {
return this
.path(in.getPath().orNull())
.name(in.getName().orNull())
.id(in.getId())
.arn(in.getArn())
.createDate(in.getCreateDate())
;
}
}
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
@Override
protected ConcreteBuilder self() {
return this;
}
}
private final Optional<String> path;
private final Optional<String> name;
private final String id;
private final String arn;
private final Date createDate;
protected User(Optional<String> path, Optional<String> name, String id, String arn, Date createDate) {
this.path = path;
this.name = name;
this.id = id;
this.arn = arn;
this.createDate = createDate;
}
/**
* you can also optionally give the entity a path that you define. You might use the path to
* identify which division or part of the organization the entity belongs in. For example:
* /division_abc/subdivision_xyz/product_1234/engineering/
*/
public Optional<String> getPath() {
return path;
}
/**
* When you create a user, a role, or a group, or when you upload a server certificate, you give
* it a friendly name, such as Bob, TestApp1, Developers, or ProdServerCert. Whenever you need to
* specify a particular entity in an API call to IAM (for example, to delete a user, or update a
* group with a new user), you use the friendly name.
*/
public Optional<String> getName() {
return name;
}
/**
* We assign each user, group, and server certificate a globally unique identifier (GUID), which
* we return to you when you use the API or CLI to create it. We recommend you store the GUID in
* your own database along with the user, group, or certificate name. Internally we use the GUID
* to identify the user, group, or certificate, and we translate the value into the ARN or
* friendly name as appropriate when displaying the user, group, or certificate information to
* you. If you delete a user, group, or server certificate, any residual remote references to
* that item display the GUID as the friendly name part in the ARN. If you've stored the GUID in
* your own system, you can then use the displayed GUID to identify the deleted item being
* referred to.
*/
public String getId() {
return id;
}
/**
* Although most resources have a friendly name (for example, a user named Bob or a group named
* Developers), the access policy language requires you to specify the resource or resources
* using the following Amazon Resource Name (ARN) format.
*
* {@code arn:aws:<service>:<region>:<namespace>:<relative-id>}
*/
public String getArn() {
return arn;
}
/**
* Date the user was created
*/
public Date getCreateDate() {
return createDate;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hashCode(id, arn);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
return Objects.equal(this.id, other.id) && Objects.equal(this.arn, other.arn);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return Objects.toStringHelper(this).add("path", path).add("name", name).add("id", id).add("arn", arn).add(
"createDate", createDate).toString();
}
}

View File

@ -0,0 +1,88 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.features;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.options.ListUsersOptions;
import org.jclouds.iam.xml.ListUsersResultHandler;
import org.jclouds.iam.xml.UserHandler;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to Amazon IAM via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/IAM/latest/APIReference" />
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@VirtualHost
public interface UserAsyncClient {
/**
* @see UserClient#getCurrent()
*/
@POST
@Path("/")
@XMLResponseParser(UserHandler.class)
@FormParams(keys = "Action", values = "GetUser")
ListenableFuture<User> getCurrent();
/**
* @see UserClient#get()
*/
@POST
@Path("/")
@XMLResponseParser(UserHandler.class)
@FormParams(keys = "Action", values = "GetUser")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<User> get(@FormParam("UserName") String name);
/**
* @see UserClient#list()
*/
@POST
@Path("/")
@XMLResponseParser(ListUsersResultHandler.class)
@FormParams(keys = "Action", values = "ListUsers")
ListenableFuture<PaginatedSet<User>> list();
/**
* @see UserClient#list(ListUsersOptions)
*/
@POST
@Path("/")
@XMLResponseParser(ListUsersResultHandler.class)
@FormParams(keys = "Action", values = "ListUsers")
ListenableFuture<PaginatedSet<User>> list(ListUsersOptions options);
}

View File

@ -0,0 +1,75 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.concurrent.Timeout;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.options.ListUsersOptions;
import org.jclouds.javax.annotation.Nullable;
/**
* Provides access to Amazon IAM via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/IAM/latest/APIReference" />
* @author Adrian Cole
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface UserClient {
/**
* Retrieves information about the current user, including the user's path, GUID, and ARN.
*/
User getCurrent();
/**
* Retrieves information about the specified user, including the user's path, GUID, and ARN.
*
* @param name
* Name of the user to get information about.
* @return null if not found
*/
@Nullable
User get(String name);
/**
* Lists the users that have the specified path prefix. If there are none, the action returns an
* empty list.
*
* <br/>
* You can paginate the results using the {@link ListUsersOptions parameter}
*
* @param options
* the options describing the users query
*
* @return the response object
*/
PaginatedSet<User> list(ListUsersOptions options);
/**
* Lists the users that have the specified path prefix. If there are none, the action returns an
* empty list.
*
* @return the response object
*/
PaginatedSet<User> list();
}

View File

@ -0,0 +1,169 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.collect.Multimap;
/**
* Options used to list available users.
*
* @see <a href="http://docs.amazonwebservices.com/IAM/latest/APIReference/API_ListUsers.html" />
*
* @author Adrian Cole
*/
public class ListUsersOptions extends BaseHttpRequestOptions implements Cloneable {
private Integer maxItems;
private String pathPrefix;
private String marker;
/**
* @see ListUsersOptions#getMarker()
*/
public ListUsersOptions marker(String marker) {
this.marker = marker;
return this;
}
/**
* @see ListUsersOptions#getMaxItems()
*/
public ListUsersOptions maxItems(Integer maxItems) {
this.maxItems = maxItems;
return this;
}
/**
* @see ListUsersOptions#getPathPrefix()
*/
public ListUsersOptions pathPrefix(String pathPrefix) {
this.pathPrefix = pathPrefix;
return this;
}
/**
* Use this parameter only when paginating results to indicate the maximum number of user names
* you want in the response. If there are additional user names beyond the maximum you specify,
* the IsTruncated response element is true.
*/
@Nullable
public Integer getMaxItems() {
return maxItems;
}
/**
* The path prefix for filtering the results. For example: /division_abc/subdivision_xyz/, which
* would get all user names whose path starts with /division_abc/subdivision_xyz/.
* <p/>
* This parameter is optional. If it is not included, it defaults to a slash (/), listing all
* user names.
*/
@Nullable
public String getPathPrefix() {
return pathPrefix;
}
/**
* Use this parameter only when paginating results, and only in a subsequent request after you've
* received a response where the results are truncated. Set it to the value of the Marker element
* in the response you just received.
*/
@Nullable
public String getMarker() {
return marker;
}
public static class Builder {
/**
* @see ListUsersOptions#getMarker()
*/
public static ListUsersOptions marker(String marker) {
return new ListUsersOptions().marker(marker);
}
/**
* @see ListUsersOptions#getMaxItems()
*/
public static ListUsersOptions maxItems(Integer maxItems) {
return new ListUsersOptions().maxItems(maxItems);
}
/**
* @see ListUsersOptions#getPathPrefix()
*/
public static ListUsersOptions pathPrefix(String pathPrefix) {
return new ListUsersOptions().pathPrefix(pathPrefix);
}
}
@Override
public Multimap<String, String> buildFormParameters() {
Multimap<String, String> params = super.buildFormParameters();
if (marker != null)
params.put("Marker", marker);
if (maxItems != null)
params.put("MaxItems", maxItems.toString());
if (pathPrefix != null)
params.put("PathPrefix", pathPrefix);
return params;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hashCode(marker, maxItems, pathPrefix);
}
@Override
public ListUsersOptions clone() {
return new ListUsersOptions().marker(marker).maxItems(maxItems).pathPrefix(pathPrefix);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ListUsersOptions other = ListUsersOptions.class.cast(obj);
return Objects.equal(this.marker, other.marker) && Objects.equal(this.maxItems, other.maxItems)
&& Objects.equal(this.pathPrefix, other.pathPrefix);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return Objects.toStringHelper(this).omitNullValues().add("marker", marker).add("maxItems", maxItems).add(
"pathPrefix", pathPrefix).toString();
}
}

View File

@ -0,0 +1,105 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.xml;
import java.util.Set;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.iam.domain.User;
import org.jclouds.util.SaxUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
/**
* @see <a href="http://docs.amazonwebservices.com/IAM/latest/APIReference/API_ListUsers.html" />
*
* @author Adrian Cole
*/
public class ListUsersResultHandler extends ParseSax.HandlerForGeneratedRequestWithResult<PaginatedSet<User>> {
private final UserHandler userHandler;
private StringBuilder currentText = new StringBuilder();
private Set<User> users = Sets.newLinkedHashSet();
private boolean inUsers;
private String marker;
@Inject
public ListUsersResultHandler(UserHandler userHandler) {
this.userHandler = userHandler;
}
/**
* {@inheritDoc}
*/
@Override
public PaginatedSet<User> getResult() {
return PaginatedSet.copyOfWithMarker(users, marker);
}
/**
* {@inheritDoc}
*/
@Override
public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException {
if (SaxUtils.equalsOrSuffix(qName, "Users")) {
inUsers = true;
}
if (inUsers) {
userHandler.startElement(url, name, qName, attributes);
}
}
/**
* {@inheritDoc}
*/
@Override
public void endElement(String uri, String name, String qName) throws SAXException {
if (inUsers) {
if (qName.equals("Users")) {
inUsers = false;
} else if (qName.equals("member")) {
users.add(userHandler.getResult());
} else {
userHandler.endElement(uri, name, qName);
}
} else if (qName.equals("Marker")) {
marker = SaxUtils.currentOrNull(currentText);
}
currentText = new StringBuilder();
}
/**
* {@inheritDoc}
*/
@Override
public void characters(char ch[], int start, int length) {
if (inUsers) {
userHandler.characters(ch, start, length);
} else {
currentText.append(ch, start, length);
}
}
}

View File

@ -0,0 +1,84 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.xml;
import javax.inject.Inject;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.iam.domain.User;
import org.jclouds.util.SaxUtils;
import org.xml.sax.SAXException;
/**
* @see <a href="http://docs.amazonwebservices.com/IAM/latest/APIReference/API_GetUser.html" />
*
* @author Adrian Cole
*/
public class UserHandler extends ParseSax.HandlerForGeneratedRequestWithResult<User> {
private final DateService dateService;
@Inject
protected UserHandler(DateService dateService){
this.dateService = dateService;
}
private StringBuilder currentText = new StringBuilder();
private User.Builder<?> builder = User.builder();
/**
* {@inheritDoc}
*/
@Override
public User getResult() {
try {
return builder.build();
} finally {
builder = User.builder();
}
}
/**
* {@inheritDoc}
*/
@Override
public void endElement(String uri, String name, String qName) throws SAXException {
if (qName.equals("Path")) {
builder.path(SaxUtils.currentOrNull(currentText));
} else if (qName.equals("UserName")) {
builder.name(SaxUtils.currentOrNull(currentText));
} else if (qName.equals("UserId")) {
builder.id(SaxUtils.currentOrNull(currentText));
} else if (qName.equals("Arn")) {
builder.arn(SaxUtils.currentOrNull(currentText));
} else if (qName.equals("CreateDate")) {
builder.createDate(dateService.iso8601SecondsDateParse(SaxUtils.currentOrNull(currentText)));
}
currentText = new StringBuilder();
}
/**
* {@inheritDoc}
*/
@Override
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -0,0 +1 @@
org.jclouds.iam.IAMApiMetadata

View File

@ -0,0 +1,39 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam;
import org.jclouds.View;
import org.jclouds.rest.internal.BaseRestApiMetadataTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "IAMApiMetadataTest")
public class IAMApiMetadataTest extends BaseRestApiMetadataTest {
// no tenant abstraction, yet
public IAMApiMetadataTest() {
super(new IAMApiMetadata(), ImmutableSet.<TypeToken<? extends View>> of());
}
}

View File

@ -0,0 +1,58 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam;
import org.jclouds.apis.BaseContextLiveTest;
import org.jclouds.rest.RestContext;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.reflect.TypeToken;
/**
* Tests behavior of {@code IAM}.
*
* @author Adrian Cole
*/
public class IAMClientLiveTest extends BaseContextLiveTest<RestContext<? extends IAMClient, ? extends IAMAsyncClient>> {
public IAMClientLiveTest() {
provider = "iam";
}
private IAMClient client;
@Override
@BeforeClass(groups = { "integration", "live" })
public void setupContext() {
super.setupContext();
client = context.getApi();
}
@Override
protected TypeToken<RestContext<? extends IAMClient, ? extends IAMAsyncClient>> contextType() {
return IAMApiMetadata.CONTEXT_TOKEN;
}
@Test
protected void testWired() {
client.getCurrentUser();
}
}

View File

@ -0,0 +1,62 @@
package org.jclouds.iam;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import org.easymock.EasyMock;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.features.UserClient;
import org.jclouds.iam.options.ListUsersOptions;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
* Tests behavior of {@code IAM}.
*
* @author Adrian Cole
*/
@Test(testName = "IAMTest")
public class IAMTest {
@Test
public void testSinglePageResult() throws Exception {
UserClient userClient = createMock(UserClient.class);
ListUsersOptions options = new ListUsersOptions();
PaginatedSet<User> response = PaginatedSet.copyOf(ImmutableSet.of(createMock(User.class)));
expect(userClient.list(options))
.andReturn(response)
.once();
EasyMock.replay(userClient);
Assert.assertEquals(1, Iterables.size(IAM.list(userClient, options)));
}
@Test
public void testMultiPageResult() throws Exception {
UserClient userClient = createMock(UserClient.class);
ListUsersOptions options = new ListUsersOptions();
PaginatedSet<User> response1 = PaginatedSet.copyOfWithMarker(ImmutableSet.of(createMock(User.class)), "NEXTTOKEN");
PaginatedSet<User> response2 = PaginatedSet.copyOf(ImmutableSet.of(createMock(User.class)));
expect(userClient.list(anyObject(ListUsersOptions.class)))
.andReturn(response1)
.once();
expect(userClient.list(anyObject(ListUsersOptions.class)))
.andReturn(response2)
.once();
EasyMock.replay(userClient);
Assert.assertEquals(2, Iterables.size(IAM.list(userClient, options)));
}
}

View File

@ -0,0 +1,188 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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
*
* Unles 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 expres or implied. See the License for the
* specific language governing permisions and limitations
* under the License.
*/
package org.jclouds.iam.features;
import static org.jclouds.iam.options.ListUsersOptions.Builder.pathPrefix;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import java.net.URI;
import java.util.TimeZone;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.iam.IAMClient;
import org.jclouds.iam.internal.BaseIAMClientExpectTest;
import org.jclouds.iam.parse.GetUserResponseTest;
import org.jclouds.iam.parse.ListUsersResponseTest;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "UserClientExpectTest")
public class UserClientExpectTest extends BaseIAMClientExpectTest {
public UserClientExpectTest() {
TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
}
public void testGetCurrentWhenResponseIs2xx() throws Exception {
HttpRequest get = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://iam.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "iam.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
"Action=GetUser" +
"&Signature=2UamWqKKgoSbaZpvixX0LKqGW%2FIIP9L319DLEUtYu3A%3D" +
"&SignatureMethod=HmacSHA256" +
"&SignatureVersion=2" +
"&Timestamp=2009-11-08T15%3A54%3A08.897Z" +
"&Version=2010-05-08" +
"&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded"))
.build();
HttpResponse getResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/get_user.xml", "text/xml")).build();
IAMClient clientWhenExist = requestSendsResponse(
get, getResponse);
assertEquals(clientWhenExist.getUserClient().getCurrent().toString(), new GetUserResponseTest().expected().toString());
}
HttpRequest get = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://iam.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "iam.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
"Action=GetUser" +
"&Signature=cnY%2FAaG656cruOmb3y7YHtjnPB1qg3aavff6PPxIMs0%3D" +
"&SignatureMethod=HmacSHA256" +
"&SignatureVersion=2" +
"&Timestamp=2009-11-08T15%3A54%3A08.897Z" +
"&UserName=name" +
"&Version=2010-05-08" +
"&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded"))
.build();
public void testGetWhenResponseIs2xx() throws Exception {
HttpResponse getResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/get_user.xml", "text/xml")).build();
IAMClient clientWhenExist = requestSendsResponse(
get, getResponse);
assertEquals(clientWhenExist.getUserClient().get("name").toString(), new GetUserResponseTest().expected().toString());
}
public void testGetWhenResponseIs404() throws Exception {
HttpResponse getResponse = HttpResponse.builder().statusCode(404).build();
IAMClient clientWhenDontExist = requestSendsResponse(
get, getResponse);
assertNull(clientWhenDontExist.getUserClient().get("name"));
}
HttpRequest list = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://iam.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "iam.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
"Action=ListUsers" +
"&Signature=ed4OrONGuVlGpHSY8u5X2m9LVwx6oiihu7HbvA0iZkY%3D" +
"&SignatureMethod=HmacSHA256" +
"&SignatureVersion=2" +
"&Timestamp=2009-11-08T15%3A54%3A08.897Z" +
"&Version=2010-05-08" +
"&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded"))
.build();
public void testListWhenResponseIs2xx() throws Exception {
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_users.xml", "text/xml")).build();
IAMClient clientWhenExist = requestSendsResponse(
list, listResponse);
assertEquals(clientWhenExist.getUserClient().list().toString(), new ListUsersResponseTest().expected().toString());
}
// TODO: this should really be an empty set
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testListWhenResponseIs404() throws Exception {
HttpResponse listResponse = HttpResponse.builder().statusCode(404).build();
IAMClient clientWhenDontExist = requestSendsResponse(
list, listResponse);
clientWhenDontExist.getUserClient().list();
}
public void testListWithOptionsWhenResponseIs2xx() throws Exception {
HttpRequest listWithOptions =
HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://iam.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String>builder()
.put("Host", "iam.amazonaws.com")
.build())
.payload(payloadFromStringWithContentType(
"Action=ListUsers" +
"&Marker=MARKER" +
"&PathPrefix=%2Ffoo" +
"&Signature=1%2BeCgNIAjHr%2BraNdDd3rsVC5Qok3AuTrJOa5mZwmE7g%3D" +
"&SignatureMethod=HmacSHA256" +
"&SignatureVersion=2" +
"&Timestamp=2009-11-08T15%3A54%3A08.897Z" +
"&Version=2010-05-08" +
"&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded"))
.build();
HttpResponse listWithOptionsResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_users.xml", "text/xml")).build();
IAMClient clientWhenWithOptionsExist = requestSendsResponse(listWithOptions,
listWithOptionsResponse);
assertEquals(clientWhenWithOptionsExist.getUserClient().list(pathPrefix("/foo").marker("MARKER")).toString(),
new ListUsersResponseTest().expected().toString());
}
}

View File

@ -0,0 +1,73 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.features;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.internal.BaseIAMClientLiveTest;
import org.jclouds.iam.options.ListUsersOptions;
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
@Test(groups = "live", testName = "UserClientLiveTest")
public class UserClientLiveTest extends BaseIAMClientLiveTest {
@Test
protected void testGetCurrentUser() {
User user = client().getCurrent();
checkUser(user);
}
private void checkUser(User user) {
checkNotNull(user.getArn(), "Arn cannot be null for a User.");
checkNotNull(user.getId(), "Id cannot be null for a User.");
checkNotNull(user.getName(), "While Name can be null for a User, its Optional wrapper cannot.");
checkNotNull(user.getPath(), "While Path can be null for a User, its Optional wrapper cannot.");
checkNotNull(user.getCreateDate(), "CreateDate cannot be null for a User.");
}
@Test
protected void testListUsers() {
PaginatedSet<User> response = client().list();
for (User user : response) {
checkUser(user);
}
if (response.size() > 0) {
User user = response.iterator().next();
Assert.assertEquals(client().get(user.getName().get()), user);
}
// Test with a Marker, even if it's null
response = client().list(ListUsersOptions.Builder.marker(response.getNextMarker()));
for (User user : response) {
checkUser(user);
}
}
protected UserClient client() {
return context.getApi().getUserClient();
}
}

View File

@ -0,0 +1,38 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.internal;
import java.util.Properties;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.iam.IAMAsyncClient;
import com.google.common.base.Function;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class BaseIAMAsyncClientExpectTest extends BaseIAMExpectTest<IAMAsyncClient> {
public IAMAsyncClient createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
return createInjector(fn, module, props).getInstance(IAMAsyncClient.class);
}
}

View File

@ -0,0 +1,29 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.internal;
import org.jclouds.iam.IAMClient;
/**
*
* @author Adrian Cole
*/
public class BaseIAMClientExpectTest extends BaseIAMExpectTest<IAMClient> {
}

View File

@ -0,0 +1,47 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.internal;
import org.jclouds.apis.BaseContextLiveTest;
import org.jclouds.iam.IAMApiMetadata;
import org.jclouds.iam.IAMAsyncClient;
import org.jclouds.iam.IAMClient;
import org.jclouds.rest.RestContext;
import org.testng.annotations.Test;
import com.google.common.reflect.TypeToken;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live")
public class BaseIAMClientLiveTest extends
BaseContextLiveTest<RestContext<? extends IAMClient, ? extends IAMAsyncClient>> {
public BaseIAMClientLiveTest() {
provider = "iam";
}
@Override
protected TypeToken<RestContext<? extends IAMClient, ? extends IAMAsyncClient>> contextType() {
return IAMApiMetadata.CONTEXT_TOKEN;
}
}

View File

@ -0,0 +1,51 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.internal;
import org.jclouds.date.DateService;
import org.jclouds.iam.config.IAMRestClientModule;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.internal.BaseRestClientExpectTest;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class BaseIAMExpectTest<T> extends BaseRestClientExpectTest<T> {
public BaseIAMExpectTest() {
provider = "iam";
}
@ConfiguresRestClient
private static final class TestIAMRestClientModule extends IAMRestClientModule {
@Override
protected String provideTimeStamp(final DateService dateService) {
return "2009-11-08T15:54:08.897Z";
}
}
@Override
protected Module createModule() {
return new TestIAMRestClientModule();
}
}

View File

@ -0,0 +1,68 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.options;
import static org.jclouds.iam.options.ListUsersOptions.Builder.marker;
import static org.jclouds.iam.options.ListUsersOptions.Builder.maxItems;
import static org.jclouds.iam.options.ListUsersOptions.Builder.pathPrefix;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code ListUsersOptions}
*
* @author Adrian Cole
*/
@Test(groups = "maxItems", testName = "ListUsersOptionsTest")
public class ListUsersOptionsTest {
public void testMarker() {
ListUsersOptions options = new ListUsersOptions().marker("FFFFF");
assertEquals(ImmutableSet.of("FFFFF"), options.buildFormParameters().get("Marker"));
}
public void testMarkerStatic() {
ListUsersOptions options = marker("FFFFF");
assertEquals(ImmutableSet.of("FFFFF"), options.buildFormParameters().get("Marker"));
}
public void testMaxItems() {
ListUsersOptions options = new ListUsersOptions().maxItems(1000);
assertEquals(ImmutableSet.of("1000"), options.buildFormParameters().get("MaxItems"));
}
public void testMaxItemsStatic() {
ListUsersOptions options = maxItems(1000);
assertEquals(ImmutableSet.of("1000"), options.buildFormParameters().get("MaxItems"));
}
public void testPathPrefix() {
ListUsersOptions options = new ListUsersOptions().pathPrefix("/division_abc/subdivision_xyz/");
assertEquals(ImmutableSet.of("/division_abc/subdivision_xyz/"), options.buildFormParameters().get("PathPrefix"));
}
public void testPathPrefixStatic() {
ListUsersOptions options = pathPrefix("/division_abc/subdivision_xyz/");
assertEquals(ImmutableSet.of("/division_abc/subdivision_xyz/"), options.buildFormParameters().get("PathPrefix"));
}
}

View File

@ -0,0 +1,60 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.parse;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.xml.UserHandler;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "GetUserResponseTest")
public class GetUserResponseTest extends BaseHandlerTest {
public void test() {
InputStream is = getClass().getResourceAsStream("/get_user.xml");
User expected = expected();
UserHandler handler = injector.getInstance(UserHandler.class);
User result = factory.create(handler).parse(is);
assertEquals(result, expected);
assertEquals(result.getPath(), expected.getPath());
assertEquals(result.getName(), expected.getName());
}
public User expected() {
return User.builder()
.path("/division_abc/subdivision_xyz/")
.name("Bob")
.id("AIDACKCEVSQ6C2EXAMPLE")
.arn("arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob")
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2009-03-06T21:47:48Z")).build();
}
}

View File

@ -0,0 +1,69 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.iam.parse;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.iam.domain.User;
import org.jclouds.iam.xml.ListUsersResultHandler;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "ListUsersResponseTest")
public class ListUsersResponseTest extends BaseHandlerTest {
public void test() {
InputStream is = getClass().getResourceAsStream("/list_users.xml");
PaginatedSet<User> expected = expected();
ListUsersResultHandler handler = injector.getInstance(ListUsersResultHandler.class);
PaginatedSet<User> result = factory.create(handler).parse(is);
assertEquals(result.toString(), expected.toString());
}
public PaginatedSet<User> expected() {
return PaginatedSet.copyOf(ImmutableSet.of(
User.builder()
.path("/division_abc/subdivision_xyz/engineering/")
.name("Andrew")
.id("AID2MAB8DPLSRHEXAMPLE")
.arn("arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/engineering/Andrew")
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2009-03-06T21:47:48Z")).build(),
User.builder()
.path("/division_abc/subdivision_xyz/engineering/")
.name("Jackie")
.id("AIDIODR4TAW7CSEXAMPLE")
.arn("arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/engineering/Jackie")
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2009-03-06T21:47:48Z")).build()));
}
}

View File

@ -0,0 +1,16 @@
<GetUserResponse>
<GetUserResult>
<User>
<Path>/division_abc/subdivision_xyz/</Path>
<UserName>Bob</UserName>
<UserId>AIDACKCEVSQ6C2EXAMPLE</UserId>
<Arn>
arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob
</Arn>
<CreateDate>2009-03-06T21:47:48Z</CreateDate>
</User>
</GetUserResult>
<ResponseMetadata>
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
</ResponseMetadata>
</GetUserResponse>

View File

@ -0,0 +1,24 @@
<ListUsersResponse>
<ListUsersResult>
<Users>
<member>
<Path>/division_abc/subdivision_xyz/engineering/</Path>
<UserName>Andrew</UserName>
<UserId>AID2MAB8DPLSRHEXAMPLE</UserId>
<Arn>arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/engineering/Andrew</Arn>
<CreateDate>2009-03-06T21:47:48Z</CreateDate>
</member>
<member>
<Path>/division_abc/subdivision_xyz/engineering/</Path>
<UserName>Jackie</UserName>
<UserId>AIDIODR4TAW7CSEXAMPLE</UserId>
<Arn>arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/engineering/Jackie</Arn>
<CreateDate>2009-03-06T21:47:48Z</CreateDate>
</member>
</Users>
<IsTruncated>false</IsTruncated>
</ListUsersResult>
<ResponseMetadata>
<RequestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestId>
</ResponseMetadata>
</ListUsersResponse>

View File

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!--
For more configuration infromation and examples see the Apache
Log4j website: http://logging.apache.org/log4j/
-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="BLOBSTOREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-blobstore.log" />
<param name="Append" value="true" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="SSHFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-ssh.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNCSSH" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="SSHFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<appender name="ASYNCBLOBSTORE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="BLOBSTOREFILE" />
</appender>
<!-- ================ -->
<!-- Limit categories -->
<!-- ================ -->
<category name="org.jclouds">
<priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.ssh">
<priority value="DEBUG" />
<appender-ref ref="ASYNCSSH" />
</category>
<category name="jclouds.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.blobstore">
<priority value="DEBUG" />
<appender-ref ref="ASYNCBLOBSTORE" />
</category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<priority value="WARN" />
</root>
</log4j:configuration>

View File

@ -52,5 +52,7 @@
<module>rackspace-cloudservers-us</module> <module>rackspace-cloudservers-us</module>
<module>greenqloud-compute</module> <module>greenqloud-compute</module>
<module>greenqloud-storage</module> <module>greenqloud-storage</module>
<module>iam</module>
<module>aws-iam</module>
</modules> </modules>
</project> </project>