Tuesday, March 21, 2017

How to communicate a custom mediator error to the end user

You can use the Class mediator and custom mediators for user-specific custom developments when there is no built-in mediator that already provides the required functionality.Let's assume that in my custom mediator if an error occurs while mediating,I log an error and break the mediation chain by returning false in mediate() . However, I'd like to communicate it to the end user (which knows nothing about logs) such that he received the error text in the HTTP response.

Here is a sample custom mediator which I created to achieve that requirement. I’ve added comments for you to understand the code.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package com.sachini;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.synapse.Mediator;
import org.apache.synapse.MessageContext;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.llom.OMTextImpl;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.axiom.soap.SOAPBody;

import javax.xml.stream.XMLStreamException;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axis2.AxisFault;

public class SampleMediator extends AbstractMediator {
 private String myname = "";
 private String sequenceKey = "customFaultSeq";
 public String getMyname() {
  return myname;
 }
 public void setMyname(String myname) {
  this.myname = myname;
 }
 public boolean mediate(MessageContext context) {
  // TODO Implement your mediation logic here 
  System.out.println("**myname ****" + myname);
  if (myname.equalsIgnoreCase("sachini")) {
   System.out.println(myname + "***inside true***");
   return true;
  }

  else {
   System.out.println("***inside false***");
   //Get the axis2MessageContext synapse message context
   org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) context).getAxis2MessageContext();

   //Get Current Envelop       
   SOAPEnvelope axisMsgEnvelope = axis2MessageContext.getEnvelope();
   //Create the custom message which you need to send to enduser
   OMElement customPayloadElement = null;
   String customErrorMessage = "There is an error in your mediation flow";
   //Add the created custom message to context
   try {
    customPayloadElement = AXIOMUtil.stringToOM("<text>" + "<![CDATA[" + customErrorMessage + "]]>" + "</text>");
    context.setEnvelope(createSOAPEnvelope(customPayloadElement));
   } catch(XMLStreamException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch(AxisFault e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   //call the sequence created as customFaultSeq inside ESB
   Mediator sequenceMediatorToInvoke = null;
   if (sequenceKey != null) {
    sequenceMediatorToInvoke = context.getSequence("customFaultSeq");
   } else {
    if (log.isDebugEnabled()) {
     log.debug("Sequence Key not specified.");
    }
   }
   //pass the created message to the customFaultSeq
   sequenceMediatorToInvoke.mediate(context);

   return false;

  }

 }
 private SOAPEnvelope createSOAPEnvelope(OMElement documentElement) {
  SOAPEnvelope envelope;
  SOAPFactory soapFactory = OMAbstractFactory.getSOAP11Factory();
  envelope = soapFactory.getDefaultEnvelope();
  if (documentElement != null) {
   envelope.getBody().addChild(documentElement);
  }
  return envelope;
 }
}

Here is the proxy service which invoke the custom mediator

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="SacProxy"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <log level="full"/>
         <property name="myname" value="sachini" scope="default" type="STRING"/>
         <class name="com.sachini.SampleMediator">
            <property name="myname" value="madhu"/>
         </class>
         <log level="custom">
            <property name="afterClass" value="**afterClass***"/>
         </log>
         <log level="full"/>
      </inSequence>
   </target>
   <description/>
</proxy>
                                

Here is the Custom Fault Sequence which is getting hit when there is an error of mediation in my custom mediator


1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="customFaultSeq" xmlns="http://ws.apache.org/ns/synapse">
    <log level="custom">
        <property name="prop1" value="**inside customFault***"/>
    </log>
    <log level="full"/>
    <respond/>
</sequence>

Here is the response I got through SOAP UI once I invoke the proxy. We are getting our custom error message as HTTP response in our enduser side.



Thanks.

No comments:

Post a Comment

Blogger Widgets