divconq framework’s mumps api - amazon s3stored... · java code connects to the mumps database...
TRANSCRIPT
DivConq Framework’s MUMPS API
Overview of DivConq database handling and Request-Response flow
Linux Box Linux, Windows or OS X Box
Java App w/ DivConq
MUMPS SSH
Java code connects to the MUMPS database via an SSH connection. This keeps
the data secure while in transit.
Linux Box
Java App w/ DivConq
MUMPS SSH
Of course there is no reason why Java cannot run on the same box. SSH is still
used, connecting over the loopback network interface.
Linux Box Linux, Windows or OS X Box
Java App w/ DivConq
MUMPS Session
One SSH session is used. Multiple SSH channels enable greater throughput.
Typically DivConq uses three channels, which creates three MUMPS processes.
Channels
Linux Box Linux, Windows or OS X Box
Java App w/ DivConq
MUMPS
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.
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.
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 }
Java App w/ DivConq
MUMPS
#1 - Your code builds a request and submits it. Request submission is
asynchronous, so you also must provide a callback to handle the result.
DivConq Database Interface
Your Application
Code
Request Queue
Datab
ase W
orkers
MUMPS Process
MUMPS Process
MUMPS Process
#1
DivConq Schema
Request Verifier
Response Verifier
Java App w/ DivConq
MUMPS
#2 – Your request is verified, including validating the parameters with what is
declared in the schema.
DivConq Database Interface
Your Application
Code
Request Queue
Datab
ase W
orkers
MUMPS Process
MUMPS Process
MUMPS Process
#1
DivConq Schema
Request Verifier
Response Verifier
#2
Java App w/ DivConq
MUMPS
#3 – If verification passes your request is put on to the request queue.
DivConq Database Interface
Your Application
Code
Request Queue
Datab
ase W
orkers
MUMPS Process
MUMPS Process
MUMPS Process
#1
DivConq Schema
Request Verifier
Response Verifier
#2
#3
Java App w/ DivConq
MUMPS
#4 – When a database worker (channel) is available, it takes the request from the
queue and sends it to MUMPS.
DivConq Database Interface
Your Application
Code
Request Queue
Datab
ase W
orkers
MUMPS Process
MUMPS Process
MUMPS Process
#1
DivConq Schema
Request Verifier
Response Verifier
#2
#3 #4
#4
Java App w/ DivConq
MUMPS
#5 – That worker then reads (blocking) the result and any accompanying
debug/error messages.
DivConq Database Interface
Your Application
Code
Request Queue
Datab
ase W
orkers
MUMPS Process
MUMPS Process
MUMPS Process
#1
DivConq Schema
Request Verifier
Response Verifier
#2
#3 #4
#4
and
#5
Java App w/ DivConq
MUMPS
#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.
DivConq Database Interface
Your Application
Code
Request Queue
Datab
ase W
orkers
MUMPS Process
MUMPS Process
MUMPS Process
#1
DivConq Schema
Request Verifier
Response Verifier
#2
#3 #4
#4
and
#5 #6
Java App w/ DivConq
MUMPS
#7 – The response and any debug/error messages are delivered to your code via
a the callback you provided at submission.
DivConq Database Interface
Your Application
Code
Request Queue
Datab
ase W
orkers
MUMPS Process
MUMPS Process
MUMPS Process
#1
DivConq Schema
Request Verifier
Response Verifier
#2
#3 #4
#4
and
#5 #6
#7
Request-Response handling within Java
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.
Example RecordStruct ages = new RecordStruct(); ages.setField("MinAge", 3); ages.setField("MaxAge", 8);
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.
Example RecordStruct ages = new RecordStruct(); ages.setField("MinAge", 3); ages.setField("MaxAge", 8); QueryRequest request = new QueryRequest("dctListPeople", ages);
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.
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()); } };
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.
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);
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”.
<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.
<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>
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.
Request (Params) Examples a: { “MinAge”: 30, “MaxAge”: 48 } b: { “MaxAge”: 48 } c: null
Response Examples a: [ “Jim”, “Beth”, “Sandy” ] b: [ ]
Linux Box
Java App w/ DivConq MUMPS
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.
DivConq Database Interface
Your Application
Code
MUMPS Process
MUMPS Process
MUMPS Process DivConq Schema
Windows User w/
Web Browser
External App on Linux DivConq
Web Server (HTTP + Web
Sockets)
Request-Response handling within MUMPS
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.
Java Request (Params) { “MinAge”: 30, “MaxAge”: 48 }
MUMPS Params Params(“MinAge”)=30 Params(“MaxAge”)=48
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.
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
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.
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
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.
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()); } };
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.