Those JSON classes that just got added in the last patch....

98 views
Skip to first unread message

Adrian Williamson

unread,
Jan 19, 2018, 3:41:00 AM1/19/18
to openroa...@googlegroups.com

Hi,

 

Today I need to write some software to make and consume JSON RPC calls.

 

I get this type of output returned from the JSON URL:

 

{"PPSN":"1234567T","FirstName":"Joe","Surname":"Bloggs","BirthSurname":"BLoggs","MothersBirthSurname":"Doe","Gender":"Male","Nationality":"UK","CivilStatus":"Married","DateOfMarriage":"20080531","SafeRegistrationLevel2":true,"DateOfDeath":"","DeceasedIndictor":false,"IsPPSNPurged":false}'

 

So when I found all those new JSON objects I thought – that’s handy I do not need to write all the code to marshal datatypes.

 

But I found two problems which caused me to pause.

 

  1. JsonRPCRequest Method

 

       jsonstring = 'http://mockdspapi.cloudapp.net/api/client/1234567T/19800101';      

       //httpresponse is a stringobject mapped to an entryfield.

       httpresponse = JsonHandler.JsonRpcRequest(request = jsonstring);

 

Which returns:

 

{"error":{"data":"Invalid value. (offset: 0)","message":"Parse error","code":-32700},"jsonrpc":"2.0"}

 

Is this not what  the method JsonRPCRequest()  is for?

 

Using the WinHTTP external library this works i.e. I get my JSON string above returned:

 

    http.Open('GET','http://mockdspapi.cloudapp.net/api/client/1234567T/19800101',FALSE);

    http.Send();

    httpresponse = http.ResponseText;

 

 

  1. Unpacking the JSON data into an OpenROAD class.

 

I wrote:

 

declare

    jsonmanager = jsonhandler;

    jsonstring = StringObject;

    JV = JSONValue;

enddclare

begin

.

.

.

       JV = jsonmanager.Parse(json = httpresponse);

       jsonmanager.JsonObject2Object(jsonobj = JV , existing_obj = citizen );

        //jsonerror is a field on the form

       jsonerror = jsonmanager.ErrorText;

 

       Field(citizen).UpdField();

 

End;

 

 

So citizen points to a matrixfield which is mapped to a userclass called 'dspdataset'.

 

Each of the attributes have the same name as the tag in JSON string

 

e.g. Citizen.PPSN

 

But I get the following error:

 

Class 'dspdataset' does not have or allow setting of attribute 'DeceasedIndictor'.

 

That’s got a value of ‘false’ – so I deleted that from the JSON string, then it complained about the other Boolean so I deleted that, then it complained about one of the varchars.

 

It was at that point I thought – I’m not doing something right here.

 

Anyone want to give me a nudge in the right direction?

 

Thanks

 

Adrian

 

 

 

Adrian Williamson

unread,
Jan 19, 2018, 3:42:50 AM1/19/18
to openroa...@googlegroups.com
I wonder is Google Groups is not keen on HTML formatted emails....

From: Adrian Williamson [mailto:adrian.w...@rationalcommerce.com]
Sent: 18 January 2018 13:59
To: 'openroa...@googlegroups.com' <openroa...@googlegroups.com>
Subject: Those JSON classes that just got added in the last patch....

Hi,

Today I need to write some software to make and consume JSON RPC calls.

I get this type of output returned from the JSON URL:

{"PPSN":"1234567T","FirstName":"Joe","Surname":"Bloggs","BirthSurname":"BLoggs","MothersBirthSurname":"Doe","Gender":"Male","Nationality":"UK","CivilStatus":"Married","DateOfMarriage":"20080531","SafeRegistrationLevel2":true,"DateOfDeath":"","DeceasedIndictor":false,"IsPPSNPurged":false}'

So when I found all those new JSON objects I thought – that’s handy I do not need to write all the code to marshal datatypes.

But I found two problems which caused me to pause.

1. JsonRPCRequest Method

jsonstring = 'http://mockdspapi.cloudapp.net/api/client/1234567T/19800101';
//httpresponse is a stringobject mapped to an entryfield.
httpresponse = JsonHandler.JsonRpcRequest(request = jsonstring);

Which returns:

{"error":{"data":"Invalid value. (offset: 0)","message":"Parse error","code":-32700},"jsonrpc":"2.0"}

Is this not what the method JsonRPCRequest() is for?

Using the WinHTTP external library this works i.e. I get my JSON string above returned:

http.Open('GET','http://mockdspapi.cloudapp.net/api/client/1234567T/19800101',FALSE);
http.Send();
httpresponse = http.ResponseText;


2. Unpacking the JSON data into an OpenROAD class.

Adrian Williamson

unread,
Jan 19, 2018, 3:42:55 AM1/19/18
to openroa...@googlegroups.com

Not sure why this message did not make the lists…

 

From: Adrian Williamson [mailto:adrian.w...@rationalcommerce.com]
Sent: 18 January 2018 13:59
To: 'openroa...@googlegroups.com' <openroa...@googlegroups.com>
Subject: Those JSON classes that just got added in the last patch....

 

Hi,

 

Today I need to write some software to make and consume JSON RPC calls.

 

I get this type of output returned from the JSON URL:

 

{"PPSN":"1234567T","FirstName":"Joe","Surname":"Bloggs","BirthSurname":"BLoggs","MothersBirthSurname":"Doe","Gender":"Male","Nationality":"UK","CivilStatus":"Married","DateOfMarriage":"20080531","SafeRegistrationLevel2":true,"DateOfDeath":"","DeceasedIndictor":false,"IsPPSNPurged":false}'

 

So when I found all those new JSON objects I thought – that’s handy I do not need to write all the code to marshal datatypes.

 

But I found two problems which caused me to pause.

 

  1. JsonRPCRequest Method

 

       jsonstring = 'http://mockdspapi.cloudapp.net/api/client/1234567T/19800101';      

       //httpresponse is a stringobject mapped to an entryfield.

       httpresponse = JsonHandler.JsonRpcRequest(request = jsonstring);

 

Which returns:

 

{"error":{"data":"Invalid value. (offset: 0)","message":"Parse error","code":-32700},"jsonrpc":"2.0"}

 

Is this not what  the method JsonRPCRequest()  is for?

 

Using the WinHTTP external library this works i.e. I get my JSON string above returned:

 

    http.Open('GET','http://mockdspapi.cloudapp.net/api/client/1234567T/19800101',FALSE);

    http.Send();

    httpresponse = http.ResponseText;

 

 

  1. Unpacking the JSON data into an OpenROAD class.

Adrian Williamson

unread,
Jan 19, 2018, 4:28:49 AM1/19/18
to openroa...@googlegroups.com

Ah there you are…

 

From: openroa...@googlegroups.com [mailto:openroa...@googlegroups.com] On Behalf Of Adrian Williamson


Sent: 18 January 2018 13:59
To: openroa...@googlegroups.com

--
You received this message because you are subscribed to the Google Groups "OpenROAD Users Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openroad-user...@googlegroups.com.
To post to this group, send email to openroa...@googlegroups.com.
Visit this group at https://groups.google.com/group/openroad-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/openroad-users/001b01d39064%246e1bee90%244a53cbb0%24%40rationalcommerce.com.
For more options, visit https://groups.google.com/d/optout.

Bodo Bergmann

unread,
Jan 19, 2018, 4:40:21 AM1/19/18
to openroa...@googlegroups.com

Hi Adrian,

 

1.

The request you provided to the JsonRpcRequest() method is a URL rather than the JSON-RPC 2.0 request string (see http://www.jsonrpc.org/specification).

The parser detects that the request (your “jsonstring” variable) is not in JSON format (which should be contained in a StringObject).

Anyway, the method is provided to call 4GL procedures in an OpenROAD Server application via a JSON-RPC 2.0 interface (i.e. via the new OpenROADJSONRPC servlet).

The methods offers a lot of new features and removes the existing limitations for such calls, e.g.:

  • 4GL procedures can have a return value. This value will be represented in the "result" of the response message.
  • Multiple/circular references are preserved in objects passed as parameters and returned. They will be represented using "$id" and "$ref" meta properties.
  • Subclass objects/arrays can be passed to parameters of a defined class/array type.
  • Objects of system classes can be passed.
  • The serializable attributes for classes are configurable.
  • Offers different ways to return values to the caller (return value and/or byref).
  • A batch of requests is possible to be passed to the server with one call (JSON array containing request objects).
  • The actual procedure to be executed will be passed in the method parameter of the JSON-RPC request string.
  • Language independent (like the existing XML interface, but without its limitations)

We have started to provide some demos on https://github.com/ActianCorp/OpenROAD_json

We will also provide more detailed usage information using a blog post.

 

2.

The boolean values (true/false) are definitely able to be parsed (they are getting represented as JsonNumber) and assigned to an OpenROAD object’s numeric attribute, as long as they are public.

Could it be that the attributes are private?
The JsonObject2Object() method can only assign values to public attributes.

 

BTW: You do not have to declare a JsonHandler variable, you can immediately use the JsonHandler attribute of the SessionObject class (CurSession.JsonHandler).

 

HTH.

 

Kind regards,

Bodo.

 

Bodo Bergmann

Principal Software Engineer

Actian | Engineering

Phone: +49.6103.3033.734

www.actian.com

GESELLSCHAFTSANGABEN: Actian Germany GmbH | Geschäftsführer: Stephen Mark Padgett, Suzanne Gisborn, Gregory S. Hampton

Sitz der Gesellschaft: Hamburg| Handelsregister: Amtsgericht Hamburg | HRB 135991| USt-IdNr: DE252449897

 

From: openroa...@googlegroups.com [mailto:openroa...@googlegroups.com] On Behalf Of Adrian Williamson
Sent: Thursday, January 18, 2018 2:59 PM
To: openroa...@googlegroups.com
Subject: [openroad-users] Those JSON classes that just got added in the last patch....

 

Hi,

--

Adrian Williamson

unread,
Jan 19, 2018, 5:01:43 AM1/19/18
to openroa...@googlegroups.com

Hi Bodo,

 

What would you call the mechanism that I’ve sited in question (1) – is it JSON over REST?

 

Is it possible to use the JsonRpcRequest method to call any other platform offering JSON-RPC?

 

Or is it only supported to call the OR App server?

 

I’m not worried about that at the moment but I thought I’d ask. (When App Server first turned up and I commissioned  a SOAP wrapper for it I recall asking Ingres at the time – so how do we make SOAP calls out to other platforms)

 

So, #2 – all the attributes of the class are public – I’ve attached my ‘working notes’ on this.

 

TestDSP Frame – is where I’ve been kicking the tires.

DSPDataSet – is the class that the matrix field is mapped to.

 

It should run for you – the URL is in the public domain.

 

Cheers

 

Adrian

DSPAPI.exp

Bodo Bergmann

unread,
Jan 19, 2018, 6:13:09 AM1/19/18
to openroa...@googlegroups.com

Hi Adrian,

 

1.

It seams that you just GET some JSON from a URL, you do not provide anything (method with parameters).

The JsonRpcRequest() method of the RemoteServer class should be able to send JSON-RPC 2.0 requests to other (non-OpenROAD) service providers.

We are also currently working on developing additional system class(es) to allow communication with URLs (similar to the “curl” utility).

 

2.

Just a quick look at the userclass DSPDataSet showed me that the datatypes and actual data do not match:

 

DeceasedIndicator is varchar(60) – Do you really want to assign a Boolean (numeric) value to it?

DateOfMarriage is a date - "20080531" is not a valid date format (at least not on my machine) – you should use ISO88601 format: "2008-05-31"

Formatting according your II_DATE_FORMAT should also work, so if your date format allows to enter 20080531 into a date field then you should be fine.


As you probably cannot change the service that provides the data, you will have to change your class:

DeceasedIndicator : smallint

DateOfMarriage: varchar(8)

 

Running the frame gave a different result (which of course could not be converted):

{"Code":"BAAS2","Message":"Not a Valid PPS 1234567F format, e.g. 9999999xx is a valid PPS"}

 

Therefore I used the JSON string you had written in your original email – and detected a problem in our implementation:

The JsonObject2Object() method only works if the member names are lowercase (The method succeeded after I changed the JSON string accordingly).

I am going to fix this.

 

Bodo.

Adrian Williamson

unread,
Jan 19, 2018, 7:03:30 AM1/19/18
to openroa...@googlegroups.com

Hi,

 

That’s got a value of ‘false’ – so I deleted that from the JSON string, then it complained about the other Boolean so I deleted that, then it complained about one of the varchars.”

 

I had not got to the stage where I was worried about the data types – I had been deleting the Booleans until it reached a plain varchar – when it failed at that I started writing the original note for the forum.

 

The varchar failure is the ‘case issue’ you have identified.

 

As for the date – this works:

 

method ConvertDate(txt = varchar(2000) not null) =

declare

       noquotes = varchar(2000) not null;

enddeclare

begin

       noquotes = CurObject.StripQuotes(txt = txt);

       return left(noquotes,4)+'-'+ left(right(noquotes,4),2) + '-'+ right(noquotes,2);

end;

 

As in the native text-to-date conversion works.

 

I’ve had to write my own JSONParser for now – getting a patch rolled out for this customer in the timescales needed for the release I’m working on would be challenging.

 

Cheers

 

Adrian

PS Being able to call SOAP might be nice too – or is SOAP too last century now?

Cristian Ianculovici

unread,
Jan 23, 2018, 5:58:45 AM1/23/18
to openroa...@googlegroups.com

I’m hoping that this post would clarify more how JSON / JSON-RPC works…

 

https://www.actian.com/company/blog/simplifying-development-openroad-json-rpc/

 

This should come along with Bodo’s example link on github: https://github.com/ActianCorp/OpenROAD_json

Adrian Williamson

unread,
Jan 24, 2018, 5:08:26 PM1/24/18
to openroa...@googlegroups.com

Hi Cristian,

 

I had looked at the those web pages, but in this case I wanted to decode JSON given to me by an HTTP Get on a URL (as Bodo pointed out).

 

I’ve had to write my own JSON to OpenROAD conversion classes as I will not be able to get this latest patch onto the target site in Q1.

 

Once we get the go-ahead to put any patch in place, I’ll switch over to the system classes.

 

Cheers

 

Adrian

Bodo Bergmann

unread,
Aug 20, 2021, 6:00:15 AM8/20/21
to openroa...@googlegroups.com

As a follow-up on this discussion, I want to mention, that with OpenROAD 11.2 there is no need to use any external library (like WinHTTP) to get/put data from/to URLs.
You can use the new UrlConnection class to send HTTP GET/PUT requests and directly get the data retrieved into a StringObject or a file
(if the data is JSON you can then parse it using the JsonHandler class).
See https://docs.actian.com/openroad/11.2/index.html#page/LangRef%2FUrlConnection_Class.htm%23 .

 

There is also a video/course about using the UrlConnection class in the Actian Academy: https://academy.actian.com/openroad-using-the-urlconnection-class

 

Best regards,
Bodo.

Paul White

unread,
Nov 12, 2021, 4:17:02 AM11/12/21
to openroa...@googlegroups.com

The link has been updated

https://academy.actian.com/openroad-urlconnection-class-connecting-openroad-to-the-outside-world

Best approach is to navigate to  https://academy.actian.com

Then filter for OpenROAD content.

Paul

Reply all
Reply to author
Forward
0 new messages