From 39c79f6ffa5138987048693b02970074c9392c2c Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Fri, 24 Feb 2012 13:55:55 +0200 Subject: [PATCH] Issue 845: opsource-servers skeleton --- core/src/main/resources/rest.properties | 3 + labs/opsource-servers/pom.xml | 137 ++++++++++++++++ .../opsource/servers/OpSourceNameSpaces.java | 28 ++++ .../servers/OpSourceServersAsyncClient.java | 38 +++++ .../servers/OpSourceServersClient.java | 42 +++++ .../OpSourceServersContextBuilder.java | 43 +++++ .../OpSourceServersPropertiesBuilder.java | 47 ++++++ .../OpSourceServersRestClientModule.java | 69 ++++++++ .../opsource/servers/domain/Account.java | 105 ++++++++++++ .../servers/features/AccountAsyncClient.java | 48 ++++++ .../servers/features/AccountClient.java | 44 +++++ .../handlers/OpSourceServersErrorHandler.java | 66 ++++++++ ...SourceServersClientExperimentLiveTest.java | 37 +++++ .../features/AccountClientExpectTest.java | 60 +++++++ .../features/AccountClientLiveTest.java | 38 +++++ .../OpSourceServersErrorHandlerTest.java | 105 ++++++++++++ .../BaseOpSourceServersClientLiveTest.java | 64 ++++++++ ...seOpSourceServersRestClientExpectTest.java | 37 +++++ .../src/test/resources/log4j.xml | 151 ++++++++++++++++++ .../src/test/resources/myaccount.xml | 32 ++++ labs/pom.xml | 1 + 21 files changed, 1195 insertions(+) create mode 100644 labs/opsource-servers/pom.xml create mode 100644 labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceNameSpaces.java create mode 100644 labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersAsyncClient.java create mode 100644 labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersClient.java create mode 100644 labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersContextBuilder.java create mode 100644 labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersPropertiesBuilder.java create mode 100644 labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/config/OpSourceServersRestClientModule.java create mode 100644 labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/domain/Account.java create mode 100644 labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/features/AccountAsyncClient.java create mode 100644 labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/features/AccountClient.java create mode 100644 labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/handlers/OpSourceServersErrorHandler.java create mode 100644 labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/OpSourceServersClientExperimentLiveTest.java create mode 100644 labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/features/AccountClientExpectTest.java create mode 100644 labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/features/AccountClientLiveTest.java create mode 100644 labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/handlers/OpSourceServersErrorHandlerTest.java create mode 100644 labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/internal/BaseOpSourceServersClientLiveTest.java create mode 100644 labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/internal/BaseOpSourceServersRestClientExpectTest.java create mode 100644 labs/opsource-servers/src/test/resources/log4j.xml create mode 100644 labs/opsource-servers/src/test/resources/myaccount.xml diff --git a/core/src/main/resources/rest.properties b/core/src/main/resources/rest.properties index 25219b9ca7..76cd22a9a7 100644 --- a/core/src/main/resources/rest.properties +++ b/core/src/main/resources/rest.properties @@ -183,6 +183,9 @@ softlayer.propertiesbuilder=org.jclouds.softlayer.SoftLayerPropertiesBuilder glesys.contextbuilder=org.jclouds.glesys.GleSYSContextBuilder glesys.propertiesbuilder=org.jclouds.glesys.GleSYSPropertiesBuilder +opsource-servers.contextbuilder=org.jclouds.opsource.servers.OpSourceServersContextBuilder +opsource-servers.propertiesbuilder=org.jclouds.opsource.servers.OpSourceServersPropertiesBuilder + savvis-symphonyvpdc.contextbuilder=org.jclouds.savvis.vpdc.VPDCContextBuilder savvis-symphonyvpdc.propertiesbuilder=org.jclouds.savvis.vpdc.VPDCPropertiesBuilder diff --git a/labs/opsource-servers/pom.xml b/labs/opsource-servers/pom.xml new file mode 100644 index 0000000000..ef4eb9cb8a --- /dev/null +++ b/labs/opsource-servers/pom.xml @@ -0,0 +1,137 @@ + + + + 4.0.0 + + org.jclouds + jclouds-project + 1.5.0-SNAPSHOT + ../../project/pom.xml + + org.jclouds.labs + opsource-servers + jcloud opsource-servers api + jclouds components to access an implementation of OpSource Cloud Servers + bundle + + + https://api.opsourcecloud.net/oec/${jclouds.api-version} + 0.9 + + FIXME_USERNAME + FIXME_PASSWORD + + + + + + + + org.jclouds + jclouds-compute + ${project.version} + + + org.jclouds + jclouds-core + ${project.version} + test-jar + test + + + org.jclouds + jclouds-compute + ${project.version} + test-jar + test + + + org.jclouds.driver + jclouds-sshj + ${project.version} + test + + + org.jclouds.driver + jclouds-log4j + ${project.version} + test + + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration + integration-test + + test + + + + ${test.opsource-servers.endpoint} + ${test.opsource-servers.api-version} + ${test.opsource-servers.build-version} + ${test.opsource-servers.identity} + ${test.opsource-servers.credential} + ${test.opsource-servers.image-id} + ${test.opsource-servers.image.login-user} + ${test.opsource-servers.image.authenticate-sudo} + + + + + + + + + + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.vcloud.director.v1_5*;version="${project.version}" + + org.jclouds.compute.internal;version="${project.version}", + org.jclouds.rest.internal;version="${project.version}", + org.jclouds*;version="${project.version}", + * + + + + + + + + diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceNameSpaces.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceNameSpaces.java new file mode 100644 index 0000000000..474dd6d3a1 --- /dev/null +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceNameSpaces.java @@ -0,0 +1,28 @@ +/* + * 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.opsource.servers; + + +/** + * + * @author Adrian Cole + */ +public interface OpSourceNameSpaces { + public static final String DIRECTORY = "http://oec.api.opsource.net/schemas/directory"; +} diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersAsyncClient.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersAsyncClient.java new file mode 100644 index 0000000000..2b07e18972 --- /dev/null +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersAsyncClient.java @@ -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.opsource.servers; + +import org.jclouds.opsource.servers.features.AccountAsyncClient; +import org.jclouds.rest.annotations.Delegate; + +/** + * Provides asynchronous access to OpSourceServers via their REST API. + * + * @see OpSourceServersClient + * @author Adrian Cole + */ +public interface OpSourceServersAsyncClient { + + /** + * @return asynchronous access to {@link Account} features + */ + @Delegate + AccountAsyncClient getAccountClient(); + +} diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersClient.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersClient.java new file mode 100644 index 0000000000..16822419ff --- /dev/null +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersClient.java @@ -0,0 +1,42 @@ +/** + * 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.opsource.servers; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.opsource.servers.features.AccountClient; +import org.jclouds.rest.annotations.Delegate; + +/** + * Provides synchronous access to OpSourceServers. + * + * @see OpSourceServersAsyncClient + * @author Adrian Cole + */ +@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) +public interface OpSourceServersClient { + + /** + * @return synchronous access to {@link Account} features + */ + @Delegate + AccountClient getAccountClient(); + +} diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersContextBuilder.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersContextBuilder.java new file mode 100644 index 0000000000..5c8cf97d26 --- /dev/null +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersContextBuilder.java @@ -0,0 +1,43 @@ +/** + * 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.opsource.servers; + +import java.util.List; +import java.util.Properties; + +import org.jclouds.rest.RestContextBuilder; +import org.jclouds.opsource.servers.config.OpSourceServersRestClientModule; + +import com.google.inject.Module; + +/** + * @author Adrian Cole + */ +public class OpSourceServersContextBuilder extends RestContextBuilder { + + public OpSourceServersContextBuilder(Properties props) { + super(OpSourceServersClient.class, OpSourceServersAsyncClient.class, props); + } + + @Override + protected void addClientModule(List modules) { + modules.add(new OpSourceServersRestClientModule()); + } + +} diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersPropertiesBuilder.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersPropertiesBuilder.java new file mode 100644 index 0000000000..28cc359507 --- /dev/null +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/OpSourceServersPropertiesBuilder.java @@ -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.opsource.servers; + +import static org.jclouds.Constants.PROPERTY_API_VERSION; +import static org.jclouds.Constants.PROPERTY_ENDPOINT; + +import java.util.Properties; + +import org.jclouds.PropertiesBuilder; + +/** + * Builds properties used in OpSourceServers clients + * + * @author Adrian Cole + */ +public class OpSourceServersPropertiesBuilder extends PropertiesBuilder { + + @Override + public Properties defaultProperties() { + Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ENDPOINT, "https://api.opsourcecloud.net/oec/${jclouds.api-version}"); + properties.setProperty(PROPERTY_API_VERSION, "0.9"); + return properties; + } + + public OpSourceServersPropertiesBuilder(Properties properties) { + super(properties); + } + +} diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/config/OpSourceServersRestClientModule.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/config/OpSourceServersRestClientModule.java new file mode 100644 index 0000000000..736526e296 --- /dev/null +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/config/OpSourceServersRestClientModule.java @@ -0,0 +1,69 @@ +/** + * 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.opsource.servers.config; + +import java.util.Map; + +import org.jclouds.http.HttpErrorHandler; +import org.jclouds.http.RequiresHttp; +import org.jclouds.http.annotation.ClientError; +import org.jclouds.http.annotation.Redirection; +import org.jclouds.http.annotation.ServerError; +import org.jclouds.location.suppliers.ImplicitLocationSupplier; +import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone; +import org.jclouds.opsource.servers.OpSourceServersAsyncClient; +import org.jclouds.opsource.servers.OpSourceServersClient; +import org.jclouds.opsource.servers.features.AccountAsyncClient; +import org.jclouds.opsource.servers.features.AccountClient; +import org.jclouds.opsource.servers.handlers.OpSourceServersErrorHandler; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.config.RestClientModule; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Scopes; + +/** + * Configures the OpSourceServers connection. + * + * @author Adrian Cole + */ +@RequiresHttp +@ConfiguresRestClient +public class OpSourceServersRestClientModule extends + RestClientModule { + + public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder()// + .put(AccountClient.class, AccountAsyncClient.class).build(); + + public OpSourceServersRestClientModule() { + super(OpSourceServersClient.class, OpSourceServersAsyncClient.class, DELEGATE_MAP); + } + + @Override + protected void bindErrorHandlers() { + bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(OpSourceServersErrorHandler.class); + bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(OpSourceServersErrorHandler.class); + bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(OpSourceServersErrorHandler.class); + } + + @Override + protected void installLocations() { + super.installLocations(); + bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Scopes.SINGLETON); + } +} diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/domain/Account.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/domain/Account.java new file mode 100644 index 0000000000..43d8e88b3f --- /dev/null +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/domain/Account.java @@ -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.opsource.servers.domain; + +import static com.google.common.base.Objects.equal; +import static org.jclouds.opsource.servers.OpSourceNameSpaces.DIRECTORY; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.google.common.base.Objects; + +/** + * + * + */ +@XmlRootElement(name = "Account", namespace = DIRECTORY) +public class Account { + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().fromAccount(this); + } + + public static class Builder { + + private String orgId; + + /** + * @see Account#getOrgId() + */ + public Builder orgId(String orgId) { + this.orgId = orgId; + return this; + } + + public Account build() { + return new Account(orgId); + } + + public Builder fromAccount(Account in) { + return orgId(in.getOrgId()); + } + } + + private Account() { + // For JAXB and builder use + } + + @XmlElement(namespace = DIRECTORY) + protected String orgId; + + private Account(String orgId) { + this.orgId = orgId; + } + + /** + * + * @return your Organization ID that will be used as the basis for subsequent + * API interactions + * + */ + public String getOrgId() { + return orgId; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Account that = Account.class.cast(o); + return equal(orgId, that.orgId); + } + + @Override + public int hashCode() { + return Objects.hashCode(orgId); + } + + @Override + public String toString() { + return Objects.toStringHelper("").add("orgId", orgId).toString(); + } + +} diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/features/AccountAsyncClient.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/features/AccountAsyncClient.java new file mode 100644 index 0000000000..7c3f8fbb9c --- /dev/null +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/features/AccountAsyncClient.java @@ -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.opsource.servers.features; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.jclouds.http.filters.BasicAuthentication; +import org.jclouds.opsource.servers.domain.Account; +import org.jclouds.rest.annotations.JAXBResponseParser; +import org.jclouds.rest.annotations.RequestFilters; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * @see AccountClient + * @author Adrian Cole + */ +@RequestFilters(BasicAuthentication.class) +public interface AccountAsyncClient { + + /** + * @see AccountClient#getMyAccount() + */ + @GET + @Path("/myaccount") + @Consumes + @JAXBResponseParser + ListenableFuture getMyAccount(); + +} diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/features/AccountClient.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/features/AccountClient.java new file mode 100644 index 0000000000..1495a87924 --- /dev/null +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/features/AccountClient.java @@ -0,0 +1,44 @@ +/** + * 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.opsource.servers.features; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.opsource.servers.domain.Account; + +/** + * Provides synchronous access to Account. + *

+ * + * @see AccountAsyncClient + * @author Adrian Cole + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface AccountClient { + + /** + * Before you can begin using the range of Server, Network and Image APIs, + * you will need to first obtain your organization details. + * + * @return the user's details, including their organization ID. + */ + Account getMyAccount(); + +} diff --git a/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/handlers/OpSourceServersErrorHandler.java b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/handlers/OpSourceServersErrorHandler.java new file mode 100644 index 0000000000..d3d905b400 --- /dev/null +++ b/labs/opsource-servers/src/main/java/org/jclouds/opsource/servers/handlers/OpSourceServersErrorHandler.java @@ -0,0 +1,66 @@ +/** + * 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.opsource.servers.handlers; + +import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream; + +import javax.inject.Singleton; + +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpErrorHandler; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.HttpResponseException; +import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.ResourceNotFoundException; + +/** + * This will parse and set an appropriate exception on the command object. + * + * @author Adrian Cole + * + */ +@Singleton +public class OpSourceServersErrorHandler implements HttpErrorHandler { + + public void handleError(HttpCommand command, HttpResponse response) { + // it is important to always read fully and close streams + byte[] data = closeClientButKeepContentStream(response); + String message = data != null ? new String(data) : null; + + Exception exception = message != null ? new HttpResponseException(command, response, message) + : new HttpResponseException(command, response); + message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(), + response.getStatusLine()); + switch (response.getStatusCode()) { + case 401: + exception = new AuthorizationException(message, exception); + break; + case 404: + if (!command.getCurrentRequest().getMethod().equals("DELETE")) { + exception = new ResourceNotFoundException(message, exception); + } + break; + default: + exception = new HttpResponseException(command, response, message); + break; + } + command.setException(exception); + } + +} diff --git a/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/OpSourceServersClientExperimentLiveTest.java b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/OpSourceServersClientExperimentLiveTest.java new file mode 100644 index 0000000000..584a74709d --- /dev/null +++ b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/OpSourceServersClientExperimentLiveTest.java @@ -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.opsource.servers; + +import org.jclouds.opsource.servers.domain.Account; +import org.jclouds.opsource.servers.internal.BaseOpSourceServersClientLiveTest; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", testName = "OpSourceServersClientExperimentLiveTest") +public class OpSourceServersClientExperimentLiveTest extends BaseOpSourceServersClientLiveTest { + + public void testImplicitSession() { + Account account = context.getApi().getAccountClient().getMyAccount(); + assert account.getOrgId() != null; + } + +} diff --git a/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/features/AccountClientExpectTest.java b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/features/AccountClientExpectTest.java new file mode 100644 index 0000000000..c0e759c0ee --- /dev/null +++ b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/features/AccountClientExpectTest.java @@ -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.opsource.servers.features; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.opsource.servers.OpSourceServersClient; +import org.jclouds.opsource.servers.domain.Account; +import org.jclouds.opsource.servers.internal.BaseOpSourceServersRestClientExpectTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; + +/** + * Allows us to test the {@link AccountClient} via its side effects. + * + * @author Adrian Cole + */ +@Test(groups = { "unit" }, singleThreaded = true, testName = "AccountClientExpectTest") +public class AccountClientExpectTest extends BaseOpSourceServersRestClientExpectTest { + + @Test + public void testGetMyAccount() { + OpSourceServersClient client = requestSendsResponse( + HttpRequest + .builder() + .method("GET") + .endpoint(URI.create("https://api.opsourcecloud.net/oec/0.9/myaccount")) + .headers( + ImmutableMultimap. builder().put("Accept", "*/*") + .put("Authorization", "Basic dXNlcjpwYXNzd29yZA==").build()).build(), + + HttpResponse.builder().statusCode(200).payload(payloadFromResource("/myaccount.xml")).build()); + + Account expected = Account.builder().orgId("8a8f6abc-2745-4d8a-9cbc-8dabe5a7d0e4").build(); + + assertEquals(client.getAccountClient().getMyAccount(), expected); + } + +} diff --git a/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/features/AccountClientLiveTest.java b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/features/AccountClientLiveTest.java new file mode 100644 index 0000000000..a2c2bf3ccb --- /dev/null +++ b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/features/AccountClientLiveTest.java @@ -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.opsource.servers.features; + +import org.jclouds.opsource.servers.domain.Account; +import org.jclouds.opsource.servers.internal.BaseOpSourceServersClientLiveTest; +import org.testng.annotations.Test; + +/** + * Tests live behavior of {@link AccountClient}. + * + * @author Adrian Cole + */ +@Test(groups = { "live" }, singleThreaded = true, testName = "AccountClientLiveTest") +public class AccountClientLiveTest extends BaseOpSourceServersClientLiveTest { + + public void testGetMyAccount() { + Account account = context.getApi().getAccountClient().getMyAccount(); + assert account.getOrgId() != null; + } + +} diff --git a/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/handlers/OpSourceServersErrorHandlerTest.java b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/handlers/OpSourceServersErrorHandlerTest.java new file mode 100644 index 0000000000..9022e802b9 --- /dev/null +++ b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/handlers/OpSourceServersErrorHandlerTest.java @@ -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.opsource.servers.handlers; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reportMatcher; +import static org.easymock.EasyMock.verify; + +import java.net.URI; + +import org.easymock.IArgumentMatcher; +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.io.Payloads; +import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.ResourceNotFoundException; +import org.jclouds.util.Strings2; +import org.testng.annotations.Test; + +import com.google.inject.Guice; + +/** + * + * @author Adrian Cole + */ +@Test(groups = { "unit" }) +public class OpSourceServersErrorHandlerTest { + + @Test + public void test401MakesAuthorizationException() { + assertCodeMakes("GET", URI.create("https://api.opsourcecloud.net/oec/0.9/foo"), 401, "", "Unauthorized", + AuthorizationException.class); + } + + @Test + public void test404MakesResourceNotFoundException() { + assertCodeMakes("GET", URI.create("https://api.opsourcecloud.net/oec/0.9/foo"), 404, "", "Not Found", + ResourceNotFoundException.class); + } + + private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content, + Class expected) { + assertCodeMakes(method, uri, statusCode, message, "text/xml", content, expected); + } + + private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType, + String content, Class expected) { + + OpSourceServersErrorHandler function = Guice.createInjector().getInstance(OpSourceServersErrorHandler.class); + + HttpCommand command = createMock(HttpCommand.class); + HttpRequest request = new HttpRequest(method, uri); + HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Strings2 + .toInputStream(content))); + response.getPayload().getContentMetadata().setContentType(contentType); + + expect(command.getCurrentRequest()).andReturn(request).atLeastOnce(); + command.setException(classEq(expected)); + + replay(command); + + function.handleError(command, response); + + verify(command); + } + + public static Exception classEq(final Class in) { + reportMatcher(new IArgumentMatcher() { + + @Override + public void appendTo(StringBuffer buffer) { + buffer.append("classEq("); + buffer.append(in); + buffer.append(")"); + } + + @Override + public boolean matches(Object arg) { + return arg.getClass() == in; + } + + }); + return null; + } + +} diff --git a/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/internal/BaseOpSourceServersClientLiveTest.java b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/internal/BaseOpSourceServersClientLiveTest.java new file mode 100644 index 0000000000..9aba439acb --- /dev/null +++ b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/internal/BaseOpSourceServersClientLiveTest.java @@ -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.opsource.servers.internal; + +import java.util.Properties; + +import org.jclouds.compute.BaseVersionedServiceLiveTest; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.opsource.servers.OpSourceServersAsyncClient; +import org.jclouds.opsource.servers.OpSourceServersClient; +import org.jclouds.rest.RestContext; +import org.jclouds.rest.RestContextFactory; +import org.jclouds.sshj.config.SshjSshClientModule; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Module; + +/** + * Tests behavior of {@link OpSourceServersClient} and acts as parent for other + * client live tests. + * + * @author Adrian Cole + */ +@Test(groups = "live") +public abstract class BaseOpSourceServersClientLiveTest extends BaseVersionedServiceLiveTest { + + protected BaseOpSourceServersClientLiveTest() { + provider = "opsource-servers"; + } + + protected RestContext context; + + @BeforeClass(groups = { "live" }) + public void setupContext() { + setupCredentials(); + Properties overrides = setupProperties(); + + context = new RestContextFactory().createContext(provider, identity, credential, + ImmutableSet. of(new Log4JLoggingModule(), new SshjSshClientModule()), overrides); + } + + protected void tearDown() { + if (context != null) + context.close(); + } +} diff --git a/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/internal/BaseOpSourceServersRestClientExpectTest.java b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/internal/BaseOpSourceServersRestClientExpectTest.java new file mode 100644 index 0000000000..c5720cd222 --- /dev/null +++ b/labs/opsource-servers/src/test/java/org/jclouds/opsource/servers/internal/BaseOpSourceServersRestClientExpectTest.java @@ -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.opsource.servers.internal; + +import org.jclouds.opsource.servers.OpSourceServersClient; +import org.jclouds.rest.BaseRestClientExpectTest; + +/** + * Base class for writing OpSourceServersClient Expect tests + * + * @author Adrian Cole + */ +public class BaseOpSourceServersRestClientExpectTest extends BaseRestClientExpectTest { + + public BaseOpSourceServersRestClientExpectTest() { + provider = "opsource-servers"; + identity = "user"; + credential = "password"; + } + +} diff --git a/labs/opsource-servers/src/test/resources/log4j.xml b/labs/opsource-servers/src/test/resources/log4j.xml new file mode 100644 index 0000000000..63810d3ca0 --- /dev/null +++ b/labs/opsource-servers/src/test/resources/log4j.xml @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/opsource-servers/src/test/resources/myaccount.xml b/labs/opsource-servers/src/test/resources/myaccount.xml new file mode 100644 index 0000000000..afc9b1107c --- /dev/null +++ b/labs/opsource-servers/src/test/resources/myaccount.xml @@ -0,0 +1,32 @@ + + + testuser + Test User + Test + User + test@example.com + 8a8f6abc-2745-4d8a-9cbc-8dabe5a7d0e4 + + + create image + + + reports + + + server + + + primary administrator + + + network + + + \ No newline at end of file diff --git a/labs/pom.xml b/labs/pom.xml index 62213128e1..ad0519c072 100644 --- a/labs/pom.xml +++ b/labs/pom.xml @@ -36,5 +36,6 @@ virtualbox vcloud-director glesys + opsource-servers