This repository has been archived by the owner on Apr 24, 2021. It is now read-only.
/
ComputeEngineSample.java
264 lines (232 loc) · 11.2 KB
/
ComputeEngineSample.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/*
* 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.api.services.samples.computeengine.cmdline;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.compute.Compute;
import com.google.api.services.compute.ComputeScopes;
import com.google.api.services.compute.model.AccessConfig;
import com.google.api.services.compute.model.AttachedDisk;
import com.google.api.services.compute.model.AttachedDiskInitializeParams;
import com.google.api.services.compute.model.Instance;
import com.google.api.services.compute.model.InstanceList;
import com.google.api.services.compute.model.Metadata;
import com.google.api.services.compute.model.NetworkInterface;
import com.google.api.services.compute.model.Operation;
import com.google.api.services.compute.model.ServiceAccount;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Command-line sample to demo listing Google Compute Engine instances using Java and the Google
* Compute Engine API
*
* @author Jonathan Simon
*/
public class ComputeEngineSample {
/**
* Be sure to specify the name of your application. If the application name is {@code null} or
* blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0".
*/
private static final String APPLICATION_NAME = "";
/** Set PROJECT_ID to your Project ID from the Overview pane in the Developers console. */
private static final String PROJECT_ID = "YOUR_PROJECT_ID";
/** Set Compute Engine zone */
private static final String ZONE_NAME = "us-central1-f";
/** Set the name of the sample VM instance to be created. */
private static final String SAMPLE_INSTANCE_NAME = "my-sample-instance";
/** Set the path of the OS image for the sample VM instance to be created. */
private static final String SOURCE_IMAGE_PREFIX = "https://www.googleapis.com/compute/v1/projects/";
private static final String SOURCE_IMAGE_PATH = "debian-cloud/global/images/debian-7-wheezy-v20150710";
/** Set the Network configuration values of the sample VM instance to be created. */
private static final String NETWORK_INTERFACE_CONFIG = "ONE_TO_ONE_NAT";
private static final String NETWORK_ACCESS_CONFIG = "External NAT";
/** Set the time out limit for operation calls to the Compute Engine API. */
private static final long OPERATION_TIMEOUT_MILLIS = 60 * 1000;
/** Global instance of the HTTP transport. */
private static HttpTransport httpTransport;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
public static void main(String[] args) {
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
// Authenticate using Google Application Default Credentials.
GoogleCredential credential = GoogleCredential.getApplicationDefault();
if (credential.createScopedRequired()) {
List<String> scopes = new ArrayList<>();
// Set Google Cloud Storage scope to Full Control.
scopes.add(ComputeScopes.DEVSTORAGE_FULL_CONTROL);
// Set Google Compute Engine scope to Read-write.
scopes.add(ComputeScopes.COMPUTE);
credential = credential.createScoped(scopes);
}
// Create Compute Engine object for listing instances.
Compute compute = new Compute.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
// List out instances, looking for the one created by this sample app.
boolean foundOurInstance = printInstances(compute);
Operation op;
if (foundOurInstance) {
op = deleteInstance(compute, SAMPLE_INSTANCE_NAME);
} else {
op = startInstance(compute, SAMPLE_INSTANCE_NAME);
}
// Call Compute Engine API operation and poll for operation completion status
System.out.println("Waiting for operation completion...");
Operation.Error error = blockUntilComplete(compute, op, OPERATION_TIMEOUT_MILLIS);
if (error == null) {
System.out.println("Success!");
} else {
System.out.println(error.toPrettyString());
}
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
System.exit(1);
}
// [START list_instances]
/**
* Print available machine instances.
*
* @param compute The main API access point
* @return {@code true} if the instance created by this sample app is in the list
*/
public static boolean printInstances(Compute compute) throws IOException {
System.out.println("================== Listing Compute Engine Instances ==================");
Compute.Instances.List instances = compute.instances().list(PROJECT_ID, ZONE_NAME);
InstanceList list = instances.execute();
boolean found = false;
if (list.getItems() == null) {
System.out.println("No instances found. Sign in to the Google Developers Console and create "
+ "an instance at: https://console.developers.google.com/");
} else {
for (Instance instance : list.getItems()) {
System.out.println(instance.toPrettyString());
if (instance.getName().equals(SAMPLE_INSTANCE_NAME)) {
found = true;
}
}
}
return found;
}
// [END list_instances]
// [START create_instances]
public static Operation startInstance(Compute compute, String instanceName) throws IOException {
System.out.println("================== Starting New Instance ==================");
// Create VM Instance object with the required properties.
Instance instance = new Instance();
instance.setName(instanceName);
instance.setMachineType("https://www.googleapis.com/compute/v1/projects/" + PROJECT_ID +
"/zones/" + ZONE_NAME + "/machineTypes/n1-standard-1");
// Add Network Interface to be used by VM Instance.
NetworkInterface ifc = new NetworkInterface();
ifc.setNetwork("https://www.googleapis.com/compute/v1/projects/" + PROJECT_ID + "/global/networks/default");
List<AccessConfig> configs = new ArrayList<>();
AccessConfig config = new AccessConfig();
config.setType(NETWORK_INTERFACE_CONFIG);
config.setName(NETWORK_ACCESS_CONFIG);
configs.add(config);
ifc.setAccessConfigs(configs);
instance.setNetworkInterfaces(Collections.singletonList(ifc));
// Add attached Persistent Disk to be used by VM Instance.
AttachedDisk disk = new AttachedDisk();
disk.setBoot(true);
disk.setAutoDelete(true);
disk.setType("PERSISTENT");
AttachedDiskInitializeParams params = new AttachedDiskInitializeParams();
// Assign the Persistent Disk the same name as the VM Instance.
params.setDiskName(instanceName);
// Specify the source operating system machine image to be used by the VM Instance.
params.setSourceImage(SOURCE_IMAGE_PREFIX + SOURCE_IMAGE_PATH);
// Specify the disk type as Standard Persistent Disk
params.setDiskType("https://www.googleapis.com/compute/v1/projects/" + PROJECT_ID + "/zones/"
+ ZONE_NAME + "/diskTypes/pd-standard");
disk.setInitializeParams(params);
instance.setDisks(Collections.singletonList(disk));
// Initialize the service account to be used by the VM Instance and set the API access scopes.
ServiceAccount account = new ServiceAccount();
account.setEmail("default");
List<String> scopes = new ArrayList<>();
scopes.add("https://www.googleapis.com/auth/devstorage.full_control");
scopes.add("https://www.googleapis.com/auth/compute");
account.setScopes(scopes);
instance.setServiceAccounts(Collections.singletonList(account));
// Optional - Add a startup script to be used by the VM Instance.
Metadata meta = new Metadata();
Metadata.Items item = new Metadata.Items();
item.setKey("startup-script-url");
// If you put a script called "vm-startup.sh" in this Google Cloud Storage bucket, it will execute on VM startup.
// This assumes you've created a bucket named the same as your PROJECT_ID
// For info on creating buckets see: https://cloud.google.com/storage/docs/cloud-console#_creatingbuckets
item.setValue("gs://" + PROJECT_ID + "/vm-startup.sh");
meta.setItems(Collections.singletonList(item));
instance.setMetadata(meta);
System.out.println(instance.toPrettyString());
Compute.Instances.Insert insert = compute.instances().insert(PROJECT_ID, ZONE_NAME, instance);
return insert.execute();
}
// [END create_instances]
private static Operation deleteInstance(Compute compute, String instanceName) throws Exception {
System.out.println("================== Deleting Instance " + instanceName + " ==================");
Compute.Instances.Delete delete = compute.instances().delete(PROJECT_ID, ZONE_NAME, instanceName);
return delete.execute();
}
// [START wait_until_complete]
/**
* Wait until {@code operation} is completed.
* @param compute the {@code Compute} object
* @param operation the operation returned by the original request
* @param timeout the timeout, in millis
* @return the error, if any, else {@code null} if there was no error
* @throws InterruptedException if we timed out waiting for the operation to complete
* @throws IOException if we had trouble connecting
*/
public static Operation.Error blockUntilComplete(Compute compute, Operation operation, long timeout)
throws Exception {
long start = System.currentTimeMillis();
final long POLL_INTERVAL = 5 * 1000;
String zone = operation.getZone(); // null for global/regional operations
if (zone != null) {
String[] bits = zone.split("/");
zone = bits[bits.length-1];
}
String status = operation.getStatus();
String opId = operation.getName();
while (operation != null && !status.equals("DONE")) {
Thread.sleep(POLL_INTERVAL);
long elapsed = System.currentTimeMillis() - start;
if (elapsed >= timeout) {
throw new InterruptedException("Timed out waiting for operation to complete");
}
System.out.println("waiting...");
if (zone != null) {
Compute.ZoneOperations.Get get = compute.zoneOperations().get(PROJECT_ID, zone, opId);
operation = get.execute();
} else {
Compute.GlobalOperations.Get get = compute.globalOperations().get(PROJECT_ID, opId);
operation = get.execute();
}
if (operation != null) {
status = operation.getStatus();
}
}
return operation == null ? null : operation.getError();
}
// [END wait_until_complete]
}