diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md new file mode 100644 index 000000000000..d1909f904095 --- /dev/null +++ b/gcloud-java-compute/README.md @@ -0,0 +1,101 @@ +Google Cloud Java Client for Compute (Alpha) +==================================== + +Java idiomatic client for [Google Cloud Compute] (https://cloud.google.com/compute). + +[![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) +[![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) + +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) + +- [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) + + + +> Note: This client is a work-in-progress, and may occasionally +> make backwards-incompatible changes. + +Quickstart +---------- +If you are using Maven, add this to your pom.xml file + +If you are using Gradle, add this to your dependencies + +If you are using SBT, add this to your dependencies + + +Example Application +------------------- + + +Authentication +-------------- + +See the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) section in the base directory's README. + +About Google Cloud Compute +-------------------------- + +[Google Cloud Compute][cloud-compute] delivers virtual machines running in Google's innovative data +centers and worldwide fiber network. Compute Engine's tooling and workflow support enable scaling +from single instances to global, load-balanced cloud computing. Compute Engine's VMs boot quickly, +come with persistent disk storage, deliver consistent performance and are available in many +configurations. + +Be sure to activate the Google Cloud Compute API on the Developer's Console to use Compute from +your project. + +See the ``gcloud-java`` API [compute documentation][compute-api] to learn how to interact +with Google Cloud Compute using this Client Library. + +Getting Started +--------------- + + +Troubleshooting +--------------- + +To get help, follow the `gcloud-java` links in the `gcloud-*`[shared Troubleshooting document](https://github.com/GoogleCloudPlatform/gcloud-common/blob/master/troubleshooting/readme.md#troubleshooting). + +Java Versions +------------- + +Java 7 or above is required for using this client. + +Testing +------- + +This library has tools to help make tests for code using Cloud Compute. + +See [TESTING] to read more about testing. + +Versioning +---------- + +This library follows [Semantic Versioning] (http://semver.org/). + +It is currently in major version zero (``0.y.z``), which means that anything +may change at any time and the public API should not be considered +stable. + +Contributing +------------ + +Contributions to this library are always welcome and highly encouraged. + +See [CONTRIBUTING] for more information on how to get started. + +License +------- + +Apache 2.0 - See [LICENSE] for more information. + + +[CONTRIBUTING]:https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/CONTRIBUTING.md +[LICENSE]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/LICENSE +[TESTING]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/TESTING.md#testing-code-that-uses-compute +[cloud-platform]: https://cloud.google.com/ + +[cloud-compute]: https://cloud.google.com/compute/ +[compute-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/compute/package-summary.html diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml new file mode 100644 index 000000000000..5bf336e01a2f --- /dev/null +++ b/gcloud-java-compute/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + gcloud-java-compute + jar + GCloud Java compute + + Java idiomatic client for Google Cloud Compute Engine. + + + com.google.gcloud + gcloud-java-pom + 0.1.5-SNAPSHOT + + + gcloud-java-compute + + + + ${project.groupId} + gcloud-java-core + ${project.version} + + + com.google.apis + google-api-services-compute + v1-rev97-1.21.0 + compile + + + com.google.guava + guava-jdk5 + + + + + junit + junit + 4.12 + test + + + org.easymock + easymock + 3.4 + test + + + diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java new file mode 100644 index 000000000000..4576f62f84b9 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -0,0 +1,27 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.gcloud.Service; + +/** + * An interface for Google Cloud Compute Engine. + * + * @see Google Cloud Compute Engine + */ +public interface Compute extends Service { +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java new file mode 100644 index 000000000000..94a409305338 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java @@ -0,0 +1,59 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.common.collect.ImmutableSet; +import com.google.gcloud.BaseServiceException; +import com.google.gcloud.RetryHelper.RetryHelperException; +import com.google.gcloud.RetryHelper.RetryInterruptedException; + +import java.io.IOException; +import java.util.Set; + +/** + * Compute Engine service exception. + */ +public class ComputeException extends BaseServiceException { + + private static final Set RETRYABLE_ERRORS = ImmutableSet.of(new Error(500, null)); + private static final long serialVersionUID = -8039359778707845810L; + + public ComputeException(int code, String message) { + super(code, message, null, true); + } + + public ComputeException(IOException exception) { + super(exception, true); + } + + @Override + protected Set retryableErrors() { + return RETRYABLE_ERRORS; + } + + /** + * Translate RetryHelperException to the ComputeException that caused the error. This method will + * always throw an exception. + * + * @throws ComputeException when {@code ex} was caused by a {@code ComputeException} + * @throws RetryInterruptedException when {@code ex} is a {@code RetryInterruptedException} + */ + static BaseServiceException translateAndThrow(RetryHelperException ex) { + BaseServiceException.translateAndPropagateIfPossible(ex); + throw new ComputeException(UNKNOWN_CODE, ex.getMessage()); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java new file mode 100644 index 000000000000..100631eef91d --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java @@ -0,0 +1,25 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.gcloud.ServiceFactory; + +/** + * An interface for Compute factories. + */ +public interface ComputeFactory extends ServiceFactory { +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java new file mode 100644 index 000000000000..8a3a82af8827 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -0,0 +1,30 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.gcloud.BaseService; +import com.google.gcloud.spi.ComputeRpc; + +final class ComputeImpl extends BaseService implements Compute { + + private final ComputeRpc computeRpc; + + ComputeImpl(ComputeOptions options) { + super(options); + computeRpc = options.rpc(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java new file mode 100644 index 000000000000..9fab138b26b4 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java @@ -0,0 +1,114 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.common.collect.ImmutableSet; +import com.google.gcloud.ServiceOptions; +import com.google.gcloud.spi.ComputeRpc; +import com.google.gcloud.spi.ComputeRpcFactory; +import com.google.gcloud.spi.DefaultComputeRpc; + +import java.util.Set; + +public class ComputeOptions extends ServiceOptions { + + private static final String COMPUTE_SCOPE = "https://www.googleapis.com/auth/compute"; + private static final Set SCOPES = ImmutableSet.of(COMPUTE_SCOPE); + private static final long serialVersionUID = 6509557711917342058L; + + public static class DefaultComputeFactory implements ComputeFactory { + + private static final ComputeFactory INSTANCE = new DefaultComputeFactory(); + + @Override + public Compute create(ComputeOptions options) { + return new ComputeImpl(options); + } + } + + public static class DefaultComputeRpcFactory implements ComputeRpcFactory { + + private static final ComputeRpcFactory INSTANCE = new DefaultComputeRpcFactory(); + + @Override + public ComputeRpc create(ComputeOptions options) { + return new DefaultComputeRpc(options); + } + } + + public static class Builder extends + ServiceOptions.Builder { + + private Builder() { + } + + private Builder(ComputeOptions options) { + super(options); + } + + @Override + public ComputeOptions build() { + return new ComputeOptions(this); + } + } + + private ComputeOptions(Builder builder) { + super(ComputeFactory.class, ComputeRpcFactory.class, builder); + } + + @Override + protected ComputeFactory defaultServiceFactory() { + return DefaultComputeFactory.INSTANCE; + } + + @Override + protected ComputeRpcFactory defaultRpcFactory() { + return DefaultComputeRpcFactory.INSTANCE; + } + + @Override + protected Set scopes() { + return SCOPES; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public int hashCode() { + return baseHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ComputeOptions)) { + return false; + } + ComputeOptions other = (ComputeOptions) obj; + return baseEquals(other); + } + + public static ComputeOptions defaultInstance() { + return builder().build(); + } + + public static Builder builder() { + return new Builder(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java new file mode 100644 index 000000000000..c80071dde10a --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java @@ -0,0 +1,172 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.util.Objects; + +/** + * The deprecation status associated to a Google Compute Engine resource. + * + * @param The Google Compute Engine resource to which the deprecation status refers to. + */ +public final class DeprecationStatus implements Serializable { + + private static final long serialVersionUID = -2695077634793679794L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final Long deleted; + private final Long deprecated; + private final Long obsolete; + private final T replacement; + private final Status status; + + /** + * The deprecation status of a Google Compute Engine resource. + */ + public enum Status { + /** + * Operations that create a Google Compute Engine entity using a deprecated resource will return + * successfully but with a warning indicating the deprecation and suggesting a replacement. + */ + DEPRECATED, + + /** + * Operations that create a Google Compute Engine entity using an obsolete resource will be + * rejected and result in an error. + */ + OBSOLETE, + + /** + * Operations that create a Google Compute Engine entity using a deleted resource will be + * rejected and result in an error. + */ + DELETED + } + + DeprecationStatus(Long deleted, Long deprecated, Long obsolete, T replacement, Status status) { + this.deleted = deleted; + this.deprecated = deprecated; + this.obsolete = obsolete; + this.replacement = replacement; + this.status = status; + } + + /** + * Returns the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#DELETED}. In milliseconds since epoch. + */ + public Long deleted() { + return deleted; + } + + /** + * Returns the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#DEPRECATED}. In milliseconds since epoch. + */ + public Long deprecated() { + return deprecated; + } + + /** + * Returns the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#OBSOLETE}. In milliseconds since epoch. + */ + public Long obsolete() { + return obsolete; + } + + /** + * Returns the identity of the suggested replacement for a deprecated resource. The suggested + * replacement resource must be the same kind of resource as the deprecated resource. + */ + public T replacement() { + return replacement; + } + + /** + * Returns the deprecation state of this resource. + */ + public Status status() { + return status; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("deleted", deleted) + .add("deprecated", deprecated) + .add("obsolete", obsolete) + .add("replacement", replacement) + .add("status", status) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(deleted, deprecated, obsolete, replacement, status); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof DeprecationStatus + && Objects.equals(toPb(), ((DeprecationStatus) obj).toPb()); + } + + com.google.api.services.compute.model.DeprecationStatus toPb() { + com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb = + new com.google.api.services.compute.model.DeprecationStatus(); + if (deleted != null) { + deprecationStatusPb.setDeleted(TIMESTAMP_FORMATTER.print(deleted)); + } + if (deprecated != null) { + deprecationStatusPb.setDeprecated(TIMESTAMP_FORMATTER.print(deprecated)); + } + if (obsolete != null) { + deprecationStatusPb.setObsolete(TIMESTAMP_FORMATTER.print(obsolete)); + } + if (replacement != null) { + deprecationStatusPb.setReplacement(replacement.selfLink()); + } + if (status() != null) { + deprecationStatusPb.setState(status.name()); + } + return deprecationStatusPb; + } + + static DeprecationStatus fromPb( + com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb, + Function fromUrl) { + return new DeprecationStatus<>( + deprecationStatusPb.getDeleted() != null + ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getDeleted()) : null, + deprecationStatusPb.getDeprecated() != null + ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getDeprecated()) : null, + deprecationStatusPb.getObsolete() != null + ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getObsolete()) : null, + deprecationStatusPb.getReplacement() != null + ? fromUrl.apply(deprecationStatusPb.getReplacement()) : null, + deprecationStatusPb.getState() != null + ? Status.valueOf(deprecationStatusPb.getState()) : null); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java new file mode 100644 index 000000000000..ce57067786c4 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java @@ -0,0 +1,240 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.Objects; + +/** + * A Google Compute Engine disk type. A disk type represents the type of disk to use, such as + * {@code pd-ssd} or {@code pd-standard}. + * + * @see Disk Types + */ +public final class DiskType implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public DiskType apply(com.google.api.services.compute.model.DiskType pb) { + return DiskType.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.DiskType apply(DiskType diskType) { + return diskType.toPb(); + } + }; + + private static final long serialVersionUID = -944042261695072026L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final String id; + private final DiskTypeId diskTypeId; + private final Long creationTimestamp; + private final String description; + private final String validDiskSize; + private final Long defaultDiskSizeGb; + private final DeprecationStatus deprecationStatus; + + static final class Builder { + + private String id; + private DiskTypeId diskTypeId; + private Long creationTimestamp; + private String description; + private String validDiskSize; + private Long defaultDiskSizeGb; + private DeprecationStatus deprecationStatus; + + private Builder() {} + + Builder id(String id) { + this.id = id; + return this; + } + + Builder creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + Builder diskTypeId(DiskTypeId diskTypeId) { + this.diskTypeId = diskTypeId; + return this; + } + + Builder description(String description) { + this.description = description; + return this; + } + + Builder validDiskSize(String validDiskSize) { + this.validDiskSize = validDiskSize; + return this; + } + + Builder defaultDiskSizeGb(Long defaultDiskSizeGb) { + this.defaultDiskSizeGb = defaultDiskSizeGb; + return this; + } + + Builder deprecationStatus(DeprecationStatus deprecationStatus) { + this.deprecationStatus = deprecationStatus; + return this; + } + + DiskType build() { + return new DiskType(this); + } + } + + private DiskType(Builder builder) { + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.diskTypeId = builder.diskTypeId; + this.description = builder.description; + this.validDiskSize = builder.validDiskSize; + this.defaultDiskSizeGb = builder.defaultDiskSizeGb; + this.deprecationStatus = builder.deprecationStatus; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns the disk type's identity. + */ + public DiskTypeId diskTypeId() { + return diskTypeId; + } + + /** + * Returns an unique identifier for the disk type; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns a textual description of the disk type. + */ + public String description() { + return description; + } + + /** + * Returns an optional textual description of the valid disk size, such as "10GB-10TB". + */ + public String validDiskSize() { + return validDiskSize; + } + + /** + * Returns the service-defined default disk size in GB. + */ + public Long defaultDiskSizeGb() { + return defaultDiskSizeGb; + } + + /** + * Returns the deprecation status of the disk type. If {@link DeprecationStatus#status()} is + * either {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} + * the disk type should not be used. Returns {@code null} if the disk type is not deprecated. + */ + public DeprecationStatus deprecationStatus() { + return deprecationStatus; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("description", description) + .add("validDiskSize", validDiskSize) + .add("defaultDiskSizeGb", defaultDiskSizeGb) + .add("deprecationStatus", deprecationStatus) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(diskTypeId); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof DiskType && Objects.equals(toPb(), ((DiskType) obj).toPb()); + } + + com.google.api.services.compute.model.DiskType toPb() { + com.google.api.services.compute.model.DiskType diskTypePb = + new com.google.api.services.compute.model.DiskType(); + if (id != null) { + diskTypePb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + diskTypePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + diskTypePb.setDescription(description); + diskTypePb.setValidDiskSize(validDiskSize); + diskTypePb.setSelfLink(diskTypeId.selfLink()); + diskTypePb.setDefaultDiskSizeGb(defaultDiskSizeGb); + diskTypePb.setZone(diskTypeId.zoneId().selfLink()); + if (deprecationStatus != null) { + diskTypePb.setDeprecated(deprecationStatus.toPb()); + } + return diskTypePb; + } + + static Builder builder() { + return new Builder(); + } + + static DiskType fromPb(com.google.api.services.compute.model.DiskType diskTypePb) { + Builder builder = builder(); + if (diskTypePb.getId() != null) { + builder.id(diskTypePb.getId().toString()); + } + if (diskTypePb.getCreationTimestamp() != null) { + builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(diskTypePb.getCreationTimestamp())); + } + builder.diskTypeId(DiskTypeId.fromUrl(diskTypePb.getSelfLink())); + builder.description(diskTypePb.getDescription()); + builder.validDiskSize(diskTypePb.getValidDiskSize()); + builder.defaultDiskSizeGb(diskTypePb.getDefaultDiskSizeGb()); + if (diskTypePb.getDeprecated() != null) { + builder.deprecationStatus( + DeprecationStatus.fromPb(diskTypePb.getDeprecated(), DiskTypeId.FROM_URL_FUNCTION)); + } + return builder.build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java new file mode 100644 index 000000000000..cdf1fd42eedc --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java @@ -0,0 +1,130 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine disk type. + */ +public final class DiskTypeId extends ZoneResourceId { + + static final Function FROM_URL_FUNCTION = new Function() { + @Override + public DiskTypeId apply(String pb) { + return DiskTypeId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = new Function() { + @Override + public String apply(DiskTypeId diskTypeId) { + return diskTypeId.selfLink(); + } + }; + + private static final String REGEX = ZoneResourceId.REGEX + "diskTypes/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = 7337881474103686219L; + + private final String diskType; + + private DiskTypeId(String project, String zone, String diskType) { + super(project, zone); + this.diskType = checkNotNull(diskType); + } + + /** + * Returns the name of the disk type. + */ + public String diskType() { + return diskType; + } + + @Override + public String selfLink() { + return super.selfLink() + "/diskTypes/" + diskType; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("diskType", diskType); + } + + @Override + public int hashCode() { + return Objects.hash(super.baseHashCode(), diskType); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof DiskTypeId + && baseEquals((DiskTypeId) obj) + && Objects.equals(diskType, ((DiskTypeId) obj).diskType); + } + + @Override + DiskTypeId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return DiskTypeId.of(projectId, zone(), diskType); + } + + /** + * Returns a disk type identity given the zone identity and the disk type name. + */ + public static DiskTypeId of(ZoneId zoneId, String diskType) { + return new DiskTypeId(zoneId.project(), zoneId.zone(), diskType); + } + + /** + * Returns a disk type identity given the zone and disk type names. + */ + public static DiskTypeId of(String zone, String diskType) { + return of(ZoneId.of(null, zone), diskType); + } + + /** + * Returns a disk type identity given project disk, zone and disk type names. + */ + public static DiskTypeId of(String project, String zone, String diskType) { + return of(ZoneId.of(project, zone), diskType); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a disk type URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static DiskTypeId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid disk type URL"); + } + return DiskTypeId.of(matcher.group(1), matcher.group(2), matcher.group(3)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java new file mode 100644 index 000000000000..2c6cb4ac9422 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java @@ -0,0 +1,89 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * A Google Compute Engine License. A License represents a software license. Licenses are used to + * track software usage in images, persistent disks, snapshots, and virtual machine instances. + * + * @see Licenses + */ +public final class License implements Serializable { + + private static final long serialVersionUID = 6907923910319640363L; + + private final LicenseId licenseId; + private final Boolean chargesUseFee; + + License(LicenseId licenseId, Boolean chargesUseFee) { + this.licenseId = checkNotNull(licenseId); + this.chargesUseFee = chargesUseFee; + } + + /** + * Returns the identity of the license. + */ + public LicenseId licenseId() { + return licenseId; + } + + /** + * Returns {@code true} if the customer will be charged a license fee for running software that + * contains this license on an instance. + */ + public Boolean chargesUseFee() { + return chargesUseFee; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("licenseId", licenseId) + .add("chargesUseFee", chargesUseFee) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(licenseId); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof License && Objects.equals(toPb(), ((License) obj).toPb()); + } + + com.google.api.services.compute.model.License toPb() { + com.google.api.services.compute.model.License licensePb = + new com.google.api.services.compute.model.License(); + licensePb.setName(licenseId.license()); + licensePb.setChargesUseFee(chargesUseFee); + licensePb.setSelfLink(licenseId.selfLink()); + return licensePb; + } + + static License fromPb(com.google.api.services.compute.model.License licensePb) { + return new License(LicenseId.fromUrl(licensePb.getSelfLink()), licensePb.getChargesUseFee()); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java new file mode 100644 index 000000000000..36d3037bc41b --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java @@ -0,0 +1,123 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine license. + */ +public final class LicenseId extends ResourceId { + + static final Function FROM_URL_FUNCTION = new Function() { + @Override + public LicenseId apply(String pb) { + return LicenseId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = new Function() { + @Override + public String apply(LicenseId licenseId) { + return licenseId.selfLink(); + } + }; + + private static final String REGEX = ResourceId.REGEX + "global/licenses/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = -2239484554024469651L; + + private final String license; + + private LicenseId(String project, String license) { + super(project); + this.license = checkNotNull(license); + } + + /** + * Returns the name of the license. + */ + public String license() { + return license; + } + + @Override + public String selfLink() { + return super.selfLink() + "/global/licenses/" + license; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("license", license); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), license); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof LicenseId + && baseEquals((LicenseId) obj) + && Objects.equals(license, ((LicenseId) obj).license); + } + + @Override + LicenseId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return LicenseId.of(projectId, license); + } + + /** + * Returns a license identity given the license name. + */ + public static LicenseId of(String license) { + return new LicenseId(null, license); + } + + /** + * Returns a license identity given project and license names. + */ + public static LicenseId of(String project, String license) { + return new LicenseId(project, license); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a license URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static LicenseId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid license URL"); + } + return LicenseId.of(matcher.group(1), matcher.group(2)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java new file mode 100644 index 000000000000..ee242c0d1ef0 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java @@ -0,0 +1,320 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.api.services.compute.model.MachineType.ScratchDisks; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine machine type. A machine type determine the virtualized hardware + * specifications of your virtual machine instances, such as the amount of memory or number of + * virtual CPUs. + * + * @see Machine Types + */ +public final class MachineType implements Serializable { + + static final Function + FROM_PB_FUNCTION = + new Function() { + @Override + public MachineType apply(com.google.api.services.compute.model.MachineType pb) { + return MachineType.fromPb(pb); + } + }; + static final Function + TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.MachineType apply(MachineType type) { + return type.toPb(); + } + }; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private static final long serialVersionUID = -4210962597502860450L; + + private final MachineTypeId machineTypeId; + private final String id; + private final Long creationTimestamp; + private final String description; + private final Integer cpus; + private final Integer memoryMb; + private final List scratchDisksSizeGb; + private final Integer maximumPersistentDisks; + private final Long maximumPersistentDisksSizeGb; + private final DeprecationStatus deprecationStatus; + + static final class Builder { + + private MachineTypeId machineTypeId; + private String id; + private Long creationTimestamp; + private String description; + private Integer cpus; + private Integer memoryMb; + private List scratchDisksSizeGb; + private Integer maximumPersistentDisks; + private Long maximumPersistentDisksSizeGb; + private DeprecationStatus deprecationStatus; + + private Builder() {} + + Builder machineTypeId(MachineTypeId machineTypeId) { + this.machineTypeId = machineTypeId; + return this; + } + + Builder id(String id) { + this.id = id; + return this; + } + + Builder creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + Builder description(String description) { + this.description = description; + return this; + } + + Builder cpus(Integer cpus) { + this.cpus = cpus; + return this; + } + + Builder memoryMb(Integer memoryMb) { + this.memoryMb = memoryMb; + return this; + } + + Builder scratchDisksSizeGb(List scratchDisksSizeGb) { + this.scratchDisksSizeGb = scratchDisksSizeGb; + return this; + } + + Builder maximumPersistentDisks(Integer maximumPersistentDisks) { + this.maximumPersistentDisks = maximumPersistentDisks; + return this; + } + + Builder maximumPersistentDisksSizeGb(Long maximumPersistentDisksSizeGb) { + this.maximumPersistentDisksSizeGb = maximumPersistentDisksSizeGb; + return this; + } + + Builder deprecationStatus(DeprecationStatus deprecationStatus) { + this.deprecationStatus = deprecationStatus; + return this; + } + + MachineType build() { + return new MachineType(this); + } + } + + private MachineType(Builder builder) { + this.machineTypeId = builder.machineTypeId; + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.description = builder.description; + this.cpus = builder.cpus; + this.memoryMb = builder.memoryMb; + this.scratchDisksSizeGb = builder.scratchDisksSizeGb; + this.maximumPersistentDisks = builder.maximumPersistentDisks; + this.maximumPersistentDisksSizeGb = builder.maximumPersistentDisksSizeGb; + this.deprecationStatus = builder.deprecationStatus; + } + + /** + * Returns the machine type's identity. + */ + public MachineTypeId machineTypeId() { + return machineTypeId; + } + + /** + * Returns an unique identifier for the machine type; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns an optional textual description of the machine type. + */ + public String description() { + return description; + } + + /** + * Returns the number of virtual CPUs that are available to the instance. + */ + public Integer cpus() { + return cpus; + } + + /** + * Returns the amount of physical memory available to the instance, defined in MB. + */ + public Integer memoryMb() { + return memoryMb; + } + + /** + * Returns the size of all extended scratch disks assigned to the instance, defined in GB. + */ + public List scratchDisksSizeGb() { + return scratchDisksSizeGb; + } + + /** + * Returns the maximum number of persistent disks allowed by this instance type. + */ + public Integer maximumPersistentDisks() { + return maximumPersistentDisks; + } + + /** + * Returns the maximum total persistent disks size allowed, defined in GB. + */ + public Long maximumPersistentDisksSizeGb() { + return maximumPersistentDisksSizeGb; + } + + /** + * Returns the deprecation status of the machine type. If {@link DeprecationStatus#status()} is + * either {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} + * the machine type should not be used. Returns {@code null} if the machine type is not + * deprecated. + */ + public DeprecationStatus deprecationStatus() { + return deprecationStatus; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("machineTypeId", machineTypeId) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("description", description) + .add("cpus", cpus) + .add("memoryMb", memoryMb) + .add("scratchDisksSizeGb", scratchDisksSizeGb) + .add("maximumPersistentDisks", maximumPersistentDisks) + .add("maximumPersistentDisksSizeGb", maximumPersistentDisksSizeGb) + .add("deprecationStatus", deprecationStatus) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(machineTypeId); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof MachineType && Objects.equals(toPb(), ((MachineType) obj).toPb()); + } + + com.google.api.services.compute.model.MachineType toPb() { + com.google.api.services.compute.model.MachineType machineTypePb = + new com.google.api.services.compute.model.MachineType(); + if (id != null) { + machineTypePb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + machineTypePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + machineTypePb.setName(machineTypeId.machineType()); + machineTypePb.setDescription(description); + machineTypePb.setSelfLink(machineTypeId.selfLink()); + machineTypePb.setGuestCpus(cpus); + machineTypePb.setMemoryMb(memoryMb); + if (scratchDisksSizeGb != null) { + machineTypePb.setScratchDisks(Lists.transform(scratchDisksSizeGb, + new Function() { + @Override + public ScratchDisks apply(Integer diskSize) { + return new ScratchDisks().setDiskGb(diskSize); + } + })); + } + machineTypePb.setMaximumPersistentDisks(maximumPersistentDisks); + machineTypePb.setMaximumPersistentDisksSizeGb(maximumPersistentDisksSizeGb); + machineTypePb.setZone(machineTypeId.zoneId().zone()); + if (deprecationStatus != null) { + machineTypePb.setDeprecated(deprecationStatus.toPb()); + } + return machineTypePb; + } + + static Builder builder() { + return new Builder(); + } + + static MachineType fromPb(com.google.api.services.compute.model.MachineType machineTypePb) { + Builder builder = builder(); + builder.machineTypeId(MachineTypeId.fromUrl(machineTypePb.getSelfLink())); + if (machineTypePb.getId() != null) { + builder.id(machineTypePb.getId().toString()); + } + if (machineTypePb.getCreationTimestamp() != null) { + builder.creationTimestamp( + TIMESTAMP_FORMATTER.parseMillis(machineTypePb.getCreationTimestamp())); + } + builder.description(machineTypePb.getDescription()); + builder.cpus(machineTypePb.getGuestCpus()); + builder.memoryMb(machineTypePb.getMemoryMb()); + if (machineTypePb.getScratchDisks() != null) { + builder.scratchDisksSizeGb( + Lists.transform(machineTypePb.getScratchDisks(), new Function() { + @Override + public Integer apply(ScratchDisks scratchDiskPb) { + return scratchDiskPb.getDiskGb(); + } + })); + } + builder.maximumPersistentDisks(machineTypePb.getMaximumPersistentDisks()); + builder.maximumPersistentDisksSizeGb(machineTypePb.getMaximumPersistentDisksSizeGb()); + if (machineTypePb.getDeprecated() != null) { + builder.deprecationStatus( + DeprecationStatus.fromPb(machineTypePb.getDeprecated(), MachineTypeId.FROM_URL_FUNCTION)); + } + return builder.build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java new file mode 100644 index 000000000000..1252719e05d7 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java @@ -0,0 +1,125 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine machine type. + */ +public final class MachineTypeId extends ZoneResourceId { + + static final Function FROM_URL_FUNCTION = + new Function() { + @Override + public MachineTypeId apply(String pb) { + return MachineTypeId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = + new Function() { + @Override + public String apply(MachineTypeId machineTypeId) { + return machineTypeId.selfLink(); + } + }; + + private static final String REGEX = ZoneResourceId.REGEX + "machineTypes/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = -5819598544478859608L; + + private final String machineType; + + private MachineTypeId(String project, String zone, String machineType) { + super(project, zone); + this.machineType = checkNotNull(machineType); + } + + /** + * Returns the name of the machine type. + */ + public String machineType() { + return machineType; + } + + @Override + public String selfLink() { + return super.selfLink() + "/machineTypes/" + machineType; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("machineType", machineType); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), machineType); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof MachineTypeId + && baseEquals((MachineTypeId) obj) + && Objects.equals(machineType, ((MachineTypeId) obj).machineType); + } + + @Override + MachineTypeId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return MachineTypeId.of(projectId, zone(), machineType); + } + + /** + * Returns a machine type identity given the zone and type names. + */ + public static MachineTypeId of(String zone, String machineType) { + return new MachineTypeId(null, zone, machineType); + } + + /** + * Returns a machine type identity given project, zone and type names. + */ + public static MachineTypeId of(String project, String zone, String machineType) { + return new MachineTypeId(project, zone, machineType); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a machine type URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static MachineTypeId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid machine type URL"); + } + return MachineTypeId.of(matcher.group(1), matcher.group(2), matcher.group(3)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java new file mode 100644 index 000000000000..38f79a691721 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java @@ -0,0 +1,374 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine region. + * + * @see Region and Zones + */ +public final class Region implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public Region apply(com.google.api.services.compute.model.Region pb) { + return Region.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.Region apply(Region region) { + return region.toPb(); + } + }; + + private static final long serialVersionUID = -3578710133393645135L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final RegionId regionId; + private final String id; + private final Long creationTimestamp; + private final String description; + private final Status status; + private final List zones; + private final List quotas; + private final DeprecationStatus deprecationStatus; + + /** + * Status of the region. + */ + public enum Status { + UP, + DOWN + } + + /** + * A quota assigned to this region. + */ + public static final class Quota implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public Quota apply(com.google.api.services.compute.model.Quota pb) { + return Quota.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.Quota apply(Quota quota) { + return quota.toPb(); + } + }; + private static final long serialVersionUID = -4357118665133226338L; + + private final String metric; + private final double limit; + private final double usage; + + /** + * Returns a region quota object. + */ + Quota(String metric, double limit, double usage) { + this.metric = metric; + this.limit = limit; + this.usage = usage; + } + + /** + * Returns the name of the quota metric. + */ + public String metric() { + return metric; + } + + /** + * Returns the quota limit for this metric. + */ + public double limit() { + return limit; + } + + /** + * Returns the current usage for this quota. + */ + public double usage() { + return usage; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("metric", metric) + .add("limit", limit) + .add("usage", usage) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(metric, limit, usage); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Quota)) { + return false; + } + Quota other = (Quota) obj; + return Objects.equals(metric, other.metric) + && Objects.equals(limit, other.limit) + && Objects.equals(usage, other.usage); + } + + com.google.api.services.compute.model.Quota toPb() { + return new com.google.api.services.compute.model.Quota() + .setMetric(metric) + .setLimit(limit) + .setUsage(usage); + } + + static Quota fromPb(com.google.api.services.compute.model.Quota quotaPb) { + return new Quota(quotaPb.getMetric(), quotaPb.getLimit(), quotaPb.getUsage()); + } + } + + static final class Builder { + + private RegionId regionId; + private String id; + private Long creationTimestamp; + private String description; + + private Status status; + private List zones; + private List quotas; + private DeprecationStatus deprecationStatus; + + private Builder() {} + + Builder regionId(RegionId regionId) { + this.regionId = regionId; + return this; + } + + Builder id(String id) { + this.id = id; + return this; + } + + Builder creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + Builder description(String description) { + this.description = description; + return this; + } + + Builder status(Status status) { + this.status = status; + return this; + } + + Builder zones(List zones) { + this.zones = ImmutableList.copyOf(zones); + return this; + } + + Builder quotas(List quotas) { + this.quotas = ImmutableList.copyOf(quotas); + return this; + } + + Builder deprecationStatus(DeprecationStatus deprecationStatus) { + this.deprecationStatus = deprecationStatus; + return this; + } + + Region build() { + return new Region(this); + } + } + + private Region(Builder builder) { + this.regionId = builder.regionId; + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.description = builder.description; + this.status = builder.status; + this.zones = builder.zones; + this.quotas = builder.quotas; + this.deprecationStatus = builder.deprecationStatus; + } + + /** + * Returns the region's identity. + */ + public RegionId regionId() { + return regionId; + } + + /** + * Returns an unique identifier for the region; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns an optional textual description of the region. + */ + public String description() { + return description; + } + + /** + * Returns the status of the status. + */ + public Status status() { + return status; + } + + /** + * Returns a list of identities of zones available in this region. + */ + public List zones() { + return zones; + } + + /** + * Returns quotas assigned to this region. + */ + public List quotas() { + return quotas; + } + + /** + * Returns the deprecation status of the region. If {@link DeprecationStatus#status()} is either + * {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} the + * region should not be used. Returns {@code null} if the region is not deprecated. + */ + public DeprecationStatus deprecationStatus() { + return deprecationStatus; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("regionId", regionId) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("description", description) + .add("status", status) + .add("zones", zones) + .add("quotas", quotas) + .add("deprecationStatus", deprecationStatus) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(regionId); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Region && Objects.equals(toPb(), ((Region) obj).toPb()); + } + + com.google.api.services.compute.model.Region toPb() { + com.google.api.services.compute.model.Region regionPb = + new com.google.api.services.compute.model.Region(); + if (id != null) { + regionPb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + regionPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + regionPb.setName(regionId.region()); + regionPb.setDescription(description); + regionPb.setSelfLink(regionId.selfLink()); + if (status != null) { + regionPb.setStatus(status.name()); + } + if (zones != null) { + regionPb.setZones(Lists.transform(zones, ZoneId.TO_URL_FUNCTION)); + } + if (quotas != null) { + regionPb.setQuotas(Lists.transform(quotas, Quota.TO_PB_FUNCTION)); + } + if (deprecationStatus != null) { + regionPb.setDeprecated(deprecationStatus.toPb()); + } + return regionPb; + } + + static Builder builder() { + return new Builder(); + } + + static Region fromPb(com.google.api.services.compute.model.Region regionPb) { + Builder builder = builder(); + builder.regionId(RegionId.fromUrl(regionPb.getSelfLink())); + if (regionPb.getId() != null) { + builder.id(regionPb.getId().toString()); + } + if (regionPb.getCreationTimestamp() != null) { + builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(regionPb.getCreationTimestamp())); + } + builder.description(regionPb.getDescription()); + if (regionPb.getStatus() != null) { + builder.status(Status.valueOf(regionPb.getStatus())); + } + if (regionPb.getZones() != null) { + builder.zones(Lists.transform(regionPb.getZones(), ZoneId.FROM_URL_FUNCTION)); + } + if (regionPb.getQuotas() != null) { + builder.quotas(Lists.transform(regionPb.getQuotas(), Quota.FROM_PB_FUNCTION)); + } + if (regionPb.getDeprecated() != null) { + builder.deprecationStatus( + DeprecationStatus.fromPb(regionPb.getDeprecated(), RegionId.FROM_URL_FUNCTION)); + } + return builder.build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java new file mode 100644 index 000000000000..403edd47ce48 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java @@ -0,0 +1,128 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A Google Compute Engine region identity. + */ +public final class RegionId extends ResourceId { + + static final Function FROM_URL_FUNCTION = new Function() { + @Override + public RegionId apply(String pb) { + return RegionId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = new Function() { + @Override + public String apply(RegionId regionId) { + return regionId.selfLink(); + } + }; + + private static final String REGEX = ResourceId.REGEX + "regions/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = 5569092266957249294L; + + private final String region; + + private RegionId(String project, String region) { + super(project); + this.region = checkNotNull(region); + } + + private RegionId(RegionId regionId) { + super(regionId.project()); + this.region = checkNotNull(regionId.region()); + } + + /** + * Returns the name of the region. + */ + public final String region() { + return region; + } + + @Override + public String selfLink() { + return super.selfLink() + "/regions/" + region; + } + + @Override + ToStringHelper toStringHelper() { + return super.toStringHelper().add("region", region); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), region); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof RegionId + && baseEquals((RegionId) obj) + && Objects.equals(region, ((RegionId) obj).region); + } + + @Override + RegionId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return RegionId.of(projectId, region); + } + + /** + * Returns a new region identity given project and region names. + */ + public static RegionId of(String project, String region) { + return new RegionId(project, region); + } + + /** + * Returns a new region identity given region name. + */ + public static RegionId of(String region) { + return RegionId.of(null, region); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a region URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static RegionId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid region URL"); + } + return RegionId.of(matcher.group(1), matcher.group(2)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java new file mode 100644 index 000000000000..eeb288b07be1 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java @@ -0,0 +1,80 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; + +/** + * A base class for the identity of Google Compute Engine resources that live in a region. + */ +public abstract class RegionResourceId extends ResourceId { + + static final String REGEX = ResourceId.REGEX + "regions/([^/]+)/"; + private static final long serialVersionUID = 5569092266957249294L; + + private final String region; + + RegionResourceId(String project, String region) { + super(project); + this.region = checkNotNull(region); + } + + RegionResourceId(RegionId regionId) { + super(regionId.project()); + this.region = checkNotNull(regionId.region()); + } + + /** + * Returns the name of the region this resource belongs to. + */ + public final String region() { + return region; + } + + /** + * Returns the identity of the region this resource belongs to. + */ + public final RegionId regionId() { + return RegionId.of(project(), region); + } + + @Override + public String selfLink() { + return super.selfLink() + "/regions/" + region; + } + + @Override + ToStringHelper toStringHelper() { + return super.toStringHelper().add("region", region); + } + + @Override + final int baseHashCode() { + return Objects.hash(super.baseHashCode(), region); + } + + @Override + final boolean baseEquals(ResourceId resourceId) { + return resourceId instanceof RegionResourceId + && super.baseEquals(resourceId) + && Objects.equals(region, ((RegionResourceId) resourceId).region); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java new file mode 100644 index 000000000000..38e0fe576ac8 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java @@ -0,0 +1,71 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Base class for Google Compute Engine resource identities. + */ +public abstract class ResourceId implements Serializable { + + static final String REGEX = ".*?projects/([^/]+)/"; + private static final String BASE_URL = "https://www.googleapis.com/compute/v1/projects/"; + private static final long serialVersionUID = -8028734746870421573L; + + private final String project; + + ResourceId(String project) { + this.project = project; + } + + /** + * Returns a fully qualified URL to the entity. + */ + public String selfLink() { + return BASE_URL + project; + } + + /** + * Returns the name of the project. + */ + public final String project() { + return project; + } + + MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this).add("project", project); + } + + @Override + public String toString() { + return toStringHelper().toString(); + } + + int baseHashCode() { + return Objects.hash(project); + } + + boolean baseEquals(ResourceId resourceId) { + return Objects.equals(project, resourceId.project); + } + + abstract ResourceId setProjectId(String projectId); +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java new file mode 100644 index 000000000000..20c64946d7ce --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -0,0 +1,395 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import com.google.api.services.compute.model.Zone.MaintenanceWindows; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine zone. + * + * @see Region and Zones + */ +public final class Zone implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public Zone apply(com.google.api.services.compute.model.Zone pb) { + return Zone.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.Zone apply(Zone region) { + return region.toPb(); + } + }; + + private static final long serialVersionUID = 6113636504417213010L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final ZoneId zoneId; + private final String id; + private final Long creationTimestamp; + private final String description; + private final Status status; + private final List maintenanceWindows; + private final RegionId region; + private final DeprecationStatus deprecationStatus; + + /** + * Status of the region. + */ + public enum Status { + UP, + DOWN + } + + /** + * A scheduled maintenance windows for this zone. When a zone is in a maintenance window, all + * resources which reside in the zone will be unavailable. + * + * @see Maintenance + * Windows + */ + public static final class MaintenanceWindow implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public MaintenanceWindow apply(MaintenanceWindows pb) { + return MaintenanceWindow.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public MaintenanceWindows apply(MaintenanceWindow maintenanceWindow) { + return maintenanceWindow.toPb(); + } + }; + + private static final long serialVersionUID = 2270641266683329963L; + + private final String name; + private final String description; + private final Long beginTime; + private final Long endTime; + + /** + * Returns a zone maintenance window object. + */ + MaintenanceWindow(String name, String description, Long beginTime, Long endTime) { + this.name = name; + this.description = description; + this.beginTime = beginTime; + this.endTime = endTime; + } + + /** + * Returns the name of the maintenance window. + */ + public String name() { + return name; + } + + /** + * Returns a textual description of the maintenance window. + */ + public String description() { + return description; + } + + /** + * Returns the starting time of the maintenance window in milliseconds since epoch. + */ + public Long beginTime() { + return beginTime; + } + + /** + * Returns the ending time of the maintenance window in milliseconds since epoch. + */ + public Long endTime() { + return endTime; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("disk", name) + .add("description", description) + .add("beginTime", beginTime) + .add("endTime", endTime) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(name, description, beginTime, endTime); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof MaintenanceWindow + && Objects.equals(toPb(), ((MaintenanceWindow) obj).toPb()); + } + + MaintenanceWindows toPb() { + return new MaintenanceWindows() + .setName(name) + .setDescription(description) + .setBeginTime(beginTime != null ? TIMESTAMP_FORMATTER.print(beginTime) : null) + .setEndTime(endTime != null ? TIMESTAMP_FORMATTER.print(endTime) : null); + } + + static MaintenanceWindow fromPb(MaintenanceWindows windowPb) { + return new MaintenanceWindow(windowPb.getName(), windowPb.getDescription(), + windowPb.getBeginTime() != null + ? TIMESTAMP_FORMATTER.parseMillis(windowPb.getBeginTime()) : null, + windowPb.getEndTime() != null + ? TIMESTAMP_FORMATTER.parseMillis(windowPb.getEndTime()) : null); + } + } + + static final class Builder { + + private ZoneId zoneId; + private String id; + private Long creationTimestamp; + private String description; + + private Status status; + private List maintenanceWindows; + private RegionId region; + private DeprecationStatus deprecationStatus; + + private Builder() {} + + Builder zoneId(ZoneId zoneId) { + this.zoneId = zoneId; + return this; + } + + Builder id(String id) { + this.id = id; + return this; + } + + Builder creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + Builder description(String description) { + this.description = description; + return this; + } + + Builder status(Status status) { + this.status = status; + return this; + } + + Builder maintenanceWindows(List maintenanceWindows) { + this.maintenanceWindows = maintenanceWindows; + return this; + } + + Builder region(RegionId region) { + this.region = region; + return this; + } + + Builder deprecationStatus(DeprecationStatus deprecationStatus) { + this.deprecationStatus = deprecationStatus; + return this; + } + + Zone build() { + return new Zone(this); + } + } + + private Zone(Builder builder) { + this.zoneId = builder.zoneId; + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.description = builder.description; + this.status = builder.status; + this.maintenanceWindows = builder.maintenanceWindows; + this.region = builder.region; + this.deprecationStatus = builder.deprecationStatus; + } + + /** + * Returns the zone's identity. + */ + public ZoneId zoneId() { + return zoneId; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns an optional textual description of the zone. + */ + public String description() { + return description; + } + + /** + * Returns an unique identifier for the zone; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns the status of the zone. + */ + public Status status() { + return status; + } + + /** + * Returns the scheduled maintenance windows for this zone, if any. When the zone is in a + * maintenance window, all resources which reside in the zone will be unavailable. + * + * @see Maintenance + * Windows + */ + public List maintenanceWindows() { + return maintenanceWindows; + } + + /** + * Returns the identity of the region that hosts the zone. + */ + public RegionId region() { + return region; + } + + /** + * Returns the deprecation status of the zone. If {@link DeprecationStatus#status()} is either + * {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} the zone + * should not be used. Returns {@code null} if the zone is not deprecated. + */ + public DeprecationStatus deprecationStatus() { + return deprecationStatus; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("zoneId", zoneId) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("description", description) + .add("status", status) + .add("maintenanceWindows", maintenanceWindows) + .add("region", region) + .add("deprecationStatus", deprecationStatus) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(zoneId); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Zone && Objects.equals(toPb(), ((Zone) obj).toPb()); + } + + com.google.api.services.compute.model.Zone toPb() { + com.google.api.services.compute.model.Zone zonePb = + new com.google.api.services.compute.model.Zone(); + if (id != null) { + zonePb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + zonePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + zonePb.setName(zoneId.zone()); + zonePb.setDescription(description); + zonePb.setSelfLink(zoneId.selfLink()); + if (status != null) { + zonePb.setStatus(status.name()); + } + if (maintenanceWindows != null) { + zonePb.setMaintenanceWindows( + Lists.transform(maintenanceWindows, MaintenanceWindow.TO_PB_FUNCTION)); + } + if (region != null) { + zonePb.setRegion(region.selfLink()); + } + if (deprecationStatus != null) { + zonePb.setDeprecated(deprecationStatus.toPb()); + } + return zonePb; + } + + static Builder builder() { + return new Builder(); + } + + static Zone fromPb(com.google.api.services.compute.model.Zone zonePb) { + Builder builder = builder(); + builder.zoneId(ZoneId.fromUrl(zonePb.getSelfLink())); + if (zonePb.getId() != null) { + builder.id(zonePb.getId().toString()); + } + if (zonePb.getCreationTimestamp() != null) { + builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(zonePb.getCreationTimestamp())); + } + builder.description(zonePb.getDescription()); + if (zonePb.getStatus() != null) { + builder.status(Status.valueOf(zonePb.getStatus())); + } + if (zonePb.getMaintenanceWindows() != null) { + builder.maintenanceWindows( + Lists.transform(zonePb.getMaintenanceWindows(), MaintenanceWindow.FROM_PB_FUNCTION)); + } + if (zonePb.getRegion() != null) { + builder.region(RegionId.fromUrl(zonePb.getRegion())); + } + if (zonePb.getDeprecated() != null) { + builder.deprecationStatus( + DeprecationStatus.fromPb(zonePb.getDeprecated(), ZoneId.FROM_URL_FUNCTION)); + } + return builder.build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java new file mode 100644 index 000000000000..74ac5be58201 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java @@ -0,0 +1,123 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A Google Compute Engine zone identity. + */ +public final class ZoneId extends ResourceId { + + static final Function FROM_URL_FUNCTION = new Function() { + @Override + public ZoneId apply(String pb) { + return ZoneId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = new Function() { + @Override + public String apply(ZoneId zoneId) { + return zoneId.selfLink(); + } + }; + + private static final String REGEX = ResourceId.REGEX + "zones/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = -7635391994812946733L; + + private final String zone; + + private ZoneId(String project, String zone) { + super(project); + this.zone = checkNotNull(zone); + } + + /** + * Returns the name of the zone. + */ + public final String zone() { + return zone; + } + + @Override + public String selfLink() { + return super.selfLink() + "/zones/" + zone; + } + + @Override + ToStringHelper toStringHelper() { + return super.toStringHelper().add("zone", zone); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), zone); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ZoneId + && baseEquals((ZoneId) obj) + && Objects.equals(zone, ((ZoneId) obj).zone); + } + + @Override + ZoneId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return ZoneId.of(projectId, zone); + } + + /** + * Returns a new zone identity given project and zone names. + */ + public static ZoneId of(String project, String zone) { + return new ZoneId(project, zone); + } + + /** + * Returns a new zone identity given zone name. + */ + public static ZoneId of(String zone) { + return ZoneId.of(null, zone); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a zone URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return url.matches(REGEX); + } + + static ZoneId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid zone URL"); + } + return ZoneId.of(matcher.group(1), matcher.group(2)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java new file mode 100644 index 000000000000..60117684c056 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java @@ -0,0 +1,80 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; + +/** + * A base class for the identity of Google Compute Engine resources that live in a zone. + */ +public abstract class ZoneResourceId extends ResourceId { + + static final String REGEX = ResourceId.REGEX + "zones/([^/]+)/"; + private static final long serialVersionUID = -6249546895344926888L; + + private final String zone; + + ZoneResourceId(String project, String zone) { + super(project); + this.zone = checkNotNull(zone); + } + + ZoneResourceId(ZoneId zoneId) { + super(zoneId.project()); + this.zone = checkNotNull(zoneId.zone()); + } + + /** + * Returns the name of the zone this resource belongs to. + */ + public final String zone() { + return zone; + } + + /** + * Returns the identity of the zone this resource belongs to. + */ + public final ZoneId zoneId() { + return ZoneId.of(project(), zone); + } + + @Override + public String selfLink() { + return super.selfLink() + "/zones/" + zone; + } + + @Override + ToStringHelper toStringHelper() { + return super.toStringHelper().add("zone", zone); + } + + @Override + final int baseHashCode() { + return Objects.hash(super.baseHashCode(), zone); + } + + @Override + final boolean baseEquals(ResourceId resourceId) { + return resourceId instanceof ZoneResourceId + && super.baseEquals(resourceId) + && Objects.equals(zone, ((ZoneResourceId) resourceId).zone); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java new file mode 100644 index 000000000000..b7a59a9413c4 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -0,0 +1,20 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.spi; + +public interface ComputeRpc { +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java new file mode 100644 index 000000000000..5defc86199ef --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java @@ -0,0 +1,26 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.spi; + +import com.google.gcloud.compute.ComputeOptions; + +/** + * An interface for Compute RPC factory. + * Implementation will be loaded via {@link java.util.ServiceLoader}. + */ +public interface ComputeRpcFactory extends ServiceRpcFactory { +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java new file mode 100644 index 000000000000..6667588dd0ef --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java @@ -0,0 +1,46 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.spi; + +import com.google.api.client.http.HttpRequestInitializer; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.json.jackson.JacksonFactory; +import com.google.api.services.compute.Compute; +import com.google.gcloud.compute.ComputeException; +import com.google.gcloud.compute.ComputeOptions; + +import java.io.IOException; + +public class DefaultComputeRpc implements ComputeRpc { + + private final ComputeOptions options; + private final Compute compute; + + public DefaultComputeRpc(ComputeOptions options) { + HttpTransport transport = options.httpTransportFactory().create(); + HttpRequestInitializer initializer = options.httpRequestInitializer(); + this.options = options; + compute = new Compute.Builder(transport, new JacksonFactory(), initializer) + .setRootUrl(options.host()) + .setApplicationName(options.applicationName()) + .build(); + } + + private static ComputeException translate(IOException exception) { + return new ComputeException(exception); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java new file mode 100644 index 000000000000..e8d29669da7b --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java @@ -0,0 +1,78 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import com.google.gcloud.compute.DeprecationStatus.Status; + +import org.junit.Test; + +public class DeprecationStatusTest { + + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; + private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); + private static final MachineTypeId MACHINE_TYPE_ID = + MachineTypeId.of("project", "zone", "machineType"); + private static final Status STATUS = Status.DELETED; + private static final DeprecationStatus DISK_TYPE_STATUS = + new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, DISK_TYPE_ID, STATUS); + private static final DeprecationStatus MACHINE_TYPE_STATUS = + new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, STATUS); + + @Test + public void testConstructor() { + assertEquals(DELETED, DISK_TYPE_STATUS.deleted()); + assertEquals(DEPRECATED, DISK_TYPE_STATUS.deprecated()); + assertEquals(OBSOLETE, DISK_TYPE_STATUS.obsolete()); + assertEquals(DISK_TYPE_ID, DISK_TYPE_STATUS.replacement()); + assertEquals(STATUS, DISK_TYPE_STATUS.status()); + assertEquals(DELETED, MACHINE_TYPE_STATUS.deleted()); + assertEquals(DEPRECATED, MACHINE_TYPE_STATUS.deprecated()); + assertEquals(OBSOLETE, MACHINE_TYPE_STATUS.obsolete()); + assertEquals(MACHINE_TYPE_ID, MACHINE_TYPE_STATUS.replacement()); + assertEquals(STATUS, MACHINE_TYPE_STATUS.status()); + } + + @Test + public void testToAndFromPb() { + DeprecationStatus diskStatus = + DeprecationStatus.fromPb(DISK_TYPE_STATUS.toPb(), DiskTypeId.FROM_URL_FUNCTION); + compareDeprecationStatus(DISK_TYPE_STATUS, diskStatus); + DeprecationStatus machineStatus = + DeprecationStatus.fromPb(MACHINE_TYPE_STATUS.toPb(), MachineTypeId.FROM_URL_FUNCTION); + compareDeprecationStatus(MACHINE_TYPE_STATUS, machineStatus); + diskStatus = new DeprecationStatus<>(null, DEPRECATED, null, DISK_TYPE_ID, STATUS); + assertEquals(diskStatus, + DeprecationStatus.fromPb(diskStatus.toPb(), DiskTypeId.FROM_URL_FUNCTION)); + machineStatus = new DeprecationStatus<>(null, DEPRECATED, null, MACHINE_TYPE_ID, STATUS); + assertEquals(machineStatus, + DeprecationStatus.fromPb(machineStatus.toPb(), MachineTypeId.FROM_URL_FUNCTION)); + } + + private void compareDeprecationStatus(DeprecationStatus expected, DeprecationStatus value) { + assertEquals(expected, value); + assertEquals(expected.deleted(), value.deleted()); + assertEquals(expected.deprecated(), value.deprecated()); + assertEquals(expected.obsolete(), value.obsolete()); + assertEquals(expected.replacement(), value.replacement()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java new file mode 100644 index 000000000000..5ff61d5777ba --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java @@ -0,0 +1,84 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class DiskTypeIdTest { + + private static final String PROJECT = "project"; + private static final String ZONE = "zone"; + private static final String DISK_TYPE = "diskType"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/zones/zone/diskTypes/diskType"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); + assertEquals(PROJECT, diskTypeId.project()); + assertEquals(ZONE, diskTypeId.zone()); + assertEquals(DISK_TYPE, diskTypeId.diskType()); + assertEquals(URL, diskTypeId.selfLink()); + diskTypeId = DiskTypeId.of(ZONE, DISK_TYPE); + assertNull(diskTypeId.project()); + assertEquals(ZONE, diskTypeId.zone()); + assertEquals(DISK_TYPE, diskTypeId.diskType()); + } + + @Test + public void testToAndFromUrl() { + DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); + assertSame(diskTypeId, diskTypeId.setProjectId(PROJECT)); + compareDiskTypeId(diskTypeId, DiskTypeId.fromUrl(diskTypeId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid disk type URL"); + DiskTypeId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); + assertSame(diskTypeId, diskTypeId.setProjectId(PROJECT)); + compareDiskTypeId(diskTypeId, DiskTypeId.of(ZONE, DISK_TYPE).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(DiskTypeId.matchesUrl(DiskTypeId.of(PROJECT, ZONE, DISK_TYPE).selfLink())); + assertFalse(DiskTypeId.matchesUrl("notMatchingUrl")); + } + + private void compareDiskTypeId(DiskTypeId expected, DiskTypeId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.zone(), expected.zone()); + assertEquals(expected.diskType(), expected.diskType()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java new file mode 100644 index 000000000000..7cacf256523a --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java @@ -0,0 +1,78 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import java.math.BigInteger; + +public class DiskTypeTest { + + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final String VALID_DISK_SIZE = "10GB-10TB"; + private static final Long DEFAULT_DISK_SIZE_GB = 10L; + private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; + private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED; + private static final DeprecationStatus DEPRECATION_STATUS = + new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, DISK_TYPE_ID, STATUS); + private static final DiskType DISK_TYPE = DiskType.builder() + .id(ID) + .diskTypeId(DISK_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .validDiskSize(VALID_DISK_SIZE) + .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB) + .deprecationStatus(DEPRECATION_STATUS) + .build(); + + @Test + public void testBuilder() { + assertEquals(ID, DISK_TYPE.id()); + assertEquals(DISK_TYPE_ID, DISK_TYPE.diskTypeId()); + assertEquals(CREATION_TIMESTAMP, DISK_TYPE.creationTimestamp()); + assertEquals(DESCRIPTION, DISK_TYPE.description()); + assertEquals(VALID_DISK_SIZE, DISK_TYPE.validDiskSize()); + assertEquals(DEFAULT_DISK_SIZE_GB, DISK_TYPE.defaultDiskSizeGb()); + assertEquals(DEPRECATION_STATUS, DISK_TYPE.deprecationStatus()); + } + + @Test + public void testToPbAndFromPb() { + compareDiskTypes(DISK_TYPE, DiskType.fromPb(DISK_TYPE.toPb())); + DiskType diskType = DiskType.builder().diskTypeId(DISK_TYPE_ID).build(); + compareDiskTypes(diskType, DiskType.fromPb(diskType.toPb())); + } + + private void compareDiskTypes(DiskType expected, DiskType value) { + assertEquals(expected, value); + assertEquals(expected.id(), value.id()); + assertEquals(expected.diskTypeId(), value.diskTypeId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.validDiskSize(), value.validDiskSize()); + assertEquals(expected.defaultDiskSizeGb(), value.defaultDiskSizeGb()); + assertEquals(expected.deprecationStatus(), value.deprecationStatus()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java new file mode 100644 index 000000000000..d06fd48cff9a --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class LicenseIdTest { + + private static final String PROJECT = "project"; + private static final String LICENSE = "license"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/global/licenses/license"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); + assertEquals(PROJECT, licenseId.project()); + assertEquals(LICENSE, licenseId.license()); + assertEquals(URL, licenseId.selfLink()); + licenseId = LicenseId.of(LICENSE); + assertNull(licenseId.project()); + assertEquals(LICENSE, licenseId.license()); + } + + @Test + public void testToAndFromUrl() { + LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); + compareLicenseId(licenseId, LicenseId.fromUrl(licenseId.selfLink())); + } + + @Test + public void testSetProjectId() { + LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); + assertSame(licenseId, licenseId.setProjectId(PROJECT)); + compareLicenseId(licenseId, LicenseId.of(LICENSE).setProjectId(PROJECT)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid license URL"); + LicenseId.fromUrl("notMatchingUrl"); + } + + @Test + public void testMatchesUrl() { + assertTrue(LicenseId.matchesUrl(LicenseId.of(PROJECT, LICENSE).selfLink())); + assertFalse(LicenseId.matchesUrl("notMatchingUrl")); + } + + private void compareLicenseId(LicenseId expected, LicenseId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.license(), expected.license()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java new file mode 100644 index 000000000000..c9fb95fab9c6 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class LicenseTest { + + private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); + private static final Boolean CHARGES_USE_FEE = true; + private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE); + + @Test + public void testBuilder() { + assertEquals(LICENSE_ID, LICENSE.licenseId()); + assertEquals(CHARGES_USE_FEE, LICENSE.chargesUseFee()); + } + + @Test + public void testToAndFromPb() { + License license = License.fromPb(LICENSE.toPb()); + compareLicenses(LICENSE, license); + assertEquals(LICENSE_ID.project(), license.licenseId().project()); + assertEquals(LICENSE_ID.license(), license.licenseId().license()); + } + + private void compareLicenses(License expected, License value) { + assertEquals(expected, value); + assertEquals(expected.licenseId(), value.licenseId()); + assertEquals(expected.chargesUseFee(), value.chargesUseFee()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java new file mode 100644 index 000000000000..7e3f4d7eae35 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java @@ -0,0 +1,83 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class MachineTypeIdTest { + + private static final String PROJECT = "project"; + private static final String ZONE = "zone"; + private static final String TYPE = "type"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/zones/zone/machineTypes/type"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); + assertEquals(PROJECT, machineTypeId.project()); + assertEquals(ZONE, machineTypeId.zone()); + assertEquals(TYPE, machineTypeId.machineType()); + assertEquals(URL, machineTypeId.selfLink()); + machineTypeId = MachineTypeId.of(ZONE, TYPE); + assertNull(machineTypeId.project()); + assertEquals(ZONE, machineTypeId.zone()); + assertEquals(TYPE, machineTypeId.machineType()); + } + + @Test + public void testToAndFromUrl() { + MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); + compareMachineTypeId(machineTypeId, MachineTypeId.fromUrl(machineTypeId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid machine type URL"); + MachineTypeId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); + assertSame(machineTypeId, machineTypeId.setProjectId(PROJECT)); + compareMachineTypeId(machineTypeId, MachineTypeId.of(ZONE, TYPE).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(MachineTypeId.matchesUrl(MachineTypeId.of(PROJECT, ZONE, TYPE).selfLink())); + assertFalse(MachineTypeId.matchesUrl("notMatchingUrl")); + } + + private void compareMachineTypeId(MachineTypeId expected, MachineTypeId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.zone(), expected.zone()); + assertEquals(expected.machineType(), expected.machineType()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java new file mode 100644 index 000000000000..969b370ddce8 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java @@ -0,0 +1,92 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +import java.util.List; + +public class MachineTypeTest { + + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type"); + private static final Integer CPUS = 1; + private static final Integer MEMORY_MB = 2; + private static final List SCRATCH_DISKS = ImmutableList.of(3); + private static final Integer MAXIMUM_PERSISTENT_DISKS = 4; + private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L; + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; + private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED; + private static final DeprecationStatus DEPRECATION_STATUS = + new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, STATUS); + private static final MachineType MACHINE_TYPE = MachineType.builder() + .id(ID) + .machineTypeId(MACHINE_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .cpus(CPUS) + .memoryMb(MEMORY_MB) + .scratchDisksSizeGb(SCRATCH_DISKS) + .maximumPersistentDisks(MAXIMUM_PERSISTENT_DISKS) + .maximumPersistentDisksSizeGb(MAXIMUM_PERSISTENT_DISKS_SIZE_GB) + .deprecationStatus(DEPRECATION_STATUS) + .build(); + + @Test + public void testBuilder() { + assertEquals(ID, MACHINE_TYPE.id()); + assertEquals(MACHINE_TYPE_ID, MACHINE_TYPE.machineTypeId()); + assertEquals(CREATION_TIMESTAMP, MACHINE_TYPE.creationTimestamp()); + assertEquals(DESCRIPTION, MACHINE_TYPE.description()); + assertEquals(CPUS, MACHINE_TYPE.cpus()); + assertEquals(MEMORY_MB, MACHINE_TYPE.memoryMb()); + assertEquals(SCRATCH_DISKS, MACHINE_TYPE.scratchDisksSizeGb()); + assertEquals(MAXIMUM_PERSISTENT_DISKS, MACHINE_TYPE.maximumPersistentDisks()); + assertEquals(MAXIMUM_PERSISTENT_DISKS_SIZE_GB, MACHINE_TYPE.maximumPersistentDisksSizeGb()); + assertEquals(DEPRECATION_STATUS, MACHINE_TYPE.deprecationStatus()); + } + + @Test + public void testToPbAndFromPb() { + compareMachineTypes(MACHINE_TYPE, MachineType.fromPb(MACHINE_TYPE.toPb())); + MachineType machineType = MachineType.builder().machineTypeId(MACHINE_TYPE_ID).build(); + compareMachineTypes(machineType, MachineType.fromPb(machineType.toPb())); + } + + private void compareMachineTypes(MachineType expected, MachineType value) { + assertEquals(expected, value); + assertEquals(expected.machineTypeId(), value.machineTypeId()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.cpus(), value.cpus()); + assertEquals(expected.memoryMb(), value.memoryMb()); + assertEquals(expected.scratchDisksSizeGb(), value.scratchDisksSizeGb()); + assertEquals(expected.maximumPersistentDisks(), value.maximumPersistentDisks()); + assertEquals(expected.maximumPersistentDisksSizeGb(), value.maximumPersistentDisksSizeGb()); + assertEquals(expected.deprecationStatus(), value.deprecationStatus()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java new file mode 100644 index 000000000000..3474a73c3030 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class RegionIdTest { + + private static final String PROJECT = "project"; + private static final String REGION = "region"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/regions/region"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + RegionId regionId = RegionId.of(PROJECT, REGION); + assertEquals(PROJECT, regionId.project()); + assertEquals(REGION, regionId.region()); + assertEquals(URL, regionId.selfLink()); + regionId = RegionId.of(REGION); + assertNull(regionId.project()); + assertEquals(REGION, regionId.region()); + } + + @Test + public void testToAndFromUrl() { + RegionId regionId = RegionId.of(PROJECT, REGION); + compareRegionId(regionId, RegionId.fromUrl(regionId.selfLink())); + } + + @Test + public void testSetProjectId() { + RegionId regionId = RegionId.of(PROJECT, REGION); + assertSame(regionId, regionId.setProjectId(PROJECT)); + compareRegionId(regionId, RegionId.of(REGION).setProjectId(PROJECT)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid region URL"); + RegionId.fromUrl("notMatchingUrl"); + } + + @Test + public void testMatchesUrl() { + assertTrue(RegionId.matchesUrl(RegionId.of(PROJECT, REGION).selfLink())); + assertFalse(RegionId.matchesUrl("notMatchingUrl")); + } + + private void compareRegionId(RegionId expected, RegionId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.region(), expected.region()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java new file mode 100644 index 000000000000..072823933110 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java @@ -0,0 +1,93 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +import java.math.BigInteger; +import java.util.List; + +public class RegionTest { + + private static final RegionId REGION_ID = RegionId.of("project", "region"); + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final Region.Status STATUS = Region.Status.DOWN; + private static final ZoneId ZONE_ID1 = ZoneId.of("project", "zone1"); + private static final ZoneId ZONE_ID2 = ZoneId.of("project", "zone2"); + private static final List ZONES = ImmutableList.of(ZONE_ID1, ZONE_ID2); + private static final Region.Quota QUOTA1 = + new Region.Quota("METRIC1", 2, 1); + private static final Region.Quota QUOTA2 = + new Region.Quota("METRIC2", 4, 3); + private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2); + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; + private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>( + DELETED, DEPRECATED, OBSOLETE, REGION_ID, DeprecationStatus.Status.DELETED); + private static final Region REGION = Region.builder() + .regionId(REGION_ID) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .zones(ZONES) + .quotas(QUOTAS) + .deprecationStatus(DEPRECATION_STATUS) + .build(); + + @Test + public void testBuilder() { + assertEquals(REGION_ID, REGION.regionId()); + assertEquals(ID, REGION.id()); + assertEquals(CREATION_TIMESTAMP, REGION.creationTimestamp()); + assertEquals(DESCRIPTION, REGION.description()); + assertEquals(STATUS, REGION.status()); + assertEquals(ZONES, REGION.zones()); + assertEquals(QUOTAS, REGION.quotas()); + assertEquals(DEPRECATION_STATUS, REGION.deprecationStatus()); + } + + @Test + public void testToAndFromPb() { + Region region = Region.fromPb(REGION.toPb()); + compareRegions(REGION, region); + assertEquals(REGION_ID.project(), region.regionId().project()); + assertEquals(REGION_ID.region(), region.regionId().region()); + region = Region.builder().regionId(REGION_ID).build(); + compareRegions(region, Region.fromPb(region.toPb())); + } + + private void compareRegions(Region expected, Region value) { + assertEquals(expected, value); + assertEquals(expected.regionId(), value.regionId()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.zones(), value.zones()); + assertEquals(expected.quotas(), value.quotas()); + assertEquals(expected.deprecationStatus(), value.deprecationStatus()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java new file mode 100644 index 000000000000..74c062fd6c27 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -0,0 +1,160 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.AuthCredentials; +import com.google.gcloud.RetryParams; +import com.google.gcloud.compute.Zone.MaintenanceWindow; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.List; + +public class SerializationTest { + + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final String VALID_DISK_SIZE = "10GB-10TB"; + private static final Long DEFAULT_DISK_SIZE_GB = 10L; + private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); + private static final DiskType DISK_TYPE = DiskType.builder() + .id(ID) + .diskTypeId(DISK_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .validDiskSize(VALID_DISK_SIZE) + .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB) + .build(); + private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type"); + private static final Integer GUEST_CPUS = 1; + private static final Integer MEMORY_MB = 2; + private static final List SCRATCH_DISKS = ImmutableList.of(3); + private static final Integer MAXIMUM_PERSISTENT_DISKS = 4; + private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L; + private static final MachineType MACHINE_TYPE = MachineType.builder() + .id(ID) + .machineTypeId(MACHINE_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .cpus(GUEST_CPUS) + .memoryMb(MEMORY_MB) + .scratchDisksSizeGb(SCRATCH_DISKS) + .maximumPersistentDisks(MAXIMUM_PERSISTENT_DISKS) + .maximumPersistentDisksSizeGb(MAXIMUM_PERSISTENT_DISKS_SIZE_GB) + .build(); + private static final RegionId REGION_ID = RegionId.of("project", "region"); + private static final Region.Status REGION_STATUS = Region.Status.DOWN; + private static final ZoneId ZONE_ID1 = ZoneId.of("project", "zone1"); + private static final ZoneId ZONE_ID2 = ZoneId.of("project", "zone2"); + private static final List ZONES = ImmutableList.of(ZONE_ID1, ZONE_ID2); + private static final Region.Quota QUOTA1 = + new Region.Quota("METRIC1", 2, 1); + private static final Region.Quota QUOTA2 = + new Region.Quota("METRIC2", 4, 3); + private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2); + private static final Region REGION = Region.builder() + .regionId(REGION_ID) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(REGION_STATUS) + .zones(ZONES) + .quotas(QUOTAS) + .build(); + private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); + private static final Zone.Status ZONE_STATUS = Zone.Status.DOWN; + private static final Long BEGIN_TIME = 1453293420000L; + private static final Long END_TIME = 1453293480000L; + private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1", + BEGIN_TIME, END_TIME); + private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", + BEGIN_TIME, END_TIME); + private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); + private static final Zone ZONE = Zone.builder() + .zoneId(ZONE_ID) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(ZONE_STATUS) + .maintenanceWindows(WINDOWS) + .region(REGION_ID) + .build(); + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; + private static final DeprecationStatus DEPRECATION_STATUS = + new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, + DeprecationStatus.Status.DELETED); + private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); + private static final Boolean CHARGES_USE_FEE = true; + private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE); + + @Test + public void testServiceOptions() throws Exception { + ComputeOptions options = ComputeOptions.builder() + .projectId("p1") + .authCredentials(AuthCredentials.createForAppEngine()) + .build(); + ComputeOptions serializedCopy = serializeAndDeserialize(options); + assertEquals(options, serializedCopy); + + options = options.toBuilder() + .projectId("p2") + .retryParams(RetryParams.defaultInstance()) + .authCredentials(null) + .build(); + serializedCopy = serializeAndDeserialize(options); + assertEquals(options, serializedCopy); + } + + @Test + public void testModelAndRequests() throws Exception { + Serializable[] objects = {DISK_TYPE_ID, DISK_TYPE, MACHINE_TYPE_ID, MACHINE_TYPE, REGION_ID, + REGION, ZONE_ID, ZONE, LICENSE_ID, LICENSE, DEPRECATION_STATUS}; + for (Serializable obj : objects) { + Object copy = serializeAndDeserialize(obj); + assertEquals(obj, obj); + assertEquals(obj, copy); + assertNotSame(obj, copy); + assertEquals(copy, copy); + } + } + + @SuppressWarnings("unchecked") + private T serializeAndDeserialize(T obj) + throws IOException, ClassNotFoundException { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { + output.writeObject(obj); + } + try (ObjectInputStream input = + new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { + return (T) input.readObject(); + } + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java new file mode 100644 index 000000000000..a147f0e21f63 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class ZoneIdTest { + + private static final String PROJECT = "project"; + private static final String ZONE = "zone"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/zones/zone"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + ZoneId zoneId = ZoneId.of(PROJECT, ZONE); + assertEquals(PROJECT, zoneId.project()); + assertEquals(ZONE, zoneId.zone()); + assertEquals(URL, zoneId.selfLink()); + zoneId = ZoneId.of(ZONE); + assertNull(zoneId.project()); + assertEquals(ZONE, zoneId.zone()); + } + + @Test + public void testToAndFromUrl() { + ZoneId zoneId = ZoneId.of(PROJECT, ZONE); + compareZoneId(zoneId, ZoneId.fromUrl(zoneId.selfLink())); + } + + @Test + public void testSetProjectId() { + ZoneId zoneId = ZoneId.of(PROJECT, ZONE); + assertSame(zoneId, zoneId.setProjectId(PROJECT)); + compareZoneId(zoneId, ZoneId.of(ZONE).setProjectId(PROJECT)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid zone URL"); + ZoneId.fromUrl("notMatchingUrl"); + } + + @Test + public void testMatchesUrl() { + assertTrue(ZoneId.matchesUrl(ZoneId.of(PROJECT, ZONE).selfLink())); + assertFalse(ZoneId.matchesUrl("notMatchingUrl")); + } + + private void compareZoneId(ZoneId expected, ZoneId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.zone(), expected.zone()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java new file mode 100644 index 000000000000..bdc96d3d9069 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java @@ -0,0 +1,96 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.Zone.MaintenanceWindow; + +import org.junit.Test; + +import java.math.BigInteger; +import java.util.List; + +public class ZoneTest { + + private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); + private static final RegionId REGION_ID = RegionId.of("project", "region"); + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final Zone.Status STATUS = Zone.Status.DOWN; + private static final Long BEGIN_TIME = 1453293420000L; + private static final Long END_TIME = 1453293480000L; + private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1", + BEGIN_TIME, END_TIME); + private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", + BEGIN_TIME, END_TIME); + private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; + private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>( + DELETED, DEPRECATED, OBSOLETE, ZONE_ID, DeprecationStatus.Status.DELETED); + private static final Zone ZONE = Zone.builder() + .zoneId(ZONE_ID) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .maintenanceWindows(WINDOWS) + .deprecationStatus(DEPRECATION_STATUS) + .region(REGION_ID) + .build(); + + @Test + public void testBuilder() { + assertEquals(REGION_ID, ZONE.region()); + assertEquals(ID, ZONE.id()); + assertEquals(CREATION_TIMESTAMP, ZONE.creationTimestamp()); + assertEquals(DESCRIPTION, ZONE.description()); + assertEquals(STATUS, ZONE.status()); + assertEquals(WINDOWS, ZONE.maintenanceWindows()); + assertEquals(REGION_ID, ZONE.region()); + assertEquals(DEPRECATION_STATUS, ZONE.deprecationStatus()); + } + + @Test + public void testToAndFromPb() { + com.google.api.services.compute.model.Zone zonePb = ZONE.toPb(); + assertEquals(REGION_ID.selfLink(), zonePb.getRegion()); + Zone zone = Zone.fromPb(zonePb); + compareZones(ZONE, zone); + assertEquals(ZONE_ID.project(), zone.zoneId().project()); + assertEquals(ZONE_ID.zone(), zone.zoneId().zone()); + zone = Zone.builder().zoneId(ZONE_ID).build(); + compareZones(zone, Zone.fromPb(zone.toPb())); + } + + private void compareZones(Zone expected, Zone value) { + assertEquals(expected, value); + assertEquals(expected.zoneId(), value.zoneId()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.maintenanceWindows(), value.maintenanceWindows()); + assertEquals(expected.region(), value.region()); + assertEquals(expected.deprecationStatus(), value.deprecationStatus()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index adfa716fe27b..e76d349483bd 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -18,6 +18,11 @@ gcloud-java-bigquery ${project.version} + + ${project.groupId} + gcloud-java-compute + ${project.version} + ${project.groupId} gcloud-java-core diff --git a/pom.xml b/pom.xml index 4bc8f37c35de..5f37fd2b7d6a 100644 --- a/pom.xml +++ b/pom.xml @@ -95,6 +95,7 @@ gcloud-java gcloud-java-bigquery + gcloud-java-compute gcloud-java-contrib gcloud-java-core gcloud-java-datastore