Skip to content

Commit

Permalink
Added implementation of Dns and test. Renamed getProjectInfo.
Browse files Browse the repository at this point in the history
  • Loading branch information
mderka committed Feb 7, 2016
1 parent 5be58b3 commit d1c4512
Show file tree
Hide file tree
Showing 5 changed files with 727 additions and 4 deletions.
6 changes: 3 additions & 3 deletions gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public interface Dns extends Service<DnsOptions> {
* The fields of a project.
*
* <p>These values can be used to specify the fields to include in a partial response when calling
* {@link Dns#getProjectInfo(ProjectOption...)}. Project ID is always returned, even if not
* {@link Dns#getProject(ProjectOption...)}. Project ID is always returned, even if not
* specified.
*/
enum ProjectField {
Expand Down Expand Up @@ -429,7 +429,7 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) {
* @see <a href="https://cloud.google.com/dns/api/v1/managedZones/create">Cloud DNS Managed Zones:
* create</a>
*/
ZoneInfo create(ZoneInfo zoneInfo, ZoneOption... options);
Zone create(ZoneInfo zoneInfo, ZoneOption... options);

/**
* Returns the zone by the specified zone name. Returns {@code null} if the zone is not found. The
Expand Down Expand Up @@ -485,7 +485,7 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) {
* @throws DnsException upon failure
* @see <a href="https://cloud.google.com/dns/api/v1/projects/get">Cloud DNS Projects: get</a>
*/
ProjectInfo getProjectInfo(ProjectOption... fields);
ProjectInfo getProject(ProjectOption... fields);

/**
* Submits a change request for the specified zone. The returned object contains the following
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package com.google.gcloud.dns;

import com.google.gcloud.BaseServiceException;
import com.google.gcloud.RetryHelper.RetryHelperException;
import com.google.gcloud.RetryHelper.RetryInterruptedException;

import java.io.IOException;

Expand All @@ -31,5 +33,21 @@ public DnsException(IOException exception) {
super(exception, true);
}

public DnsException(int code, String message) {
super(code, message, null, true);
}

/**
* Translate RetryHelperException to the DnsException that caused the error. This method will
* always throw an exception.
*
* @throws DnsException when {@code ex} was caused by a {@code DnsException}
* @throws RetryInterruptedException when {@code ex} is a {@code RetryInterruptedException}
*/
static DnsException translateAndThrow(RetryHelperException ex) {
BaseServiceException.translateAndPropagateIfPossible(ex);
throw new DnsException(UNKNOWN_CODE, ex.getMessage());
}

//TODO(mderka) Add translation and retry functionality. Created issue #593.
}
335 changes: 335 additions & 0 deletions gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,335 @@
/*
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed 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 com.google.gcloud.dns;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.gcloud.RetryHelper.RetryHelperException;
import static com.google.gcloud.RetryHelper.runWithRetries;
import static com.google.gcloud.dns.ChangeRequest.fromPb;

import com.google.api.services.dns.model.Change;
import com.google.api.services.dns.model.ManagedZone;
import com.google.api.services.dns.model.ResourceRecordSet;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.gcloud.BaseService;
import com.google.gcloud.Page;
import com.google.gcloud.PageImpl;
import com.google.gcloud.RetryHelper;
import com.google.gcloud.spi.DnsRpc;

import java.util.Map;
import java.util.concurrent.Callable;

/**
* A default implementation of Dns.
*/
final class DnsImpl extends BaseService<DnsOptions> implements Dns {

private final DnsRpc dnsRpc;

private static class ZonePageFetcher implements PageImpl.NextPageFetcher<Zone> {

private static final long serialVersionUID = 2158209410430566961L;
private final Map<DnsRpc.Option, ?> requestOptions;
private final DnsOptions serviceOptions;

ZonePageFetcher(DnsOptions serviceOptions, String cursor,
Map<DnsRpc.Option, ?> optionMap) {
this.requestOptions =
PageImpl.nextRequestOptions(DnsRpc.Option.PAGE_TOKEN, cursor, optionMap);
this.serviceOptions = serviceOptions;
}

@Override
public Page<Zone> nextPage() {
return listZones(serviceOptions, requestOptions);
}
}

private static class ChangeRequestPageFetcher implements PageImpl.NextPageFetcher<ChangeRequest> {

private static final Function<Change, ChangeRequest> PB_TO_CHANGE_REQUEST =
new Function<Change, ChangeRequest>() {
@Override
public ChangeRequest apply(com.google.api.services.dns.model.Change changePb) {
return fromPb(changePb);
}
};
private static final long serialVersionUID = -8737501076674042014L;
private final String zoneName;
private final Map<DnsRpc.Option, ?> requestOptions;
private final DnsOptions serviceOptions;

ChangeRequestPageFetcher(String zoneName, DnsOptions serviceOptions, String cursor,
Map<DnsRpc.Option, ?> optionMap) {
this.zoneName = zoneName;
this.requestOptions =
PageImpl.nextRequestOptions(DnsRpc.Option.PAGE_TOKEN, cursor, optionMap);
this.serviceOptions = serviceOptions;
}

@Override
public Page<ChangeRequest> nextPage() {
return listChangeRequests(zoneName, serviceOptions, requestOptions, PB_TO_CHANGE_REQUEST);
}
}

private static class DnsRecordPageFetcher implements PageImpl.NextPageFetcher<DnsRecord> {

private static final Function<ResourceRecordSet, DnsRecord> PB_TO_DNS_RECORD =
new Function<ResourceRecordSet, DnsRecord>() {
@Override
public DnsRecord apply(com.google.api.services.dns.model.ResourceRecordSet pb) {
return DnsRecord.fromPb(pb);
}
};
private static final long serialVersionUID = 670996349097667660L;
private final Map<DnsRpc.Option, ?> requestOptions;
private final DnsOptions serviceOptions;
private final String zoneName;

DnsRecordPageFetcher(String zoneName, DnsOptions serviceOptions, String cursor,
Map<DnsRpc.Option, ?> optionMap) {
this.zoneName = zoneName;
this.requestOptions =
PageImpl.nextRequestOptions(DnsRpc.Option.PAGE_TOKEN, cursor, optionMap);
this.serviceOptions = serviceOptions;
}

@Override
public Page<DnsRecord> nextPage() {
return listDnsRecords(zoneName, serviceOptions, requestOptions, PB_TO_DNS_RECORD);
}
}

private static Page<Zone> listZones(final DnsOptions serviceOptions,
final Map<DnsRpc.Option, ?> optionsMap) {
// define transformation function
// this differs from the other list operations since zone is functional and requires dns service
Function<ManagedZone, Zone> pbToZoneFunction = new Function<ManagedZone, Zone>() {
@Override
public Zone apply(
com.google.api.services.dns.model.ManagedZone zonePb) {
return new Zone(serviceOptions.service(), ZoneInfo.fromPb(zonePb));
}
};
try {
// get a list of managed zones
DnsRpc.ListResult<ManagedZone> result =
runWithRetries(new Callable<DnsRpc.ListResult<ManagedZone>>() {
@Override
public DnsRpc.ListResult<ManagedZone> call() {
return serviceOptions.rpc().listZones(optionsMap);
}
}, serviceOptions.retryParams(), EXCEPTION_HANDLER);
String cursor = result.pageToken();
// transform that list into zone objects
Iterable<Zone> zones = result.results() == null
? ImmutableList.<Zone>of() : Iterables.transform(result.results(), pbToZoneFunction);
return new PageImpl<>(new ZonePageFetcher(serviceOptions, cursor, optionsMap),
cursor, zones);
} catch (RetryHelperException e) {
throw DnsException.translateAndThrow(e);
}
}

private static Page<ChangeRequest> listChangeRequests(final String zoneName,
final DnsOptions serviceOptions, final Map<DnsRpc.Option, ?> optionsMap,
Function<Change, ChangeRequest> TRANSFORM_FUNCTION) {
try {
// get a list of changes
DnsRpc.ListResult<Change> result = runWithRetries(new Callable<DnsRpc.ListResult<Change>>() {
@Override
public DnsRpc.ListResult<Change> call() {
return serviceOptions.rpc().listChangeRequests(zoneName, optionsMap);
}
}, serviceOptions.retryParams(), EXCEPTION_HANDLER);
String cursor = result.pageToken();
// transform that list into change request objects
Iterable<ChangeRequest> changes = result.results() == null
? ImmutableList.<ChangeRequest>of()
: Iterables.transform(result.results(), TRANSFORM_FUNCTION);
return new PageImpl<>(new ChangeRequestPageFetcher(zoneName, serviceOptions, cursor,
optionsMap), cursor, changes);
} catch (RetryHelperException e) {
throw DnsException.translateAndThrow(e);
}
}

private static Page<DnsRecord> listDnsRecords(final String zoneName,
final DnsOptions serviceOptions, final Map<DnsRpc.Option, ?> optionsMap,
Function<ResourceRecordSet, DnsRecord> TRANSFORM_FUNCTION) {
try {
// get a list of resource record sets
DnsRpc.ListResult<ResourceRecordSet> result = runWithRetries(
new Callable<DnsRpc.ListResult<ResourceRecordSet>>() {
@Override
public DnsRpc.ListResult<ResourceRecordSet> call() {
return serviceOptions.rpc().listDnsRecords(zoneName, optionsMap);
}
}, serviceOptions.retryParams(), EXCEPTION_HANDLER);
String cursor = result.pageToken();
// transform that list into dns records
Iterable<DnsRecord> records = result.results() == null
? ImmutableList.<DnsRecord>of()
: Iterables.transform(result.results(), TRANSFORM_FUNCTION);
return new PageImpl<>(new DnsRecordPageFetcher(zoneName, serviceOptions, cursor, optionsMap),
cursor, records);
} catch (RetryHelperException e) {
throw DnsException.translateAndThrow(e);
}
}

DnsImpl(DnsOptions options) {
super(options);
dnsRpc = options.rpc();
}

@Override
public Page<Zone> listZones(ZoneListOption... options) {
return listZones(options(), optionMap(options));
}

@Override
public Page<ChangeRequest> listChangeRequests(String zoneName,
ChangeRequestListOption... options) {
return listChangeRequests(zoneName, options(), optionMap(options),
ChangeRequestPageFetcher.PB_TO_CHANGE_REQUEST);
}

@Override
public Page<DnsRecord> listDnsRecords(String zoneName, DnsRecordListOption... options) {
return listDnsRecords(zoneName, options(), optionMap(options),
DnsRecordPageFetcher.PB_TO_DNS_RECORD);
}

@Override
public Zone create(final ZoneInfo zoneInfo, Dns.ZoneOption... options) {
final Map<DnsRpc.Option, ?> optionsMap = optionMap(options);
try {
com.google.api.services.dns.model.ManagedZone answer = runWithRetries(
new Callable<com.google.api.services.dns.model.ManagedZone>() {
@Override
public com.google.api.services.dns.model.ManagedZone call() {
return dnsRpc.create(zoneInfo.toPb(), optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : Zone.fromPb(this, answer);
} catch (RetryHelper.RetryHelperException ex) {
throw DnsException.translateAndThrow(ex);
}
}

@Override
public Zone getZone(final String zoneName, Dns.ZoneOption... options) {
final Map<DnsRpc.Option, ?> optionsMap = optionMap(options);
try {
com.google.api.services.dns.model.ManagedZone answer = runWithRetries(
new Callable<com.google.api.services.dns.model.ManagedZone>() {
@Override
public com.google.api.services.dns.model.ManagedZone call() {
return dnsRpc.getZone(zoneName, optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : Zone.fromPb(this, answer);
} catch (RetryHelper.RetryHelperException ex) {
throw DnsException.translateAndThrow(ex);
}
}

@Override
public boolean delete(final String zoneName) {
try {
return runWithRetries(new Callable<Boolean>() {
@Override
public Boolean call() {
return dnsRpc.deleteZone(zoneName);
}
}, options().retryParams(), EXCEPTION_HANDLER);
} catch (RetryHelper.RetryHelperException ex) {
throw DnsException.translateAndThrow(ex);
}
}

@Override
public ProjectInfo getProject(Dns.ProjectOption... fields) {
final Map<DnsRpc.Option, ?> optionsMap = optionMap(fields);
try {
com.google.api.services.dns.model.Project answer = runWithRetries(
new Callable<com.google.api.services.dns.model.Project>() {
@Override
public com.google.api.services.dns.model.Project call() {
return dnsRpc.getProject(optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : ProjectInfo.fromPb(answer); // should never be null
} catch (RetryHelper.RetryHelperException ex) {
throw DnsException.translateAndThrow(ex);
}
}

@Override
public ChangeRequest applyChangeRequest(final String zoneName, final ChangeRequest changeRequest,
Dns.ChangeRequestOption... options) {
final Map<DnsRpc.Option, ?> optionsMap = optionMap(options);
try {
com.google.api.services.dns.model.Change answer =
runWithRetries(
new Callable<com.google.api.services.dns.model.Change>() {
@Override
public com.google.api.services.dns.model.Change call() {
return dnsRpc.applyChangeRequest(zoneName, changeRequest.toPb(), optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : fromPb(answer); // should never be null
} catch (RetryHelper.RetryHelperException ex) {
throw DnsException.translateAndThrow(ex);
}
}

@Override
public ChangeRequest getChangeRequest(final String zoneName, final String changeRequestId,
Dns.ChangeRequestOption... options) {
final Map<DnsRpc.Option, ?> optionsMap = optionMap(options);
try {
com.google.api.services.dns.model.Change answer =
runWithRetries(
new Callable<com.google.api.services.dns.model.Change>() {
@Override
public com.google.api.services.dns.model.Change call() {
return dnsRpc.getChangeRequest(zoneName, changeRequestId, optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : fromPb(answer); // should never be null
} catch (RetryHelper.RetryHelperException ex) {
throw DnsException.translateAndThrow(ex);
}
}

private Map<DnsRpc.Option, ?> optionMap(AbstractOption... options) {
Map<DnsRpc.Option, Object> temp = Maps.newEnumMap(DnsRpc.Option.class);
for (AbstractOption option : options) {
Object prev = temp.put(option.rpcOption(), option.value());
checkArgument(prev == null, "Duplicate option %s", option);
}
return ImmutableMap.copyOf(temp);
}
}
Loading

0 comments on commit d1c4512

Please sign in to comment.