Amazon RDS: Launching "db.t1.micro" instances using the JAVA SDK - java

I'm trying to start a new MySql Instance on Amazon RDS using the Java API and the following code:
CreateDBInstanceRequest createDBInstanceRequest = new CreateDBInstanceRequest();
createDBInstanceRequest.setEngine("MySQL");
createDBInstanceRequest.setLicenseModel("general-public-license");
createDBInstanceRequest.setEngineVersion("5.5.25a");
createDBInstanceRequest.setDBInstanceClass("db.t1.micro");
createDBInstanceRequest.setMultiAZ(false);
createDBInstanceRequest.setAutoMinorVersionUpgrade(true);
createDBInstanceRequest.setAllocatedStorage(5);
createDBInstanceRequest.setDBInstanceIdentifier("mydbinstance");
createDBInstanceRequest.setMasterUsername("master");
createDBInstanceRequest.setMasterUserPassword("password");
createDBInstanceRequest.setDBName("dbname");
createDBInstanceRequest.setPort(3306);
createDBInstanceRequest.setDBParameterGroupName("default.mysql5.5");
createDBInstanceRequest.setDBSubnetGroupName("dev");
createDBInstanceRequest.setBackupRetentionPeriod(1);
DBInstance dbInstance = RDS.createDBInstance(createDBInstanceRequest);
The problem is that this always results in the following error:
AWS Error Code: InsufficientDBInstanceCapacity, AWS Error Message:
Cannot create a database instance because there is no availability
zone with sufficient capacity. Please try your request again at a
later time.
As suggested, I tried at a later time but have never been able to launch a new instance programatically but when I try to launch an instance using the Amazon Mgmt Console, using exactly the same parameters, it launches instantly.
I have also noticed that this problem only occurs with DB Instance Class "db.t1.micro".
Is this instance class not available through the API?

Are you certain this exact version of MySQL is available in any of the availability zones in your region?
I would suggest to execute DescribeOrderableDBInstanceOptions for your engine of choice first, filter using your own criteria (e.g. DBInstanceClass="db.t1.micro") and then select the version from that.

Related

How to start CloudFoundry app using ReactorCloudFoundryClient?

I used StartApplicationRequest to create a sample request to start the application as given below:
StartApplicationRequest request = StartApplicationRequest.builder()
.applicationId("test-app-name")
.build();
Then, I used the ReactorCloudFoundryClient to start the application as shown below:
cloudFoundryClient.applicationsV3().start(request);
But my test application test-app-name is not getting started. I'm using latest Java CF client version (v4.5.0 RELEASE), but not seeing a way around to start the application.
Quite surprisingly, the outdated version seems to be working with the below code:
cfstatus = cfClient.startApplication("test-app-name"); //start app
cfstatus = cfClient.stopApplication("test-app-name"); //stop app
cfstatus = cfClient.restartApplication("test-app-name"); //stop app
I want to do the same with latest CF client library, but I don't see any useful reference. I referred to test cases written at CloudFoundry official Github repo. I derived to the below code after checking out a lot of docs:
StartApplicationRequest request = StartApplicationRequest.builder()
.applicationId("test-app-name")
.build();
cloudFoundryClient.applicationsV3().start(request);
Note that cloudFoundryClient is ReactorCloudFoundryClient instance as the latest library doesn't support the client class used with outdated code. I would like to do all operations (start/stop/restart) with latest library. The above code isn't working.
A couple things here...
Using the reactor based client, your call to cloudFoundryClient.applicationsV3().start(request) returns a Mono<StartApplicationResponse>. That's not the actual response, it's the possibility of one. You need to do something to get the response. See here for more details.
If you would like similar behavior to the original cf-java-client, you can call .block() on the Mono<StartApplicationResponse> and it will wait and turn into a response.
Ex:
client.applicationsV3()
.start(StartApplicationRequest.builder()
.applicationId("test-app-name")
.build())
.block()
The second thing is that it's .applicationId not applicationName. You need to pass in an application guid, not the name. As it is, you're going to get a 404 saying the application doesn't exist. You can use the client to fetch the guid, or you can use CloudFoundryOperations instead (see #3).
The CloudFoundryOperations interface is a higher-level API. It's easier to use, in general, and supports things like starting an app based on the name instead of the guid.
Ex:
ops.applications()
.start(StartApplicationRequest.builder()
.name("test-app-name").build())
.block();

Backend server: how to retain FirebaseApp instance?

I've been trying to implement the Firebase Admin SDK into our backend server, running on JAVA. The source of my question is this piece of code, provided by Google:
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
I've already tested it and have integrated it properly in my code. However, I dislike how it seems like I need to leave the serviceAccountKey.json in my server in order to use the Admin SDK.
I have two simple questions for you guys:
Is there a way to prevent me from having to store the sensible information (serviceAccountKey.json) in the server (since it could possibly be reverse-engineered)?
Is the .setDatabaseUrl(...) necessary if I'm using my own MySQL DB? The only database Firebase effectively has on their server for me is my user-base, since I use Firebase-authentication. I store the UID in my own DB to refer to users.
Yes, there are alternative ways to load the configuration needed for the Admin SDK and it's mentioned in this post by Hiranya Jayathilaka:
You can create a JSON file similar to the one below
{
"databaseURL": "https://database-name.firebaseio.com",
"projectId": "my-project-id",
"storageBucket": "bucket-name.appspot.com"
}
And then create an Environment Variable named FIREBASE_CONFIG in your server, and set it to point to the JSON file.
Then you'd only need to call FirebaseApp.initializeApp() with no parameters.
As the name suggests, that method is only needed to indicate the Realtime Database URL. If you're not using it, it can be omitted.

Java Google datastore async calls

I do not want to block threads in my application and so I am wondering are calls to the the Google Datastore async? For example the docs show something like this to retrieve an entity:
// Key employeeKey = ...;
LookupRequest request = LookupRequest.newBuilder().addKey(employeeKey).build();
LookupResponse response = datastore.lookup(request);
if (response.getMissingCount() == 1) {
throw new RuntimeException("entity not found");
}
Entity employee = response.getFound(0).getEntity();
This does not look like an async call to me, so it is possible to make aysnc calls to the database in Java? I noticed App engine has some libraries for async calls in its Java API, but I am not using appengine, I will be calling the datastore from my own instances. As well, if there is an async library can I test it on my local server (for example app engine's async library I could not find a way to set it up to use my local server for example I this library can't get my environment variables).
In your shoes, I'd give a try to Spotify's open-source Asynchronous Google Datastore Client -- I have not personally tried it, but it appears to meet all of your requirements, including being able to test on your local server. Please give it a try and let us all know how well it meets your needs, so we can all benefit and learn -- thanks!

Couchbase failure to find bucket local instance

Following the implementation guide from Spring on creating CouchbaseConfig by extending AbstractCouchbaseConfiguration.
Problem #1
My local Couch instance exists on "http://localhost:5984/" At application runtime the default port always results in the value "11210" which ultimatly results in connectivity failure.
Solution
To resolve this issue I am overriding the implementation which creates CouchbaseClient within my CouchbaseConfig component (Code snippet below)
public CouchbaseClient couchbaseClient() throws Exception {
CouchbaseClient client = null;
URI local=new URI("http://127.0.0.1:5984");
List<URI> baseURIs=new ArrayList<URI>();
baseURIs.add(local);
client = new CouchbaseClient(baseURIs, bucketValue, "");
......
I am still not able to locate the bucket I have setup in my local couch instance
http-bio-8080-exec-25] INFO 18:18:14,172 SLF4JLogger.log(87) - Could not fetch config from http seed nodes.
com.couchbase.client.vbucket.ConfigurationException: Configuration for bucket "bucketValue" was not found in server list ([http://127.0.0.1:5984]).
at com.couchbase.client.vbucket.ConfigurationProviderHTTP.readPools(ConfigurationProviderHTTP.java:271)
at com.couchbase.client.vbucket.ConfigurationProviderHTTP.getBucketConfiguration(ConfigurationProviderHTTP.java:143)
at com.couchbase.client.vbucket.provider.BucketConfigurationProvider.bootstrapHttp(BucketConfigurationProvider.java:351)
Any information on how to resolve this would be greatly appreciated.
So, I think what you have done here is confused Couchbase and CouchDb - they are entirely different platforms, even though they have confusingly-similar names.
You need to install a local instance of Couchbase if that is what you are trying to do, and get rid of Couchdb.

AWS Error Message: InvalidInstanceID.NotFound

I'm trying to start a Amazon EC2 cloud machine with [startInstance][2] method using aws-sdk in Java. My code is as follows.
public String startInstance(String instanceId) throws Exception {
List<String> instanceIds = new ArrayList<String>();
instanceIds.add(instanceId);
StartInstancesRequest startRequest = new StartInstancesRequest(
instanceIds);
startRequest.setRequestCredentials(getCredentials());
StartInstancesResult startResult = ec2.startInstances(startRequest);
List<InstanceStateChange> stateChangeList = startResult
.getStartingInstances();
log.trace("Starting instance '{}':", instanceId);
// Wait for the instance to be started
return waitForTransitionCompletion(stateChangeList, "running",
instanceId);
}
When I run the above code, i'm getting the following AWS error:
Status Code: 400, AWS Request ID: e1bd4795-a609-44d1-9e80-43611e80006b, AWS Erro
r Code: InvalidInstanceID.NotFound, AWS Error Message: The instance ID 'i-2b97ac
2f' does not exist
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpCli
ent.java:538)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.ja
va:283)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:168
)
at com.amazonaws.services.ec2.AmazonEC2Client.invoke(AmazonEC2Client.jav
a:5208)
at com.amazonaws.services.ec2.AmazonEC2Client.startInstances(AmazonEC2Cl
ient.java:2426)
AWS Error Message: The instance ID 'i-2b97ac2f' does not exist
You'll have to take the AWS response for granted here, i.e. the instance does not exist ;)
But seriously: Presumably you have already verified that you are actually running an instance with this ID in your account? Then this is most likely caused by targeting the wrong API endpoint, insofar an instance ID is only valid within a specific region (if not specified, the region defaults to 'us-east-1', see below).
In this case you need to specify the actual instance region via the setEndpoint() method of the AmazonEC2Client object within the apparently global ec2 variable before calling startInstances().
There are some examples regarding Using Regions with the AWS SDKs and all currently available AWS regional endpoint URLs are listed in Regions and Endpoints, specifically the Amazon Elastic Compute Cloud (EC2) defaults to 'us-east-1':
If you just specify the general endpoint (ec2.amazonaws.com), Amazon
EC2 directs your request to the us-east-1 endpoint.
We run a service (Qubole) that frequently spawns and then tags (and in some cases terminates) AWS instances immediately.
We have found that Amazon will, every once in a while, claim an instanceid as invalid - even though it has just created it. Retrying a few times with some sleep time thrown in usually solves the problem. Even a total retry interval of 15s proved insufficient in rare cases.
This experience comes from the useast region. We do not make api calls to different regions - so that is not an explanation. More likely - this is the infamous eventual consistency at work - where AWS is unable to provide read-after-write consistency for these api calls.
I am using the AWS ruby api and I noticed the same issue when creating an AMI image and its status is pending when I look in the AWS console but after a while the image is available for use.
Here is my script
image = ec2.images.create(:name => image_name, :instance_id => ami_id, :description => desc)
sleep 5 while image.state != :available
I sleep for about 5 sec for image to be in available but I get the error saying that the "AWS Error Message: InvalidInstanceID.NotFound". During my testing this is fine but most of the time this seems to be failing during continuous integration builds.
InvalidInstanceID.NotFound means the specified instance does not exist.
Ensure that you have indicated the region in which the instance is located, if it's not in the default region.
This error may occur because the ID of a recently created instance has not propagated through the system. For more information, see Eventual Consistency.

Categories