08.09.2017, 11:11 | #1 |
Участник
|
gideonvos: Execute COBOL & Fortran in Dynamics AX
Источник: https://gideonvos.wordpress.com/2016...n-dynamics-ax/
============== A coworker of mine was pondering the idea of integrating R for data analytics into AX the other day and that got me wondering how we could make that work. Say you have some legacy code in COBOL or Fortran, or maybe some algorithm in a Python script which you want to use from within Dynamics AX. Your options would be some form of integration if supported, or file extract and upload from AX to the legacy platform; or you could study Python and redo it all in X++. Let’s get started. Our first stop is to register for a demo account at Sphere Engine. This gives us 1000 credits for execution. Sphere Engine has over 60 online compilers and supports languages ranging from COBOL to Fortran, C++ to VB.NET and even some lesser known languages like Lua and Erlang. Sadly I do not see R listed (yet!). It also allows the online execution of code, and supports input and output of parameters. It seems to be aimed at training and testing – so your mileage may vary. But we’ll give it a go as a test. For production, you would want to replicate what they do by hosting your legacy environment behind an API wrapper. Same idea. The Sphere API provided is a simple REST interface with JSON. Below I’ve coded up a simple helper class with a number of static methods: class SphereEngineAPI { public static str SphereLanguages() { System.Net.HttpWebRequest myRequest; System.IO.Stream s; System.IO.StreamReader sr; str jsonResponse = ""; myRequest = System.Net.WebRequest::Create("http://api.compilers.sphere-engine.com/api/v3/languages?access_token="); myRequest.Method = "POST"; myRequest.Timeout = 30000; s = myRequest.GetResponse().GetResponseStream(); sr = new System.IO.StreamReader(s); jsonResponse = sr.ReadToEnd(); s.Close(); sr.Close(); return jsonResponse; } public static str SphereSubmit(str jsonInput) { System.Net.HttpWebRequest myRequest; System.IO.Stream s; System.IO.StreamWriter sw; System.IO.StreamReader sr; str jsonResponse = ""; myRequest = System.Net.WebRequest::Create("http://api.compilers.sphere-engine.com/api/v3/submissions?access_token="); myRequest.Method = "POST"; myRequest.Timeout = 30000; myRequest.ContentType = "application/json"; s = myRequest.GetRequestStream(); sw = new System.IO.StreamWriter(s); sw.Write(jsonInput); sw.Close(); s.Close(); s = myRequest.GetResponse().GetResponseStream(); sr = new System.IO.StreamReader(s); jsonResponse = sr.ReadToEnd(); s.Close(); sr.Close(); return jsonResponse; } public static int SphereStatus(str submissionCode) { System.Net.HttpWebRequest myRequest; System.IO.Stream s; System.IO.StreamWriter sw; System.IO.StreamReader sr; str jsonResponse = ""; Newtonsoft.Json.Linq.JObject j; int statusCode = 0; myRequest = System.Net.WebRequest::Create("http://api.compilers.sphere-engine.com/api/v3/submissions/" + submissionCode + "?withOutput=1&access_token="); myRequest.Method = "GET"; myRequest.Timeout = 30000; s = myRequest.GetResponse().GetResponseStream(); sr = new System.IO.StreamReader(s); jsonResponse = sr.ReadToEnd(); s.Close(); sr.Close(); j = Newtonsoft.Json.Linq.JObject::Parse(jsonResponse); statusCode = str2Int(j.Property("status").Value.ToString()); return statusCode; } public static str SphereOutput(str submissionCode) { System.Net.HttpWebRequest myRequest; System.IO.Stream s; System.IO.StreamWriter sw; System.IO.StreamReader sr; str jsonResponse = ""; Newtonsoft.Json.Linq.JObject j; str result = ""; myRequest = System.Net.WebRequest::Create("http://api.compilers.sphere-engine.com/api/v3/submissions/" + submissionCode + "?withOutput=1&access_token="); myRequest.Method = "GET"; myRequest.Timeout = 30000; s = myRequest.GetResponse().GetResponseStream(); sr = new System.IO.StreamReader(s); jsonResponse = sr.ReadToEnd(); s.Close(); sr.Close(); j = Newtonsoft.Json.Linq.JObject::Parse(jsonResponse); result = j.Property("output").Value.ToString().Replace("\n",""); return result; } public static str SphereTest() { System.Net.HttpWebRequest myRequest; System.IO.Stream s; System.IO.StreamReader sr; str jsonResponse = ""; myRequest = System.Net.WebRequest::Create("http://api.compilers.sphere-engine.com/api/v3/test?access_token="); myRequest.Method = "POST"; myRequest.Timeout = 30000; s = myRequest.GetResponse().GetResponseStream(); sr = new System.IO.StreamReader(s); jsonResponse = sr.ReadToEnd(); s.Close(); sr.Close(); return jsonResponse; } } SphereTest() executes the API test routine, to make sure everything is up and running. SphereLanguages() returns a JSON list of supported languages and their corresponding ID’s. Note down the ID for the language you require. Our example is in Pascal, so I’ll select 2. SphereSubmit() submits a job for compilation and execution. You pass your API Key, language ID, and source code in JSON format. SphereStatus() checks the execution status of the job. SphereOutput() returns the result, if one is returned from your legacy code. Inputs we will pass in our example runnable class. The code below is a simple test class which runs through the API calls listed above. In our example Pascal code, we send in the value 55 (you can send as many values as you want, really) and multiply that by 2, returning the result back to X++. class TestSphereClass { /// /// Runs the class with the specified arguments. /// /// The specified arguments. public static void main(Args _args) { str jsonResult; str jsonInput; str submissionID; Newtonsoft.Json.Linq.JObject j; str result = ""; // Test Sphere API is up and running jsonResult = SphereEngineAPI::SphereTest(); // get list of supported programming languages jsonResult = SphereEngineAPI::SphereLanguages(); // submit a Pascal program for execution. Takes a number as input and multiplies it by 2, then returns the result jsonInput = '{"language": 2,"sourceCode":"program test; var x: integer; begin readln(x); writeln(x * 2); end.", "input": "55"}'; jsonResult = SphereEngineAPI::SphereSubmit(jsonInput); j = Newtonsoft.Json.Linq.JObject::Parse(jsonResult); submissionID = j.Property("id").Value.ToString(); while (SphereEngineAPI::SphereStatus(submissionID) != 0) { // while not done, wait patiently... } // should check API for proper results (error code, failed compile) but add TODO result = SphereEngineAPI::SphereOutput(submissionID); } } Let’s run this in debug mode and see how we go: Tada! Execution completed and the result was correctly returned. This gives us one option to support legacy code, albeit with some limitations. Long live Pascal! Источник: https://gideonvos.wordpress.com/2016...n-dynamics-ax/
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
|
|