Review 1) how DivConq connects to MUMPS, 2) how to create a request, 3) the request-response flow, 4) Java example code, 5) schema example declaration, 6) MUMPS example code, 7) JSON and interoperability
3. Linux, Windows Linux Box
or OS X Box
Java App SSH
MUMPS
w/ DivConq
Java code connects to the MUMPS database via an SSH connection. This keeps
the data secure while in transit.
4. Linux Box
Java App SSH
MUMPS
w/ DivConq
Of course there is no reason why Java cannot run on the same box. SSH is still
used, connecting over the loopback network interface.
5. Linux, Windows Linux Box
or OS X Box
Session
Java App
MUMPS
w/ DivConq
Channels
One SSH session is used. Multiple SSH channels enable greater throughput.
Typically DivConq uses three channels, which creates three MUMPS processes.
6. Linux, Windows Linux Box
or OS X Box
Java App
MUMPS
w/ DivConq
Communication is Request-Response only, requests are originated in Java and
responses are supplied by MUMPS code.
By using three channels, up to three requests can be processed at once. A long
running request does not hold up other requests.
7. Structure
Name: [Stored Procedure Name]
Kind: “Update” or “Query”
Params: [any JSON-like data structure]
Example
Name: “dctListPeople”
Kind: “Query”
Params: { “MinAge”: 30, “MaxAge”: 48 }
Your code builds a request and submits it to DivConq’s database interface. A
request must have a name and a kind, parameters are optional. Name = name of
the stored procedure. Kind will be Update only if it changes data within the
database (Insert, Update, Delete), otherwise use Query.
8. Java App MUMPS
DivConq
w/ DivConq
Database Interface MUMPS
Process
Request
Your Queue
MUMPS
Database
Request
Workers
Application
Verifier Process
Code #1
Response MUMPS
Verifier
Process
DivConq Schema
#1 - Your code builds a request and submits it. Request submission is
asynchronous, so you also must provide a callback to handle the result.
9. Java App MUMPS
DivConq
w/ DivConq
Database Interface MUMPS
Process
Request
Your Queue
MUMPS
Database
Request
Workers
Application
Verifier Process
Code #1
Response MUMPS
Verifier
Process
#2
DivConq Schema
#2 – Your request is verified, including validating the parameters with what is
declared in the schema.
10. Java App MUMPS
DivConq
w/ DivConq
Database Interface MUMPS
Process
#3 Request
Your Queue
MUMPS
Database
Request
Workers
Application
Verifier Process
Code #1
Response MUMPS
Verifier
Process
#2
DivConq Schema
#3 – If verification passes your request is put on to the request queue.
11. Java App MUMPS
DivConq
w/ DivConq
Database Interface MUMPS
Process
#3 Request #4
Your Queue
MUMPS
Database
Request
Workers
Application
Verifier Process
Code #1
Response #4 MUMPS
Verifier
Process
#2
DivConq Schema
#4 – When a database worker (channel) is available, it takes the request from the
queue and sends it to MUMPS.
12. Java App MUMPS
DivConq
w/ DivConq
Database Interface MUMPS
Process
#3 Request #4
Your Queue
MUMPS
Database
Request
Workers
Application
Verifier Process
Code #1
Response #4 MUMPS
Verifier and Process
#2 #5
DivConq Schema
#5 – That worker then reads (blocking) the result and any accompanying
debug/error messages.
13. Java App MUMPS
DivConq
w/ DivConq
Database Interface MUMPS
Process
#3 Request #4
Your Queue
MUMPS
Database
Request
Workers
Application
Verifier Process
Code #1
Response #4 MUMPS
Verifier and Process
#2 #5
#6
DivConq Schema
#6 – The response is verified by validating the (JSON-like) result with what is
declared in the schema. If response does not validate, error messages are
added to messages collected from MUMPS.
14. Java App MUMPS
DivConq
w/ DivConq
Database Interface MUMPS
Process
#3 Request #4
Your Queue
MUMPS
Database
Request
Workers
Application
Verifier Process
Code #1
Response #4 MUMPS
#7 Verifier and Process
#2 #5
#6
DivConq Schema
#7 – The response and any debug/error messages are delivered to your code via
a the callback you provided at submission.
16. Example
RecordStruct ages = new RecordStruct();
ages.setField("MinAge", 3);
ages.setField("MaxAge", 8);
Parameters are composed of JSON-like structures. In DivConq use RecordStruct
to compose records (aka Objects in JSON) and ListStruct to compose lists (aka
Arrays in JSON). Records (aka Objects) have fields – just as in JSON – the field
values may be lists, records or scalars. Above we are using numeric scalars.
17. Example
RecordStruct ages = new RecordStruct();
ages.setField("MinAge", 3);
ages.setField("MaxAge", 8);
QueryRequest request = new QueryRequest("dctListPeople", ages);
Create the request object. The Name and Kind are required. Kind can be
derived from the class name (QueryRequest vs UpdateRequest). Name is the
first parameter to the constructor. The parameters, optionally, follow the name in
the call to the constructor.
18. ObjectCallback callback = new ObjectCallback() {
@Override
public void process(ObjectResult result) {
System.out.println("Messages:");
TestDb.printPretty(result.getMessages());
System.out.println();
System.out.println("Result:");
TestDb.printPretty(result.getResult());
}
};
You also need to create a callback object. This example callback simply prints
the messages and results to the console as JSON output. You may call
“getResultAsRec” (RecordStruct) or “getResultAsList” (ListStruct) to process the
result using DivConq’s JSON-like API.
19. Example
RecordStruct ages = new RecordStruct();
ages.setField("MinAge", 3);
ages.setField("MaxAge", 8);
QueryRequest request = new QueryRequest("dctListPeople", ages);
ObjectCallback callback = new ObjectCallback() ...
Hub.instance.getDatabase().submit(request, callback);
Finally, to get the request to the database call the “submit” method and pass in
the request and callback. Your result, even if it is just an error message, will be
presented in the callback’s “process” method.
20. <Procedure Name="dctListPeople" Execute="listPeople^dctToyTest">
<Description>
Get a list of names of all people in test data.
Optionally apply an age range filter
</Description>
<RecRequest>
<Field Name="MinAge" Type="Integer" />
<Field Name="MaxAge" Type="Integer" />
</RecRequest>
<ListResponse Type="String" />
</Procedure>
A DivConq schema file holds custom data types, table declarations, stored
procedure declarations and more. Above is just one snipped from the schema file
showing the declaration for the stored procedure “dctListPeople”.
21. <Procedure Name="dctListPeople" Execute="listPeople^dctToyTest">
<Description>
Get a list of names of all people in test data.
Optionally apply an age range filter
</Description>
<RecRequest>
<Field Name="MinAge" Type="Integer" />
<Field Name="MaxAge" Type="Integer" />
</RecRequest>
<ListResponse Type="String" />
</Procedure>
Key elements here are the Request and Response which provide the validation
rules for this procedure. Expect either a RecRequest (RecordStruct) or a
ListRequest (ListStruct) for request – those are our options for request
parameters. Likewise, expect a RecResponse or a ListResponse for the
response.
22. Request (Params) Examples
a: { “MinAge”: 30, “MaxAge”: 48 }
b: { “MaxAge”: 48 }
c: null
Response Examples
a: [ “Jim”, “Beth”, “Sandy” ]
b: [ ]
Note that the params are not marked as required (in the schema), so any of the
three examples for request are valid.
The response is a list of strings. No minimum is given, so a list of zero is valid.
23. Linux Box
Windows
Java App w/ DivConq MUMPS
User w/
Web Browser MUMPS
Your Process
DivConq
Application
Database
Code MUMPS
Interface
External Process
App on
DivConq MUMPS
Linux
Web Server DivConq Schema Process
(HTTP + Web
Sockets)
There are many reasons to “why JSON?” – one of the best is interoperability with
web apps and other external applications. Through HTTP or WebSocket calls
JSON parameters can be sent and JSON results can be returned. To minimize
interoperability hassles DivConq favors JSON-like structures throughout.
25. Java Request (Params)
{ “MinAge”: 30, “MaxAge”: 48 }
MUMPS Params
Params(“MinAge”)=30
Params(“MaxAge”)=48
JSON can be adopted to MUMPS structures without much effort, details in a
future presentation. As far as this overview is concerned, the key point is that
JSON-like structures get transformed into MUMPS structures before the stored
procedure is called.
26. Schema Declaration
<Procedure Name="dctListPeople" Execute="listPeople^dctToyTest">
MUMPS Code
listPeople ;
;
w StartList ; start list of people
w ScalarStr_“Jim” ; write a scalar
w ScalarStr_“Beth” ; write another scalar
w EndList ; end list of people
;
quit
The schema tells us what MUMPS routine and function to call. Above is a hint at
what the code has to do – return a list of strings. Note how the result from the
procedure is sent back to Java by using the “write” command.
27. listPeople n id,minage,maxage,age
s minage=Params("MinAge"),maxage=Params("MaxAge")
;
w StartList ; start list of people (name only)
;
f s id=$o(^dctData("People",id)) q:id="" d
. s age=^dctData("People",id,"Age")
. i (minage'="")&(age<minage) q
. i (maxage'="")&(age>maxage) q
. w ScalarStr_^dctData("People",id,"Name")
;
w EndList ; end list of people
;
quit
You’ll need to review the dctToyTest routine to get the details on this example, but
what you can see here is that we loop through all the people an apply the
(optional) filter. People who are not filtered are returned as scalars (just names)
in the list.
28. ObjectCallback callback = new ObjectCallback() {
@Override
public void process(ObjectResult result) {
if (result.hasErrors()) {
System.out.println("Error in List");
return;
}
ListStruct names = result.getResultAsList();
for (Struct item : names.getItems())
System.out.println("Name: " + item.toString());
}
};
Back in Java you can process the result via ListStruct by looping all the items.
We know, because of the schema validation and the call to “hasErrors”, that our
items are all just strings. There are a few ways to work with a string item, but
certainly calling “toString” will work.
29. There is a lot more to learn about stored procedures, but now you have an
overview of how it works as well as some of the design philosophy.