Skip to content

Commit

Permalink
Add functional methods for images and Image class
Browse files Browse the repository at this point in the history
  • Loading branch information
mziccard committed Mar 31, 2016
1 parent f2231c6 commit 2812b94
Show file tree
Hide file tree
Showing 8 changed files with 1,212 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,54 @@ public static SnapshotFilter notEquals(SnapshotField field, long value) {
}
}

/**
* Class for filtering image lists.
*/
class ImageFilter extends ListFilter {

private static final long serialVersionUID = -3601427417234098397L;

private ImageFilter(ImageField field, ComparisonOperator operator, Object value) {
super(field.selector(), operator, value);
}

/**
* Returns an 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 ImageFilter equals(ImageField field, String value) {
return new ImageFilter(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 ImageFilter notEquals(ImageField field, String value) {
return new ImageFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
}

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

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

/**
* Class for specifying disk type get options.
*/
Expand Down Expand Up @@ -1469,6 +1517,74 @@ public static SnapshotListOption fields(SnapshotField... fields) {
}
}

/**
* Class for specifying image get options.
*/
class ImageOption extends Option {

private static final long serialVersionUID = -7622190783089299272L;

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

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

/**
* Class for specifying image list options.
*/
class ImageListOption extends Option {

private static final long serialVersionUID = -4927977224287915654L;

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

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

/**
* Returns an option to specify the maximum number of images returned per page. {@code pageSize}
* must be between 0 and 500 (inclusive). If not specified 500 is used.
*/
public static ImageListOption pageSize(long pageSize) {
return new ImageListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
}

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

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

/**
* Returns the requested disk type or {@code null} if not found.
*
Expand Down Expand Up @@ -1699,4 +1815,52 @@ public static SnapshotListOption fields(SnapshotField... fields) {
* Deleting a snapshot</a>
*/
Operation deleteSnapshot(String snapshot, OperationOption... options);

/**
* Creates a new image.
*
* @return a global operation for image's creation
* @throws ComputeException upon failure
*/
Operation create(ImageInfo image, OperationOption... options);

/**
* Returns the requested image or {@code null} if not found.
*
* @throws ComputeException upon failure
*/
Image get(ImageId imageId, ImageOption... options);

/**
* Lists images in the provided project that are available to the current user.
*
* @throws ComputeException upon failure
*/
Page<Image> listImages(String project, ImageListOption... options);

/**
* Lists images in the current project.
*
* @throws ComputeException upon failure
*/
Page<Image> listImages(ImageListOption... options);

/**
* Deletes the requested image.
*
* @return a global operation if the delete request was issued correctly, {@code null} if the
* image was not found
* @throws ComputeException upon failure
*/
Operation delete(ImageId image, OperationOption... options);

/**
* Deprecates the requested image.
*
* @return a global operation if the deprecation request was issued correctly, {@code null} if the
* image was not found
* @throws ComputeException upon failure
*/
Operation deprecate(ImageId image, DeprecationStatus<ImageId> deprecationStatus,
OperationOption... options);
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,27 @@ public Page<Snapshot> nextPage() {
}
}

private static class ImagePageFetcher implements NextPageFetcher<Image> {

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

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

@Override
public Page<Image> nextPage() {
return listImages(project, serviceOptions, requestOptions);
}
}

private final ComputeRpc computeRpc;

ComputeImpl(ComputeOptions options) {
Expand Down Expand Up @@ -1026,6 +1047,117 @@ public com.google.api.services.compute.model.Operation call() {
}
}

@Override
public Operation create(ImageInfo image, OperationOption... options) {
final ImageInfo completeImage = image.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.createImage(completeImage.toPb(), optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : Operation.fromPb(this, answer);
} catch (RetryHelper.RetryHelperException e) {
throw ComputeException.translateAndThrow(e);
}
}

@Override
public Image get(ImageId imageId, ImageOption... options) {
final ImageId completeImageId = imageId.setProjectId(options().projectId());
final Map<ComputeRpc.Option, ?> optionsMap = optionMap(options);
try {
com.google.api.services.compute.model.Image answer =
runWithRetries(new Callable<com.google.api.services.compute.model.Image>() {
@Override
public com.google.api.services.compute.model.Image call() {
return computeRpc.getImage(completeImageId.project(), completeImageId.image(),
optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : Image.fromPb(this, answer);
} catch (RetryHelper.RetryHelperException e) {
throw ComputeException.translateAndThrow(e);
}
}

@Override
public Page<Image> listImages(String project, ImageListOption... options) {
return listImages(project, options(), optionMap(options));
}

@Override
public Page<Image> listImages(ImageListOption... options) {
return listImages(options().projectId(), options(), optionMap(options));
}

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

@Override
public Operation delete(final ImageId image, 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.deleteImage(image.image(), optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : Operation.fromPb(this, answer);
} catch (RetryHelper.RetryHelperException e) {
throw ComputeException.translateAndThrow(e);
}
}

@Override
public Operation deprecate(final ImageId image,
final DeprecationStatus<ImageId> deprecationStatus, 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.deprecateImage(image.image(), deprecationStatus.toPb(), optionsMap);
}
}, options().retryParams(), EXCEPTION_HANDLER);
return answer == null ? null : Operation.fromPb(this, answer);
} catch (RetryHelper.RetryHelperException e) {
throw ComputeException.translateAndThrow(e);
}
}

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

0 comments on commit 2812b94

Please sign in to comment.