removed async api from dynect

This commit is contained in:
adriancole 2013-04-09 22:35:05 -07:00
parent d1af582ed0
commit 7e0c4cfb00
13 changed files with 438 additions and 714 deletions

View File

@ -18,24 +18,34 @@
*/ */
package org.jclouds.dynect.v3; package org.jclouds.dynect.v3;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import java.io.Closeable; import java.io.Closeable;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.dynect.v3.domain.Job; import org.jclouds.dynect.v3.domain.Job;
import org.jclouds.dynect.v3.features.RecordApi; import org.jclouds.dynect.v3.features.RecordApi;
import org.jclouds.dynect.v3.features.SessionApi; import org.jclouds.dynect.v3.features.SessionApi;
import org.jclouds.dynect.v3.features.ZoneApi; import org.jclouds.dynect.v3.features.ZoneApi;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.RequestFilters;
/** /**
* Provides access to DynECT Managed DNS through the API2 api * Provides access to DynECT Managed DNS through the API2 api
* <p/> * <p/>
* *
* @see DynECTAsyncApi * @see <a href="https://manage.dynect.net/help/docs/api2/rest/" />
* @see <a href="https://manage.dynect.net/help/docs/api2/rest/"
* />
* @author Adrian Cole * @author Adrian Cole
*/ */
public interface DynECTApi extends Closeable { public interface DynECTApi extends Closeable {
@ -46,8 +56,15 @@ public interface DynECTApi extends Closeable {
* The ID of the job * The ID of the job
* @return null, if not found * @return null, if not found
*/ */
@Named("GetJob")
@GET
@Path("/Job/{jobId}")
@RequestFilters({ AlwaysAddContentType.class, SessionManager.class })
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
@Fallback(NullOnNotFoundOr404.class)
@Consumes(APPLICATION_JSON)
@Nullable @Nullable
Job getJob(long jobId); Job getJob(@PathParam("jobId") long jobId);
/** /**
* Provides synchronous access to Session features. * Provides synchronous access to Session features.

View File

@ -23,8 +23,8 @@ import java.util.Properties;
import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.ApiMetadata;
import org.jclouds.dynect.v3.config.DynECTParserModule; import org.jclouds.dynect.v3.config.DynECTParserModule;
import org.jclouds.dynect.v3.config.DynECTRestClientModule; import org.jclouds.dynect.v3.config.DynECTHttpApiModule;
import org.jclouds.rest.internal.BaseRestApiMetadata; import org.jclouds.rest.internal.BaseHttpApiMetadata;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.inject.Module; import com.google.inject.Module;
@ -34,9 +34,7 @@ import com.google.inject.Module;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class DynECTApiMetadata extends BaseRestApiMetadata { public class DynECTApiMetadata extends BaseHttpApiMetadata<DynECTApi> {
public static final String ANONYMOUS_IDENTITY = "ANONYMOUS";
@Override @Override
public Builder toBuilder() { public Builder toBuilder() {
@ -52,27 +50,24 @@ public class DynECTApiMetadata extends BaseRestApiMetadata {
} }
public static Properties defaultProperties() { public static Properties defaultProperties() {
Properties properties = BaseRestApiMetadata.defaultProperties(); Properties properties = BaseHttpApiMetadata.defaultProperties();
return properties; return properties;
} }
public static class Builder extends BaseRestApiMetadata.Builder<Builder> { public static class Builder extends BaseHttpApiMetadata.Builder<DynECTApi, Builder> {
protected Builder() { protected Builder() {
super(DynECTApi.class, DynECTAsyncApi.class);
id("dynect") id("dynect")
.name("DynECT API2") .name("DynECT API2")
.identityName("Username (or " + ANONYMOUS_IDENTITY + " if anonymous)") .identityName("${customer}:${userName}")
.defaultIdentity(ANONYMOUS_IDENTITY) .credentialName("${password}")
.credentialName("Password")
.defaultCredential(ANONYMOUS_IDENTITY)
.documentation(URI.create("https://manage.dynect.net/help/docs/api2/rest/")) .documentation(URI.create("https://manage.dynect.net/help/docs/api2/rest/"))
.version("3.3.8") .version("3.3.8")
.defaultEndpoint("https://api2.dynect.net/REST") .defaultEndpoint("https://api2.dynect.net/REST")
.defaultProperties(DynECTApiMetadata.defaultProperties()) .defaultProperties(DynECTApiMetadata.defaultProperties())
.defaultModules(ImmutableSet.<Class<? extends Module>>builder() .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(DynECTParserModule.class) .add(DynECTParserModule.class)
.add(DynECTRestClientModule.class).build()); .add(DynECTHttpApiModule.class).build());
} }
@Override @Override

View File

@ -1,86 +0,0 @@
/**
* 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.dynect.v3;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import java.io.Closeable;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.dynect.v3.domain.Job;
import org.jclouds.dynect.v3.features.RecordAsyncApi;
import org.jclouds.dynect.v3.features.SessionAsyncApi;
import org.jclouds.dynect.v3.features.ZoneAsyncApi;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.RequestFilters;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to DynECT Managed DNS through the API2 api
* <p/>
*
* @see DynECTApi
* @see <a href="https://manage.dynect.net/help/docs/api2/rest/" />
* @author Adrian Cole
* @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(DynECTApi.class)} as
* {@link DynECTAsyncApi} interface will be removed in jclouds 1.7.
*/
public interface DynECTAsyncApi extends Closeable {
/**
* @see DynECTApi#getJob
*/
@Named("GetJob")
@GET
@Path("/Job/{jobId}")
@RequestFilters({ AlwaysAddContentType.class, SessionManager.class })
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
@Fallback(NullOnNotFoundOr404.class)
@Consumes(APPLICATION_JSON)
ListenableFuture<Job> getJob(@PathParam("jobId") long jobId);
/**
* Provides asynchronous access to Session features.
*/
@Delegate
SessionAsyncApi getSessionApi();
/**
* Provides asynchronous access to Zone features.
*/
@Delegate
ZoneAsyncApi getZoneApi();
/**
* Provides asynchronous access to Record features
*/
@Delegate
RecordAsyncApi getRecordApiForZone(@PathParam("zone") String zone);
}

View File

@ -0,0 +1,55 @@
/**
* 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.dynect.v3.binders;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.http.Uris.uriBuilder;
import java.net.URI;
import javax.inject.Inject;
import org.jclouds.dynect.v3.domain.CreateRecord;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.Json;
import org.jclouds.rest.Binder;
import com.google.common.collect.ImmutableMap;
public class CreateRecordBinder implements Binder {
private final Json json;
@Inject
CreateRecordBinder(Json json){
this.json = checkNotNull(json, "json");
}
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object arg) {
CreateRecord<?> in = CreateRecord.class.cast(checkNotNull(arg, "record to create"));
URI path = uriBuilder(request.getEndpoint())
.build(ImmutableMap.<String, Object> builder()
.put("type", in.getType())
.put("fqdn", in.getFQDN()).build());
return (R) request.toBuilder()
.endpoint(path)
.payload(json.toJson(ImmutableMap.of("rdata", in.getRData(), "ttl", in.getTTL()))).build();
}
}

View File

@ -0,0 +1,45 @@
/**
* 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.dynect.v3.binders;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.http.Uris.uriBuilder;
import java.net.URI;
import org.jclouds.dynect.v3.domain.RecordId;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
import com.google.common.collect.ImmutableMap;
public class RecordIdBinder implements Binder {
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object recordId) {
RecordId valueToAppend = RecordId.class.cast(checkNotNull(recordId, "recordId"));
URI path = uriBuilder(request.getEndpoint()).appendPath("/{type}Record/{zone}/{fqdn}/{id}").build(
ImmutableMap.<String, Object> builder()
.put("type", valueToAppend.getType())
.put("zone", valueToAppend.getZone())
.put("fqdn", valueToAppend.getFQDN())
.put("id", valueToAppend.getId()).build());
return (R) request.toBuilder().endpoint(path).build();
}
}

View File

@ -19,13 +19,12 @@
package org.jclouds.dynect.v3.config; package org.jclouds.dynect.v3.config;
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream; import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
import static org.jclouds.rest.config.BinderUtils.bindMappedHttpApi; import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import java.io.IOException; import java.io.IOException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.Proxy; import java.net.Proxy;
import java.net.URI; import java.net.URI;
import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
@ -36,13 +35,7 @@ import javax.net.ssl.SSLContext;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.concurrent.SingleThreaded; import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.dynect.v3.DynECTApi; import org.jclouds.dynect.v3.DynECTApi;
import org.jclouds.dynect.v3.DynECTAsyncApi;
import org.jclouds.dynect.v3.features.RecordApi;
import org.jclouds.dynect.v3.features.RecordAsyncApi;
import org.jclouds.dynect.v3.features.SessionApi; import org.jclouds.dynect.v3.features.SessionApi;
import org.jclouds.dynect.v3.features.SessionAsyncApi;
import org.jclouds.dynect.v3.features.ZoneApi;
import org.jclouds.dynect.v3.features.ZoneAsyncApi;
import org.jclouds.dynect.v3.filters.SessionManager; import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.dynect.v3.handlers.DynECTErrorHandler; import org.jclouds.dynect.v3.handlers.DynECTErrorHandler;
import org.jclouds.dynect.v3.handlers.GetJobRedirectionRetryHandler; import org.jclouds.dynect.v3.handlers.GetJobRedirectionRetryHandler;
@ -60,12 +53,11 @@ import org.jclouds.http.handlers.RedirectionRetryHandler;
import org.jclouds.http.internal.HttpWire; import org.jclouds.http.internal.HttpWire;
import org.jclouds.http.internal.JavaUrlHttpCommandExecutorService; import org.jclouds.http.internal.JavaUrlHttpCommandExecutorService;
import org.jclouds.io.ContentMetadataCodec; import org.jclouds.io.ContentMetadataCodec;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.HttpApiModule;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.ListeningExecutorService;
/** /**
@ -73,18 +65,12 @@ import com.google.common.util.concurrent.ListeningExecutorService;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@ConfiguresRestClient @ConfiguresHttpApi
// only one job at a time or error "This session already has a job running" // only one job at a time or error "This session already has a job running"
@SingleThreaded @SingleThreaded
public class DynECTRestClientModule extends RestClientModule<DynECTApi, DynECTAsyncApi> { public class DynECTHttpApiModule extends HttpApiModule<DynECTApi> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder() public DynECTHttpApiModule() {
.put(SessionApi.class, SessionAsyncApi.class)
.put(ZoneApi.class, ZoneAsyncApi.class)
.put(RecordApi.class, RecordAsyncApi.class).build();
public DynECTRestClientModule() {
super(DELEGATE_MAP);
} }
@Override @Override
@ -105,16 +91,15 @@ public class DynECTRestClientModule extends RestClientModule<DynECTApi, DynECTAs
bind(SessionManager.class); bind(SessionManager.class);
bind(RedirectionRetryHandler.class).to(GetJobRedirectionRetryHandler.class); bind(RedirectionRetryHandler.class).to(GetJobRedirectionRetryHandler.class);
super.configure(); super.configure();
// Bind apis that are used directly vs via DynECTApi // for authentication filters
bindMappedHttpApi(binder(), SessionApi.class, SessionAsyncApi.class); bindHttpApi(binder(), SessionApi.class);
bind(JavaUrlHttpCommandExecutorService.class).to(SillyRabbit200sAreForSuccess.class);
}
// dynect returns the following as a 200. // dynect returns the following as a 200.
// {"status": "failure", "data": {}, "job_id": 274509427, "msgs": // {"status": "failure", "data": {}, "job_id": 274509427, "msgs":
// [{"INFO": "token: This session already has a job running", "SOURCE": // [{"INFO": "token: This session already has a job running", "SOURCE":
// "API-B", "ERR_CD": "OPERATION_FAILED", "LVL": "ERROR"}]} // "API-B", "ERR_CD": "OPERATION_FAILED", "LVL": "ERROR"}]}
bind(JavaUrlHttpCommandExecutorService.class).to(SillyRabbit200sAreForSuccess.class);
}
@Singleton @Singleton
private static class SillyRabbit200sAreForSuccess extends JavaUrlHttpCommandExecutorService { private static class SillyRabbit200sAreForSuccess extends JavaUrlHttpCommandExecutorService {
@ -129,8 +114,11 @@ public class DynECTRestClientModule extends RestClientModule<DynECTApi, DynECTAs
untrustedSSLContextProvider, proxyForURI); untrustedSSLContextProvider, proxyForURI);
} }
/**
* synchronized to prevent multiple callers from overlapping requests on the same session
*/
@Override @Override
protected HttpResponse invoke(HttpURLConnection connection) throws IOException, InterruptedException { synchronized protected HttpResponse invoke(HttpURLConnection connection) throws IOException, InterruptedException {
HttpResponse response = super.invoke(connection); HttpResponse response = super.invoke(connection);
if (response.getStatusCode() == 200) { if (response.getStatusCode() == 200) {
byte[] data = closeClientButKeepContentStream(response); byte[] data = closeClientButKeepContentStream(response);

View File

@ -18,9 +18,24 @@
*/ */
package org.jclouds.dynect.v3.features; package org.jclouds.dynect.v3.features;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import java.util.Map; import java.util.Map;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException; import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException;
import org.jclouds.dynect.v3.binders.CreateRecordBinder;
import org.jclouds.dynect.v3.binders.RecordIdBinder;
import org.jclouds.dynect.v3.domain.CreateRecord; import org.jclouds.dynect.v3.domain.CreateRecord;
import org.jclouds.dynect.v3.domain.Job; import org.jclouds.dynect.v3.domain.Job;
import org.jclouds.dynect.v3.domain.Record; import org.jclouds.dynect.v3.domain.Record;
@ -36,42 +51,71 @@ import org.jclouds.dynect.v3.domain.rdata.SPFData;
import org.jclouds.dynect.v3.domain.rdata.SRVData; import org.jclouds.dynect.v3.domain.rdata.SRVData;
import org.jclouds.dynect.v3.domain.rdata.SSHFPData; import org.jclouds.dynect.v3.domain.rdata.SSHFPData;
import org.jclouds.dynect.v3.domain.rdata.TXTData; import org.jclouds.dynect.v3.domain.rdata.TXTData;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.dynect.v3.functions.ToRecordIds;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import com.google.common.collect.FluentIterable; import com.google.common.collect.FluentIterable;
/** /**
* @see RecordAsyncApi
* @author Adrian Cole * @author Adrian Cole
*/ */
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
@RequestFilters({ AlwaysAddContentType.class, SessionManager.class })
public interface RecordApi { public interface RecordApi {
/** /**
* Retrieves a list of resource record ids for all records of any type in the given zone. * Retrieves a list of resource record ids for all records of any type in the
* given zone.
* *
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
@Named("GetAllRecord")
@GET
@Path("/AllRecord/{zone}")
@ResponseParser(ToRecordIds.class)
FluentIterable<RecordId> list() throws JobStillRunningException; FluentIterable<RecordId> list() throws JobStillRunningException;
/** /**
* Retrieves a list of resource record ids for all records of the fqdn in the given zone * Retrieves a list of resource record ids for all records of the fqdn in the
* given zone
* *
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
FluentIterable<RecordId> listByFQDN(String fqdn) throws JobStillRunningException; @Named("GetRecord")
@GET
@Path("/AllRecord/{zone}/{fqdn}")
@ResponseParser(ToRecordIds.class)
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
FluentIterable<RecordId> listByFQDN(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
/** /**
* Retrieves a list of resource record ids for all records of the fqdn and type in the given zone * Retrieves a list of resource record ids for all records of the fqdn and
* type in the given zone
* *
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
FluentIterable<RecordId> listByFQDNAndType(String fqdn, String type) throws JobStillRunningException; @Named("GetRecord")
@GET
@Path("/{type}Record/{zone}/{fqdn}")
@ResponseParser(ToRecordIds.class)
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
FluentIterable<RecordId> listByFQDNAndType(@PathParam("fqdn") String fqdn, @PathParam("type") String type)
throws JobStillRunningException;
/** /**
* Schedules addition of a new record into the current session. Calling {@link ZoneApi#publish(String)} will publish * Schedules addition of a new record into the current session. Calling
* the zone, creating the record. * {@link ZoneApi#publish(String)} will publish the zone, creating the
* record.
* *
* @param newRecord * @param newRecord
* record to create * record to create
@ -79,20 +123,31 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Job scheduleCreate(CreateRecord<?> newRecord) throws JobStillRunningException; @Named("CreateRecord")
@POST
@Path("/{type}Record/{zone}/{fqdn}")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
Job scheduleCreate(@BinderParam(CreateRecordBinder.class) CreateRecord<?> newRecord) throws JobStillRunningException;
/** /**
* Schedules deletion of a record into the current session. Calling {@link ZoneApi#publish(String)} will publish the * Schedules deletion of a record into the current session. Calling
* changes, deleting the record. * {@link ZoneApi#publish(String)} will publish the changes, deleting the
* record.
* *
* @param recordId * @param recordId
* record to delete * record to delete
* @return job relating to the scheduled deletion or null, if the record never existed. * @return job relating to the scheduled deletion or null, if the record
* never existed.
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
@Nullable @Nullable
Job scheduleDelete(RecordId recordId) throws JobStillRunningException; @Named("DeleteRecord")
@DELETE
@Fallback(NullOnNotFoundOr404.class)
@Consumes(APPLICATION_JSON)
Job scheduleDelete(@BinderParam(RecordIdBinder.class) RecordId recordId) throws JobStillRunningException;
/** /**
* retrieves a resource record without regard to type * retrieves a resource record without regard to type
@ -101,7 +156,13 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<? extends Map<String, Object>> get(RecordId recordId) throws JobStillRunningException; @Named("GetRecord")
@GET
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<? extends Map<String, Object>> get(@BinderParam(RecordIdBinder.class) RecordId recordId)
throws JobStillRunningException;
/** /**
* Gets the {@link AAAARecord} or null if not present. * Gets the {@link AAAARecord} or null if not present.
@ -114,7 +175,14 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<AAAAData> getAAAA(String fqdn, long recordId) throws JobStillRunningException; @Named("GetAAAARecord")
@GET
@Path("/AAAARecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<AAAAData> getAAAA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId)
throws JobStillRunningException;
/** /**
* Gets the {@link ARecord} or null if not present. * Gets the {@link ARecord} or null if not present.
@ -127,7 +195,13 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<AData> getA(String fqdn, long recordId) throws JobStillRunningException; @Named("GetARecord")
@GET
@Path("/ARecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<AData> getA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/** /**
* Gets the {@link CNAMERecord} or null if not present. * Gets the {@link CNAMERecord} or null if not present.
@ -140,7 +214,14 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<CNAMEData> getCNAME(String fqdn, long recordId) throws JobStillRunningException; @Named("GetCNAMERecord")
@GET
@Path("/CNAMERecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<CNAMEData> getCNAME(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId)
throws JobStillRunningException;
/** /**
* Gets the {@link MXRecord} or null if not present. * Gets the {@link MXRecord} or null if not present.
@ -153,7 +234,13 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<MXData> getMX(String fqdn, long recordId) throws JobStillRunningException; @Named("GetMXRecord")
@GET
@Path("/MXRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<MXData> getMX(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/** /**
* Gets the {@link NSRecord} or null if not present. * Gets the {@link NSRecord} or null if not present.
@ -166,7 +253,13 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<NSData> getNS(String fqdn, long recordId) throws JobStillRunningException; @Named("GetNSRecord")
@GET
@Path("/NSRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<NSData> getNS(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/** /**
* Gets the {@link PTRRecord} or null if not present. * Gets the {@link PTRRecord} or null if not present.
@ -179,7 +272,14 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<PTRData> getPTR(String fqdn, long recordId) throws JobStillRunningException; @Named("GetPTRRecord")
@GET
@Path("/PTRRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<PTRData> getPTR(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId)
throws JobStillRunningException;
/** /**
* Gets the {@link SOARecord} or null if not present. * Gets the {@link SOARecord} or null if not present.
@ -192,7 +292,13 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
SOARecord getSOA(String fqdn, long recordId) throws JobStillRunningException; @Named("GetSOARecord")
@GET
@Path("/SOARecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
SOARecord getSOA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/** /**
* Gets the {@link SPFRecord} or null if not present. * Gets the {@link SPFRecord} or null if not present.
@ -205,7 +311,14 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<SPFData> getSPF(String fqdn, long recordId) throws JobStillRunningException; @Named("GetSPFRecord")
@GET
@Path("/SPFRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<SPFData> getSPF(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId)
throws JobStillRunningException;
/** /**
* Gets the {@link SRVRecord} or null if not present. * Gets the {@link SRVRecord} or null if not present.
@ -218,7 +331,14 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<SRVData> getSRV(String fqdn, long recordId) throws JobStillRunningException; @Named("GetSRVRecord")
@GET
@Path("/SRVRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<SRVData> getSRV(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId)
throws JobStillRunningException;
/** /**
* Gets the {@link SSHFPRecord} or null if not present. * Gets the {@link SSHFPRecord} or null if not present.
@ -231,7 +351,14 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<SSHFPData> getSSHFP(String fqdn, long recordId) throws JobStillRunningException; @Named("GetSSHFPRecord")
@GET
@Path("/SSHFPRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<SSHFPData> getSSHFP(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId)
throws JobStillRunningException;
/** /**
* Gets the {@link TXTRecord} or null if not present. * Gets the {@link TXTRecord} or null if not present.
@ -244,5 +371,12 @@ public interface RecordApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Record<TXTData> getTXT(String fqdn, long recordId) throws JobStillRunningException; @Named("GetTXTRecord")
@GET
@Path("/TXTRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Record<TXTData> getTXT(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId)
throws JobStillRunningException;
} }

View File

@ -1,291 +0,0 @@
/**
* 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, String 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.dynect.v3.features;
import static com.google.common.base.Preconditions.checkNotNull;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.jclouds.http.Uris.uriBuilder;
import java.net.URI;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException;
import org.jclouds.dynect.v3.domain.CreateRecord;
import org.jclouds.dynect.v3.domain.Job;
import org.jclouds.dynect.v3.domain.Record;
import org.jclouds.dynect.v3.domain.RecordId;
import org.jclouds.dynect.v3.domain.SOARecord;
import org.jclouds.dynect.v3.domain.rdata.AAAAData;
import org.jclouds.dynect.v3.domain.rdata.AData;
import org.jclouds.dynect.v3.domain.rdata.CNAMEData;
import org.jclouds.dynect.v3.domain.rdata.MXData;
import org.jclouds.dynect.v3.domain.rdata.NSData;
import org.jclouds.dynect.v3.domain.rdata.PTRData;
import org.jclouds.dynect.v3.domain.rdata.SPFData;
import org.jclouds.dynect.v3.domain.rdata.SRVData;
import org.jclouds.dynect.v3.domain.rdata.SSHFPData;
import org.jclouds.dynect.v3.domain.rdata.TXTData;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.dynect.v3.functions.ToRecordIds;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.Json;
import org.jclouds.rest.Binder;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ListenableFuture;
/**
*
* @see RecordApi
* @see <a
* href="https://manage.dynect.net/help/docs/api2/rest/resources/AllRecord.html">doc</a>
* @author Adrian Cole
*/
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
@RequestFilters({ AlwaysAddContentType.class, SessionManager.class })
public interface RecordAsyncApi {
/**
* @see RecordApi#list
*/
@Named("GetAllRecord")
@GET
@Path("/AllRecord/{zone}")
@ResponseParser(ToRecordIds.class)
ListenableFuture<FluentIterable<RecordId>> list() throws JobStillRunningException;
/**
* @see RecordApi#listByFQDN
*/
@Named("GetRecord")
@GET
@Path("/AllRecord/{zone}/{fqdn}")
@ResponseParser(ToRecordIds.class)
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
ListenableFuture<FluentIterable<RecordId>> listByFQDN(@PathParam("fqdn") String fqdn)
throws JobStillRunningException;
/**
* @see RecordApi#listByFQDNAndType
*/
@Named("GetRecord")
@GET
@Path("/{type}Record/{zone}/{fqdn}")
@ResponseParser(ToRecordIds.class)
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
ListenableFuture<FluentIterable<RecordId>> listByFQDNAndType(@PathParam("fqdn") String fqdn,
@PathParam("type") String type) throws JobStillRunningException;
/**
* @see RecordApi#scheduleCreate
*/
@Named("CreateRecord")
@POST
@Path("/{type}Record/{zone}/{fqdn}")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
ListenableFuture<Job> scheduleCreate(@BinderParam(CreateRecordBinder.class) CreateRecord<?> newRecord)
throws JobStillRunningException;
static class CreateRecordBinder implements Binder {
private final Json json;
@Inject
CreateRecordBinder(Json json){
this.json = checkNotNull(json, "json");
}
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object arg) {
CreateRecord<?> in = CreateRecord.class.cast(checkNotNull(arg, "record to create"));
URI path = uriBuilder(request.getEndpoint())
.build(ImmutableMap.<String, Object> builder()
.put("type", in.getType())
.put("fqdn", in.getFQDN()).build());
return (R) request.toBuilder()
.endpoint(path)
.payload(json.toJson(ImmutableMap.of("rdata", in.getRData(), "ttl", in.getTTL()))).build();
}
}
/**
* @see RecordApi#scheduleDelete
*/
@Named("DeleteRecord")
@DELETE
@Fallback(NullOnNotFoundOr404.class)
@Consumes(APPLICATION_JSON)
ListenableFuture<Job> scheduleDelete(@BinderParam(RecordIdBinder.class) RecordId recordId) throws JobStillRunningException;
/**
* @see RecordApi#get
*/
@Named("GetRecord")
@GET
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<? extends Map<String, Object>>> get(@BinderParam(RecordIdBinder.class) RecordId recordId) throws JobStillRunningException;
static class RecordIdBinder implements Binder {
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object recordId) {
RecordId valueToAppend = RecordId.class.cast(checkNotNull(recordId, "recordId"));
URI path = uriBuilder(request.getEndpoint())
.appendPath("/{type}Record/{zone}/{fqdn}/{id}")
.build(ImmutableMap.<String, Object> builder()
.put("type", valueToAppend.getType())
.put("zone", valueToAppend.getZone())
.put("fqdn", valueToAppend.getFQDN())
.put("id", valueToAppend.getId()).build());
return (R) request.toBuilder().endpoint(path).build();
}
}
/**
* @see RecordApi#getAAAA
*/
@Named("GetAAAARecord")
@GET
@Path("/AAAARecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<AAAAData>> getAAAA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/**
* @see RecordApi#getA
*/
@Named("GetARecord")
@GET
@Path("/ARecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<AData>> getA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/**
* @see RecordApi#getCNAME
*/
@Named("GetCNAMERecord")
@GET
@Path("/CNAMERecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<CNAMEData>> getCNAME(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/**
* @see RecordApi#getMX
*/
@Named("GetMXRecord")
@GET
@Path("/MXRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<MXData>> getMX(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/**
* @see RecordApi#getNS
*/
@Named("GetNSRecord")
@GET
@Path("/NSRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<NSData>> getNS(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/**
* @see RecordApi#getPTR
*/
@Named("GetPTRRecord")
@GET
@Path("/PTRRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<PTRData>> getPTR(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/**
* @see RecordApi#getSOA
*/
@Named("GetSOARecord")
@GET
@Path("/SOARecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<SOARecord> getSOA(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/**
* @see RecordApi#getSPF
*/
@Named("GetSPFRecord")
@GET
@Path("/SPFRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<SPFData>> getSPF(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/**
* @see RecordApi#getSRV
*/
@Named("GetSRVRecord")
@GET
@Path("/SRVRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<SRVData>> getSRV(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/**
* @see RecordApi#getSSHFP
*/
@Named("GetSSHFPRecord")
@GET
@Path("/SSHFPRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<SSHFPData>> getSSHFP(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
/**
* @see RecordApi#getTXT
*/
@Named("GetTXTRecord")
@GET
@Path("/TXTRecord/{zone}/{fqdn}/{id}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Record<TXTData>> getTXT(@PathParam("fqdn") String fqdn, @PathParam("id") long recordId) throws JobStillRunningException;
}

View File

@ -18,21 +18,46 @@
*/ */
package org.jclouds.dynect.v3.features; package org.jclouds.dynect.v3.features;
import javax.inject.Named;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.dynect.v3.DynECTFallbacks.FalseOn400;
import org.jclouds.dynect.v3.domain.Session; import org.jclouds.dynect.v3.domain.Session;
import org.jclouds.dynect.v3.domain.SessionCredentials; import org.jclouds.dynect.v3.domain.SessionCredentials;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.binders.BindToJsonPayload;
/** /**
* @see SessionAsyncApi
* @see <a * @see <a
* href="https://manage.dynect.net/help/docs/api2/rest/resources/Session.html" * href="https://manage.dynect.net/help/docs/api2/rest/resources/Session.html"
* /> * />
* @author Adrian Cole * @author Adrian Cole
*/ */
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
@Path("/Session")
@RequestFilters(AlwaysAddContentType.class)
public interface SessionApi { public interface SessionApi {
Session login(SessionCredentials credentials); @Named("POST:Session")
@POST
@SelectJson("data")
Session login(@BinderParam(BindToJsonPayload.class) SessionCredentials credentials);
boolean isValid(String token); @Named("GET:Session")
@GET
@Fallback(FalseOn400.class)
boolean isValid(@HeaderParam("Auth-Token") String token);
void logout(String token); @Named("DELETE:Session")
@DELETE
void logout(@HeaderParam("Auth-Token") String token);
} }

View File

@ -1,76 +0,0 @@
/**
* 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.dynect.v3.features;
import javax.inject.Named;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.dynect.v3.DynECTFallbacks.FalseOn400;
import org.jclouds.dynect.v3.domain.Session;
import org.jclouds.dynect.v3.domain.SessionCredentials;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to DynECT Managed DNS through the API2 api
* <p/>
*
* @see SessionApi
* @see <a href="https://manage.dynect.net/help/docs/api2/rest/" />
* @author Adrian Cole
*/
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
@Path("/Session")
@RequestFilters(AlwaysAddContentType.class)
public interface SessionAsyncApi {
/**
* @see SessionApi#create
*/
@Named("POST:Session")
@POST
@SelectJson("data")
ListenableFuture<Session> login(@BinderParam(BindToJsonPayload.class) SessionCredentials credentials);
/**
* @see SessionApi#isValid
*/
@Named("GET:Session")
@GET
@Fallback(FalseOn400.class)
ListenableFuture<Boolean> isValid(@HeaderParam("Auth-Token") String token);
/**
* @see SessionApi#logout
*/
@Named("DELETE:Session")
@DELETE
ListenableFuture<Void> logout(@HeaderParam("Auth-Token") String token);
}

View File

@ -18,21 +18,49 @@
*/ */
package org.jclouds.dynect.v3.features; package org.jclouds.dynect.v3.features;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException; import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException;
import org.jclouds.dynect.v3.DynECTExceptions.TargetExistsException; import org.jclouds.dynect.v3.DynECTExceptions.TargetExistsException;
import org.jclouds.dynect.v3.domain.CreatePrimaryZone; import org.jclouds.dynect.v3.domain.CreatePrimaryZone;
import org.jclouds.dynect.v3.domain.CreatePrimaryZone.ToFQDN;
import org.jclouds.dynect.v3.domain.Job; import org.jclouds.dynect.v3.domain.Job;
import org.jclouds.dynect.v3.domain.Zone; import org.jclouds.dynect.v3.domain.Zone;
import org.jclouds.dynect.v3.domain.Zone.SerialStyle; import org.jclouds.dynect.v3.domain.Zone.SerialStyle;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.dynect.v3.functions.ExtractZoneNames;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.collect.FluentIterable; import com.google.common.collect.FluentIterable;
/** /**
* @see ZoneAsyncApi
* @author Adrian Cole * @author Adrian Cole
*/ */
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
@RequestFilters({ AlwaysAddContentType.class, SessionManager.class })
public interface ZoneApi { public interface ZoneApi {
/** /**
* Lists all zone ids. * Lists all zone ids.
@ -40,11 +68,16 @@ public interface ZoneApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
@Named("ListZones")
@GET
@Path("/Zone")
@SelectJson("data")
@Transform(ExtractZoneNames.class)
FluentIterable<String> list() throws JobStillRunningException; FluentIterable<String> list() throws JobStillRunningException;
/** /**
* Schedules addition of a new primary zone into the current session. Calling {@link ZoneApi#publish(String)} will * Schedules addition of a new primary zone into the current session. Calling
* publish the zone, creating the zone. * {@link ZoneApi#publish(String)} will publish the zone, creating the zone.
* *
* @param zone * @param zone
* required parameters to create the zone. * required parameters to create the zone.
@ -54,11 +87,18 @@ public interface ZoneApi {
* @throws TargetExistsException * @throws TargetExistsException
* if the same fqdn exists * if the same fqdn exists
*/ */
Job scheduleCreate(CreatePrimaryZone zone) throws JobStillRunningException, TargetExistsException; @Named("CreatePrimaryZone")
@POST
@Path("/Zone/{fqdn}")
@Consumes(APPLICATION_JSON)
Job scheduleCreate(
@PathParam("fqdn") @ParamParser(ToFQDN.class) @BinderParam(BindToJsonPayload.class) CreatePrimaryZone createZone)
throws JobStillRunningException, TargetExistsException;
/** /**
* Schedules addition of a new primary zone with one hour default TTL and {@link SerialStyle#INCREMENT} into the * Schedules addition of a new primary zone with one hour default TTL and
* current session. Calling {@link ZoneApi#publish(String)} will publish the zone, creating the zone. * {@link SerialStyle#INCREMENT} into the current session. Calling
* {@link ZoneApi#publish(String)} will publish the zone, creating the zone.
* *
* @param fqdn * @param fqdn
* fqdn of the zone to create {@ex. jclouds.org} * fqdn of the zone to create {@ex. jclouds.org}
@ -70,42 +110,65 @@ public interface ZoneApi {
* @throws TargetExistsException * @throws TargetExistsException
* if the same fqdn exists * if the same fqdn exists
*/ */
Job scheduleCreateWithContact(String fqdn, String contact) throws JobStillRunningException, TargetExistsException; @Named("CreatePrimaryZone")
@POST
@Produces(APPLICATION_JSON)
@Payload("%7B\"rname\":\"{contact}\",\"serial_style\":\"increment\",\"ttl\":3600%7D")
@Path("/Zone/{fqdn}")
@Consumes(APPLICATION_JSON)
Job scheduleCreateWithContact(@PathParam("fqdn") String fqdn, @PayloadParam("contact") String contact)
throws JobStillRunningException, TargetExistsException;
/** /**
* Retrieves information about the specified zone. * Retrieves information about the specified zone.
* *
* @param fqdn * @param fqdn
* fqdn of the zone to get information about. ex {@code jclouds.org} * fqdn of the zone to get information about. ex
* {@code jclouds.org}
* @return null if not found * @return null if not found
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
@Named("GetZone")
@GET
@Path("/Zone/{fqdn}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
@Nullable @Nullable
Zone get(String fqdn) throws JobStillRunningException; Zone get(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
/** /**
* Deletes the zone. No need to call @link ZoneApi#publish(String)}. * Deletes the zone. No need to call @link ZoneApi#publish(String)}.
* *
* @param fqdn * @param fqdn
* zone to delete * zone to delete
* @return job relating to the scheduled deletion or null, if the zone never existed. * @return job relating to the scheduled deletion or null, if the zone never
* existed.
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
@Named("DeleteZone")
@DELETE
@Path("/Zone/{fqdn}")
@Fallback(NullOnNotFoundOr404.class)
@Consumes(APPLICATION_JSON)
@Nullable @Nullable
Job delete(String fqdn) throws JobStillRunningException; Job delete(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
/** /**
* Deletes changes to the specified zone that have been created during the current session but not yet published to * Deletes changes to the specified zone that have been created during the
* the zone. * current session but not yet published to the zone.
* *
* @param fqdn * @param fqdn
* fqdn of the zone to delete changes from ex {@code jclouds.org} * fqdn of the zone to delete changes from ex {@code jclouds.org}
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Job deleteChanges(String fqdn) throws JobStillRunningException; @Named("DeleteZoneChanges")
@DELETE
@Path("/ZoneChanges/{fqdn}")
@Consumes(APPLICATION_JSON)
Job deleteChanges(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
/** /**
* Publishes the current zone * Publishes the current zone
@ -117,7 +180,13 @@ public interface ZoneApi {
* @throws ResourceNotFoundException * @throws ResourceNotFoundException
* if the zone doesn't exist * if the zone doesn't exist
*/ */
Zone publish(String fqdn) throws JobStillRunningException, ResourceNotFoundException; @Named("PublishZone")
@PUT
@Path("/Zone/{fqdn}")
@Produces(APPLICATION_JSON)
@Payload("{\"publish\":true}")
@SelectJson("data")
Zone publish(@PathParam("fqdn") String fqdn) throws JobStillRunningException, ResourceNotFoundException;
/** /**
* freezes the specified zone. * freezes the specified zone.
@ -127,7 +196,13 @@ public interface ZoneApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Job freeze(String fqdn) throws JobStillRunningException; @Named("FreezeZone")
@PUT
@Path("/Zone/{fqdn}")
@Produces(APPLICATION_JSON)
@Payload("{\"freeze\":true}")
@Consumes(APPLICATION_JSON)
Job freeze(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
/** /**
* thaws the specified zone. * thaws the specified zone.
@ -137,5 +212,11 @@ public interface ZoneApi {
* @throws JobStillRunningException * @throws JobStillRunningException
* if a different job in the session is still running * if a different job in the session is still running
*/ */
Job thaw(String fqdn) throws JobStillRunningException; @Named("ThawZone")
@PUT
@Path("/Zone/{fqdn}")
@Produces(APPLICATION_JSON)
@Payload("{\"thaw\":true}")
@Consumes(APPLICATION_JSON)
Job thaw(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
} }

View File

@ -1,163 +0,0 @@
/**
* 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, String 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.dynect.v3.features;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.dynect.v3.DynECTExceptions.JobStillRunningException;
import org.jclouds.dynect.v3.DynECTExceptions.TargetExistsException;
import org.jclouds.dynect.v3.domain.CreatePrimaryZone;
import org.jclouds.dynect.v3.domain.CreatePrimaryZone.ToFQDN;
import org.jclouds.dynect.v3.domain.Job;
import org.jclouds.dynect.v3.domain.Zone;
import org.jclouds.dynect.v3.filters.AlwaysAddContentType;
import org.jclouds.dynect.v3.filters.SessionManager;
import org.jclouds.dynect.v3.functions.ExtractZoneNames;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.collect.FluentIterable;
import com.google.common.util.concurrent.ListenableFuture;
/**
*
* @see ZoneApi
* @see <a
* href="https://manage.dynect.net/help/docs/api2/rest/resources/Zone.html">doc</a>
* @author Adrian Cole
*/
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
@RequestFilters({ AlwaysAddContentType.class, SessionManager.class })
public interface ZoneAsyncApi {
/**
* @see ZoneApi#list
*/
@Named("ListZones")
@GET
@Path("/Zone")
@SelectJson("data")
@Transform(ExtractZoneNames.class)
ListenableFuture<FluentIterable<String>> list() throws JobStillRunningException;
/**
* @see ZoneApi#get
*/
@Named("GetZone")
@GET
@Path("/Zone/{fqdn}")
@SelectJson("data")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Zone> get(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
/**
* @see ZoneApi#scheduleCreate
*/
@Named("CreatePrimaryZone")
@POST
@Path("/Zone/{fqdn}")
@Consumes(APPLICATION_JSON)
ListenableFuture<Job> scheduleCreate(
@PathParam("fqdn") @ParamParser(ToFQDN.class) @BinderParam(BindToJsonPayload.class) CreatePrimaryZone createZone)
throws JobStillRunningException, TargetExistsException;
/**
* @see ZoneApi#scheduleCreateWithContact
*/
@Named("CreatePrimaryZone")
@POST
@Produces(APPLICATION_JSON)
@Payload("%7B\"rname\":\"{contact}\",\"serial_style\":\"increment\",\"ttl\":3600%7D")
@Path("/Zone/{fqdn}")
@Consumes(APPLICATION_JSON)
ListenableFuture<Job> scheduleCreateWithContact(@PathParam("fqdn") String fqdn,
@PayloadParam("contact") String contact) throws JobStillRunningException, TargetExistsException;
/**
* @see ZoneApi#delete
*/
@Named("DeleteZone")
@DELETE
@Path("/Zone/{fqdn}")
@Fallback(NullOnNotFoundOr404.class)
@Consumes(APPLICATION_JSON)
ListenableFuture<Job> delete(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
/**
* @see ZoneApi#deleteChanges
*/
@Named("DeleteZoneChanges")
@DELETE
@Path("/ZoneChanges/{fqdn}")
@Consumes(APPLICATION_JSON)
ListenableFuture<Job> deleteChanges(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
/**
* @see ZoneApi#publish
*/
@Named("PublishZone")
@PUT
@Path("/Zone/{fqdn}")
@Produces(APPLICATION_JSON)
@Payload("{\"publish\":true}")
@SelectJson("data")
ListenableFuture<Zone> publish(@PathParam("fqdn") String fqdn) throws JobStillRunningException, ResourceNotFoundException;
/**
* @see ZoneApi#freeze
*/
@Named("FreezeZone")
@PUT
@Path("/Zone/{fqdn}")
@Produces(APPLICATION_JSON)
@Payload("{\"freeze\":true}")
@Consumes(APPLICATION_JSON)
ListenableFuture<Job> freeze(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
/**
* @see ZoneApi#thaw
*/
@Named("ThawZone")
@PUT
@Path("/Zone/{fqdn}")
@Produces(APPLICATION_JSON)
@Payload("{\"thaw\":true}")
@Consumes(APPLICATION_JSON)
ListenableFuture<Job> thaw(@PathParam("fqdn") String fqdn) throws JobStillRunningException;
}

View File

@ -20,13 +20,13 @@ package org.jclouds.dynect.v3.internal;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import org.jclouds.dynect.v3.config.DynECTRestClientModule; import org.jclouds.dynect.v3.config.DynECTHttpApiModule;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.http.config.SSLModule; import org.jclouds.http.config.SSLModule;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
import org.jclouds.io.Payloads; import org.jclouds.io.Payloads;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.internal.BaseRestApiExpectTest; import org.jclouds.rest.internal.BaseRestApiExpectTest;
import com.google.inject.Module; import com.google.inject.Module;
@ -45,11 +45,11 @@ public class BaseDynECTExpectTest<T> extends BaseRestApiExpectTest<T> {
@Override @Override
protected Module createModule() { protected Module createModule() {
return new TestDynECTRestClientModule(); return new TestDynECTHttpApiModule();
} }
@ConfiguresRestClient @ConfiguresHttpApi
private static final class TestDynECTRestClientModule extends DynECTRestClientModule { private static final class TestDynECTHttpApiModule extends DynECTHttpApiModule {
@Override @Override
protected void configure() { protected void configure() {
install(new SSLModule()); install(new SSLModule());