0 Followers · 129 Posts

NET Framework (pronounced dot net) is a software framework developed by Microsoft that runs primarily on Microsoft Windows.

Official site.

.NET support in InterSystems Data Platform.

Question Mark Dashwood · Feb 10, 2023

Hi

I am upgrading our application from dotNet Framework to dotNet Core.

Prior to the upgrade I was able to connect to both my Cache & IRIS instances using the IRIS ADO.NET driver.

However, in dotNet Core, whilst I can connect to IRIS, I get the following error connecting to Cache.

InterSystems IRIS Provider is not compatible with Cache xDBC server
 

I am using the IRIS  driver from the Windows (x86-64) 2022.1 distribution (the one in dev\dotnet\bin\net5.0).

The cache version is Cache for Windows (x86-64) 2018.1.2

Thanks

4
0 820
Question Chenyang Fu · Jan 9, 2023

Product version

I try the 2021.2 2020.2 , they own have this issus

For this issus i have submit to dotnet , hope they can solve this or find the reson for this and solve this.

platform

ubuntu using unixOdbc dirver

Describe the problem you're observing:

using dotnet nuget System.Data.Odbc to connet the iris for some sql will have bug on linux,but it is ok on windows
and that driver is ok for other db type .
I have put a issue on dotnet also (dotnet/runtime#80015)
Is anyone can have a look for that

2
0 275
Article Wojciech Czyz · Nov 10, 2016 5m read

Integrating Cache with .net may be difficult, as we need to know both technologies and tools involved. Let’s follow the simplest possible example and see the pitfalls lurking on our way.

1. Creating .Net Assembly

.Net assembly is unit that contains compiled code and other resources.

Let’s create the simplest .Net assembly that will contain the code we want to execute.

We will use assembly of type Class Library, as we will use classes and their methods contained within. This type of assembly has .dll extension.

For this the easiest way is to use Visual Studio 2015, you can use free edition.

12
0 1941
Article Pierre-Yves Duquesnoy · Jan 27, 2021 29m read

Introduction {#Webinar:ImplementingIntegrationswith.NetorJava-Introduction}

InterSystems IRIS 2020.1 includes PEX (Production EXtension Framework) to facilitate the development of IRIS Interoperability productions with components written in Java or .NET.

Thanks to PEX, an integration developer with knowledge of Java or .NET can benefit from the power, scalability, and robustness of the InterSystems IRIS Interoperability framework and be productive in no time.

For an IRIS Interoperability framework expert, PEX makes it easy to enrich integrations with pre-existing Java- or .NET-language external components.

This tutorial will explore PEX and guide .NET developers along their first steps with PEX. The code is available at https://github.com/es-comunidad-intersystems/webinar-PE

The tutorial supplements the PEX documentation available online at https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=EPEX.

 

InterSystems IRIS Interoperability Architecture {#Webinar:ImplementarIntegracionescon.NetoJava-ArquitecturadeInteroperabilidadInterSystemsIRIS}

PEX allows you to choose the programming language (currently Java or .NET, and later Python) to implement any of the components (Business Service, Business Process, Business Operation, InboundAdapter, OutboundAdapter, Messages) that form an IRIS Interoperability production.

There are 3 main components of IRIS interoperability:

  • Business Services: Components that offer a service can be used from outside. Examples of Business Services are a REST Service and SOAP Web Service, but also a Service that reads and processes new files that have been written in a directory, a service that reads and processes rows of a database table, and/or a service that reads files via FTP, etc. The Business Service can have an associated Inbound Adapter, which takes care of the implementation details of a specific protocol (SQLInboundAdapter for reading SQL tables, FileInboundAdapter for reading files, etc.). The Business Service is responsible for processing the information, copying it to an IRIS Interoperability message, and sending the message to a Business Process or Business Operations and possibly waiting for a response if there is one.  
  • Business Operation: A component that receives an IRIS interoperability message and operates on an external system, possibly with the help of an OutboundAdapter that takes care of protocol implementation details (TCP, REST, SOAP, Files, SQL, etc.). The Business Operation may or may not return a response to the caller.  
  • Business Process: An orchestration process that, when receiving an IRS Interoperability message, can make processes and calls to one or more other business processes or operations to perform complex operations and/or return a message with information added to the Business Service that has sent it.

The components configuration is grouped in a "Production", an InterSystems IRIS class that contains the definition of all the integrations that start together when IRIS initiates and the configuration for each component of these integrations. It can be edited as an IRIS class or modified from the management portal.

 

PEX Architecture {#Webinar:ImplementarIntegracionescon.NetoJava-ArquitecturadePEX}

To run the .NET or Java code, InterSystems IRIS uses the corresponding Object Gateway. This Gateway can be instantiated locally or on a remote server.

Java and .Net Gateways {#Webinar:ImplementarIntegracionescon.NetoJava-LosJavay.NetGateways}

The Gateway is a native .NET or Java component that listens on a specific TCP/IP port and receives requests from the IRIS process, executes them, and returns the results.

Pre-Built PEX Components {#Webinar:ImplementarIntegracionescon.NetoJava-LosComponentesPEXpre-construidos}

To use PEX in an IRIS production, a pre-built component must be added to the Production for each component developed in Java or .NET. The pre-built component serves as a wrapper for the external element it refers to and allows its properties and configuration to be defined within the production.

Java or .NET components running from the corresponding Gateway must inherit (be subclassed) from a pre-existing PEX component. Here is an overview of these elements:

IRIS Components {#Webinar:ImplementarIntegracionescon.NetoJava-ComponentesdeIRIS}

For .NET and Java

<colgroup><col><col><col></colgroup>
<th>
  Class
</th>

<th>
  Comment
</th>
<td>
  EnsLib.PEX.BusinessService
</td>

<td>
  Configured adapter: Ens.InboundAdapter
</td>
<td>
  EnsLib.PEX.BusinessProcess.
</td>

<td>
   
</td>
<td>
  EnsLib.PEX.BusinessOperation
</td>

<td>
   
</td>
<td>
  EnsLib.PEX.InboundAdapter
</td>

<td>
   
</td>
<td>
  EnsLib.PEX.OutboundAdapter
</td>

<td>
   
</td>
<td>
  EnsLib.PEX.Message
</td>

<td>
  Message to send to a PEX component
</td>
<td>
  Maps to the IRIS Message
</td>

<td>
  The PEX component's message to the IRIS component
</td>
Function
Business Service
Business Process
Business Operation
Inbound Adapter
Outbound Adapter
PEX Message
IRIS Message

 

Java or .NET Components

These components are available in libraries that must be added to the Java or .NET project. The minimum library to reference in a PEX project is the same as the Gateway's. Additionally, if you want to use IRISObject messages to call IRIS components from PEX, you must reference the IRISClient library:

<colgroup><col><col></colgroup>
<th>
  Libraries
</th>
<td>
  &lt;installdir>\dev\dotnet\bin\v4.5\InterSystems.Data.Gateway64.exe &lt;installdir>\dev\dotnet\bin\v4.5\InterSystems.Data.IRISClient.dll
</td>
<td>
  &lt;installdir>\dev\java\lib\JDK18\intersystems-gateway-3.1.0.jar &lt;installdir>\dev\java\lib\JDK18\intersystems-jdbc-3.1.0.jar &lt;installdir>\dev\java\lib\gson\gson-2.8.5.jar
</td>
Language
.NET
Java

 

Superclass to use for .NET components

<colgroup><col><col></colgroup>
<th>
  .NET class
</th>
<td>
  InterSystems.EnsLib.PEX.BusinessService
</td>
<td>
  InterSystems.EnsLib.PEX.BusinessProcess
</td>
<td>
  InterSystems.EnsLib.PEX.BusinessOperation
</td>
<td>
  InterSystems.EnsLib.PEX.InboundAdapter
</td>
<td>
  InterSystems.EnsLib.PEX.OutboundAdapter
</td>
<td>
  InterSystems.EnsLib.PEX.Message
</td>
<td>
  InterSystems.Data.IRISClient.ADO.IRISObject
</td>
Function
Business Service
Business Process
Business Operation
Inbound Adapter
Outbound Adapter
PEX Message
IRIS Message

 

Superclass to use for Java components

<colgroup><col><col></colgroup>
<th>
  Java class
</th>
<td>
  com.intersystems.enslib.BusinessService
</td>
<td>
  com.intersystems.enslib.BusinessProcess
</td>
<td>
  com.intersystems.enslib.BusinessOperation.
</td>
<td>
  com.intersystems.enslib.pex.InboundAdapter
</td>
<td>
  com.intersystems.enslib.pex.OutboundAdapter
</td>
<td>
  com.intersystems.enslib.pex.Message
</td>
<td>
  &lt;...>.IRISObject
</td>
Function
Business Service
Business Process
Business Operation
Inbound Adapter
Outbound Adapter
PEX message
IRIS message

 

Utility Functions {#Webinar:ImplementarIntegracionescon.NetoJava-FuncionesdeUtilidades}

In the components implemented in ObjectScript, InterSystems IRIS offers some commands in the form of MACRO to populate information to the IRIS Event log. These methods are available in Java and .NET as follows:

<colgroup><col><col></colgroup>
<th>
  Description
</th>
<td>
  Add a message to the Events Log with the status "info"
</td>
<td>
  Add a message to the Events Log with the status "alert"
</td>
<td>
  Add a message to the Events Log with the status "warning"
</td>
<td>
  Add a message to the Events Log with the status "error"
</td>
<td>
  Add a message to the Events Log with the status "assert"
</td>
Method
LOGINFO(message)
LOGALERT(message)
LOGWARNING(message)
LOGERROR(message)
LOGASSERT(message)

 

Interoperability between native and PEX components {#Webinar:ImplementarIntegracionescon.NetoJava-InteroperabilidadentrecomponentesnativosycomponentesPEX}

It's possible to combine components in InterSystems IRIS's native ObjectScript language with PEX components developed in Java or .NET.

  • When both components are BusinessService type — InboundAdapter or BusinessOperation — OutboundAdapter, the developer can choose the type of data/object to use in the calls: Calls are made between IRIS and the Java/.NET gateway following the data transformation rules that determine the Gateway.
  • When both components that exchange information are Business Hosts (BS, BP, BO), the component that must receive the message (request or response) imposes the type of objects to use for the message:
    • A PEX component always receives the message EnsLib.PEX.Message
    • An IRIS component receives the message IRISObject

EnsLib.PEX.Message {#Webinar:ImplementarIntegracionescon.NetoJava-EnsLib.PEX.Message}

EnsLib.PEX.Message allows a message whose structure has been defined in .NET or Java to be represented in the IRIS ObjectScript. IRIS uses the DynamicObject function to manipulate properties. Internally, IRIS uses JSON as the transport medium between IRIS and .NET/Java. When creating a PEX message in IRIS, the name of the NET/Java class that must be instantiated to use the message must be set as %classname.

IRISObject {#Webinar:ImplementarIntegracionescon.NetoJava-IRISObject}

To call a pre-built InterSystems IRIS component from a PEX component, an IRISObject type message must be defined (in .NET, the complete class is InterSystems.Data.IRISClient.ADO.IRISObject).

The First Steps with PEX and .NET {#Webinar:ImplementarIntegracionescon.NetoJava-PrimerosPasosconPEXy.NET}

In these first steps, we:

  • Create a .NET project with the necessary PEX libraries, version 4.5 of the .NET framework
  • Add a BusinessOperation and a Simple message to the .NET project
  • Configure the Intersystems IRIS's .NET Gateway
  • Create an Interoperability Production
  • Add a pre-built BO

Creating a .NET Project with Visual Studio 2019 {#Webinar:ImplementingIntegrationswith.NetorJava-Creatinga.NETProjectwithVisualStudio2019}

We create a new "Class Library .Net Standard in C #" type project In Visual Studio. We'll name it "PEX.Webinar.FirstDemo":

To work with PEX, we add the necessary dependencies from "Solution Explorer" and the "Add Reference" context menu:

and we add two libraries (.NET Framework 4.5! compatible ) located in a subdirectory of the InterSystems IRIS installation with the "Browse" button:

<colgroup><col></colgroup>
<installdir>\dev\dotnet\bin\v4.5\InterSystems.Data.Gateway64.exe <installdir>\dev\dotnet\bin\v4.5\InterSystems.Data.IRISClient.dll

It's then renamed from the solution Explorer Class1.cs to "FirstOperation.cs", and the class is modified to inherit from the BusinessOperation PEX class (InterSystems.EnsLib.PEX.BusinessOperation). All 3 PEX.BusinessOperation methods are overwritten:

<colgroup><col><col></colgroup>
<th>
  Description
</th>
<td>
  It runs 1 time when this component is started in the production. It allows libraries, connections, and variables to be initiated...
</td>
<td>
  It runs 1 time when this component or the production stop. It makes it possible to free up resources used in the component's life cycle
</td>
<td>
  It runs for each Message received. It allows the message to be processed and return a response
</td>
Method
OnInit
OnTearDown
OnMessage

 

As of now, no messages or tasks to perform have been defined. For that reason, LOGINFO functions are added in the 3 methods. On the other hand, the superclass method doesn't need to be called, so we can eliminate the calls to the base class (base.OnInit (), base.OnTearDown(), base.OnMessage). We leave the implementation as follows:

<colgroup><col><col></colgroup>
<th>
  Initial Deploy
</th>
<td>
  OnInit public override void OnInit()         {             LOGINFO("PEX.Webinar.FirstDemo.FirstOperation:OnInit()");         }
</td>
<td>
  OnTearDown public override void OnTearDown()        {            LOGINFO("PEX.Webinar.FirstDemo.FirstOperation:OnTearDown()");        }
</td>
<td>
  OnMessage public override object OnMessage(object request)        {            LOGINFO("PEX.Webinar.FirstDemo.FirstOperation:OnMessage()");            return request;        }
</td>
Method
OnInit
OnTearDown
OnMessage

 

This allows the initial version of the .NET project to be compiled with the "Build Solution" menu. IRIS then generates the following file, which is used next:

<colgroup><col></colgroup>
1>------ Build started: Project: PEX.Webinar.FirstDemo, Configuration: Debug Any CPU ------1>PEX.Webinar.FirstDemo -> C:\Dev\PEX\PEX.Webinar.FirstDemo\bin\Debug\netstandard2.0\PEX.Webinar.FirstDemo.dll========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

InterSystems IRIS Interoperability Production Creation {#Webinar:ImplementingIntegrationswith.NetorJava-InterSystemsIRISInteroperabilityProductionCreation}

The IRIS Management Portal now lets you choose the "Interoperability" menu, the "Ensemble" namespace, and the "Configure" and "Production" menus. The "Actions" tab and the "New" button allow you to define a new IRIS Integration production.

To activate the Testing Service, select the "Settings" tab, enable "Testing Enabled" in the last section of the list ("Development and Debugging"), and click the Apply button:

Adding the .NET Gateway to the Production {#Webinar:ImplementingIntegrationswith.NetorJava-Addingthe.NETGatewaytotheProducción}

To work with the PEX, the corresponding Java or .NET Gateway should start. InterSystems recommends configuring and starting these gateways from the menu "System Administration/Configuration/Connectivity/Object Gateways" for production environments (live). For this development environment, a component can be added directly to the production to start the Gateway. This allows the gateway to be started and stopped at the same time as the production in a single click, thus freeing up access to the .NET project's .DLL when you want to recompile it (Visual Studio can't recompile it if the .NET gateway has been started).

To add the ".Net Gateway" component, add a Business Service to the production using the "+" button next to "Services". "EnsLib.DotNetGateway.Service" is the component class name (Service Class) to be added, and "Enable now" is selected to enable the component.

The added component's configuration parameters can be edited by clicking it, filling in the values in the "Settings" tab, and clicking the "Apply" button:

<colgroup><col><col><col></colgroup>
<th>
  Value
</th>

<th>
  Description
</th>
<td>
  44444
</td>

<td>
  This can be changed to the port if port 55000 is busy with another process by default.
</td>
<td>
  &lt;installdir>\dev\dotnet\bin\v4.5\
</td>

<td>
  This indicates the location where the executable Gateway (InterSystems.Data.Gateway64.exe) is located &lt;InstallDir> is the IRIS installation directory: For example: C:\InterSystems\IRIS20201\dev\dotnet\bin\v4.5\
</td>
<td>
  true
</td>

<td>
  Select the 64-bit gateway version
</td>
<td>
  4.5
</td>

<td>
  The .Net version must be 4.5
</td>
Parameter
Port
FilePath
Exec64
.NET Version

 

Adding the Business Operation created in .NET  {#Webinar:ImplementingIntegrationswith.NetorJava-AddingtheBusinessOperationcreatedin.NET}

Now we add a PEX Business Operation using the "+" button next to "Operations" to reference the previously created .NET code. "EnsLib.PEX.BusinessOperation" is the class type, the (optional) component is called "PEX.Webinar.FirstOperation", and it's enabled using "Enable Now".

Next, the component is configured (by clicking the added component) and selecting the "Settings" tab on the right:

<colgroup><col><col><col></colgroup>
<th>
  Value
</th>

<th>
  Description
</th>
<td>
  PEX.Webinar.FirstDemo.FirstOperation
</td>

<td>
  Name of the generated .NET class
</td>
<td>
  44444
</td>

<td>
  The TCP port in which the .NET Gateway is configured
</td>
<td>
  C:\Dev\PEX\PEX.Webinar.FirstDemo\bin\Debug\ netstandard2.0\PEX.Webinar.FirstDemo.dll
</td>

<td>
  Location of the .DLLs to include. This is the location where the Visual Studio build generated the .DLL
</td>
Parameter
Remote Classname
Gateway Port
Gateway Extra CLASSPATH

To apply the changes, click the "Apply" button:

Adding and Testing the Production {#Webinar:ImplementingIntegrationswith.NetorJava-AddingandStartingtheProduction}

The "Start" button starts the production and all its components:

InterSystems IRIS allows simple, isolated testing of a component. Click to select the "Business Operation" called "PEX.Webinar.FirstOperation" and select the "Test" button from the Actions tab:

The following data is filled on the next screen as follows:

<colgroup><col><col><col></colgroup>
<th>
  Value
</th>

<th>
  Description
</th>
<td>
  EnsLib.PEX.Message
</td>

<td>
  The type of IRIS message sent. It's always EnsLib.PEX.Message. It allows dynamic properties to pass values to the Java or .NET PEX component.
</td>
<td>
  InterSystems.EnsLib.PEX.Message
</td>

<td>
  It's the classname for the message defined in Java or .NET as a component request. For .NET, this must be InterSystems.EnsLib.PEX.Message or a subclass
</td>
Parameter
Request Type
%classname

When clicking "Invoke Testing Service", the IRIS Interoperability framework sends the message to the component, and the .NET code is executed.

Clicking "Visual Trace" allows the details to be viewed. The white dot (#3) displays the "LOGINFO" trace implemented in .NET.

The IRIS Events Log contains a compilation of all the generated LOGINFO() messages, including in OnInit() and OnTearDown().

The Next Steps with PEX: Completing the Production {#Webinar:ImplementingIntegrationswith.NetorJava-NextStepswithPEX:CompletingtheProduction}

Below, other types of components are created in .NET:

  • .NET Messages
  • .NET Business Services
  • .NET Business Process

Creating and Using a PEX Message with Data {#Webinar:ImplementingIntegrationswith.NetorJava-CreatingandUsingaPEXMessagewithData}

To pass information from Ensemble to PEX components, define a class in .NET as the subclass InterSystems.EnsLib.PEX.Message with properties for the information to be passed. Continuing with a simplified example, we add a string "value" property to the message. The PEX Business Operation will become the same type of message with the content transformed to capital letters.

Message class in .NET {#Webinar:ImplementarIntegracionescon.NetoJava-Clasedemensajeen.NET}

A new "FirstMessage.cs" file is added to the .NET project with the following definition:

FirstMessage

using System; using System.Collections.Generic; using System.Text; namespace PEX.Webinar.FirstDemo {     class FirstMessage : InterSystems.EnsLib.PEX.Message     {         public string value;     } }

Using a message from .NET {#Webinar:ImplementarIntegracionescon.NetoJava-Usodelmensajedesde.NET}

In the FirstOperation Business Operation, the data type for OnMessage is defined as an Object. It should be cast to the "FirstMessage" class to use it:

OnMessageV2

public override object OnMessage(object request)         {             LOGINFO("PEX.Webinar.FirstDemo.FirstOperation:OnMessage()");             ///the response message instantiates             FirstMessage response = new FirstMessage();             //The value is copied in "uppercase" from the request             response.value = ((FirstMessage)request).value.ToUpper();             //The response is returned             return response;         }

The IRIS production has to be stopped (with the "Stop" button), or the .NET Gateway has to at least be disabled (double-click the component) and compile the .NET project.

Using a class from InterSystems IRIS {#Webinar:ImplementarIntegracionescon.NetoJava-UsodelaclasedesdeInterSystemsIRIS}

The "Test" button (Testing Service) doesn't allow the dynamic properties of the EnsLib class to be filled.PEX.Message. However, the Testing Service can be used with an IRIS-native "Ens.StringRequest" message type and can be transformed (through Data Transformation) to a PEX message. The transformation is invoked from a pre-built Router-type Business Process.

Data Transformation {#Webinar:ImplementingIntegrationswith.NetorJava-DataTransformation}

A Data Transformation is created to copy data from the native ensemble message:

<colgroup><col><col><col><col></colgroup>
<th>
  Source
</th>

<th>
  Target
</th>

<th>
  Comment
</th>
<td>
  EnsLib.StringRequest
</td>

<td>
  EnsLib.PEX.Message
</td>

<td>
  The classes for the transformation source and target
</td>
<td>
  n/a
</td>

<td>
  PEX.Webinar.FirstDemo.FirstMessage
</td>

<td>
  For a PEX message (target), %classname defines the .NET/Java classname to be used.
</td>
<td>
  source.StringValue
</td>

<td>
  target.%jsonObject.value
</td>

<td>
  In the target PEX message, the dynamic properties are located inside %jsonObject.
</td>
 
Class
%classname
property

 

The Data Transformation can be created from the "Interoperability"/"Build"/"Data Transformations" management portal with the "New" button:

After that, the parameters for the transformation from the "source" to the "target" message are defined as described in the previous table using the graphic tool and completing the text in the "Action" tab to the right to obtain the two lines of text displayed at the bottom. Then, you can Save, Compile, and Test in the "Tools" tab.

Now, by opening the tools tab, you can test this Data Transformation:

The Test Window opens, where you can specify values for the source message (in StringValue) and verify the result:

As you can see, the PEX message uses an internal JSON representation to transfer the values between IRIS and Java or .NET.

Creating a Router-type Business Process {#Webinar:ImplementingIntegrationswith.NetorJava-CreatingaRoutertypeBusinessProcess}

It's now possible to add a Router type Business Process to the Production and define a Routing rule that calls the created Data Transformation and sends a message to the existing Business Operation.

In the management portal, return to the Production Configuration screen ("Interoperability" / "Configure" / "Production"), and add the Business Process type "EnsLib.Message.Router", by clicking the "+" next to "Processes", and filling in as follows:

<colgroup><col><col><col></colgroup>
<th>
  Value
</th>

<th>
  Description
</th>
<td>
  EnsLib.MsgRouter.RoutingEngine
</td>

<td>
  A Business Process for rule-based message routing
</td>
<td>
  TRUE
</td>

<td>
  Defining the skeleton of a routing rule
</td>
<td>
  MessageRouter
</td>

<td>
  A name for this component in the production
</td>
<td>
  TRUE
</td>

<td>
  Activate this component immediately
</td>
<td>
  1
</td>

<td>
  Scalability. It allows the number of active processes running simultaneously to be defined.
</td>
Parameter
Business Process Class
Auto-Create Rule
Business Process Name
Enable Now
Pool Size

 

The Routing Rule for this component remains to be edited. To do this, select the "MessageRouter" component in the production, and click on the magnifying glass next to the Business Rule Name:

The Rules editor makes it possible to edit the Rule to send all "Ens.StringRequest" messages to the "PEX.Webinar.FirstOperation" Business Operation after the transformation is applied to them. The "+" button lets you add elements to rules and edit an element when selecting it in advance. The rule to keep should be as follows:

By default, this component doesn't expect a response. Change your settings in the component's "Settings" tab to receive the response from the Business Operation:

Testing the Router with the Testing Service {#Webinar:ImplementarIntegracionescon.NetoJava-PruebadelEnrutadorconelServiciodePruebas}

Back to the production page, you can use the "Start" button to start the production, select the "MessageRouter" component, and with the "Actions" tab, click the "Test" button, to send an "Ens.StringRequest" type message:

The Test Response message can be viewed under "Test Results", and the full message log shows all details of the execution on the various components of the IRIS Interoperability production:

Response:

  {#Webinar:ImplementarIntegracionescon.NetoJava-}

Tracing the messages:

.NET Business Services {#Webinar:ImplementarIntegracionescon.NetoJava-BusinessServiceen.NET}

.NET Implementation {#Webinar:ImplementingIntegrationswith.NetorJava-Implementationin.NET}

Return to Visual Studio to create a .NET Business Service. In this initial example, this Business Service has no specific "Inbound Adapter" associated; it uses the "EnsLib.InboundAdapter", a component that runs at regular intervals (according to set CallInterval value) and makes a call to the Business Service every CallInterval. 

In Visual Studio, a new file "FirstService.cs" is generated for the "FirstService" class. The processing of each event detected by the Inbound Adapter is done using the "OnProcessInput" method. The object set in parameter depends on the implementation of the InboundAdapter; in this case, it's not used:

FirstService:OnProcessInput

public override object OnProcessInput(object messageInput)         {             //create a new Request Object             FirstMessage myRequest = new FirstMessage();             myRequest.value = "The send time is: " + System.DateTime.Now.ToString();             //To send without waiting for a response:             //SendRequestAsync("PEX.Webinar.FirstOperation", myRequest);             //To send and wait for a response with a 20-second timeout:             FirstMessage myResponse=(FirstMessage) SendRequestSync("PEX.Webinar.FirstOperation", myRequest, 20);             return null;         }

FirstService:OnProcessInput

public override object OnProcessInput(object messageInput)         {             //create a new Request Object             FirstMessage myRequest = new FirstMessage();             myRequest.value = "The send time is: " + System.DateTime.Now.ToString();             //To send without waiting for a response:             //SendRequestAsync("PEX.Webinar.FirstOperation", myRequest);             //To send and wait for a response with a 20-second timeout:             FirstMessage myResponse=(FirstMessage) SendRequestSync("PEX.Webinar.FirstOperation", myRequest, 20);             return null;         }

To send the message to any component of the production without recompiling it, you can use a parameter configured from the management portal; the values are specified as a JSON string within the "RemoteSettings" configuration parameter.

Parameters

class FirstService : InterSystems.EnsLib.PEX.BusinessService     {         /// <summary>         /// A parameter that can be changed from the Portal         /// </summary>         public string TargetConfigName;      (...)

If the value specified for "TargetConfigName" is set to null, the Business Service won't send the message to any destination. To detect this problem as soon as possible, one option is to validate the value of TargetConfigName when the component is started, in the OnInit() call:

FirstService:OnInit

public override void OnInit()         {            //Verify that the properties are correctly reported            if (TargetConfigName==null )             {                 LOGWARNING("TargetConfigName is missing; assign it a value in RemoteSettings");             }else             {                 LOGINFO("TargetConfigname=" + TargetConfigName);             }         }

Now, you can change the OnProcessInput to  use the value of TargetConfigName:

OnProcessInput

//Send and wait for the answer with a timeout of 20 seconds: FirstMessage myResponse=(FirstMessage) SendRequestSync(TargetConfigName, myRequest, 20);

PEX Business Service in InterSystems IRIS {#Webinar:ImplementarIntegracionescon.NetoJava-BusinessServicePEXenInterSystemsIRIS}

In the management portal, add a Business Service type component to the Production definition by clicking the "+" next to 

Then, configure the component (by clicking on the added component) and select the "Settings" tab on the right: 

<colgroup><col><col><col></colgroup>
<th>
  Value
</th>

<th>
  Description
</th>
<td>
  20
</td>

<td>
  The time between each execution of the OnTask() of the Associated Adapter and each call to the OnProcessInput()
</td>
<td>
  PEX.Webinar.FirstDemo.FirstService
</td>

<td>
  Name of the generated .NET class
</td>
<td>
  TargetConfigName=PEX.Webinar.FirstOperation
</td>

<td>
  A List of parameters in param=value format, separated by &lt;newline>
</td>
<td>
  44444
</td>

<td>
  The TCP port in which the .NET Gateway is configured
</td>
<td>
  C:\Dev\PEX\PEX.Webinar.FirstDemo\bin\Debug\ netstandard2.0\PEX.Webinar.FirstDemo.dll
</td>

<td>
  Location of the .DLLs to include. This is the location where the Visual Studio build generated the .DLL
</td>
Parameter
CallInterval
Remote Classname
Remote Settings
Gateway Port
Gateway Extra CLASSPATH

 

When this Business Service is activated, each CallIntervall of the OnTask() associated adapter (Ens.InboundAdapter) is executed. Here the OnTask just calls FirstService.OnProcessInput(). That is, each callInterval and FirstService.OnProcessInput() generates a message that sends to the component defined in "TargetConfigName". This can be verified in the Message Viewer:

With details of a call:

.NET Business Process {#Webinar:ImplementarIntegracionescon.NetoJava-BusinessProcess.NET}

.NET Implementation {#Webinar:ImplementingIntegrationswith.NetorJava-.NETImplementation}

Like every Business Host, the Business Process has the CallBack OnInit() and OnTearDown() Methods. The specific Business Process methods are the following:

<colgroup><col><col></colgroup>
<th>
  Description
</th>
<td>
  It's executed for each message sent to the Business Process. It's the place to implement the initial actions of the Process and make asynchronous deliveries to other components (Processes or Operations)
</td>
<td>
  It's executed 1 time for each answer of the asynchronous calls made. It allows responses to be managed and the results to be saved.
</td>
<td>
  It's executed 1 time at the end of the Business Process execution. It allows the Process's final response message to be built.
</td>
Method
OnRequest(message)
OnResponse
OnComplete

It's important to note that a Business Process can have an extended execution time (hours or days, waiting for an asynchronous response). To enable this, the IRIS Framework can interrupt and resume the process execution. All values that you want to keep during a process have to be put in properties of the class that IRIS saves persistently. It's necessary to indicate it with the notation "[persistent]".

In this example, a minimal implementation is done, where the Business Process routes the PEX message it receives to a destination:

Two variables that can be modified from the management portal are used:

FirstProcess

class FirstProcess: InterSystems.EnsLib.PEX.BusinessProcess     {         //Timeout for Calls         public string Timeout = "PT10S";         public string TargetConfigName;         public override void OnInit()         {             //Ensure that the properties are correctly entered             if (TargetConfigName == null)             {                 LOGWARNING("Missing value for TargetConfigName; It must be assigned a value in RemoteSettings");             }             else             {                 LOGINFO("TargetConfigname=" + TargetConfigName);             }         }

When you receive a message, it's sent asynchronously to TargetConfigName:

FirstProces:OnRequest

public override object OnRequest(object request)         {             LOGINFO("OnRequest");             SendRequestAsync(TargetConfigName, (InterSystems.EnsLib.PEX.Message)request, true); //ResponseRequired=true             SetTimer(Timeout, "HasTimedOut");             return null;         }

OnResponse allows call responses to be managed:

FirstProcess:OnResponse

public override object OnResponse(object request, object response, object callRequest,  object callResponse, string completionKey)        {            LOGINFO("OnResponse, CompletionKey=" + completionKey);            if (completionKey!= "HasTimedOut")            {                response = (FirstMessage)callResponse;            }            LOGINFO("Response:" + response.ToString());            return response;        }

At the end of the process, the response is returned:

FirstProcess:OnComplete

public override object OnComplete(object request, object response)       {           LOGINFO("OnComplete");           return response;       }

PEX Business Process in InterSystems IRIS {#Webinar:ImplementarIntegracionescon.NetoJava-BusinessProcessPEXenIntersystemsIRIS}

We add an EnsLib.PEX.BusinessProcess Business Process, configure it as needed, and change the TargetConfigName for the "PEX.Webinar.FirstProcess" Business Service to send the messages to the new Process instead of sending them directly to the BO. 

The component's "Settings" are defined as follows:

<colgroup><col><col></colgroup>
<th>
  value
</th>
<td>
  PEX.Webinar.FirstDemo.FirstProcess
</td>
<td>
  Timeout=PT20STargetConfigName=PEX.Webinar.FirstOperation
</td>
<td>
  44444
</td>
<td>
  C:\Dev\PEX\PEX.Webinar.FirstDemo\bin\Debug\netstandard2.0\PEX.Webinar.FirstDemo.dll
</td>
Parameter
Remote Classname
Remote Settings
Gateway Port
Gateway Extra Classpath

The result in the trace is the following:

Conclusion

PEX allows integrations to be implemented in .NET or Java very fluently and offers the full power and robustness of the InterSystems IRIS interoperability layer for developers experienced in these languages.

4
1 1223
Question Tom Bruce · Jun 20, 2022

Hi, I tried the following exercise from the IRIS documentation. I updated the username, password and IP address, but receiving this error;

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. --->

I can use the same credentials and IP address to connect ok via VSCode to my local IRIS...

Any pointers much appreciated.

https://docs.intersystems.com/irisforhealth20211/csp/docbook/DocBook.UI…

3
0 411
Question Sagun Tangsrisanguan · May 30, 2022

Hi

I use VB.net and add reference VISM.OCX in my project to fetch my data in global ^ztonMS it had 4000 record 

code is

 AxVisM1.MServer = "CN_IPTCP:" & TCLServer & ":" & Authen
        AxVisM1.NameSpace = TCLNamespace

        AxVisM1.P0 = ""
        AxVisM1.P1 = ""
        AxVisM1.P2 = ""

        AxVisM1.P3 = ""

       AxVisM1.P4 = ""

        'AxVisM1.Execute("d RefRange^NHSNAV2")

        While True
            AxVisM1.Execute("set P0=$o(^ztonMS(""REF"",P0))")
            AxVisM1.Execute("s P1=$g(^ztonMS(""REF"",P0))")

            xP1 = AxVisM1.P0.ToString

1
0 184
Job sandeep sunny · May 26, 2022

Client: Northwell Health

Role: Senior Developer

Location: Remote

Duration: 6+ Months

Description:

Team Overview:

The FHIR Platform team is tasked with providing the core infrastructure in providing access to Northwell HIE patient data complying with HL7 FHIR and USCDI standards.

Position Summary:

The primary purpose of this role is to provide technical design, coding, testing and documentation for multiple components in the FHIR solution.

Responsibilities:

• Develop end-to-end solutions, participate in code reviews, unit test and deploy.

• Documentation of technical designs and functionality

0
0 420
Article Lucas Enard · May 13, 2022 8m read

1. Fhir-client-net

This is a simple fhir client in c# to practice with fhir resources and CRUD requests to a fhir server.
Note that for the most part auto-completion is activated.

GitHub

2. Prerequisites

Make sure you have git and Docker desktop installed.

If you are working inside the container, those modules are already installed.
if you are not, use nugget to install Hl7.Fhir.R4, we will be using Model and Rest from it :
Hl7.Fhir.Model

Hl7.Fhir.Rest

3. Installation

3.1. Installation for development

Clone/git pull the repo into any local directory e.g. like it is shown below:

git clone https://github.com/LucasEnard/fhir-client-net.git

Open the terminal in this directory and run:

docker build .

3.2. Management Portal and VSCode

This repository is ready for VS Code.

Open the locally-cloned fhir-client-net folder in VS Code.

If prompted (bottom right corner), install the recommended extensions.

3.3. Having the folder open inside the container

You can be inside the container before coding if you wish.
For this, docker must be on before opening VSCode.
Then, inside VSCode, when prompted (in the right bottom corner), reopen the folder inside the container so you will be able to use the python components within it.
The first time you do this it may take several minutes while the container is readied.

If you don't have this option, you can click in the bottom left corner and press reopen in container then select From Dockerfile

More information here

Architecture


By opening the folder remote you enable VS Code and any terminals you open within it to use the c# components within the container.

If prompted (bottom right corner), install the recommended extensions.

4. FHIR server

To complete this walktrough you will need a FHIR server.
You can either use your own or go to InterSystems free FHIR trial and follow the next few steps to set it up.

Using our free trial, just create an account and start a deployement, then in the Overview tab you will get acces to an endpoint like https://fhir.000000000.static-test-account.isccloud.io that we will use later.
Then, by going to the Credentials tab, create an api key and save it somewhere.

Now you are all done, you have you own fhir server holding up to 20GB of data with a 8GB memory.

5. Walkthrough

Complete walkthrough of the client situated at /Client.cs.

The code is separated in multiple parts, and we will cover each of them below.

5.1. Part 1

In this part we connect our client to our server using Fhir.Rest.


// Part 1

// Creation of an htpclient holding the api key of the server as an header
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("x-api-key", "api-key");


var settings = new FhirClientSettings
    {
        Timeout = 0,
        PreferredFormat = ResourceFormat.Json,
        VerifyFhirVersion = true,
        // PreferredReturn can take Prefer.ReturnRepresentation or Prefer.ReturnMinimal to return the full resource or an empty payload
        PreferredReturn = Prefer.ReturnRepresentation
    };
// Creation of our client using the right url
var client = new FhirClient("url",httpClient,settings);

In order to connect to your server you need to change the line :

httpClient.DefaultRequestHeaders.Add("x-api-key", "api-key");

And this line :

var client = new FhirClient("url",httpClient,settings);

The 'url' is an endpoint while the "api-key" is the api key to access your server.

Note that if you are not using an InterSystems server you may want to check how to authorize your acces if needed.

Just like that, we have a FHIR client capable of direct exchange with our server.

5.2. Part 2

In this part we create a Patient using Fhir.Model and we fill it with a HumanName, following the FHIR convention, use and family are string and given is a list of string. The same way, a Patient can have multiple HumanNames so we have to put our HumanName in a list before puting it into our newly created Patient.


// Part 2

// Building a new patient and setting the names
var patient0 = new Patient();
patient0.Name.Add(new HumanName().WithGiven("GivenName").AndFamily("FamilyName"));

// Creation of our client in the server
// It is to be noted that using SearchParams you can check if an equivalent resource already exists in the server
// For more information https://docs.fire.ly/projects/Firely-NET-SDK/client/crud.html
var created_pat = client.Create<Patient>(patient0);

Console.Write("Part 2 : Newly created patient id : ");
Console.WriteLine(created_pat.Id);

After that, we need to save our new Patient in our server using our client.

Note that if you start Client.cs multiple times, multiple Patients having the name we choosed will be created.
This is because, following the FHIR convention you can have multiple Patient with the same name, only the id is unique on the server.
Check the doc for more information.
It is to be noted that using SearchParams you can check if an equivalent resource already exists in the server before creating it.
For more information https://docs.fire.ly/projects/Firely-NET-SDK/client/crud.html

Therefore we advise to comment the line after the first launch.

5.3. Part 3

In this part we get a client searching for a Patient named after the one we created earlier.


// Part 3

// This gets all the Patient having the exact name "FamilyName" and we take the first one
// Note that if you have multiple patients with the same name, you will get only the first one 
// We advise to use the id, the names, and any other informations for the SearchParams to be sure to get the right patient
var q = new SearchParams().Where("name:exact=FamilyName");
Bundle bund = client.Search<Patient>(q);
patient0 = bund.Entry[0].Resource as Patient;

Console.Write("Part 3 : Name of the patient we found by searching : ");
Console.WriteLine(patient0.Name[0]);


// Creation of our patient telecom, here a phone number
patient0.Telecom.Add(new ContactPoint(new ContactPoint.ContactPointSystem(),new ContactPoint.ContactPointUse(),"1234567890"));

// Change the given name of our patient
patient0.Name[0].Given = new List<string>() { "AnotherGivenName" };

Console.Write("Part 3 : Name of the changed patient : ");
Console.WriteLine(patient0.Name[0]);

Console.Write("Part 3 : Phone of the changed patient : ");
Console.WriteLine(patient0.Telecom[0].Value);

// Update the patient
var update_pat = client.Update<Patient>(patient0);

Once we found him, we add a phone number to his profile and we change his given name to another.

Now we can use the update function of our client to update our patient in the server.

5.4. Part 4

In this part we want to create an observation for our Patient from earlier, to do this we need his id, which is his unique identifier.
From here we fill our observation and add as the subject, the id of our Patient.


// Part 4

// Building of our new observation
Observation obsv = new Observation {

    Value = new Quantity(70, "kg"),
    Code = new CodeableConcept {
        Coding = new List<Coding> {
            new Coding {
                System = "http://loinc.org",
                Code = "29463-7",
                Display = "Body weight"
            }
        }},
    Category = new List<CodeableConcept> {
        new CodeableConcept {
            Coding = new List<Coding> {
                new Coding {
                    System = "http://snomed.info/sct",
                    Code = "276327007",
                    Display = "Body weight"
                }
            }
        }},
    Status = new ObservationStatus {},
    Subject = new ResourceReference {
        Reference = "Patient/" + update_pat.Id}

    };

// Creation of our observation in the server
var new_obsv = client.Create<Observation>(obsv);

Console.Write("Part 4 : Id of the observation : ");
Console.WriteLine(new_obsv.Id);

Then, we register using the create function our observation.

5.5. Conclusion of the walkthrough

If you have followed this walkthrough you now know exactly what Client.cs does, you can start it and check in your server your newly created Patient and Observation.

To start it, open a VSCode terminal and enter :

dotnet run

You should see some information on the Patient we created and his observation.

If you are using an Intersystems server, go to API Deployement, authorize yourself with the api key and from here you can GET by id the patient and the observation we just created.

7. How to start coding

This repository is ready to code in VSCode with InterSystems plugins. Open Client.cs to start coding or using the autocompletion.

8. What's inside the repo

8.1. Dockerfile

A dockerfile to create a dot net env for you to work on.
Use docker build . to build and reopen your file in the container to work inside of it.

8.2. .vscode/settings.json

Settings file.

8.3. .vscode/launch.json

Config file if you want to debug

0
0 8192
Question Nilson Cupertino · May 10, 2022

Hello,

I have an error connecting the InterSystems cache with the odbc driver with the ODBC-2017.2.2.865.0-lnxrhx64.tar version using the ubuntu versions 20.04 and version 18.04 (which works with the .Net Core 3.1 version) with the Net 6.

Error:

2
0 403
Question Louie McLaughlin · Mar 10, 2022

I'm new to cache, come from an oracle and sql server background. In oracle and sql server I could write basically a stored procedure like script and pass it in as text to the command to execute. 

Example:

Below would be the _sqltext

DECLARE @Id INT;

select id into @Id from something;

 if @Id = 9 

BEGIN

do something

END

The _sqltext would work in sql server, what would be the equivalent for cache for it work?

I get a generic error when I try it with cache

using (var mdscmd = new CacheCommand(_sqlText, MyConnection) { CommandType = CommandType.Text }) {

}

Thanks

2
0 277
Question Eduard Lebedyuk · Jul 6, 2020

I'm building a .Net Core Gateway container. Here's the issue.

As a final step I'm building a .Net Core 2.1 library. It has a runnable dependency - .Net Gateway, which I need to start first.

However dotnet publish generates .runtimeconfig.json and .deps.json only for my library and not for my dependency (.Net Gateway).

Is there a way to force dotnet to generate .runtimeconfig.json and .deps.json for a dependency?

I have tried:

  <PropertyGroup>
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
    <GenerateDependencyFile>true</GenerateDependencyFile> 
   <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
  </PropertyGroup>

but it did not help.

As a workaround I can copy my app .runtimeconfig.json to the dependency .runtimeconfig.json but it seems hacky (it also prevents me from building self-contained Gateway container). Is there a better option?

I have prepared the test case, if anyone wants to try it:

git clone https://github.com/eduard93/gerenate-runtimeconfig.json.git
cd gerenate-runtimeconfig.json
docker build --tag mbs .
docker run --name mbs mbs
docker rm mbs --force

If you remove the comment from Line 24 in the Dockerfile with the copy workaround the image would run successfully.

Without workaround I get this error:

A fatal error was encountered. The library 'libhostpolicy.so' required to execute the application was not found in '/app/'.
Failed to run as a self-contained app. If this should be a framework-dependent app, add the /app/IRISGatewayCore21.runtimeconfig.json file specifying the appropriate framework.
2
0 8752
Question savita singh · Jul 9, 2019

When publish my application on the iis server below function not working..

Public Shared Sub Connection()
        Try
            factory = CreateObject("CacheObject.Factory")
            If Not factory.IsConnected() Then
                Dim connectstring As String
                connectstring = ConfigurationManager.AppSettings.Get("con")
                Dim success As Boolean
                success = factory.Connect(connectstring)
            End If

1
0 444
Question Paster-Bachar Gadi · Jul 11, 2018

Hi

we are trying to call a Webservice that is hosted on a Ensemble production from a .net program.

The web application in ensabmle is defined with password authntication 

we can't get to set the security header in the .net program  (<soapenv:Header> ... <wsse:Security ... <wsse:UsernameToken  ... ) in SoapUI we added the Wss usertoken and it worked like a charm.

Doe's anyone have a idea to guide us? (links,  ,samples, etc. )

Thanks

Gadi

1
0 329
Question Michael Lundberg · Dec 27, 2016

Hi!

I'm trying to connect to one of our Ensemble servers Cache database from a C#-windows form . I'm running the client from my local computer with OS win7.  Using .NET FW ver 4.5.2 in the client.

ODBC local setup using "InterSystems ODBC35"

In this ODBC konfigurationview i can put my userID and password and try a testconnect (or ping). And that run successful.

However, we don't want to leave credentials in the ODBC-configuration it self (open up for anybody to use the source) but instead send it from the klients.

1
0 480
Question David Osborne · Mar 19, 2019

I'm attempting to use the .NET Entity Framework provider that is provided by InterSystems (see: https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GBMP_eframe).  In our environment, the "Support Delimited Identifiers" option is turned off and we are not allowed to turn it on without significant testing effort.  When this setting is off, the SQL that is generated by the Entity Framework provider is not considered valid and therefore the provider doesn't work (it DOES work, however, when this setting is turned ON).

3
0 623
Question Aaron Smith · Aug 12, 2020

Is there an InterSystems supported dotnet core library or community contributed repo on the horizon?  At this time we are exploring installing the ODBC driver in our containers but would rather use more robust solution.

15
0 1422
Question Emanuel Lazar · Jul 5, 2021

 Native API  , IRIS 2019 regression vs Cache .Net provider 

1. checking the native API, with .net provider, from IS docs, I realize,

that it is not possible to wrap objectSricpt Class with .NET (C# for example) pure Class with it's methods/properties

and make pure instance syntax of: new myNetClass - as wrapper of irisClass.

as I realize, you can run  .Net Class , only with .Invoke or iris.ClassMethodVoid("class.name","method")

such syntax, cannot execute event driven on proprety change, let say, with it's build in mechanizm in .Net

2. IRIS 2019.

18
0 357
Article Eduard Lebedyuk · Aug 7, 2020 5m read

In this article, I will show how you can easily containerize  .Net/Java Gateways.

For our example, we will develop an Integration with Apache Kafka.

And to interoperate with Java/.Net code we will use PEX .

Architecture

Our solution will run completely in docker and look like this:

Java Gateway

First of all, let's develop Java Operation to send messages into Kafka. The code can be written in your IDE of choice and it can look like this.

In short:

7
1 1401
Article Iryna Mykhailova · Oct 30, 2018 11m read

InterSystems states that Caché supports at least three data models – relational, object and hierarchical (globals). On can work with data presented in relational model in a program written on C# the same way one works with any other relational DB. To work with data presented by object model in C# one needs to use .NET Managed Provider or some kind or ORM. And starting with version 2012.2 one can work directly with globals (or use direct access to hierarchical data) via Caché eXTreme for .NET

18
2 2279