Skip to content

Commit d3abf25

Browse files
committed
Merge pull request #572 from ajkannan/project-extends-projectinfo
Make Project a subclass of ProjectInfo
2 parents 4cf793e + a76e6c4 commit d3abf25

File tree

11 files changed

+398
-163
lines changed

11 files changed

+398
-163
lines changed

README.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -210,20 +210,22 @@ Google Cloud Resource Manager (Alpha)
210210
Here is a code snippet showing a simple usage example. Note that you must supply Google SDK credentials for this service, not other forms of authentication listed in the [Authentication section](#authentication).
211211
212212
```java
213-
import com.google.gcloud.resourcemanager.ProjectInfo;
213+
import com.google.gcloud.resourcemanager.Project;
214214
import com.google.gcloud.resourcemanager.ResourceManager;
215215
import com.google.gcloud.resourcemanager.ResourceManagerOptions;
216216
217217
import java.util.Iterator;
218218
219219
ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service();
220-
ProjectInfo myProject = resourceManager.get("some-project-id"); // Use an existing project's ID
221-
ProjectInfo newProjectInfo = resourceManager.replace(myProject.toBuilder()
222-
.addLabel("launch-status", "in-development").build());
223-
System.out.println("Updated the labels of project " + newProjectInfo.projectId()
224-
+ " to be " + newProjectInfo.labels());
220+
Project myProject = resourceManager.get("some-project-id"); // Use an existing project's ID
221+
Project newProject = myProject.toBuilder()
222+
.addLabel("launch-status", "in-development")
223+
.build()
224+
.replace();
225+
System.out.println("Updated the labels of project " + newProject.projectId()
226+
+ " to be " + newProject.labels());
225227
// List all the projects you have permission to view.
226-
Iterator<ProjectInfo> projectIterator = resourceManager.list().iterateAll();
228+
Iterator<Project> projectIterator = resourceManager.list().iterateAll();
227229
System.out.println("Projects I can view:");
228230
while (projectIterator.hasNext()) {
229231
System.out.println(projectIterator.next().projectId());

gcloud-java-examples/src/main/java/com/google/gcloud/examples/ResourceManagerExample.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.gcloud.examples;
1818

1919
import com.google.common.base.Joiner;
20+
import com.google.gcloud.resourcemanager.Project;
2021
import com.google.gcloud.resourcemanager.ProjectInfo;
2122
import com.google.gcloud.resourcemanager.ResourceManager;
2223
import com.google.gcloud.resourcemanager.ResourceManagerOptions;
@@ -64,7 +65,7 @@ public void run(ResourceManager resourceManager, String... args) {
6465
labels.put(args[i], "");
6566
}
6667
}
67-
ProjectInfo project =
68+
Project project =
6869
resourceManager.create(ProjectInfo.builder(projectId).labels(labels).build());
6970
System.out.printf(
7071
"Successfully created project '%s': %s.%n", projectId, projectDetails(project));

gcloud-java-resourcemanager/README.md

+20-14
Original file line numberDiff line numberDiff line change
@@ -83,33 +83,36 @@ ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().servi
8383
All you need to create a project is a globally unique project ID. You can also optionally attach a non-unique name and labels to your project. Read more about naming guidelines for project IDs, names, and labels [here](https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects). To create a project, add the following import at the top of your file:
8484

8585
```java
86+
import com.google.gcloud.resourcemanager.Project;
8687
import com.google.gcloud.resourcemanager.ProjectInfo;
8788
```
8889

8990
Then add the following code to create a project (be sure to change `myProjectId` to your own unique project ID).
9091

9192
```java
9293
String myProjectId = "my-globally-unique-project-id"; // Change to a unique project ID.
93-
ProjectInfo myProject = resourceManager.create(ProjectInfo.builder(myProjectId).build());
94+
Project myProject = resourceManager.create(ProjectInfo.builder(myProjectId).build());
9495
```
9596

96-
Note that the return value from `create` is a `ProjectInfo` that includes additional read-only information, like creation time, project number, and lifecycle state. Read more about these fields on the [Projects page](https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects).
97+
Note that the return value from `create` is a `Project` that includes additional read-only information, like creation time, project number, and lifecycle state. Read more about these fields on the [Projects page](https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects). `Project`, a subclass of `ProjectInfo`, adds a layer of service-related functionality over `ProjectInfo`.
9798

9899
#### Getting a specific project
99100
You can load a project if you know it's project ID and have read permissions to the project. For example, to get the project we just created we can do the following:
100101

101102
```java
102-
ProjectInfo projectFromServer = resourceManager.get(myProjectId);
103+
Project projectFromServer = resourceManager.get(myProjectId);
103104
```
104105

105106
#### Editing a project
106-
To edit a project, create a new `ProjectInfo` object and pass it in to the `ResourceManager.replace` method.
107+
To edit a project, create a new `ProjectInfo` object and pass it in to the `Project.replace` method.
107108

108109
For example, to add a label for the newly created project to denote that it's launch status is "in development", add the following code:
109110

110111
```java
111-
ProjectInfo newProjectInfo = resourceManager.replace(projectFromServer.toBuilder()
112-
.addLabel("launch-status", "in-development").build());
112+
Project newProject = myProject.toBuilder()
113+
.addLabel("launch-status", "in-development")
114+
.build()
115+
.replace();
113116
```
114117

115118
Note that the values of the project you pass in to `replace` overwrite the server's values for non-read-only fields, namely `projectName` and `labels`. For example, if you create a project with `projectName` "some-project-name" and subsequently call replace using a `ProjectInfo` object that didn't set the `projectName`, then the server will unset the project's name. The server ignores any attempted changes to the read-only fields `projectNumber`, `lifecycleState`, and `createTime`. The `projectId` cannot change.
@@ -124,7 +127,7 @@ import java.util.Iterator;
124127
Then add the following code to print a list of projects you can view:
125128

126129
```java
127-
Iterator<ProjectInfo> projectIterator = resourceManager.list().iterateAll();
130+
Iterator<Project> projectIterator = resourceManager.list().iterateAll();
128131
System.out.println("Projects I can view:");
129132
while (projectIterator.hasNext()) {
130133
System.out.println(projectIterator.next().projectId());
@@ -136,6 +139,7 @@ while (projectIterator.hasNext()) {
136139
Here we put together all the code shown above into one program. This program assumes that you are running from your own desktop and used the Google Cloud SDK to authenticate yourself.
137140

138141
```java
142+
import com.google.gcloud.resourcemanager.Project;
139143
import com.google.gcloud.resourcemanager.ProjectInfo;
140144
import com.google.gcloud.resourcemanager.ResourceManager;
141145
import com.google.gcloud.resourcemanager.ResourceManagerOptions;
@@ -151,20 +155,22 @@ public class GcloudJavaResourceManagerExample {
151155

152156
// Create a project.
153157
String myProjectId = "my-globally-unique-project-id"; // Change to a unique project ID.
154-
ProjectInfo myProject = resourceManager.create(ProjectInfo.builder(myProjectId).build());
158+
Project myProject = resourceManager.create(ProjectInfo.builder(myProjectId).build());
155159

156160
// Get a project from the server.
157-
ProjectInfo projectFromServer = resourceManager.get(myProjectId);
161+
Project projectFromServer = resourceManager.get(myProjectId);
158162
System.out.println("Got project " + projectFromServer.projectId() + " from the server.");
159163

160164
// Update a project
161-
ProjectInfo newProjectInfo = resourceManager.replace(myProject.toBuilder()
162-
.addLabel("launch-status", "in-development").build());
163-
System.out.println("Updated the labels of project " + newProjectInfo.projectId()
164-
+ " to be " + newProjectInfo.labels());
165+
Project newProject = myProject.toBuilder()
166+
.addLabel("launch-status", "in-development")
167+
.build()
168+
.replace();
169+
System.out.println("Updated the labels of project " + newProject.projectId()
170+
+ " to be " + newProject.labels());
165171

166172
// List all the projects you have permission to view.
167-
Iterator<ProjectInfo> projectIterator = resourceManager.list().iterateAll();
173+
Iterator<Project> projectIterator = resourceManager.list().iterateAll();
168174
System.out.println("Projects I can view:");
169175
while (projectIterator.hasNext()) {
170176
System.out.println(projectIterator.next().projectId());

gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java

+134-26
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,110 @@
1818

1919
import static com.google.common.base.Preconditions.checkNotNull;
2020

21+
import java.io.IOException;
22+
import java.io.ObjectInputStream;
23+
import java.util.Map;
24+
import java.util.Objects;
25+
2126
/**
2227
* A Google Cloud Resource Manager project object.
2328
*
2429
* <p>A Project is a high-level Google Cloud Platform entity. It is a container for ACLs, APIs,
2530
* AppEngine Apps, VMs, and other Google Cloud Platform resources. This class' member variables are
26-
* immutable. Methods that change or update the underlying Project information return a new Project
27-
* instance.
31+
* immutable. Methods that change or update the underlying Project information return a new Project
32+
* instance. {@code Project} adds a layer of service-related functionality over {@link ProjectInfo}.
2833
*/
29-
public class Project {
34+
public class Project extends ProjectInfo {
3035

31-
private final ResourceManager resourceManager;
32-
private final ProjectInfo info;
36+
private static final long serialVersionUID = 6767630161335155133L;
3337

34-
/**
35-
* Constructs a Project object that contains the ProjectInfo given.
36-
*/
37-
public Project(ResourceManager resourceManager, ProjectInfo projectInfo) {
38+
private final ResourceManagerOptions options;
39+
private transient ResourceManager resourceManager;
40+
41+
public static class Builder extends ProjectInfo.Builder {
42+
private final ResourceManager resourceManager;
43+
private ProjectInfo.BuilderImpl infoBuilder;
44+
45+
Builder(ResourceManager resourceManager) {
46+
this.resourceManager = resourceManager;
47+
this.infoBuilder = new ProjectInfo.BuilderImpl();
48+
}
49+
50+
Builder(Project project) {
51+
this.resourceManager = project.resourceManager;
52+
this.infoBuilder = new ProjectInfo.BuilderImpl(project);
53+
}
54+
55+
@Override
56+
public Builder name(String name) {
57+
infoBuilder.name(name);
58+
return this;
59+
}
60+
61+
@Override
62+
public Builder projectId(String projectId) {
63+
infoBuilder.projectId(projectId);
64+
return this;
65+
}
66+
67+
@Override
68+
public Builder addLabel(String key, String value) {
69+
infoBuilder.addLabel(key, value);
70+
return this;
71+
}
72+
73+
@Override
74+
public Builder removeLabel(String key) {
75+
infoBuilder.removeLabel(key);
76+
return this;
77+
}
78+
79+
@Override
80+
public Builder clearLabels() {
81+
infoBuilder.clearLabels();
82+
return this;
83+
}
84+
85+
@Override
86+
public Builder labels(Map<String, String> labels) {
87+
infoBuilder.labels(labels);
88+
return this;
89+
}
90+
91+
@Override
92+
Builder projectNumber(Long projectNumber) {
93+
infoBuilder.projectNumber(projectNumber);
94+
return this;
95+
}
96+
97+
@Override
98+
Builder state(State state) {
99+
infoBuilder.state(state);
100+
return this;
101+
}
102+
103+
@Override
104+
Builder createTimeMillis(Long createTimeMillis) {
105+
infoBuilder.createTimeMillis(createTimeMillis);
106+
return this;
107+
}
108+
109+
@Override
110+
Builder parent(ResourceId parent) {
111+
infoBuilder.parent(parent);
112+
return this;
113+
}
114+
115+
@Override
116+
public Project build() {
117+
return new Project(resourceManager, infoBuilder);
118+
}
119+
}
120+
121+
Project(ResourceManager resourceManager, ProjectInfo.BuilderImpl infoBuilder) {
122+
super(infoBuilder);
38123
this.resourceManager = checkNotNull(resourceManager);
39-
this.info = checkNotNull(projectInfo);
124+
this.options = resourceManager.options();
40125
}
41126

42127
/**
@@ -46,15 +131,7 @@ public Project(ResourceManager resourceManager, ProjectInfo projectInfo) {
46131
* @throws ResourceManagerException upon failure
47132
*/
48133
public static Project get(ResourceManager resourceManager, String projectId) {
49-
ProjectInfo projectInfo = resourceManager.get(projectId);
50-
return projectInfo != null ? new Project(resourceManager, projectInfo) : null;
51-
}
52-
53-
/**
54-
* Returns the {@link ProjectInfo} object associated with this Project.
55-
*/
56-
public ProjectInfo info() {
57-
return info;
134+
return resourceManager.get(projectId);
58135
}
59136

60137
/**
@@ -72,7 +149,7 @@ public ResourceManager resourceManager() {
72149
* @throws ResourceManagerException upon failure
73150
*/
74151
public Project reload() {
75-
return Project.get(resourceManager, info.projectId());
152+
return Project.get(resourceManager, projectId());
76153
}
77154

78155
/**
@@ -98,7 +175,7 @@ public Project reload() {
98175
* @throws ResourceManagerException upon failure
99176
*/
100177
public void delete() {
101-
resourceManager.delete(info.projectId());
178+
resourceManager.delete(projectId());
102179
}
103180

104181
/**
@@ -115,21 +192,52 @@ public void delete() {
115192
* @throws ResourceManagerException upon failure (including when the project can't be restored)
116193
*/
117194
public void undelete() {
118-
resourceManager.undelete(info.projectId());
195+
resourceManager.undelete(projectId());
119196
}
120197

121198
/**
122-
* Replaces the attributes of the project.
199+
* Replaces the attributes of the project with the attributes of this project.
123200
*
124201
* <p>The caller must have modify permissions for this project.
125202
*
126203
* @see <a
127204
* href="https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/update">Cloud
128205
* Resource Manager update</a>
129-
* @return the ProjectInfo representing the new project metadata
206+
* @return the Project representing the new project metadata
130207
* @throws ResourceManagerException upon failure
131208
*/
132-
public Project replace(ProjectInfo projectInfo) {
133-
return new Project(resourceManager, resourceManager.replace(checkNotNull(projectInfo)));
209+
public Project replace() {
210+
return resourceManager.replace(this);
211+
}
212+
213+
static Builder builder(ResourceManager resourceManager, String projectId) {
214+
return new Builder(resourceManager).projectId(projectId);
215+
}
216+
217+
@Override
218+
public Builder toBuilder() {
219+
return new Builder(this);
220+
}
221+
222+
@Override
223+
public boolean equals(Object obj) {
224+
return obj instanceof Project && Objects.equals(toPb(), ((Project) obj).toPb())
225+
&& Objects.equals(options, ((Project) obj).options);
226+
}
227+
228+
@Override
229+
public int hashCode() {
230+
return Objects.hash(super.hashCode(), options);
231+
}
232+
233+
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
234+
in.defaultReadObject();
235+
this.resourceManager = options.service();
236+
}
237+
238+
static Project fromPb(ResourceManager resourceManager,
239+
com.google.api.services.cloudresourcemanager.model.Project answer) {
240+
ProjectInfo info = ProjectInfo.fromPb(answer);
241+
return new Project(resourceManager, new ProjectInfo.BuilderImpl(info));
134242
}
135243
}

0 commit comments

Comments
 (0)