Skip to content

Commit

Permalink
Add functional methods for images and Image class
Browse files Browse the repository at this point in the history
Add functional methods for images and Image class
  • Loading branch information
mziccard authored and aozarov committed Apr 2, 2016
1 parent bc368cc commit 0e20ba9
Show file tree
Hide file tree
Showing 8 changed files with 1,247 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,57 @@ 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. This method can be
* used to list publicly-available images by providing the respective image project. Examples of
* image projects are: {@code centos-cloud}, {@code coreos-cloud}, {@code debian-cloud},
* {@code opensuse-cloud}, {@code rhel-cloud}, {@code suse-cloud}, {@code ubuntu-os-cloud} and
* {@code windows-cloud}. Attempting to delete or deprecate a publicly-available image will fail.
*
* @throws ComputeException upon failure
* @see <a href="https://cloud.google.com/compute/docs/operating-systems/">Operating Systems</a>
*/
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 or if {@code image} is a publicly-available image
*/
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 or if {@code image} is a publicly-available image
*/
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,120 @@ 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(ImageId image, OperationOption... options) {
final ImageId completeId = 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.deleteImage(completeId.project(), completeId.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(ImageId image,
final DeprecationStatus<ImageId> deprecationStatus, OperationOption... options) {
final ImageId completeId = 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.deprecateImage(completeId.project(), completeId.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
Loading

0 comments on commit 0e20ba9

Please sign in to comment.