diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackAsyncClient.java index 6e8aae108a..896c779f6c 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackAsyncClient.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackAsyncClient.java @@ -22,6 +22,7 @@ import org.jclouds.cloudstack.features.AccountAsyncClient; import org.jclouds.cloudstack.features.AddressAsyncClient; import org.jclouds.cloudstack.features.AsyncJobAsyncClient; import org.jclouds.cloudstack.features.ConfigurationAsyncClient; +import org.jclouds.cloudstack.features.EventAsyncClient; import org.jclouds.cloudstack.features.FirewallAsyncClient; import org.jclouds.cloudstack.features.GuestOSAsyncClient; import org.jclouds.cloudstack.features.HypervisorAsyncClient; @@ -32,15 +33,15 @@ import org.jclouds.cloudstack.features.OfferingAsyncClient; import org.jclouds.cloudstack.features.SSHKeyPairAsyncClient; import org.jclouds.cloudstack.features.SecurityGroupAsyncClient; import org.jclouds.cloudstack.features.TemplateAsyncClient; -import org.jclouds.cloudstack.features.VirtualMachineAsyncClient; import org.jclouds.cloudstack.features.VMGroupAsyncClient; +import org.jclouds.cloudstack.features.VirtualMachineAsyncClient; import org.jclouds.cloudstack.features.ZoneAsyncClient; import org.jclouds.rest.annotations.Delegate; /** * Provides asynchronous access to CloudStack via their REST API. *

- * + * * @author Adrian Cole * @see CloudStackClient * @see @@ -150,4 +151,10 @@ public interface CloudStackAsyncClient { @Delegate VMGroupAsyncClient getVMGroupClient(); + /** + * Provides synchronous access to Events + */ + @Delegate + EventAsyncClient getEventClient(); + } diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackClient.java index 17020357e0..2fbbd95c7b 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackClient.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackClient.java @@ -24,6 +24,7 @@ import org.jclouds.cloudstack.features.AccountClient; import org.jclouds.cloudstack.features.AddressClient; import org.jclouds.cloudstack.features.AsyncJobClient; import org.jclouds.cloudstack.features.ConfigurationClient; +import org.jclouds.cloudstack.features.EventClient; import org.jclouds.cloudstack.features.FirewallClient; import org.jclouds.cloudstack.features.GuestOSClient; import org.jclouds.cloudstack.features.HypervisorClient; @@ -153,4 +154,10 @@ public interface CloudStackClient { @Delegate VMGroupClient getVMGroupClient(); + /** + * Provides synchronous access to Events + */ + @Delegate + EventClient getEventClient(); + } diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java index 8a51444a1c..265e83028d 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java @@ -30,6 +30,8 @@ import org.jclouds.cloudstack.features.AsyncJobAsyncClient; import org.jclouds.cloudstack.features.AsyncJobClient; import org.jclouds.cloudstack.features.ConfigurationAsyncClient; import org.jclouds.cloudstack.features.ConfigurationClient; +import org.jclouds.cloudstack.features.EventAsyncClient; +import org.jclouds.cloudstack.features.EventClient; import org.jclouds.cloudstack.features.FirewallAsyncClient; import org.jclouds.cloudstack.features.FirewallClient; import org.jclouds.cloudstack.features.GuestOSAsyncClient; @@ -96,6 +98,7 @@ public class CloudStackRestClientModule extends RestClientModule { + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String name; + + public Builder name(String name) { + this.name = name; + return this; + } + + public EventType build() { + return new EventType(name); + } + } + + // for deserialization + EventType() { + + } + + @SerializedName("name") + private String name; + + public EventType(String name) { + this.name = name; + } + + /** + * @return the name/name of the OS type + */ + public String getName() { + return name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EventType other = (EventType) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "[name=" + name + "]"; + } + + @Override + public int compareTo(EventType arg0) { + return name.compareTo(arg0.getName()); + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/EventAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/EventAsyncClient.java new file mode 100644 index 0000000000..9b0b6574cf --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/EventAsyncClient.java @@ -0,0 +1,56 @@ +/** + * 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.cloudstack.features; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.core.MediaType; +import java.util.Set; + +import com.google.common.util.concurrent.ListenableFuture; +import org.jclouds.cloudstack.domain.EventType; +import org.jclouds.cloudstack.filters.QuerySigner; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SelectJson; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; + +/** + * Provides asynchronous access to cloudstack via their REST API. + *

+ * + * @author Vijay Kiran + * @see org.jclouds.cloudstack.features.AccountClient + * @see + */ +@RequestFilters(QuerySigner.class) +@QueryParams(keys = "response", values = "json") +public interface EventAsyncClient { + /** + * @see EventClient#listEventTypes() + */ + @GET + @QueryParams(keys = "command", values = "listEventTypes") + @SelectJson("eventtype") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listEventTypes(); + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/EventClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/EventClient.java new file mode 100644 index 0000000000..0deb1198ca --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/EventClient.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.cloudstack.features; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.cloudstack.domain.EventType; +import org.jclouds.concurrent.Timeout; + +/** + * Provides synchronous access to CloudStack Event features. + *

+ * + * @author Vijay Kiran + * @see + */ +@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) +public interface EventClient { + + /** + * List Event Types + * + * @return event types or null if not found + */ + Set listEventTypes(); +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListEventsOptions.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListEventsOptions.java new file mode 100644 index 0000000000..b5d7139276 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListEventsOptions.java @@ -0,0 +1,31 @@ +/** + * 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.cloudstack.options; + +/** + * Options used to control what events are returned + * + * @author Vijay Kiran + * @see + */ +public class ListEventsOptions { +} + diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/EventAsyncClientTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/EventAsyncClientTest.java new file mode 100644 index 0000000000..254c81c30e --- /dev/null +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/EventAsyncClientTest.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.cloudstack.features; + +import java.io.IOException; +import java.lang.reflect.Method; + +import com.google.inject.TypeLiteral; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.functions.ParseFirstJsonValueNamed; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.testng.annotations.Test; + +/** + * Tests behavior of {@code EventAsyncClient} + * + * @author Vijay Kiran + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during +// surefire +@Test(groups = "unit", testName = "EventAsyncClientTest") +public class EventAsyncClientTest extends BaseCloudStackAsyncClientTest { + + public void testListEventTypes() throws SecurityException, NoSuchMethodException, IOException { + Method method = EventAsyncClient.class.getMethod("listEventTypes"); + HttpRequest httpRequest = processor.createRequest(method); + + assertRequestLineEquals(httpRequest, + "GET http://localhost:8080/client/api?response=json&command=listEventTypes HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class); + + checkFilters(httpRequest); + + } + + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } +} diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/EventClientLiveTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/EventClientLiveTest.java new file mode 100644 index 0000000000..cfbeb17398 --- /dev/null +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/EventClientLiveTest.java @@ -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.cloudstack.features; + +import static org.testng.Assert.assertTrue; + +import java.util.Set; + +import org.jclouds.cloudstack.domain.EventType; +import org.testng.annotations.Test; + +/** + * Tests behavior of {@code EventClient} + * + * @author Vijay Kiran + */ +@Test(groups = "live", singleThreaded = true, testName = "EventClientLiveTest") +public class EventClientLiveTest extends BaseCloudStackClientLiveTest { + + public void testlistEventTypes() throws Exception { + Set response = client.getEventClient().listEventTypes(); + assert null != response; + assertTrue(response.size() >= 0); + for (EventType type : response) { + checkEventType(type); + } + } + + protected void checkEventType(EventType eventType) { + assert eventType.getName() != null : eventType; + } + +} diff --git a/sandbox-apis/cloudstack/src/test/resources/listeventtypesresponse.json b/sandbox-apis/cloudstack/src/test/resources/listeventtypesresponse.json new file mode 100644 index 0000000000..1b75dab587 --- /dev/null +++ b/sandbox-apis/cloudstack/src/test/resources/listeventtypesresponse.json @@ -0,0 +1 @@ +{ "listeventtypesresponse" : { "count":123 ,"eventtype" : [ {"name":"VM.CREATE"}, {"name":"VM.DESTROY"}, {"name":"VM.START"}, {"name":"VM.STOP"}, {"name":"VM.REBOOT"}, {"name":"VM.UPDATE"}, {"name":"VM.UPGRADE"}, {"name":"VM.RESETPASSWORD"}, {"name":"VM.MIGRATE"}, {"name":"ROUTER.CREATE"}, {"name":"ROUTER.DESTROY"}, {"name":"ROUTER.START"}, {"name":"ROUTER.STOP"}, {"name":"ROUTER.REBOOT"}, {"name":"ROUTER.HA"}, {"name":"ROUTER.UPGRADE"}, {"name":"PROXY.CREATE"}, {"name":"PROXY.DESTROY"}, {"name":"PROXY.START"}, {"name":"PROXY.STOP"}, {"name":"PROXY.REBOOT"}, {"name":"PROXY.HA"}, {"name":"VNC.CONNECT"}, {"name":"VNC.DISCONNECT"}, {"name":"NET.IPASSIGN"}, {"name":"NET.IPRELEASE"}, {"name":"NET.RULEADD"}, {"name":"NET.RULEDELETE"}, {"name":"NET.RULEMODIFY"}, {"name":"NETWORK.CREATE"}, {"name":"NETWORK.DELETE"}, {"name":"NETWORK.UPDATE"}, {"name":"LB.ASSIGN.TO.RULE"}, {"name":"LB.REMOVE.FROM.RULE"}, {"name":"LB.CREATE"}, {"name":"LB.DELETE"}, {"name":"LB.UPDATE"}, {"name":"ACCOUNT.DISABLE"}, {"name":"ACCOUNT.CREATE"}, {"name":"ACCOUNT.DELETE"}, {"name":"USER.LOGIN"}, {"name":"USER.LOGOUT"}, {"name":"USER.CREATE"}, {"name":"USER.DELETE"}, {"name":"USER.DISABLE"}, {"name":"USER.UPDATE"}, {"name":"USER.ENABLE"}, {"name":"TEMPLATE.CREATE"}, {"name":"TEMPLATE.DELETE"}, {"name":"TEMPLATE.UPDATE"}, {"name":"TEMPLATE.DOWNLOAD.START"}, {"name":"TEMPLATE.DOWNLOAD.SUCCESS"}, {"name":"TEMPLATE.DOWNLOAD.FAILED"}, {"name":"TEMPLATE.COPY"}, {"name":"TEMPLATE.EXTRACT"}, {"name":"TEMPLATE.UPLOAD"}, {"name":"TEMPLATE.CLEANUP"}, {"name":"VOLUME.CREATE"}, {"name":"VOLUME.DELETE"}, {"name":"VOLUME.ATTACH"}, {"name":"VOLUME.DETACH"}, {"name":"VOLUME.EXTRACT"}, {"name":"VOLUME.UPLOAD"}, {"name":"DOMAIN.CREATE"}, {"name":"DOMAIN.DELETE"}, {"name":"DOMAIN.UPDATE"}, {"name":"SNAPSHOT.CREATE"}, {"name":"SNAPSHOT.DELETE"}, {"name":"SNAPSHOTPOLICY.CREATE"}, {"name":"SNAPSHOTPOLICY.UPDATE"}, {"name":"SNAPSHOTPOLICY.DELETE"}, {"name":"ISO.CREATE"}, {"name":"ISO.DELETE"}, {"name":"ISO.COPY"}, {"name":"ISO.ATTACH"}, {"name":"ISO.DETACH"}, {"name":"ISO.EXTRACT"}, {"name":"ISO.UPLOAD"}, {"name":"SSVM.CREATE"}, {"name":"SSVM.DESTROY"}, {"name":"SSVM.START"}, {"name":"SSVM.STOP"}, {"name":"SSVM.REBOOT"}, {"name":"SSVM.HA"}, {"name":"SERVICE.OFFERING.CREATE"}, {"name":"SERVICE.OFFERING.EDIT"}, {"name":"SERVICE.OFFERING.DELETE"}, {"name":"DISK.OFFERING.CREATE"}, {"name":"DISK.OFFERING.EDIT"}, {"name":"DISK.OFFERING.DELETE"}, {"name":"NETWORK.OFFERING.CREATE"}, {"name":"NETWORK.OFFERING.ASSIGN"}, {"name":"NETWORK.OFFERING.EDIT"}, {"name":"NETWORK.OFFERING.REMOVE"}, {"name":"NETWORK.OFFERING.DELETE"}, {"name":"POD.CREATE"}, {"name":"POD.EDIT"}, {"name":"POD.DELETE"}, {"name":"ZONE.CREATE"}, {"name":"ZONE.EDIT"}, {"name":"ZONE.DELETE"}, {"name":"VLAN.IP.RANGE.CREATE"}, {"name":"VLAN.IP.RANGE.DELETE"}, {"name":"CONFIGURATION.VALUE.EDIT"}, {"name":"SG.AUTH.INGRESS"}, {"name":"SG.REVOKE.INGRESS"}, {"name":"SG.CREATE"}, {"name":"SG.DELETE"}, {"name":"HOST.RECONNECT"}, {"name":"MAINT.CANCEL"}, {"name":"MAINT.CANCEL.PS"}, {"name":"MAINT.PREPARE"}, {"name":"MAINT.PREPARE.PS"}, {"name":"VPN.REMOTE.ACCESS.CREATE"}, {"name":"VPN.REMOTE.ACCESS.DESTROY"}, {"name":"VPN.USER.ADD"}, {"name":"VPN.USER.REMOVE"}, {"name":"NETWORK.RESTART"}, {"name":"UPLOAD.CUSTOM.CERTIFICATE"}, {"name":"STATICNAT.ENABLE"}, {"name":"STATICNAT.DISABLE"}, {"name":"ZONE.VLAN.ASSIGN"}, {"name":"ZONE.VLAN.RELEASE"} ] } } \ No newline at end of file