HowTo: Send Custom Data to the MobileFirst Analytics Server from adapters or any java application
Yoel Nunez April 14, 2016
MobileFirst_Platform AnalyticsOverview
Sending custom data from your MobileFirst 7.1 apps to the Operational Analytics Server can be accomplished by using the log
methods from the WLAnalytics
and WL.Analytics
objects in hybrid and native Android and iOS environments. However, sending custom data from MobileFirst Adapters, JavaScript or Java, is not supported. Hence, I decided to write some code to send custom data from any java application.
- About This Library
- GitHub Repository
- Usage in Java
- Usage in JavaScript Adapters
- Adapter based authentication sample
- Final Thoughts
About This Library
I decided to go with Gradle for building, testing, managing dependencies, and packaging my code in a jar. Since I’m building a jar, I can add it to the server/lib
folder in my MobileFirst project to be able to use it with JavaScript adapters. On the other hand, if I want to use the jar with Java adapters, I just need to drop in the jar in the lib folder of the Java adapter.
The functionality of the API is very straight forward. First, I create a ServerContext
object which contains information about the MobileFirst Operational Analytics server i.e., endpoint, username, and password. Second, I create an AppContext
object which contains information about the application and device i.e., app name, app version, device id, os, os version, and model. Third, I get an instance of the AnalyticsAPI
by passing the AppContext
. Fourth, I log the data by passing a message string and a JSONObject
with all the metadata. Finally, I call the send
method from the AnalyticsAPI
and that’s all. Now, let’s jump right into the code.
GitHub Repository
https://github.com/ynunez/MobileFirstAnalyticsSender
Usage in Java
At this point I’m assuming that you have built the library from the repository listed above and added the resulting jar to your project.
import com.yoelnunez.mobilefirst.analytics.AnalyticsAPI;
import com.yoelnunez.mobilefirst.analytics.exceptions.MissingServerContextException;
import com.yoelnunez.mobilefirst.analytics.util.AppContext;
import com.yoelnunez.mobilefirst.analytics.util.ServerContext;
import org.json.JSONObject;
public class MyCustomApplication {
public static void main(String[] args) {
// should match the value of the `wl.analytics.url` jndi property in your server.xml file
String analyticsEndpoint = "http://yoelnunez.com/analytics/v2"
// IMPORTANT: setting the analytics server info
AnalyticsAPI.setContext(new ServerContext(analyticsEndpoint, "myUsername", "myPassword"));
try {
// Attach some metadata to your logs, i.e., which app and device
AppContext appContext = new AppContext();
appContext.setAppName("CustomerApplication");
appContext.setAppVersion("1.0");
appContext.setDeviceID("my-device-id");
appContext.setDeviceOS("Android");
appContext.setDeviceOSVersion("6.0");
appContext.setDeviceModel("Nexus 5X");
// Analytics api instance
AnalyticsAPI analytics = AnalyticsAPI.createInstance(appContext);
JSONObject customer1 = new JSONObject();
customer1.put("firstName", "Yoel");
customer1.put("lastName", "Nunez");
customer1.put("age", 25);
// log custom data
analytics.log("customer1", customer1);
JSONObject customer2 = new JSONObject();
customer2.put("firstName", "John");
customer2.put("lastName", "Doe");
customer2.put("age", 23);
// log custom data
analytics.log("customer2", customer2);
// send data to analytics server
AnalyticsAPI.send();
} catch (MissingServerContextException e) {
// analytics server endpoint details missing
}
}
}
Usage in JavaScript Adapters
If you want to use the library in your JavaScript adapters, then you have to make sure you add the resulting jar to the server/lib folder in your MobileFirst project and then redeploy the newly generated war to your MobileFirst server.
/**
* Aliasing the Analytics API for easier usage.
* For example, you can use:
* Analytics.Util.ServerContext
* instead of
* com.yoelnunez.mobilefirst.analytics.util.ServerContext
*/
var Analytics = {
Util: com.yoelnunez.mobilefirst.analytics.util,
API: com.yoelnunez.mobilefirst.analytics.AnalyticsAPI
};
/**
* Get the Analytics Server information like endpoint, username,
* and password form the JNDI configutation then set the server context
*/
(function() {
var url = WL.Server.configuration['wl.analytics.url'],
user = WL.Server.configuration['wl.analytics.username'],
pass = WL.Server.configuration['wl.analytics.password'];
var context = new Analytics.Util.ServerContext(url, user, pass);
Analytics.API.setContext(context);
})();
/**
* Logging custom data from procedure
*/
function adapterProcedureTest(firstName, lastName){
var httpRequest = WL.Server.getClientRequest();
var userIP = httpRequest.getRemoteAddr();
var api = Analytics.API.createInstance(appContextFromRequest(httpRequest));
var metadata = {
userIP: httpRequest.getRemoteAddr(),
fullName: firstName + " " + lastName
};
// in JS, we have to serialize the JSONObject and pass it as a string
api.log("adapter-invocation", JSON.stringify(metadata));
Analytics.API.send();
return metadata;
}
/**
* Creates an AppContext object from the request containing device and
* application information i.e., app name, version, os, model, etc.
*
* This is required to get an instance of the AnalyticsAPI
*
* @param request
* @returns {Analytics.Util.AppContext}
*/
function appContextFromRequest(request) {
var context = new Analytics.Util.AppContext();
// getting some metadata from request headers
context.setAppName(request.getHeader('x-wl-clientlog-appname'));
context.setAppVersion(request.getHeader('x-wl-clientlog-appversion'));
context.setDeviceID(request.getHeader('x-wl-device-id'));
context.setDeviceOS(request.getHeader('x-wl-clientlog-env'));
context.setDeviceOSVersion(request.getHeader('x-wl-clientlog-osversion'));
context.setDeviceModel(request.getHeader('x-wl-clientlog-model'));
return context;
}
Adapter based authentication sample
In this sample I’m logging the reason for the login failure, i.e., wrong password and user not found, and sending it over to the MobileFirst Analytics sever.
https://github.com/ynunez/AdapterBasedAuthWithCustomAnalytics
Final Thoughts
Although sending custom data from adapters is not supported, by writing some code I am able to send custom data from JavaScript adapters, Java adapters, and from any other Java application. That custom data can later be visualized by creating some Custom Charts and can even be exported to use somewhere else.
Inclusive terminology note: The Mobile First Platform team is making changes to support the IBM® initiative to replace racially biased and other discriminatory language in our code and content with more inclusive language. While IBM values the use of inclusive language, terms that are outside of IBM's direct influence are sometimes required for the sake of maintaining user understanding. As other industry leaders join IBM in embracing the use of inclusive language, IBM will continue to update the documentation to reflect those changes.