At this point, most authors use DynamoDB, for the very simple reason that it's easy, provisioned and you don't really need to think about it.
For various reasons, I want to use Couchbase, so I'm going to do that here and just apologize if that makes your life more difficult. By all means, follow along and apply the same "principles" but using DynamoDB; it's certainly possible.
The code for this is in the repository tagged API_GATEWAY_COUCHBASE.
Getting started
The overall arc that we are going to follow is to have an entry in Couchbase that holds an array of connectionIds. We want to add to that on $connect and remove on $disconnect and be able to iterate that list at will. All of that is too much to bite off in one post, however, so we will start by just getting Couchbase integrated into our Lambda so that we could, theoretically, do something with it.
It all starts with libraries, so we need to download the Couchbase client library and its dependencies in package.sh.
We then want to make sure we have a connection to a bucket established in the lambda. To do this, we need to provide some parameters: a cluster endpoint, a bucket name, a username and a password. These are going to be passed to our creation and update scripts as environment variables which are then turned into parameters for the JSON.
aws cloudformation create-stack \
--stack-name 'ignorant-gateway' \
--capabilities CAPABILITY_IAM \
--parameters \
"ParameterKey=BUCKET,ParameterValue=$BUCKET" \
"ParameterKey=COUCHBASE,ParameterValue=$COUCHBASE" \
"ParameterKey=CBUSER,ParameterValue=$CBUSER" \
"ParameterKey=CBPASSWD,ParameterValue=$CBPASSWD" \
"ParameterKey=CBBUCKET,ParameterValue=$CBBUCKET" \
--template-body "`cat src/main/resources/gateway-cf.json`"
Because we now have so many arguments, I have broken the one command out onto multiple lines.
The parameters are handled near the top of the configuration JSON:
"Parameters": {
"BUCKET": { "Type": "String" },
"COUCHBASE": { "Type": "String" },
"CBUSER": { "Type": "String" },
"CBPASSWD": { "Type": "String" },
"CBBUCKET": { "Type": "String" }
}
And are then passed in to the lambda as environment variables again
"COUCHBASE": { "Ref": "COUCHBASE" },
"CBUSER": { "Ref": "CBUSER" },
"CBPASSWD": { "Ref": "CBPASSWD" },
"CBBUCKET": { "Ref": "CBBUCKET" }
Now we can go and write some code.The initial connection obviously wants to be in our central repository of things for the lambda, so that it is covered under the same "static initialization" policy we came up with before. At the same time, we don't want too much conflation of concerns, so we will delegate to its own class:
private CouchbaseEnvironment couchbase = new CouchbaseEnvironment();
Ignoring all the boilerplate, this basically comes down to a constructor which opens the Couchbase bucket identified in the parameters:
public CouchbaseEnvironment() {
Builder builder = new DefaultCouchbaseEnvironment.Builder();
builder.connectTimeout(10000);
builder.kvTimeout(10000);
builder.retryStrategy(BestEffortRetryStrategy.INSTANCE);
DefaultCouchbaseEnvironment env = builder.build();
String server = System.getenv("COUCHBASE");
CouchbaseCluster cluster = CouchbaseCluster.fromConnectionString(env, server);
String cbuser = System.getenv("CB_USER");
String cbpasswd = System.getenv("CB_PASSWD");
PasswordAuthenticator authenticator = new PasswordAuthenticator(cbuser, cbpasswd);
cluster.authenticate(authenticator);
String testBucket = System.getenv("CB_BUCKET");
bucket = cluster.openBucket(testBucket, 15, TimeUnit.SECONDS);
}
Obviously, we also need code to provide for injecting this into handlers. Other than to say that there is an interface WithCouchbase which handlers can implement, I'm just going to put that code in the repository for you to find.Conclusion
This post has not really advanced "the state of the world". It is just a technical post that allows us to have a bucket to hand to record things in.
Now we need to capture the connectionIds on connect and store them in Couchbase for later use.
Next: Handling connections and disconnections
Next: Handling connections and disconnections
No comments:
Post a Comment