Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functional methods for images and Image class #826

Merged
merged 2 commits into from
Apr 2, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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);

This comment was marked as spam.

This comment was marked as spam.


/**
* 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