{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Look-Aside Cache for MongoDB\n",
"### This is a sample notebook for using Aerospike as a read/look-aside cache\n",
"\n",
"- This notebook demonstrates the use of Aerospike as a cache using Mongo as another primary datastore\n",
"- It is required to run Mongo as a separate container using `docker run --name some-mongo -d mongo:latest`\n",
"\n",
"To test: Run the `cache.getData(\"id\", \"data\");` method once - to fetch from Mongo and populate Aerospike\n",
"\n",
"Another run will fetch the data from Aerospike cache\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Ensure that Aerospike Database is running"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import io.github.spencerpark.ijava.IJava;\n",
"import io.github.spencerpark.jupyter.kernel.magic.common.Shell;\n",
"IJava.getKernelInstance().getMagics().registerMagics(Shell.class);\n",
"%sh asd"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Load Aerospike and Mongo dependencies from POM"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"%%loadFromPOM\n",
"\n",
" \n",
" com.aerospike\n",
" aerospike-client\n",
" 5.0.0\n",
" \n",
" \n",
" org.mongodb\n",
" mongo-java-driver\n",
" 3.12.7\n",
" \n",
""
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"import com.aerospike.client.AerospikeClient;\n",
"import com.aerospike.client.policy.WritePolicy;\n",
"import com.aerospike.client.Bin;\n",
"import com.aerospike.client.Key;\n",
"import com.aerospike.client.Record;\n",
"import com.aerospike.client.Value;\n",
"\n",
"import com.mongodb.client.MongoDatabase;\n",
"import com.mongodb.client.MongoCollection;\n",
"import com.mongodb.MongoClient; \n",
"import com.mongodb.MongoCredential; \n",
"import org.bson.Document;\n",
"import com.mongodb.client.model.Filters;\n",
"import java.util.Set;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Configure the clients\n",
"\n",
"The configuration is for \n",
" - Aerospike database running on port 3000 of localhost (IP 127.0.0.1) which is the default. \n",
" - Mongo running in a separate container whose IP can be found by `docker inspect | grep -i ipaddress`\n",
"\n",
"\n",
"Modify config if your environment is different (Aerospike database running on a different host or different port)."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"public class Cache{\n",
" //Database Constants\n",
" public static final String AEROSPIKE_HOST = \"0.0.0.0\";\n",
" public static final String MONGO_HOST = \"172.17.0.3\";\n",
" public static final int AEROSPIKE_PORT = 3000;\n",
" public static final int MONGO_PORT = 27017;\n",
" \n",
" public static final String AEROSPIKE_NAMESPACE = \"test\";\n",
" public static final String AEROSPIKE_SET = \"demo\";\n",
" public static final String MONGO_USER = \"sampleUser\";\n",
" public static final String MONGO_PASSWORD = \"password\";\n",
" public static final String MONGO_DB = \"myDb\";\n",
" public static final String MONGO_COLLECTION = \"sampleCollection\";\n",
" \n",
" private AerospikeClient client;\n",
" private MongoClient mongo;\n",
" private MongoCredential credential;\n",
" private MongoDatabase database;\n",
" \n",
" public Cache() {\n",
" client = new AerospikeClient(AEROSPIKE_HOST, AEROSPIKE_PORT);\n",
" mongo = new MongoClient(MONGO_HOST , MONGO_PORT);\n",
" credential = MongoCredential.createCredential(MONGO_USER, MONGO_DB, \n",
" MONGO_PASSWORD.toCharArray());\n",
" database = mongo.getDatabase(MONGO_DB);\n",
" }\n",
" \n",
" private boolean collectionExists(final String collectionName) {\n",
" // Check and return if the collection exists in Mongo\n",
" return database.listCollectionNames()\n",
" .into(new ArrayList()).contains(collectionName);\n",
" }\n",
"\n",
" public void populateMongoData(String id, String data) {\n",
" // Populate Mongodb first\n",
" Document document = new Document(id, data);\n",
" if (! collectionExists(MONGO_COLLECTION)) {\n",
" database.createCollection(MONGO_COLLECTION);\n",
" } else {\n",
" MongoCollection collection = database.getCollection(MONGO_COLLECTION);\n",
" collection.insertOne(document);\n",
" }\n",
" Key key = new Key(AEROSPIKE_NAMESPACE, AEROSPIKE_SET, id);\n",
" client.delete(null, key);\n",
" }\n",
" \n",
" public String getData(String id, String data) {\n",
" // This is just an example code that exhibits a cache fetch for a String id with String data\n",
" \n",
" Key key = new Key(AEROSPIKE_NAMESPACE, AEROSPIKE_SET, id);\n",
" String BIN_NAME = \"value\";\n",
" Record record = client.get(null,key);\n",
" if ( record == null ) {\n",
" System.out.println(\"First Fetch Record does not exist in Aerospike cache\");\n",
" MongoCollection collection = database.getCollection(MONGO_COLLECTION);\n",
" Document document = collection.find(Filters.eq(id, data)).first();\n",
" //System.out.println(\"Document \" + document.get(id));\n",
" String json = document.get(id).toString();\n",
" client.put(null, key, new Bin(BIN_NAME,json));\n",
" return client.get(null, key).toString(); \n",
" \n",
" } else {\n",
" System.out.println(\"Data retrieved from Aerospike cache\");\n",
" return record.toString();\n",
" \n",
" }\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"Cache cache = new Cache();\n",
"cache.populateMongoData(\"id\", \"data\");"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"First Fetch Record does not exist in Aerospike cache\n"
]
},
{
"data": {
"text/plain": [
"(gen:1),(exp:350708590),(bins:(value:data))"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cache.getData(\"id\", \"data\");\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Java",
"language": "java",
"name": "java"
},
"language_info": {
"codemirror_mode": "java",
"file_extension": ".jshell",
"mimetype": "text/x-java-source",
"name": "Java",
"pygments_lexer": "java",
"version": "11.0.8+10-LTS"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 4
}