Starting and stopping instances on google compute engine - google-compute-engine

I want to start/resume and stop/suspend instances on google compute engine, but it gives "java.lang.UnsupportedOperationException".Is there any alternative way
to perform these operations?
public class Example {
public static void main(String[] args)
{
String provider = "google-compute-engine";
String identity = "****#developer.gserviceaccount.com";
String credential = "path to private key";
String groupName = "newgroup";
credential = getCredentialFromJsonKeyFile(credential);
Iterable<Module> modules = ImmutableSet.<Module> of(
new SshjSshClientModule(),
new SLF4JLoggingModule(),
new EnterpriseConfigurationModule());
ContextBuilder builder = ContextBuilder.newBuilder(provider)
.credentials(identity, credential)
.modules(modules);
ComputeService compute=builder.buildView(ComputeServiceContext.class).getComputeService();
compute.suspendNode("Instance id");
//compute.suspendNodesMatching(Predicates.<NodeMetadata> and(inGroup(groupName)));
System.out.println("suspended");
compute.getContext().close();
}
private static String getCredentialFromJsonKeyFile(String filename) {
try {
String fileContents = Files.toString(new File(filename), UTF_8);
Supplier<Credentials> credentialSupplier = new GoogleCredentialsFromJson(fileContents);
String credential = credentialSupplier.get().credential;
return credential;
} catch (IOException e) {
System.err.println("Exception reading private key from '%s': " + filename);
e.printStackTrace();
System.exit(1);
return null;
}
}
}
Output:
suspending node(node id)
Exception in thread "main" java.lang.UnsupportedOperationException: suspend is not supported by GCE
at org.jclouds.googlecomputeengine.compute.GoogleComputeEngineServiceAdapter.suspendNode(GoogleComputeEngineServiceAdapter.java:251)
at org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies.suspendNode(AdaptingComputeServiceStrategies.java:171)
at org.jclouds.compute.internal.BaseComputeService.suspendNode(BaseComputeService.java:503)
at org.jclouds.examples.compute.basics.Example.main(Example.java:79)

It is not directly supported in the portable jclouds ComputeService, but from the ComputeServiceContext you can get the GoogleComputeEngineApi and the InstanceApi, and use the start/stop methods in there.
FYI, there is an ongoing patch to add support for the start/stop operations in the ComputeService: https://github.com/jclouds/jclouds-labs-google/pull/141

You can stop an instance from the API.
POST https://www.googleapis.com/compute/v1/projects/<project>/zones/<zone>/instances/<instance>/stop
Where :
project in URL is you project id.
zone in URL is the name of zone for the request.
instance in URL is the name of instances to stop.
Here's the docs

Related

Can we use the same signer object to sign all the requests?

I need to make mutiple rest api calls for fetching instance, volume and vnic details. Can i reuse the same signer object created for signing the other calls?
Signer object method
public RequestSigner getSigner(Properties properties, String pemFilePath, String apiKey) {
InputStream privateKeyStream;
PrivateKey privateKey = null;
try {
privateKeyStream = Files.newInputStream(Paths.get(pemFilePath));
privateKey = PEM.readPrivateKey(privateKeyStream);
} catch (InvalidKeySpecException e) {
// throw new RuntimeException("Invalid format for private key");
properties.setProperty(OracleCloudConstants.CUSTOM_DC_ERROR,
FormatUtil.getString("am.webclient.oraclecloud.customdc.invalidformat"));
AMLog.debug("OracleCloudDataCollector::CheckAuthentication()::Invalid format for private key::"
+ e.getMessage());
e.printStackTrace();
} catch (IOException e) {
properties.setProperty(OracleCloudConstants.CUSTOM_DC_ERROR,
FormatUtil.getString("am.webclient.oraclecloud.customdc.failedload"));
AMLog.debug(
"OracleCloudDataCollector::CheckAuthentication()::Failed to load private key::" + e.getMessage()); //No I18N
e.printStackTrace();
// throw new RuntimeException("Failed to load private key");
}
RequestSigner signer = null;
if (privateKey != null) {
signer = new RequestSigner(apiKey, privateKey);
}
return signer;
}
One signer object may be used to sign multiple requests. In fact, the SDK implementation does this too.
It is not clear what version of the SDK you are using. In version 1.5.7 (the most recent at the time of writing), com.oracle.bmc.http.signing.RequestSigner (https://github.com/oracle/oci-java-sdk/blob/master/bmc-common/src/main/java/com/oracle/bmc/http/signing/RequestSigner.java#L16) is an interface which cannot be new’ed as per the snippet above.

How to read .pem file with a passphrase in Oracle Cloud Infrastructure?

I need to monitor Oracle Cloud Compute VM using REST API. I found the following lines of code for Signing with headers in Oracle documentation.
String privateKeyFilename = "/.oci/oci_api_key.pem";
PrivateKey privateKey = loadPrivateKey(privateKeyFilename);
RequestSigner signer = new RequestSigner(apiKey, privateKey);
loadPrivateKey(privateKeyFilename) Method
private static PrivateKey loadPrivateKey(String privateKeyFilename) {
System.out.println(SystemUtils.getUserHome().toString() + Paths.get(privateKeyFilename));
try (InputStream privateKeyStream = Files
.newInputStream(Paths.get(SystemUtils.getUserHome().toString() + privateKeyFilename))) {
return PEM.readPrivateKey(privateKeyStream);
} catch (InvalidKeySpecException e) {
throw new RuntimeException("Invalid format for private key");
} catch (IOException e) {
throw new RuntimeException("Failed to load private key");
}
}
Do these lines will cover reading the file with passphrase. Any inputs?

Google Cloud SQL Exception

I am trying to do a SQL database in Google Cloud SQL and with a Java project make many queries to the database, but I have this answer:
Buckets:
Exception in thread "main" com.google.cloud.storage.StorageException: java.lang.NullPointerException: Required parameter project must be specified.
at com.google.cloud.storage.StorageException.translateAndThrow(StorageException.java:73)
at com.google.cloud.storage.StorageImpl.listBuckets(StorageImpl.java:288)
at com.google.cloud.storage.StorageImpl.list(StorageImpl.java:257)
at package1.Auth.authExplicit(Auth.java:46)
at package1.Main.main(Main.java:21)
Caused by: java.lang.NullPointerException: Required parameter project must be specified
public static void main(String[] args) throws IOException {
String instanceConnectionName="";
String databaseName="prueba";
String username="root";
String password="root";
String sql="SELECT * FROM alumnos";
String jsonPath="/Users/franciscomanuelpozodelmoral/Downloads/Team5-c4e75c7cb498.json";
Auth.authExplicit(jsonPath);
try {
Class.forName("com.mysql.jdbc.Driver");
String jdbcURL=String.format("jdbc:mysql://google/%s?cloudSqlInstance=%s&" +
"socketFactory=com.google.cloud.sql.mysql.SocketFactory",databaseName,instanceConnectionName);
Connection connection=DriverManager.getConnection(jdbcURL, username, password);
Statement statement=connection.createStatement();
ResultSet rs=statement.executeQuery(sql);
while(rs.next()) {
System.out.println(rs.getString("DNI") + rs.getString("Nombre") + rs.getString("Apellidos") + rs.getInt("Telefono")+rs.getInt("Curso"));
}
} catch(Exception e) {
e.printStackTrace();
}
}
public class Auth {
static void authImplicit() {
// If you don't specify credentials when constructing the client, the client library will
// look for credentials via the environment variable GOOGLE_APPLICATION_CREDENTIALS.
//Storage storage = StorageOptions.getDefaultInstance().getService();
Storage storage=StorageOptions.getDefaultInstance().getService();
System.out.println("Buckets:");
Page<Bucket> buckets = storage.list();
for (Bucket bucket : buckets.iterateAll()) {
System.out.println(bucket.toString());
}
}
static void authExplicit(String jsonPath) throws IOException {
// You can specify a credential file by providing a path to GoogleCredentials.
// Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
.createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();
System.out.println("Buckets:");
Page<Bucket> buckets = storage.list();
// for (Bucket bucket : buckets.iterateAll()) {
// System.out.println(bucket.toString());
// }
}
}
Can you help me? Thanks (The instanceConnectionName is group5...)

Apache HttpComponents CookieStore Not Storing Cookies

I'm using HttpComponents 4.5.2 and I'm trying to store cookies as I need to use them for login and other requests. The code works fine whilst the application is still running, but the problem here is when I restart it, the cookies that were supposed to be stored in CookieStore are not there. Here's what I've written:
public static void main( String[] args ) throws InterruptedException
{
RequestConfig globalConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.STANDARD).build();
BasicCookieStore cookieStore = new BasicCookieStore();
HttpClientContext context = HttpClientContext.create();
context.setCookieStore(cookieStore);
CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
.setDefaultRequestConfig(globalConfig)
.setDefaultCookieStore(cookieStore)
.build();
httpclient.start();
login(httpclient, context);
}
public static void login(CloseableHttpAsyncClient httpClient, HttpClientContext context) throws InterruptedException
{
JSONObject json = new JSONObject("{ email : blahblahblah1, password : blahblahblah2 }");
StringEntity requestEntity = new StringEntity(
json.toString(),
ContentType.APPLICATION_JSON);
HttpPost postMethod = new HttpPost("http://localhost:8080/login");
postMethod.setEntity(requestEntity);
final CountDownLatch latch = new CountDownLatch(1);
httpClient.execute(postMethod, context, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response) {
latch.countDown();
System.out.println(postMethod.getRequestLine() + "->" + response.getStatusLine());
//System.out.println(context.getCookieStore().getCookies().size());
}
public void failed(final Exception ex) {
latch.countDown();
System.out.println(postMethod.getRequestLine() + "->" + ex);
}
public void cancelled() {
latch.countDown();
System.out.println(postMethod.getRequestLine() + " cancelled");
}
});
latch.await();
}
I've read the HttpComponents documentation and the section 3.5 about cookies says:
HttpClient can work with any physical representation of a persistent cookie store that implements the CookieStore interface. The default CookieStore implementation called BasicCookieStore is a simple implementation backed by a java.util.ArrayList. Cookies stored in an BasicClientCookie object are lost when the container object get garbage collected. Users can provide more complex implementations if necessary
So I'm wondering if it's left to it's users to implement some kind of structure that can effectively store cookies or if I'm missing something.
Yes, using BasicCookieStore backed by ArrayList means that when your jvm exists, the data there is being lost just like any ArrayList in memory.
BasicCookieStore class also implements Serializable so you can use that to persist it to disk and restore back on your app startup if the file was there.
You can borrow some code from the tests verifying that flow TestBasicCookieStore#testSerialization.

Setting Description in Metadata for Google Drive Android API

Is there any way to set the Metadata Description?
https://developer.android.com/reference/com/google/android/gms/drive/Metadata.html#getDescription()
If so, what is the length limit?
I can't see anything in the api: https://developer.android.com/reference/com/google/android/gms/drive/MetadataChangeSet.Builder.html
Unfortunately not at the moment, AFAIK. What I do right now is initializing both GDAA and RESTful API (see the 'trash solution' SO 22295903) like this:
private GoogleApiClient _gac;
private com.google.api.services.drive.Drive _svc;
public GoogleApiClient init(String email){
_gac = new GoogleApiClient.Builder(UT.ACTX).addApi(com.google.android.gms.drive.Drive.API)
.addScope(com.google.android.gms.drive.Drive.SCOPE_FILE).setAccountName(email).build();
com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential crd =
GoogleAccountCredential.usingOAuth2(UT.ACTX,
Arrays.asList(com.google.api.services.drive.DriveScopes.DRIVE_FILE));
crd.setSelectedAccountName(email);
_svc = new com.google.api.services.drive.Drive.Builder(
AndroidHttp.newCompatibleTransport(), new GsonFactory(), crd).build();
return this;
}
You get the description from DGAA (GoogleApiClient _gac above), but update/write it to RESTFul like this (off UI thread):
public void oldDescUpW(String titl, String mime, String desc) {
try {
final FileList gLst = _svc.files().list()
.setQ("title = '"+titl+".jpg' and mimeType = '"+mime+"' and trashed = false")
.setFields("items(id)").execute();
if (gLst.getItems().size() == 1) {
final String sId = gLst.getItems().get(0).getId();
com.google.api.services.drive.model.File body =
new com.google.api.services.drive.model.File();
body.setDescription(desc);
_svc.files().patch(sId, body).execute();
}
} catch (Exception e) {}
}
It is also possible to use 'resource ID' from GDAA to address the file in RESTful, but it is not always immediately available (if the file is created in GDAA). See SO 22874657
DISCLAIMER:
It is a HACK and should not stay alive past GDAA delivery of an alternative.