diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 644814fa201b..1227a9e3b323 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -230,7 +230,7 @@ public static DnsRecordListOption pageSize(int pageSize) { * Restricts the list to only DNS records with this fully qualified domain name. */ public static DnsRecordListOption dnsName(String dnsName) { - return new DnsRecordListOption(DnsRpc.Option.DNS_NAME, dnsName); + return new DnsRecordListOption(DnsRpc.Option.NAME, dnsName); } /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java index d18f6163a881..73c546759260 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java @@ -27,8 +27,8 @@ public class DnsException extends BaseServiceException { private static final long serialVersionUID = 490302380416260252L; - public DnsException(IOException exception, boolean idempotent) { - super(exception, idempotent); + public DnsException(IOException exception) { + super(exception, true); } //TODO(mderka) Add translation and retry functionality. Created issue #593. diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index 1845467c2537..248fd164a55f 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableSet; import com.google.gcloud.ServiceOptions; +import com.google.gcloud.spi.DefaultDnsRpc; import com.google.gcloud.spi.DnsRpc; import com.google.gcloud.spi.DnsRpcFactory; @@ -46,8 +47,7 @@ public static class DefaultDnsRpcFactory implements DnsRpcFactory { @Override public DnsRpc create(DnsOptions options) { - // TODO(mderka) Implement when DefaultDnsRpc is available. Created issue #595. - return null; + return new DefaultDnsRpc(options); } } @@ -80,7 +80,7 @@ protected DnsFactory defaultServiceFactory() { @SuppressWarnings("unchecked") @Override protected DnsRpcFactory defaultRpcFactory() { - return null; + return DefaultDnsRpcFactory.INSTANCE; } @Override diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java new file mode 100644 index 000000000000..73e6ab4036ec --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java @@ -0,0 +1,191 @@ +package com.google.gcloud.spi; + +import static com.google.gcloud.spi.DnsRpc.ListResult.of; +import static com.google.gcloud.spi.DnsRpc.Option.DNS_NAME; +import static com.google.gcloud.spi.DnsRpc.Option.NAME; +import static com.google.gcloud.spi.DnsRpc.Option.DNS_TYPE; +import static com.google.gcloud.spi.DnsRpc.Option.FIELDS; +import static com.google.gcloud.spi.DnsRpc.Option.PAGE_SIZE; +import static com.google.gcloud.spi.DnsRpc.Option.PAGE_TOKEN; +import static com.google.gcloud.spi.DnsRpc.Option.SORTING_ORDER; +import static java.net.HttpURLConnection.HTTP_NOT_FOUND; + +import com.google.api.client.http.HttpRequestInitializer; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.json.jackson.JacksonFactory; +import com.google.api.services.dns.Dns; +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ChangesListResponse; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.ManagedZonesListResponse; +import com.google.api.services.dns.model.Project; +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.api.services.dns.model.ResourceRecordSetsListResponse; +import com.google.gcloud.dns.DnsException; +import com.google.gcloud.dns.DnsOptions; + +import java.io.IOException; +import java.util.Map; + +/** + * A default implementation of the DnsRpc interface. + */ +public class DefaultDnsRpc implements DnsRpc { + + private static final String SORT_BY = "changeSequence"; + private final Dns dns; + private final DnsOptions options; + + private static DnsException translate(IOException exception) { + return new DnsException(exception); + } + + /** + * Constructs an instance of this rpc client with provided {@link DnsOptions}. + */ + public DefaultDnsRpc(DnsOptions options) { + HttpTransport transport = options.httpTransportFactory().create(); + HttpRequestInitializer initializer = options.httpRequestInitializer(); + this.dns = new Dns.Builder(transport, new JacksonFactory(), initializer) + .setRootUrl(options.host()) + .setApplicationName(options.applicationName()) + .build(); + this.options = options; + } + + @Override + public ManagedZone create(ManagedZone zone) throws DnsException { + try { + return dns.managedZones().create(this.options.projectId(), zone).execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public ManagedZone getZone(String zoneName, Map options) throws DnsException { + // just fields option + try { + return dns.managedZones().get(this.options.projectId(), zoneName) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + DnsException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + return null; + } + throw serviceException; + } + } + + @Override + public ListResult listZones(Map options) throws DnsException { + // fields, page token, page size + try { + ManagedZonesListResponse zoneList = dns.managedZones().list(this.options.projectId()) + .setFields(FIELDS.getString(options)) + .setMaxResults(PAGE_SIZE.getInt(options)) + .setDnsName(DNS_NAME.getString(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .execute(); + return of(zoneList.getNextPageToken(), zoneList.getManagedZones()); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public boolean deleteZone(String zoneName) throws DnsException { + try { + dns.managedZones().delete(this.options.projectId(), zoneName).execute(); + return true; + } catch (IOException ex) { + DnsException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + return false; + } + throw serviceException; + } + } + + @Override + public ListResult listDnsRecords(String zoneName, Map options) + throws DnsException { + // options are fields, page token, dns name, type + try { + ResourceRecordSetsListResponse response = dns.resourceRecordSets() + .list(this.options.projectId(), zoneName) + .setFields(FIELDS.getString(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setMaxResults(PAGE_SIZE.getInt(options)) + .setName(NAME.getString(options)) + .setType(DNS_TYPE.getString(options)) + .execute(); + return of(response.getNextPageToken(), response.getRrsets()); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Project getProject(Map options) throws DnsException { + try { + return dns.projects().get(this.options.projectId()) + .setFields(FIELDS.getString(options)).execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Change applyChangeRequest(String zoneName, Change changeRequest, Map options) + throws DnsException { + try { + return dns.changes().create(this.options.projectId(), zoneName, changeRequest) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Change getChangeRequest(String zoneName, String changeRequestId, Map options) + throws DnsException { + try { + return dns.changes().get(this.options.projectId(), zoneName, changeRequestId) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + DnsException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + if (serviceException.location().equals("entity.parameters.changeId")) { + // the change id was not found, but the zone exists + return null; + } + // the zone does not exist, so throw an exception + } + throw serviceException; + } + } + + @Override + public ListResult listChangeRequests(String zoneName, Map options) + throws DnsException { + // options are fields, page token, page size, sort order + try { + Dns.Changes.List request = dns.changes().list(this.options.projectId(), zoneName) + .setFields(FIELDS.getString(options)) + .setMaxResults(PAGE_SIZE.getInt(options)) + .setPageToken(PAGE_TOKEN.getString(options)); + if (SORTING_ORDER.getString(options) != null) { + // todo check and change if more sorting options are implemented, issue #604 + request = request.setSortBy(SORT_BY).setSortOrder(SORTING_ORDER.getString(options)); + } + ChangesListResponse response = request.execute(); + return ListResult.of(response.getNextPageToken(), response.getChanges()); + } catch (IOException ex) { + throw translate(ex); + } + } +} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java index f6a0f330a327..c3cd3c690177 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java @@ -16,15 +16,23 @@ package com.google.gcloud.spi; +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.Project; +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.common.collect.ImmutableList; +import com.google.gcloud.dns.DnsException; + import java.util.Map; public interface DnsRpc { enum Option { FIELDS("fields"), - PAGE_SIZE("maxSize"), + PAGE_SIZE("maxResults"), PAGE_TOKEN("pageToken"), DNS_NAME("dnsName"), + NAME("name"), DNS_TYPE("type"), SORTING_ORDER("sortOrder"); @@ -52,5 +60,114 @@ Integer getInt(Map options) { } } - //TODO(mderka) add supported operations. Created issue #594. + class ListResult { + + private final Iterable results; + private final String pageToken; + + public ListResult(String pageToken, Iterable results) { + this.results = ImmutableList.copyOf(results); + this.pageToken = pageToken; + } + + public static ListResult of(String pageToken, Iterable list) { + return new ListResult<>(pageToken, list); + } + + public Iterable results() { + return results; + } + + public String pageToken() { + return pageToken; + } + } + + /** + * Creates a new zone. + * + * @param zone a zone to be created + * @return Updated {@code ManagedZone} object + * @throws DnsException upon failure + */ + ManagedZone create(ManagedZone zone) throws DnsException; + + /** + * Retrieves and returns an existing zone. + * + * @param zoneName name of the zone to be returned + * @param options a map of options for the service call + * @return a zone or {@code null} if not found + * @throws DnsException upon failure + */ + ManagedZone getZone(String zoneName, Map options) throws DnsException; + + /** + * Lists the zones that exist within the project. + * + * @param options a map of options for the service call + * @throws DnsException upon failure + */ + ListResult listZones(Map options) throws DnsException; + + /** + * Deletes the zone identified by the name. + * + * @return {@code true} if the zone was deleted and {@code false} otherwise + * @throws DnsException upon failure + */ + boolean deleteZone(String zoneName) throws DnsException; + + /** + * Lists DNS records for a given zone. + * + * @param zoneName name of the zone to be listed + * @param options a map of options for the service call + * @throws DnsException upon failure or if zone was not found + */ + ListResult listDnsRecords(String zoneName, Map options) + throws DnsException; + + /** + * Returns information about the current project. + * + * @param options a map of options for the service call + * @return up-to-date project information + * @throws DnsException upon failure or if the project is not found + */ + Project getProject(Map options) throws DnsException; + + /** + * Applies change request to a zone. + * + * @param zoneName the name of a zone to which the {@code Change} should be applied + * @param changeRequest change to be applied + * @param options a map of options for the service call + * @return updated change object with server-assigned ID + * @throws DnsException upon failure or if zone was not found + */ + Change applyChangeRequest(String zoneName, Change changeRequest, Map options) + throws DnsException; + + /** + * Returns an existing change request. + * + * @param zoneName the name of a zone to which the {@code Change} was be applied + * @param changeRequestId the unique id assigned to the change by the server + * @param options a map of options for the service call + * @return up-to-date change object or {@code null} if change was not found + * @throws DnsException upon failure or if zone was not found + */ + Change getChangeRequest(String zoneName, String changeRequestId, Map options) + throws DnsException; + + /** + * List existing change requests for a zone. + * + * @param zoneName the name of a zone to which the {@code Change}s were be applied + * @param options a map of options for the service call + * @throws DnsException upon failure or if zone was not found + */ + ListResult listChangeRequests(String zoneName, Map options) + throws DnsException; } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java index a60cae1d1793..c2be251cea9e 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java @@ -34,7 +34,7 @@ public void testDnsRecordListOption() { String dnsName = "some name"; Dns.DnsRecordListOption dnsRecordListOption = Dns.DnsRecordListOption.dnsName(dnsName); assertEquals(dnsName, dnsRecordListOption.value()); - assertEquals(DnsRpc.Option.DNS_NAME, dnsRecordListOption.rpcOption()); + assertEquals(DnsRpc.Option.NAME, dnsRecordListOption.rpcOption()); // page token dnsRecordListOption = Dns.DnsRecordListOption.pageToken(PAGE_TOKEN); assertEquals(PAGE_TOKEN, dnsRecordListOption.value());