Skip to main content

About Business Hosts and Adapters

This chapter discusses information that applies to all business hosts and adapters written in an external language. For implementation details about a specific production component, refer to that component’s chapter.

General Notes about Methods

As you override methods to implement a production component, keep the following in mind:

  • Each production component must override all abstract methods. For information about which methods are abstract, see PEX API Reference.

  • While native interoperability methods use one input argument and one output argument and return a status, the corresponding PEX methods take one input argument and return the output argument as a return value.

  • All error handling for PEX methods are done with exceptions.

  • For native interoperability methods that don't require persistent objects as input and output arguments, the corresponding PEX methods can also use arbitrary objects as arguments and return values. PEX utilizes forward proxy and reverse proxy of the external server gateway to map the arbitrary object appropriately.

  • For native interoperability methods that require persistent objects as arguments, such as the methods that send messages to other processes, the corresponding PEX methods can use PEX Messages as arguments and return values. Examples of such methods are SendRequestSync, SendRequestAsync, OnRequest, OnResponse and OnMessage.

  • When overriding callback methods, you should not change the formal spec of the methods even if you have customized the message class. The argument types should remain as objects.

Setting Runtime Variables

The code of a custom PEX component can contain properties that will be set at runtime based on values defined in the Management Portal. At runtime, the values specified in the remoteSettings field of the proxy component in the production are assigned to the corresponding component written in the external language. Values are defined in the format: property=value. More than one property/value pair can be specified as long as each pair is on its own line. Do not include any spaces on the line.

For example, suppose your inbound adapter needs a username and password at runtime. In your code, you create public string variables called username and pw. Then, in the Management Portal, you can define the following in the remoteSettings field of the business service that uses the adapter:


To set the values in the XML defining the production, you can set the variables using thee %remoteSettings field. Note that if a component includes an adapter, you must set the variable for the host and the adapter.

<Production Name="Demo.PEX.SimpleFileAccess"
  <Item Name="Demo.PEX.WriteDataToFileAdapterOperation" Category=""   
    <Setting Target="Host" Name="%remoteSettings">outPath=C:\Practice\Data\Out\</Setting>
    <Setting Target="Adapter" Name="%remoteSettings">outPath=C:\Practice\Data\Out\</Setting>

Your external PEX code can now access the values from the production component using a variable that matches the property in the production setting.

Java and .NET

To use the variables defined in the production component, create a public member in the external PEX class. For example:

public class CustomOutboundAdapter extends com.intersystems.enslib.pex.OutboundAdapter {
   public String username;
   public String pw;
public class CustomOperationWithAdapter : BusinessOperation
  public string username;
  public string pw;

A PEX component written in Python can use a variable defined in the proxy production component without first declaring it. However, all values defined in the production component are set as strings in the Python class, so your code must cast the variable to the appropriate data type. For example, suppose the remoteSettings setting of your production component includes min=1 and max=10. Since the variables min and max will contain strings, your code must cast these variables as integers:

class MyBusinessService(iris.pex.BusinessService):
  def OnInit(self):
    self.min = int(self.min)
    self.max = int(self.max)
    print("OnInit() is called with min: %d and max: %d" % (self.min, self.max))