How to bypass the language processor in Teneo engine requests
Request destination
In the standard scenario, requests sent to a published Teneo engine go through the linguistic processor where they trigger a step in the current dialog, which implies executing global and local Teneo scripts, checking the input against different existing conditions, passing through flow transitions, quitting or entering dialog flows, returning an answer and multiple other processes which change the current state of the dialog. There are, however, scenarios where you have to access Teneo engine without triggering this process.
These scenarios can involve, for instance, submitting or reading data from the current Teneo dialog at any point in time without “moving” the linguistic processer with all the side effects it causes, extending a Teneo engine session in case of inactivity and others. In these scenarios you cannot send a request to the Teneo engine “the standard way” since this request would inevitably trigger a movement in the whole Teneo dialog machinery which would break your dialog and distort your statistics. In these scenarios the request should on the one hand bypass the linguistic processor, but on the other hand it should have access to the data inside the current dialog.
JSPs to interact with Teneo engine
All the requests you send to Teneo engine go via a JSP, which also formats the response Teneo engine returns. Depending on where a JSP is placed inside your published Teneo engine, a request hitting that JSP will either be further dispatched to the linguistic processor or will end up in that JSP only.
There are two places you can install your JSPs: in the Teneo engine’s “/WEB-INF/views
” folder and in its “/
” (root) folder. When a request hits a JSP in “/WEB-INF/views
”, it is dispatched to the linguistic processor, and when the linguistic processor finishes its processing, the response if formatted by this JSP and returned. When a request hits a JSP in “/
” (the web application’s root folder), it is NOT dispatched to the linguistic processor, so the linguistic processor doesn’t get involved in the processing and it is up to the JSP itself to perform the necessary request handling.
Adding JSPs to a solution
To add a JSP to Teneo engine, open your solution in Teneo Studio, go to Resources/File, click “Add” and select the JSP to upload (in this case it is myJsp.jsp
). The file will get uploaded into “/WEB-INF/views
” which is displayed in Teneo Studio as “/views
”:
If you want to move it to the “/
” (application root) folder, just replace “/views
” with a “/
” in “Published Location”:
After that you have to save the solution by clicking “Save” or pressing Ctrl-S.
You can upload as many JSPs as you need to both folders.
Normally you should place your JSPs in “/WEB-INF/views
” (“/views
” in Teneo Studio) only if you want to change the output format because your client software requires it or if you have some non-standard 3rd party integration requirements.
Teneo engine JSP documentation
You can find more information about the currently used output format and session handling here:
You can find the documentation of the Teneo engine API and how to access different Teneo objects inside the JSPs here:
Accessing JSPs
Assume you have a Teneo engine published at https://my.teneo.engine.com/mywebapp/
If you want to access the linguistic processor and have its response formatted by the JSP “x.jsp
” located in “/WEB-INF/views
” (“/views
” in Teneo Studio), you should add the name of the JSP file without its extension as the value of the request parameter “viewname”, which in case of a GET request will be
https://my.teneo.engine.com/mywebapp/?viewname=x
If you want to bypass the linguistic processor and have the response formatted by the JSP “y.jsp
” located in the application root folder (“/
” in Teneo Studio), you should add the full name of the JSP to the URL of the Teneo engine, which in this case will be
https://my.teneo.engine.com/mywebapp/y.jsp
It is up to the client software code to sustain the backend session in both cases.
Passing data between JSPs and global session variables
Inside a JSP you can access the so-called script bindings via the session attribute “EngineSessionData
”, as illustrated in the following method:
private static ImmutableScriptBindingsI getScriptBindings(final HttpSession session) {`
final ImmutableSessionDataI engineSessionData;
synchronized(session) {
engineSessionData = (ImmutableSessionDataI)session.getAttribute("EngineSessionData");
}
return engineSessionData!=null ? engineSessionData.getScriptBindings() : null;
}
Further you can use the script binding to access any global session variable existing in the session inside a JSP. For instance, if you have a java.util.Map
typed global session variable “myJspMapVariable
” mapping strings to arrays of strings, you can access it as in this example:
ImmutableScriptBindingsI scrb = getScriptBindings(session);
Map<String,String[]> myJspMapVariable = (Map<String,String[]>)scrb.get("myJspMapVariable");
Then you can read and write the content of “myJspMapVariable
” inside both your JSP and you Teneo solution scripts synchronizing it properly, for example:
String[] myExistingValue, newObject = new String[10];
synchronized(myJspMapVariable) {
myExistingValue = myJspMapVariable.get("myKey");
myJspMapVariable.put("myNewKey", newObject);
}
IMPORTANT: if the JSP with the above code is installed in the application root folder (and thus requests sent to it bypass the language processor), the request sent to that JSP may NOT be the first request of the session. This limitation is due to the fact and only the linguistic processor can create global session variables. It should be taken into consideration when developing the business logic using this kind of JSPs.
Attached is an JSP example illustrating that logic. It adds the request parameters with their values to the global session variable “myJspMapVariable
” which should be defined in the solution, for instance as follows:
JSP code:
<%@page contentType="text/plain; charset=UTF-8" pageEncoding="UTF-8" %>
<%@page trimDirectiveWhitespaces="true" %>
<%@page import="com.artisol.teneo.engine.core.engine.ImmutableSessionDataI"%>
<%@page import="com.artisol.teneo.engine.core.script.ImmutableScriptBindingsI"%>
<%@page import="java.util.Map"%>
<%@page import="javax.servlet.http.HttpSession"%>
<%@include file="/WEB-INF/views/utils_tieapi.jsp"%>
<%!
private static ImmutableScriptBindingsI getScriptBindings(final HttpSession session) {
final ImmutableSessionDataI engineSessionData;
synchronized(session) {
engineSessionData = (ImmutableSessionDataI)session.getAttribute("EngineSessionData");
}
return engineSessionData!=null ? engineSessionData.getScriptBindings() : null;
}
%><%
setCorsHeaders(request,response);
String result = null;
Map<String,String[]> parameterMap = request.getParameterMap();
if (parameterMap.isEmpty()) result = "OK";
else {
final ImmutableScriptBindingsI scriptBindings = getScriptBindings(session);
if (scriptBindings==null) result = "Failure to retrieve script bindings";
else {
try {
final Map<String,String[]> myJspMapVariable = (Map<String,String[]>)scriptBindings.get("myJspMapVariable");
if (myJspMapVariable==null) result = "Missing global session variable [myJspMapVariable]";
else {
synchronized(myJspMapVariable) {
myJspMapVariable.putAll(parameterMap);
}
result = "OK";
}
} catch (final Exception ex) {
result = "Failure to handlde global session variable [myJspMapVariable]: " + ex;
}
}
}
%><%=result%>
If you have any questions, please post a comment below.