Skip to content

Commit 2812b94

Browse files
committed
Add functional methods for images and Image class
1 parent f2231c6 commit 2812b94

8 files changed

Lines changed: 1212 additions & 8 deletions

File tree

gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,54 @@ public static SnapshotFilter notEquals(SnapshotField field, long value) {
869869
}
870870
}
871871

872+
/**
873+
* Class for filtering image lists.
874+
*/
875+
class ImageFilter extends ListFilter {
876+
877+
private static final long serialVersionUID = -3601427417234098397L;
878+
879+
private ImageFilter(ImageField field, ComparisonOperator operator, Object value) {
880+
super(field.selector(), operator, value);
881+
}
882+
883+
/**
884+
* Returns an equals filter for the given field and string value. For string fields,
885+
* {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
886+
* match the entire field.
887+
*
888+
* @see <a href="https://github.com/google/re2/wiki/Syntax">RE2</a>
889+
*/
890+
public static ImageFilter equals(ImageField field, String value) {
891+
return new ImageFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
892+
}
893+
894+
/**
895+
* Returns a not-equals filter for the given field and string value. For string fields,
896+
* {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
897+
* match the entire field.
898+
*
899+
* @see <a href="https://github.com/google/re2/wiki/Syntax">RE2</a>
900+
*/
901+
public static ImageFilter notEquals(ImageField field, String value) {
902+
return new ImageFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
903+
}
904+
905+
/**
906+
* Returns an equals filter for the given field and long value.
907+
*/
908+
public static ImageFilter equals(ImageField field, long value) {
909+
return new ImageFilter(checkNotNull(field), ComparisonOperator.EQ, value);
910+
}
911+
912+
/**
913+
* Returns a not-equals filter for the given field and long value.
914+
*/
915+
public static ImageFilter notEquals(ImageField field, long value) {
916+
return new ImageFilter(checkNotNull(field), ComparisonOperator.NE, value);
917+
}
918+
}
919+
872920
/**
873921
* Class for specifying disk type get options.
874922
*/
@@ -1469,6 +1517,74 @@ public static SnapshotListOption fields(SnapshotField... fields) {
14691517
}
14701518
}
14711519

1520+
/**
1521+
* Class for specifying image get options.
1522+
*/
1523+
class ImageOption extends Option {
1524+
1525+
private static final long serialVersionUID = -7622190783089299272L;
1526+
1527+
private ImageOption(ComputeRpc.Option option, Object value) {
1528+
super(option, value);
1529+
}
1530+
1531+
/**
1532+
* Returns an option to specify the image's fields to be returned by the RPC call. If this
1533+
* option is not provided, all image's fields are returned. {@code ImageOption.fields} can be
1534+
* used to specify only the fields of interest. {@link Image#imageId()} and
1535+
* {@link Image#configuration()} are always returned, even if not specified.
1536+
*/
1537+
public static ImageOption fields(ImageField... fields) {
1538+
return new ImageOption(ComputeRpc.Option.FIELDS, ImageField.selector(fields));
1539+
}
1540+
}
1541+
1542+
/**
1543+
* Class for specifying image list options.
1544+
*/
1545+
class ImageListOption extends Option {
1546+
1547+
private static final long serialVersionUID = -4927977224287915654L;
1548+
1549+
private ImageListOption(ComputeRpc.Option option, Object value) {
1550+
super(option, value);
1551+
}
1552+
1553+
/**
1554+
* Returns an option to specify a filter on the images being listed.
1555+
*/
1556+
public static ImageListOption filter(ImageFilter filter) {
1557+
return new ImageListOption(ComputeRpc.Option.FILTER, filter.toPb());
1558+
}
1559+
1560+
/**
1561+
* Returns an option to specify the maximum number of images returned per page. {@code pageSize}
1562+
* must be between 0 and 500 (inclusive). If not specified 500 is used.
1563+
*/
1564+
public static ImageListOption pageSize(long pageSize) {
1565+
return new ImageListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
1566+
}
1567+
1568+
/**
1569+
* Returns an option to specify the page token from which to start listing images.
1570+
*/
1571+
public static ImageListOption pageToken(String pageToken) {
1572+
return new ImageListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
1573+
}
1574+
1575+
/**
1576+
* Returns an option to specify the image's fields to be returned by the RPC call. If this
1577+
* option is not provided, all image's fields are returned. {@code ImageListOption.fields} can
1578+
* be used to specify only the fields of interest. {@link Image#imageId()} and
1579+
* {@link Image#configuration()} are always returned, even if not specified.
1580+
*/
1581+
public static ImageListOption fields(ImageField... fields) {
1582+
StringBuilder builder = new StringBuilder();
1583+
builder.append("items(").append(ImageField.selector(fields)).append("),nextPageToken");
1584+
return new ImageListOption(ComputeRpc.Option.FIELDS, builder.toString());
1585+
}
1586+
}
1587+
14721588
/**
14731589
* Returns the requested disk type or {@code null} if not found.
14741590
*
@@ -1699,4 +1815,52 @@ public static SnapshotListOption fields(SnapshotField... fields) {
16991815
* Deleting a snapshot</a>
17001816
*/
17011817
Operation deleteSnapshot(String snapshot, OperationOption... options);
1818+
1819+
/**
1820+
* Creates a new image.
1821+
*
1822+
* @return a global operation for image's creation
1823+
* @throws ComputeException upon failure
1824+
*/
1825+
Operation create(ImageInfo image, OperationOption... options);
1826+
1827+
/**
1828+
* Returns the requested image or {@code null} if not found.
1829+
*
1830+
* @throws ComputeException upon failure
1831+
*/
1832+
Image get(ImageId imageId, ImageOption... options);
1833+
1834+
/**
1835+
* Lists images in the provided project that are available to the current user.
1836+
*
1837+
* @throws ComputeException upon failure
1838+
*/
1839+
Page<Image> listImages(String project, ImageListOption... options);
1840+
1841+
/**
1842+
* Lists images in the current project.
1843+
*
1844+
* @throws ComputeException upon failure
1845+
*/
1846+
Page<Image> listImages(ImageListOption... options);
1847+
1848+
/**
1849+
* Deletes the requested image.
1850+
*
1851+
* @return a global operation if the delete request was issued correctly, {@code null} if the
1852+
* image was not found
1853+
* @throws ComputeException upon failure
1854+
*/
1855+
Operation delete(ImageId image, OperationOption... options);
1856+
1857+
/**
1858+
* Deprecates the requested image.
1859+
*
1860+
* @return a global operation if the deprecation request was issued correctly, {@code null} if the
1861+
* image was not found
1862+
* @throws ComputeException upon failure
1863+
*/
1864+
Operation deprecate(ImageId image, DeprecationStatus<ImageId> deprecationStatus,
1865+
OperationOption... options);
17021866
}

gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,27 @@ public Page<Snapshot> nextPage() {
292292
}
293293
}
294294

295+
private static class ImagePageFetcher implements NextPageFetcher<Image> {
296+
297+
private static final long serialVersionUID = 6403679803137922023L;
298+
private final Map<ComputeRpc.Option, ?> requestOptions;
299+
private final ComputeOptions serviceOptions;
300+
private final String project;
301+
302+
ImagePageFetcher(String project, ComputeOptions serviceOptions, String cursor,
303+
Map<ComputeRpc.Option, ?> optionMap) {
304+
this.requestOptions =
305+
PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap);
306+
this.serviceOptions = serviceOptions;
307+
this.project = project;
308+
}
309+
310+
@Override
311+
public Page<Image> nextPage() {
312+
return listImages(project, serviceOptions, requestOptions);
313+
}
314+
}
315+
295316
private final ComputeRpc computeRpc;
296317

297318
ComputeImpl(ComputeOptions options) {
@@ -1026,6 +1047,117 @@ public com.google.api.services.compute.model.Operation call() {
10261047
}
10271048
}
10281049

1050+
@Override
1051+
public Operation create(ImageInfo image, OperationOption... options) {
1052+
final ImageInfo completeImage = image.setProjectId(options().projectId());
1053+
final Map<ComputeRpc.Option, ?> optionsMap = optionMap(options);
1054+
try {
1055+
com.google.api.services.compute.model.Operation answer =
1056+
runWithRetries(new Callable<com.google.api.services.compute.model.Operation>() {
1057+
@Override
1058+
public com.google.api.services.compute.model.Operation call() {
1059+
return computeRpc.createImage(completeImage.toPb(), optionsMap);
1060+
}
1061+
}, options().retryParams(), EXCEPTION_HANDLER);
1062+
return answer == null ? null : Operation.fromPb(this, answer);
1063+
} catch (RetryHelper.RetryHelperException e) {
1064+
throw ComputeException.translateAndThrow(e);
1065+
}
1066+
}
1067+
1068+
@Override
1069+
public Image get(ImageId imageId, ImageOption... options) {
1070+
final ImageId completeImageId = imageId.setProjectId(options().projectId());
1071+
final Map<ComputeRpc.Option, ?> optionsMap = optionMap(options);
1072+
try {
1073+
com.google.api.services.compute.model.Image answer =
1074+
runWithRetries(new Callable<com.google.api.services.compute.model.Image>() {
1075+
@Override
1076+
public com.google.api.services.compute.model.Image call() {
1077+
return computeRpc.getImage(completeImageId.project(), completeImageId.image(),
1078+
optionsMap);
1079+
}
1080+
}, options().retryParams(), EXCEPTION_HANDLER);
1081+
return answer == null ? null : Image.fromPb(this, answer);
1082+
} catch (RetryHelper.RetryHelperException e) {
1083+
throw ComputeException.translateAndThrow(e);
1084+
}
1085+
}
1086+
1087+
@Override
1088+
public Page<Image> listImages(String project, ImageListOption... options) {
1089+
return listImages(project, options(), optionMap(options));
1090+
}
1091+
1092+
@Override
1093+
public Page<Image> listImages(ImageListOption... options) {
1094+
return listImages(options().projectId(), options(), optionMap(options));
1095+
}
1096+
1097+
private static Page<Image> listImages(final String project, final ComputeOptions serviceOptions,
1098+
final Map<ComputeRpc.Option, ?> optionsMap) {
1099+
try {
1100+
ComputeRpc.Tuple<String, Iterable<com.google.api.services.compute.model.Image>> result =
1101+
runWithRetries(new Callable<ComputeRpc.Tuple<String,
1102+
Iterable<com.google.api.services.compute.model.Image>>>() {
1103+
@Override
1104+
public ComputeRpc.Tuple<String,
1105+
Iterable<com.google.api.services.compute.model.Image>> call() {
1106+
return serviceOptions.rpc().listImages(project, optionsMap);
1107+
}
1108+
}, serviceOptions.retryParams(), EXCEPTION_HANDLER);
1109+
String cursor = result.x();
1110+
Iterable<Image> images = Iterables.transform(
1111+
result.y() == null ? ImmutableList.<com.google.api.services.compute.model.Image>of()
1112+
: result.y(),
1113+
new Function<com.google.api.services.compute.model.Image, Image>() {
1114+
@Override
1115+
public Image apply(com.google.api.services.compute.model.Image image) {
1116+
return Image.fromPb(serviceOptions.service(), image);
1117+
}
1118+
});
1119+
return new PageImpl<>(new ImagePageFetcher(project, serviceOptions, cursor, optionsMap),
1120+
cursor, images);
1121+
} catch (RetryHelper.RetryHelperException e) {
1122+
throw ComputeException.translateAndThrow(e);
1123+
}
1124+
}
1125+
1126+
@Override
1127+
public Operation delete(final ImageId image, OperationOption... options) {
1128+
final Map<ComputeRpc.Option, ?> optionsMap = optionMap(options);
1129+
try {
1130+
com.google.api.services.compute.model.Operation answer =
1131+
runWithRetries(new Callable<com.google.api.services.compute.model.Operation>() {
1132+
@Override
1133+
public com.google.api.services.compute.model.Operation call() {
1134+
return computeRpc.deleteImage(image.image(), optionsMap);
1135+
}
1136+
}, options().retryParams(), EXCEPTION_HANDLER);
1137+
return answer == null ? null : Operation.fromPb(this, answer);
1138+
} catch (RetryHelper.RetryHelperException e) {
1139+
throw ComputeException.translateAndThrow(e);
1140+
}
1141+
}
1142+
1143+
@Override
1144+
public Operation deprecate(final ImageId image,
1145+
final DeprecationStatus<ImageId> deprecationStatus, OperationOption... options) {
1146+
final Map<ComputeRpc.Option, ?> optionsMap = optionMap(options);
1147+
try {
1148+
com.google.api.services.compute.model.Operation answer =
1149+
runWithRetries(new Callable<com.google.api.services.compute.model.Operation>() {
1150+
@Override
1151+
public com.google.api.services.compute.model.Operation call() {
1152+
return computeRpc.deprecateImage(image.image(), deprecationStatus.toPb(), optionsMap);
1153+
}
1154+
}, options().retryParams(), EXCEPTION_HANDLER);
1155+
return answer == null ? null : Operation.fromPb(this, answer);
1156+
} catch (RetryHelper.RetryHelperException e) {
1157+
throw ComputeException.translateAndThrow(e);
1158+
}
1159+
}
1160+
10291161
private Map<ComputeRpc.Option, ?> optionMap(Option... options) {
10301162
Map<ComputeRpc.Option, Object> optionMap = Maps.newEnumMap(ComputeRpc.Option.class);
10311163
for (Option option : options) {

0 commit comments

Comments
 (0)