Skip to content

Commit

Permalink
Add functional methods for snapshots and Snapshot class
Browse files Browse the repository at this point in the history
  • Loading branch information
mziccard committed Mar 23, 2016
1 parent f968d38 commit f3c135c
Show file tree
Hide file tree
Showing 8 changed files with 991 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,54 @@ public static AddressFilter notEquals(AddressField field, String value) {
}
}

/**
* Class for filtering snapshot lists.
*/
class SnapshotFilter extends ListFilter {

private static final long serialVersionUID = 8757711630092406747L;

SnapshotFilter(SnapshotField field, ComparisonOperator operator, Object value) {
super(field.selector(), operator, value);
}

/**
* Returns an equality filter for the given field and string value. For string fields,
* {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
* match the entire field.
*
* @see <a href="https://github.com/google/re2/wiki/Syntax">RE2</a>
*/
public static SnapshotFilter equals(SnapshotField field, String value) {
return new SnapshotFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
}

/**
* Returns a not-equals filter for the given field and string value. For string fields,
* {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
* match the entire field.
*
* @see <a href="https://github.com/google/re2/wiki/Syntax">RE2</a>
*/
public static SnapshotFilter notEquals(SnapshotField field, String value) {
return new SnapshotFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
}

/**
* Returns an equality filter for the given field and long value.
*/
public static SnapshotFilter equals(SnapshotField field, long value) {
return new SnapshotFilter(checkNotNull(field), ComparisonOperator.EQ, value);
}

/**
* Returns a not-equals filter for the given field and long value.
*/
public static SnapshotFilter notEquals(SnapshotField field, long value) {
return new SnapshotFilter(checkNotNull(field), ComparisonOperator.NE, value);
}
}

/**
* Class for specifying disk type get options.
*/
Expand Down Expand Up @@ -1344,6 +1392,73 @@ public static AddressAggregatedListOption pageToken(String pageToken) {
}
}

/**
* Class for specifying snapshot get options.
*/
class SnapshotOption extends Option {

private static final long serialVersionUID = -3505179459035500945L;

private SnapshotOption(ComputeRpc.Option option, Object value) {
super(option, value);
}

/**
* Returns an option to specify the snapshot's fields to be returned by the RPC call. If this
* option is not provided, all snapshot's fields are returned. {@code SnapshotOption.fields} can
* be used to specify only the fields of interest. {@link Snapshot#snapshotId()} is always
* returned, even if not specified.
*/
public static SnapshotOption fields(SnapshotField... fields) {
return new SnapshotOption(ComputeRpc.Option.FIELDS, SnapshotField.selector(fields));
}
}

/**
* Class for specifying snapshot list options.
*/
class SnapshotListOption extends Option {

private static final long serialVersionUID = 8278588147660831257L;

private SnapshotListOption(ComputeRpc.Option option, Object value) {
super(option, value);
}

/**
* Returns an option to specify a filter on the snapshots being listed.
*/
public static SnapshotListOption filter(SnapshotFilter filter) {
return new SnapshotListOption(ComputeRpc.Option.FILTER, filter.toPb());
}

/**
* Returns an option to specify the maximum number of snapshots returned per page.
*/
public static SnapshotListOption pageSize(long pageSize) {
return new SnapshotListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
}

/**
* Returns an option to specify the page token from which to start listing snapshots.
*/
public static SnapshotListOption pageToken(String pageToken) {
return new SnapshotListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
}

/**
* Returns an option to specify the snapshot's fields to be returned by the RPC call. If this
* option is not provided, all snapshot's fields are returned. {@code SnapshotListOption.fields}
* can be used to specify only the fields of interest. {@link Snapshot#snapshotId()} is always
* returned, even if not specified.
*/
public static SnapshotListOption fields(SnapshotField... fields) {
StringBuilder builder = new StringBuilder();
builder.append("items(").append(SnapshotField.selector(fields)).append("),nextPageToken");
return new SnapshotListOption(ComputeRpc.Option.FIELDS, builder.toString());
}
}

/**
* Returns the requested disk type or {@code null} if not found.
*
Expand Down Expand Up @@ -1525,4 +1640,53 @@ public static AddressAggregatedListOption pageToken(String pageToken) {
* @throws ComputeException upon failure
*/
Operation delete(AddressId addressId, OperationOption... options);

/**
* Creates a new snapshot.
*
* @return a zone operation if the create request was issued correctly, {@code null} if
* {@code snapshot.sourceDisk} was not found
* @throws ComputeException upon failure
*/
Operation create(SnapshotInfo snapshot, OperationOption... options);

/**
* Returns the requested snapshot or {@code null} if not found.
*
* @throws ComputeException upon failure
*/
Snapshot getSnapshot(String snapshot, SnapshotOption... options);

/**
* Lists all snapshots.
*
* @throws ComputeException upon failure
*/
Page<Snapshot> listSnapshots(SnapshotListOption... options);

/**
* Deletes the requested snapshot. Keep in mind that deleting a single snapshot might not
* necessarily delete all the data for that snapshot. If any data for the snapshot that is marked
* for deletion is needed for subsequent snapshots, the data will be moved to the next snapshot.
*
* @return a global operation if the request was issued correctly, {@code null} if the snapshot
* was not found
* @throws ComputeException upon failure
* @see <a href="https://cloud.google.com/compute/docs/disks/persistent-disks#deleting_snapshot>
* Deleting a snapshot</a>
*/
Operation deleteSnapshot(SnapshotId snapshot, OperationOption... options);

/**
* Deletes the requested snapshot. Keep in mind that deleting a single snapshot might not
* necessarily delete all the data for that snapshot. If any data on the snapshot that is marked
* for deletion is needed for subsequent snapshots, the data will be moved to the next snapshot.
*
* @return a global operation if the request was issued correctly, {@code null} if the snapshot
* was not found
* @throws ComputeException upon failure
* @see <a href="https://cloud.google.com/compute/docs/disks/persistent-disks#deleting_snapshot>
* Deleting a snapshot</a>
*/
Operation deleteSnapshot(String snapshot, OperationOption... options);
}
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,25 @@ public Page<Address> nextPage() {
}
}

private static class SnapshotPageFetcher implements NextPageFetcher<Snapshot> {

private static final long serialVersionUID = 6205774609802216986L;
private final Map<ComputeRpc.Option, ?> requestOptions;
private final ComputeOptions serviceOptions;

SnapshotPageFetcher(ComputeOptions serviceOptions, String cursor,
Map<ComputeRpc.Option, ?> optionMap) {
this.requestOptions =
PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
this.serviceOptions = serviceOptions;
}

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

private final ComputeRpc computeRpc;

ComputeImpl(ComputeOptions options) {
Expand Down Expand Up @@ -881,8 +900,8 @@ public Address apply(com.google.api.services.compute.model.Address address) {
return Address.fromPb(serviceOptions.service(), address);
}
});
return new PageImpl<>(new AggregatedAddressPageFetcher(serviceOptions, cursor,
optionsMap), cursor, operations);
return new PageImpl<>(new AggregatedAddressPageFetcher(serviceOptions, cursor, optionsMap),
cursor, operations);
} catch (RetryHelper.RetryHelperException e) {
throw ComputeException.translateAndThrow(e);
}
Expand Down Expand Up @@ -914,6 +933,99 @@ public com.google.api.services.compute.model.Operation call() {
}
}

@Override
public Operation create(SnapshotInfo snapshot, final OperationOption... options) {
final SnapshotInfo completeSnapshot = snapshot.setProjectId(options().projectId());
final Map<ComputeRpc.Option, ?> optionsMap = optionMap(options);
try {
com.google.api.services.compute.model.Operation answer =
runWithRetries(new Callable<com.google.api.services.compute.model.Operation>() {
@Override
public com.google.api.services.compute.model.Operation call() {
return computeRpc.createSnapshot(completeSnapshot.sourceDisk().zone(),
completeSnapshot.sourceDisk().disk(), completeSnapshot.snapshotId().snapshot(),
completeSnapshot.description(), optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : Operation.fromPb(this, answer);
} catch (RetryHelper.RetryHelperException e) {
throw ComputeException.translateAndThrow(e);
}
}

@Override
public Snapshot getSnapshot(final String snapshot, SnapshotOption... options) {
final Map<ComputeRpc.Option, ?> optionsMap = optionMap(options);
try {
com.google.api.services.compute.model.Snapshot answer =
runWithRetries(new Callable<com.google.api.services.compute.model.Snapshot>() {
@Override
public com.google.api.services.compute.model.Snapshot call() {
return computeRpc.getSnapshot(snapshot, optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : Snapshot.fromPb(this, answer);
} catch (RetryHelper.RetryHelperException e) {
throw ComputeException.translateAndThrow(e);
}
}

@Override
public Page<Snapshot> listSnapshots(SnapshotListOption... options) {
return listSnapshots(options(), optionMap(options));
}

private static Page<Snapshot> listSnapshots(final ComputeOptions serviceOptions,
final Map<ComputeRpc.Option, ?> optionsMap) {
try {
ComputeRpc.Tuple<String, Iterable<com.google.api.services.compute.model.Snapshot>> result =
runWithRetries(new Callable<ComputeRpc.Tuple<String,
Iterable<com.google.api.services.compute.model.Snapshot>>>() {
@Override
public ComputeRpc.Tuple<String,
Iterable<com.google.api.services.compute.model.Snapshot>> call() {
return serviceOptions.rpc().listSnapshots(optionsMap);
}
}, serviceOptions.retryParams(), EXCEPTION_HANDLER);
String cursor = result.x();
Iterable<Snapshot> snapshots = Iterables.transform(
result.y() == null ? ImmutableList.<com.google.api.services.compute.model.Snapshot>of()
: result.y(),
new Function<com.google.api.services.compute.model.Snapshot, Snapshot>() {
@Override
public Snapshot apply(com.google.api.services.compute.model.Snapshot snapshot) {
return Snapshot.fromPb(serviceOptions.service(), snapshot);
}
});
return new PageImpl<>(new SnapshotPageFetcher(serviceOptions, cursor, optionsMap), cursor,
snapshots);
} catch (RetryHelper.RetryHelperException e) {
throw ComputeException.translateAndThrow(e);
}
}

@Override
public Operation deleteSnapshot(final SnapshotId snapshot, OperationOption... options) {
final Map<ComputeRpc.Option, ?> optionsMap = optionMap(options);
try {
com.google.api.services.compute.model.Operation answer =
runWithRetries(new Callable<com.google.api.services.compute.model.Operation>() {
@Override
public com.google.api.services.compute.model.Operation call() {
return computeRpc.deleteSnapshot(snapshot.snapshot(), optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : Operation.fromPb(this, answer);
} catch (RetryHelper.RetryHelperException e) {
throw ComputeException.translateAndThrow(e);
}
}

@Override
public Operation deleteSnapshot(final String snapshot, OperationOption... options) {
return deleteSnapshot(SnapshotId.of(snapshot));
}

private Map<ComputeRpc.Option, ?> optionMap(Option... options) {
Map<ComputeRpc.Option, Object> optionMap = Maps.newEnumMap(ComputeRpc.Option.class);
for (Option option : options) {
Expand Down
Loading

0 comments on commit f3c135c

Please sign in to comment.