Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

Recently, I had a requirement in my project where my client wants a notification to be send to their external event monitoring system (via a JMS protocol) as soon as there is any failure in identified business critical interfaces. After hearing this requirement, below nice article came to my mind.

http://scn.sap.com/community/pi-and-soa-middleware/blog/2012/10/23/customize-e-mail-body-and-subject...

But having said so, I was not very keen in implementing "Alert" interfaces in my landscape and looking for something more generic. So, I started wondering (?), why I cannot create and schedule my own job (somewhat similar to "AlertConsumerJob") which will keep on inquiring interface status (using AlertRetrieveAPI) and in case of any failures read alerts from the alert store (i.e. Consumer) and report the error logs in a more readable format - just thought of mentioning it :wink: .

So, here below I am showing how we can create a custom job in PI/PO (in just 6 simple steps - yeah that's true :smile: ) which will consume alerts from the alert store using "AlertRetrieveAPI" and format the alert text.

Step 1: Create EJB (CustomJOB) and its corresponding EAR (CustomJOB_EAR) project and then import below jar files in your ejb project.

a) engine.jee5.facade.jar

b) jee5.facade.jar

c) tc~je~scheduler~api.jar

Step 2: Create one java class (in my case I have named it as Custom_Job) and start coding the business logic inside OnJob() method.

At runtime, job will execute the logic which is written inside onJob() method.


package com.customjob;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.scheduler.runtime.JobContext;
import com.sap.scheduler.runtime.JobParameter;
import com.sap.scheduler.runtime.mdb.MDBJobImplementation;
    /**
* Message-Driven Bean implementation class for: Custom_JOB
*
*/
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "JobDefinition='Custom_JOB'")
                        })
public class Custom_JOB extends MDBJobImplementation {
    /**
     * Default constructor.
     */
               /**
             * @see MessageListener#onMessage(Message)
             */
    public void onJob(JobContext ctx) {
    Logger log = ctx.getLogger();
    try {
    JobParameter Alert_URL = ctx.getJobParameter("Alert_URL");
    JobParameter Consumer = ctx.getJobParameter("Consumer");
//Cosume alerts from the alert store using custom "ConsumerURL" method
    RetrieveAlert.ConsumeURL(log, Alert_URL.getStringValue(), Consumer.getStringValue());
    }
catch (Exception e) {
    log.log(Level.SEVERE, e.toString(), e);
    throw new RuntimeException(e);
                }
        }
}

Few points to remember:

a) destinationType: Value of property "destinationType" should always be “javax.jms.Queue”.


b) messageSelector: Value of property “messageSelector” can be set as your “Job Name” (in my case it is Custom_Job). In fact, you can choose any name over here, but make sure the "JobDefinition" name which you have defined over here has to be identical with the name of job definition (which you will define later in step 4) in job-definition.xml deployment descriptor file.


c) OnJob() method: Inside this method you have to code the business logic that the instance of the job definition should perform at runtime.


d) JobContext Interface: Using this you can access a logger object to write job logs in the database. In addition to that, you can read job parameters from PI (which you will define while scheduling jobs in NWA) using getJobParameter method.


e) "ConsumeURL" method : For a clarity purpose, i have created a separate method named as "ConsumeURL" which will perform the task of consuming alerts from store using "AlertRetrieveAPI" and formatting the alert text.


Step 3: Edit "ejb-j2ee-engine.xml" deployment descriptor file.


<?xml version="1.0" encoding="UTF-8"?>
<ejb-j2ee-engine xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <enterprise-beans>
    <enterprise-bean>
      <ejb-name>Custom_JOB</ejb-name>
      <jndi-name> CustomAlert</jndi-name>
      <message-props>
        <destination-name>JobQueue</destination-name>
        <connection-factory-name>JobQueueFactory</connection-factory-name>
      </message-props>
    </enterprise-bean>
  </enterprise-beans>
</ejb-j2ee-engine>

Points to remember:

a) You have to specify "JobQueue" as the destination name, and "JobQueueFactory" as the connection factory name as shown in the code sample above.


b) You have to specify bean name (in my case it's Custom_JOB) as your ejb-name.

Step 4: Create "job-definition.xml" deployment descriptor file from scratch and then edit the same with below sample code.


<?xml version="1.0" encoding="UTF-8"?>
<job-definitions>
<job-definition name="Custom_JOB"
        description="Retrieve SAP PO Alerts from Consumer">
                                <job-definition-parameter name="Alert_URL"
                                                data-type="String" direction="IN"/>
                                <job-definition-parameter name="Consumer"
                                                data-type="String" direction="IN"/>
                </job-definition>
</job-definitions>

Job-definition.xml is an additional descriptor which identifies the deployed message driven bean as a JobBean.


Important: In the job-definition.xml file, you have to specify the name of the job definition and it has to be the same as the job name specified in the message selector in the JobBean class (i.e. Custom_JOB, refer step 2.b).

In addition to that, you have to declare the name, data type, and direction of the job parameters used in the Custom_JobBean class. The same parameters you will see while scheduling job in NWA (refer step 6).


Step 5: Open EAR project (CustomJOB_EAR) and edit application-j2ee-engine.xml file with below sample code.



<?xml version="1.0" encoding="UTF-8"?>
<application-j2ee-engine xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <provider-name>sap.com</provider-name>
  <reference reference-type="hard">
    <reference-target provider-name="sap.com" target-type= "service">
           scheduler~runtime
    </reference-target>
  </reference>
  <modules-additional>
    <module>
      <entry-name>Custom_JOB.jar</entry-name>
      <container-type>scheduler~container</container-type>
    </module>
  </modules-additional>

</application-j2ee-engine>

Step 6: Deploy EAR file on PO server and eventually schedule your custom job.


Provide values to the input parameters while scheduling custom job (i.e "AlertRetrieveAPI" Endpoint URL and Consumer Name)

And here you go :smile:

Conclusion: The steps which I have explained above will hold true while creating any custom job in SAP PI/PO and IMO, this could be useful in many types of scenarios. In fact, a replica of "AlertConsumerJob" can also be created and alerts can be send to email server in a desirable format.

References:

http://help.sap.com/saphelp_nwce71/helpdata/en/44/3652e89c3b4cc6e10000000a11466f/content.htm

http://scn.sap.com/community/pi-and-soa-middleware/blog/2013/03/27/alerting-on-aaeaex

http://help.sap.com/saphelp_nw73ehp1/helpdata/en/f0/fa16430baf4c22a5b1265a6a973f36/content.htm - Details about how to register custom consumer using standard API

15 Comments
Labels in this area