Lesson 2: Basic Concepts

 

 

 

1. An adapter within the framework


The Framework forms the heart of the IAF. To create a connection between two systems the framework doesn’t need modifications. It consist of a selection of Java-libraries and frameworks, plus standard bindings to much-used systems.
The actual application is -just as the framework- Java-based, and ensures cohesion between your adapters and the framework. The adapters you are going to make, communicate with the framework via your application. The console is also part of the actual application, a moderator can monitor here whether all processes run correctly. The application is also responsible for the transactional processing of data.
Adapters form the dynamic part of your application. These are small pieces of xml-code that perform a specific task. You can think of importing an incoming message to an Oracle database. One could say that an adapter takes care of the coupling between specific systems, transformation of data, and the general performance of business logic. To run our application we need a server with a Java Virtual Machine on board. Several servers are possible, but Apache Tomcat is the most common application server that we can use.

 

 

The adapters themselves have a specific structure that follow a certain flow of events : In an Ibis you have different configurations, which in turn consist of one or more adapters. Each adapter has three base components : A sender, the pipes in a pipeline, and a receiver, that holds a listener.  The receiver handles the incoming message that triggers the pipeline. You could think of situations when a message comes in, when somewhere a modification has taken place, a user making a request from a website, when in a database there was a change, or a certain time interval that is completed. Then there’s a series of pipes within the pipeline. They actually manipulate the incoming message, transformation, modification, anything can happen. Java-code is doing the powerlifting here, although we write our code in xml. At the end of a pipeline you have the sender, who sends our modified message to yet another component. One could think of insertion of the transformed data into a database. We use the term ‘Configuration’ to denote a set of adapters. When you upload your files via the ‘send’ button, you have uploaded a configuration. In code we could respresent an adapter as follows :

 

2. Building blocks

<ibis>
    <adapter name="HelloWorld" >
        <receiver
            name="HelloWorld"
            className="nl.nn.adapterframework.receivers.GenericReceiver">
                <listener name="HelloWorld" className="nl.nn.adapterframework.receivers.JavaListener" />
        </receiver>
        <pipeline firstPipe="HelloWorld">
            <exits>
                <exit path="EXIT" state="success"/>
            </exits>
            <pipe   name="HelloWorld" 
                    className="nl.nn.adapterframework.pipes.FixedResult"
                    returnString="Hello World" >
                <forward name="success" path="EXIT"/>
            </pipe>
        </pipeline>
    </adapter>
</ibis>

We can use the ‘hello world’ example to demonstrate the structure of an adapter.  In this case we give the Ibis a message, and the Ibis will respond with ‘hello world’. We will now get into the categories of elements one can use in an adapter:

<receiver> The receiver element usually contains a listener where a message will come in. A JavaListener gets the message from Java sources from an internal network. RestListener, HttpListener or ApiListener get their messages via http.

<pipeline> Needs firstPipe as his main attribute.

<pipe> Pipes form the main dish of the IAF. Its name and className are mandatory attributes. Dependent on its type, all kinds of other attributes can be formulated. You can browse them in the Tag Library and study their descriptions. Hover over the attributes to get more useful information.

 

 

 

 

 

 

Many pipes have special purposes, but some pipes you will use a lot when developing Ibises :

  • GenericMessageSendingPipe ;
  • FixedQuerySender. Often these two pipes are used to make a database query;
    <pipe     
        name="getUserName"
        className="nl.nn.adapterframework.pipes.GenericMessageSendingPipe"                
    >
        <sender
            className="nl.nn.adapterframework.jdbc.FixedQuerySender"
            jmsRealm="jdbc"
            queryType="select"
            query="select username from subscribers where email = ? ">
        </sender>                        
        <param name="username" value="john@abc.ru"/>
        <forward name="exception" path="ServerError" />
        <forward name="success" path="compareUserName" />
    </pipe>

    When we use sql the questionmark is used to insert a variable;  when there are more variables the sequence is just that the first questionmark in the query is the first parameter in the listing. Params can get their values in various ways. What you will use often is the sessionKey – xpathExpression combination. A sessionKey stands for a key-value pair where the value is a number, a string, a piece of xml or json. Looking at the example you could change value=’john@abc.ru’  for ‘sessionKey=”thegreeting” xpathExpression=”/greeting/text()” ‘.

  • EchoPipe is nice for debugging; in the Ladybug tool you can inspect the value that the pipeline has at a particular moment.
  • IbisLocalSender. This pipe gives you the opportunity to switch to another adapter. To give an example :
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration >
    <configuration name="Ibis4Teacher">
          <jmsRealms>
              <jmsRealm realmName="jdbc" datasourceName="jdbc/${instance.name.lc}" />
          </jmsRealms>
          <ibis>
          <adapter name="TestMyPipe" >
              <receiver
                  name="TestMyPipe"
                  className="nl.nn.adapterframework.receivers.GenericReceiver"
                  >
                  <listener
                      name="TestMyPipe"
                      className="nl.nn.adapterframework.receivers.JavaListener"
                  />
              </receiver>
              <pipeline firstPipe="createstring">
                <exits>
                    <exit path="EXIT" state="success" />
                </exits>
                <pipe className="nl.nn.adapterframework.pipes.PutParametersInSession" name="createstring">
                <param name="mystring" value="Hello precious world" />
                  <forward name="success" path="myforward1" />
                </pipe>
    
                <pipe className="nl.nn.adapterframework.pipes.FixedForwardPipe" 
                      name="myforward1"
                      getInputFromSessionKey="mystring"
                      >
                <sender 
                          className="nl.nn.adapterframework.senders.IbisLocalSender" 
                          javaListener="secondadapter" />
                  <forward name="success" path="EXIT" />
                </pipe>
              </pipeline>
          </adapter>    
    
          <adapter name="secondadapter" >
            <receiver
                name="secondadapter"
                className="nl.nn.adapterframework.receivers.GenericReceiver"
                >
                <listener
                    name="secondadapter"
                    className="nl.nn.adapterframework.receivers.JavaListener"
                />
            </receiver>
            <pipeline firstPipe="echo">
                <exits>
                    <exit path="MYNEWEXIT" state="success" />
                </exits>
              <pipe name="echo" className="nl.nn.adapterframework.pipes.EchoPipe">
                <forward name="success"  path="MYNEWEXIT"/>
                </pipe>
               
            </pipeline>
        </adapter>    
          
        </ibis>
    </configuration>
  • ForEachChildElementPipe
  • XsltPipe , our main tool in message transformation.
  • XmlIfPipe
  • XmlValidator , Json2XmlValidator  : both instrumental in validation.

 

 

3. Validation

A message undergoes various transformations on its way. When these data are somehow corrupted we want to know that and take action. A basic example of validation can be seen in a login request that sends a piece of Json to the Ibis.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration >
<configuration name="Ibis4Teacher">
      <jmsRealms>
          <jmsRealm realmName="jdbc" datasourceName="jdbc/${instance.name.lc}" />
      </jmsRealms>
     <ibis>
      <adapter name="MyTester" >
          <receiver
              name="MyTester"
              className="nl.nn.adapterframework.receivers.GenericReceiver">
                  <listener name="MyTester" className="nl.nn.adapterframework.receivers.JavaListener" />
          </receiver>
          <pipeline firstPipe="convert json to xml">
              <exits>
                  <exit path="EXIT" state="success"/>
                  <exit path="ServerError" state="failure"/>
              </exits>
             <pipe
                name="convert json to xml"
                className="nl.nn.adapterframework.pipes.Json2XmlValidator"
                schema="checkjson.xsd"
                root="mylogin"
            >
                <forward name="success" path="EXIT" />
               <forward name="failure" path="ServerError" />
            </pipe>
          </pipeline>
      </adapter>
    </ibis>
</configuration>

Use THIS  example file as your checkjson.xsd.

 

 

 

 

 

 

4.Transformation

Messages undergo some kind of a transformation. An important pipe we use for that is the XsltPipe.  The use of xslt is rather underestimated because it functions more on the backend side of things. Xslt is a  language in itself that you have to learn, but it is useful to see an example of it.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration >
<configuration name="Ibis4Teacher">
    <jmsRealms>
        <jmsRealm realmName="jdbc" datasourceName="jdbc/${instance.name.lc}" />
    </jmsRealms>
    <ibis>
    <adapter name="TestMyPipe" >
        <receiver
            name="TestMyPipe"
            className="nl.nn.adapterframework.receivers.GenericReceiver"
            >
            <listener
                name="TestMyPipe"
                className="nl.nn.adapterframework.receivers.JavaListener"
            />
        </receiver>
        <pipeline firstPipe="mypipe">
            <exits>
                <exit path="EXIT" state="success"/>
            </exits>
            <pipe className="nl.nn.adapterframework.pipes.XsltPipe" 
                  name="mypipe" 
                  styleSheetName="stylesheet.xsl"></pipe>
        </pipeline>
    </adapter>    
    </ibis>
</configuration>

Use this(plain text output), or this(will render as html) stylesheet and upload the whole to your Ibis. Please convert Ibis4Teacher to your instancename.

A more extended article on xslt within the IAF can be found  at this link

A pipe will need an input message, even in the case you wouldn’t use it at all and send just some text back. For such a case there are special properties. You could use ‘getInputFromFixedValue =”&lt;dummy&gt;dummymessage&lt;/dummy&gt;”‘ , and overcome having to give this pipe a separate input. Many of these special properties can be found in the class itself, but also in their parent classes. In this case the FixedForwardPipe provides ‘getInputFromFixedValue’.


Leave a Comment