Learn how to create a working service callout that can read from and store to a MongoDB instance using Corticon's flexible datasource management API.
Progress Corticon 5.7 includes a unified datasource configuration file allowing users to configure connections to external sources of data. While this file is mostly used for connecting to external databases (either using ADC or EDC), it’s exposed in the service callout framework so users can connect Corticon Server to a customized datasource and handle the data appropriately even if the database isn’t natively supported. This guide explains how to connect to a MongoDB instance using a REST API.
Before starting, make sure you have all the prerequisite software:
Follow the instructions on the MongoDB website to install and start MongoDB. The website offers installation guides for all major desktop operating systems.
The default connection settings should allow you to connect.
Use “Corticon” as the name for both. (You don’t need to create a document; you’ll be doing that with the REST API).
mongo-uri: MongoDB://127.0.0.1
to this:
mongo-uri: MongoDB://127.0.0.1:27017
Start RESTHeart, and you should see output like the following:
09:59:43.461 [main] INFO org.restheart.Bootstrapper - ANSI colored console: true 09:59:43.481 [main] INFO org.restheart.Bootstrapper - Starting RESTHeart instance default 09:59:43.483 [main] INFO org.restheart.Bootstrapper - version 3.2.2 09:59:43.486 [main] INFO org.restheart.Bootstrapper - Logging to file C:\Users\bblais\AppData\Local\Temp\\restheart.log with level INFO 09:59:43.486 [main] INFO org.restheart.Bootstrapper - Logging to console with level INFO 09:59:44.229 [main] INFO org.restheart.Bootstrapper - MongoDB connection pool initialized 09:59:44.230 [main] INFO org.restheart.Bootstrapper - MongoDB version 3.6.2 09:59:44.230 [main] WARN org.restheart.Bootstrapper - ***** No Identity Manager specified. Authentication disabled.09:59:44.231 [main] WARN org.restheart.Bootstrapper - ***** No access manager specified. users can do anything. 09:59:44.232 [main] INFO org.restheart.Bootstrapper - Authentication Mechanism io.undertow.security.impl.BasicAuthenticationMechanism enabled 09:59:44.232 [main] INFO org.restheart.Bootstrapper - Token based authentication enabled with token TTL 15 minutes 09:59:44.242 [main] INFO org.restheart.Bootstrapper - HTTPS listener bound at 0.0.0.0:4443 09:59:44.243 [main] INFO org.restheart.Bootstrapper - HTTP listener bound at 0.0.0.0:8080 09:59:44.244 [main] INFO org.restheart.Bootstrapper - Local cache for db and collection properties enabled with TTL1000 msecs 09:59:44.245 [main] INFO org.restheart.Bootstrapper - Local cache for schema stores not enabled 09:59:44.423 [main] INFO org.restheart.Bootstrapper - URL / bound to MongoDB resource * 09:59:44.558 [main] INFO org.restheart.Bootstrapper - Embedded static resources browser extracted in C:\Users\bblais\AppData\Local\Temp\restheart- 6229838428094629763 09:59:44.596 [main] INFO org.restheart.Bootstrapper - URL /browser bound to static resources C:\Users\bblais\AppData\Local\Temp\restheart-6229838428094629763. Access Manager: false 09:59:44.790 [main] INFO org.restheart.Bootstrapper - RESTHeart startedTest the endpoint using your favorite browser or HTTP client.
Now the REST API connected to MongoDB is up and running.
Open Corticon Studio and make a simple Vocabulary. You can follow this example of a mileage calculator. It will take in information about a car and calculate how many more miles it can drive before needing fuel.
Create a Rulesheet to do the calculation.
Make a Ruletest and add some sample data to ensure the Decision Service is working.
Run the test and check your results.
Add an ADC configuration to your Vocabulary and choose any database type. (You won’t be using that for the service callout.)
Replace the default URL with the path to the RESTHeart API and append the name of the document to the URL. In this example, the document name is “cars.”
Create a service callout. As a shortcut, import the Corticon 5.7/Samples/Weather Callout file into your project; it already contains all the necessary libraries.
After importing, delete the Java files and, optionally, rename the project.
Write the code to create a class for your callout. Start by storing the data. (In this practice example, don’t worry too much about error handling.)
public static void storeData(ICcDataObjectManager dataObjectManager) throws Exception { // // Convert our DataObjects to JSON // //Since we are talking to a REST API convert the 'cars' to JSON Set<ICcDataObject> cars = dataObjectManager.getEntitiesByName("Car"); //This will be the JSONObject we send JSONObject carsJson = new JSONObject(); //And this will be the array we put all the 'cars' into JSONArray carsArray = new JSONArray(); //Convert the data objects, each one will be a json object in the array //Each attribute will be a property for(ICcDataObject currentCar : cars) { JSONObject currentCarJSON = new JSONObject(); //Get the attribute names Set<String> attributeNames = currentCar.getAttributeNames(); //Loop through the attributes for(String currentAttributeName : attributeNames) { //Place the attribute value currentCarJSON.put(currentAttributeName, currentCar.getAttributeValue(currentAttributeName)); } //Add the new car JSON object to the array carsArray.put(currentCarJSON); } //Place the array in the JSON object carsJson.put("Cars", (Object)carsArray); // // Connect to MongoDB // //Get the datasource Manager IDatasourceManager datasourceManager = dataObjectManager.getDatasourceManager(); //Get our MongoDB datasource IDatasource mongoDBDatasource = datasourceManager.getDatasource("MongoDB"); //Open an http connection to the database URL mongoDBConnectionURL = new URL(mongoDBDatasource.getDatasourceConnectionURL()); HttpURLConnection mongoDBConnection = (HttpURLConnection) mongoDBConnectionURL.openConnection(); //Since we are storing, we want to use the 'PUT' HTTP method mongoDBConnection.setRequestMethod("PUT"); //Set the content type mongoDBConnection.setRequestProperty("Content-Type", "application/json"); //Make sure we can write to the connection mongoDBConnection.setDoOutput(true); //We are going to write the data to the connection output stream BufferedWriter jsonContentWriter = null; try { jsonContentWriter = new BufferedWriter(new OutputStreamWriter(mongoDBConnection.getOutputStream())); //Convert our JSON to a string to send to the REST API jsonContentWriter.write(carsJson.toString()); //Flush the stream jsonContentWriter.flush(); //Open the connection mongoDBConnection.connect(); //Print out a rule message on success or failure int mongoDBResponseCode = mongoDBConnection.getResponseCode(); if(mongoDBResponseCode >= 200 && mongoDBResponseCode < 300) { dataObjectManager.postMessage(ICcDataObjectManager.INFO, "MongoDB PUT call SUCCEEDED with a status of " + Integer.toString(mongoDBResponseCode), null); } else { dataObjectManager.postMessage(ICcDataObjectManager.INFO, "MongoDB PUT call FAILED with a status of " + Integer.toString(mongoDBResponseCode), null); } } finally { //Close the stream and connection once we are done if(jsonContentWriter != null) { jsonContentWriter.close(); } mongoDBConnection.disconnect(); } }
Export the JAR File and Test the New Service Callout
To export the JAR file, right-click on the project, select Export in the menu and select Java/JAR File from the wizard options.
Add the exported JAR to the project.
Create a Ruleflow to test the new service callout.
Make a new Testsheet in the Ruletest and select the Ruleflow as the test subject.
Run the test.
If you successfully hit the REST API, you should see the new document populated with data.
Now, you have stored data in MongoDB.
Go back to the service callout and update it to read the information from the REST API instead of storing it.
Add the following method to your service callout.
public static void readData(ICcDataObjectManager dataObjectManager) throws Exception { //This will be the object that holds the JSON response from the rest API JSONObject mongoDBCarDocument = null; // // Connect to MongoDB // //Get the datasource Manager IDatasourceManager datasourceManager = dataObjectManager.getDatasourceManager(); //Get our MongoDB datasource IDatasource mongoDBDatasource = datasourceManager.getDatasource("MongoDB"); //Open an http connection to the database URL mongoDBConnectionURL = new URL(mongoDBDatasource.getDatasourceConnectionURL()); HttpURLConnection mongoDBConnection = (HttpURLConnection) mongoDBConnectionURL.openConnection(); //Since we are reading, we want to use the 'GET' HTTP method mongoDBConnection.setRequestMethod("GET"); //Set the content type mongoDBConnection.setRequestProperty("Content-Type", "application/json"); //Make the connection mongoDBConnection.connect(); //Print out a rule message on success or failure int mongoDBResponseCode = mongoDBConnection.getResponseCode(); if(mongoDBResponseCode >= 200 && mongoDBResponseCode < 300) { dataObjectManager.postMessage(ICcDataObjectManager.INFO, "MongoDB GET call SUCCEEDED with a status of " + Integer.toString(mongoDBResponseCode), null); } else { dataObjectManager.postMessage(ICcDataObjectManager.INFO, "MongoDB GET call FAILED with a status of " + Integer.toString(mongoDBResponseCode), null); } //Read response data BufferedReader jsonContentReader = null; try { jsonContentReader = new BufferedReader(new InputStreamReader(mongoDBConnection.getInputStream())); //Get all the data from the stream StringBuilder jsonResultStringBuilder = new StringBuilder(); //Read each line of the input to the end String lineOfJson = null; while( (lineOfJson = jsonContentReader.readLine()) != null) { jsonResultStringBuilder.append(lineOfJson); } //Convert the entire message payload into a JSONObject mongoDBCarDocument = new JSONObject(jsonResultStringBuilder.toString()); } finally { if(jsonContentReader != null) { jsonContentReader.close(); } mongoDBConnection.disconnect(); } // // Convert our JSON to DataObjects // //Get the 'cars' array out of the Document JSONArray carsJsonArray = mongoDBCarDocument.getJSONArray("Cars"); //Create a data object based off of each car in the array. for(int carsIndex = 0; carsIndex < carsJsonArray.length(); carsIndex++) { //Get the JSONObject out of the array JSONObject currentCar = carsJsonArray.getJSONObject(carsIndex); //Create the ICcDataObject ICcDataObject carDataObject = dataObjectManager.createEntity("Car"); Set<String> attributeNames = carDataObject.getAttributeNames(); //Loop through the data object attributes and, if they are properties in the JSONObject, set them for(String currentAttributeName : attributeNames) { if(currentCar.has(currentAttributeName)) { //Get the attribute's type String currentAttributeType = carDataObject.getAttributeDataType(currentAttributeName); //Create a variable for storing the attribute value in Object currentAttributeValue = null; //Long if(currentAttributeType.contains("Long")) { currentAttributeValue = new Long(currentCar.getLong(currentAttributeName)); } //BigDecimal else if(currentAttributeType.contains("BigDecimal")) { currentAttributeValue = new BigDecimal(currentCar.getLong(currentAttributeName)); } //Integer else if(currentAttributeType.contains("Integer")) { currentAttributeValue = new Integer(currentCar.getInt(currentAttributeName)); } //String else { currentAttributeValue = currentCar.getString(currentAttributeName); } carDataObject.setAttributeValue(currentAttributeName, currentAttributeValue); } } }}Export the JAR file again and restart Corticon Studio.
Create a new Ruleflow to handle retrieval from the database. Put the calculator Rulesheet in the Ruleflow to use the data retrieved from the database.
Add a new Testsheet with the new Ruleflow as test subject to try out the new service. Run the test.
If the retrieval succeeds, bring everything together by adding the first service callout, which saves information to the database, to the Ruleflow.
Test again.
Hit the API and see the updated MilesTillEmpty property.
With that, we're done with this example. If you’re feeling adventurous, you can also export the datasource configuration file and build a Decision Service for deploying to the server. Now, you know how to create a working service callout that can read from and store to a MongoDB instance using Corticon. And you can use this approach to create interesting and useful callouts with Corticon’s flexible datasource management API.
This is just one of many new improvements we’ve delivered with Corticon 5.7. Check out everything that’s new in this release, then contact us to schedule a demo and let us know what you think.
Subscribe to get all the news, info and tutorials you need to build better business apps and sites