Wednesday, May 30, 2018

Setup Proxy On Anypoint Studio

What Is The Proxy Setting In Your Working Environment?

URL: chrome://net-internals/#proxy You should see a page looks like the following:
Got to the page: http:/wpad./wpad.dat Down load the page which contains all the proxy information like the following:
function FindProxyForURL(url,host)
{
    // set proxy server variables

    var usproxy="PROXY usproxy.XXX.com:8080";
    var dc1host="PROXY XXX.com:8080";
    var dc2host="PROXY XXX.com:8080";

Setup Proxy on Anypoint Studio

Preferences --> Network Connections
Make sure you select Active Provider as "Manual"

Tuesday, May 22, 2018

Install and Configure Java Decompiler ECD In AnyPoiintStudio 7

Introduction

ECD, Enhanced Class Decompiler, so far is the best java class decompiler plugin available for Eclipse and Mule AnyPointStudio. It support JAD, JD, FernFlower, CFE and Procyon. The best of all is that it allows us to debug the code which we don't have source code. For details, please refer to the article here

The ability to debug code without source code is critical to problem solving. In particular, nowadays, most documentation for Mule 4 are not complete. In this blog, I am going to cover the installation and configuration. For the installation, I will build the source code and install from my local. In this way, we learn the details about Eclipse plugin. And if we want to improve the plugin, we can change the code as we want.

The ECD works out of box for Mule Anypoint Studio 6.x. However, it will not work for 7.x. Actually this is caused by underlying Eclipse 4.7.x. This is the main reason I publish this article.

Build ECD Plugin

To build the ECD plugin we need to clone two repositories from github. The procedures are as the following (assume you have git directory under $HOME)
cd git
mkdir ecd
cd ecd
git clone https://github.com/ecd-plugin/ecd.git
git clone https://github.com/ecd-plugin/update.git
cd ecd
mvn clean package

Install And Configure ECD

After the successfully building the plugin, we can install it. Help --> Install New Software --> Add,
click Local
choose the update directory
You should see the following:

click Open
type ECD in the Name
click OK
Now click Finish and install as normal. After restarting the AnyPointStudio, we need to configure the ECD. Note that, it would not work out of box. First, let's check if the ECD is installed. Preference --> Java.
If you see the above, then the ECD is installed correctly. Now, if you try to look a java class, the source code would not be displayed. We need to do the following:
In the preferences, search File Assoc and client *.class, make the lower panel looks like the following
Do the same amke the *.class without source looks like the following:
Now, if you click any class, the Studio will display the source code. Per the author's article, FernFlower and JD are highly recommanded. FernFlower supports all Java versions, but JD is the fastest.

Sunday, May 20, 2018

Mule 4 Introduction - Embedded Runtime Information

Introduction

Mule Runtime 4.1 and AnypointStudio have changed significantly from Mule 3. The runtime information, such as applications, logs, libraries, etc have changed as well.

Runtime Environment Changes

First of all, if you have worked with Mule 3, you probably know where is your log, applications. They are at workspace/.mule directory as shown at the following:
gliu1@LM-SJL-11006574:~/AnypointStudio/workspace/.mule$ ll
total 16
drwxr-xr-x   3 gliu1  110500007    96 Mar  2 16:41 lib
drwxr-xr-x   5 gliu1  110500007   160 Mar 10 14:46 e0334610-24b4-11e8-b36c-acde48001122
drwxr-xr-x   5 gliu1  110500007   160 Mar 10 14:47 02ac31c0-24b5-11e8-b36c-acde48001122
drwxr-xr-x   5 gliu1  110500007   160 Mar 10 17:58 a405bdb0-24cf-11e8-b36c-acde48001122
drwxr-xr-x   5 gliu1  110500007   160 Mar 12 12:40 2dfe1450-262d-11e8-9448-acde48001122
drwxr-xr-x   5 gliu1  110500007   160 Mar 12 12:40 44128b90-262d-11e8-9448-acde48001122
drwxr-xr-x   5 gliu1  110500007   160 Apr  4 18:10 157c8440-386e-11e8-b273-acde48001122
drwxr-xr-x   5 gliu1  110500007   160 Apr  4 18:12 5eb15c80-386e-11e8-b273-acde48001122
drwxr-xr-x   5 gliu1  110500007   160 Apr  4 18:12 768759e0-386e-11e8-b273-acde48001122
drwxr-xr-x   5 gliu1  110500007   160 Apr 13 14:09 fdfecc90-3f5e-11e8-b669-acde48001122
drwxr-xr-x   5 gliu1  110500007   160 Apr 13 18:15 50393e60-3f81-11e8-b669-acde48001122
drwxr-xr-x   9 gliu1  110500007   288 May  3 19:11 plugins-tmp
drwxr-xr-x  21 gliu1  110500007   672 May  6 19:15 .
-rw-r--r--@  1 gliu1  110500007  6148 May  6 19:15 .DS_Store
drwxr-xr-x  24 gliu1  110500007   768 May 16 14:43 ..
drwxr-xr-x  75 gliu1  110500007  2400 May 17 08:26 logs
drwxr-xr-x   4 gliu1  110500007   128 May 17 19:44 conf
drwxr-xr-x   4 gliu1  110500007   128 May 17 19:44 domains
drwxr-xr-x  33 gliu1  110500007  1056 May 17 19:44 .mule
drwxr-xr-x   4 gliu1  110500007   128 May 17 19:44 apps
drwxr-xr-x   3 gliu1  110500007    96 May 17 19:44 policies
gliu1@LM-SJL-11006574:~/AnypointStudio/workspace/.mule$ 

In mule 4, this has been changed to the mule runtime installation directory. In my case, it is like the following:
gliu1@LM-SJL-11006574:/Applications/AnypointStudio-7-1-2.app/Contents/Eclipse/plugins/org.mule.tooling.server.4.1.1.ee_7.1.2.201803261303/mule$ ll
total 48
-rw-r--r--@  1 gliu1  110500007  3678 Mar 16 09:26 README.txt
-rw-r--r--@  1 gliu1  110500007   173 Mar 16 09:26 MIGRATION.txt
-rw-r--r--@  1 gliu1  110500007   518 Mar 16 09:26 LICENSE.txt
drwxr-xr-x@  8 gliu1  110500007   256 Mar 28 10:29 lib
drwxr-xr-x@  3 gliu1  110500007    96 Mar 28 10:41 tools
drwxr-xr-x@ 12 gliu1  110500007   384 Mar 28 10:41 bin
drwxr-xr-x@  8 gliu1  110500007   256 Mar 28 10:41 services
drwxr-xr-x@ 10 gliu1  110500007   320 Mar 28 10:41 ..
drwxr-xr-x   2 gliu1  110500007    64 May 18 18:16 domains-staging
drwxr-xr-x@  4 gliu1  110500007   128 May 18 18:18 server-plugins
drwxr-xr-x@  4 gliu1  110500007   128 May 18 18:18 policies
drwxr-xr-x   3 gliu1  110500007    96 May 18 18:18 tmp
-rw-r--r--   1 gliu1  110500007     0 May 19 18:18 Instance.lock
drwxr-xr-x@ 22 gliu1  110500007   704 May 19 18:18 .
-rw-r--r--   1 gliu1  110500007     6 May 19 18:18 mule_ee.pid
drwxr-xr-x   9 gliu1  110500007   288 May 19 18:18 .mule
drwxr-xr-x@ 18 gliu1  110500007   576 May 19 18:19 conf
drwxr-xr-x@  9 gliu1  110500007   288 May 19 18:19 logs
drwxr-xr-x@  4 gliu1  110500007   128 May 19 18:19 domains
drwxr-xr-x@  4 gliu1  110500007   128 May 19 18:19 apps
-rw-r--r--   1 gliu1  110500007     8 May 19 18:19 mule_ee.java.status
-rw-r--r--   1 gliu1  110500007     8 May 19 18:19 mule_ee.status
The new runtime environment is mule aligned with the standalone mule runtime directory layout. Thus, if you want to looks the runtime logs, you need to traverse to the mule directory. It is easier to create a link so that you don't have to cd to the deeper directory tree.

No More Session Variables

In mule 3, we have flowVars, sessionVars, and recordVars. In mule 4, all variables are referred as vars, i.e. vars.originalPayload. This is related to how connectors and transports work in mule 4. In mule 3, when message passes through the transport barriers the properties will change, i.e., inbound properties will become outbound properties. In Mule 4, there is no transport barrier anymore. This is because mule can handle consumable message (stream, reader, etc).

Mule Message

Mule message is mule 4 contains attributes, payload, and variables. The message.inboundproperties and message.outboundproperties are becoming attributes. message.id and message.rootId become message.serialVersionUID.

Sunday, May 13, 2018

Mule Application Dev: Email Notification With Apache Velocity Engine

Introduction

It is very common to send email notification for important event in the enterprise integration. Mule AnyPoint Platform come with parse-template component, which allow us to pass flow variables, payload, etc to the html template. This approach is very simple and straight forward for the simple email notification. The another approach is to using apache velocity engine to parse more complicated data set to the html template.

In this post, I am going to introduce the both. For the email server, I am going to using Gmail.

The complete code is available at my github repository

The Requirements

The requirement is that clients will pass a json request contains the informaiton as shown in the following:


{
 "subject": "Connection To Oracle Database Not Available",
 "emailTo": "gary.liu1119@gmail.com",
 "emailFrom": "guojiang.liu1119@gmail.com",
 "replyTo" : "gary.liu1119@gmail.com",
 "integrationId" : "OracleDB-To-SFDC",
 "body" : "This is the body message",
 "channel" : "slack channel",
 "footer": "This is generated email. Please DO NOT Reply to this email 
 
 Best Regards, 
 Mule Integration Team",
 "payload" : {
  "header" : ["column_a","column_b","column_c","column_d","column_f"],
  "data": [
   ["column_a_data1","column_b_data1","column_c_data1","column_d_data1","column_f_data1"],
   ["column_a_data2","column_b_data2","column_c_data2","column_d_data2","column_f_data2"],
   ["column_a_data3","column_b_data3","column_c_data3","column_d_data3","column_f_data3"]
   
  ]
 } 
}
The resultant email should look like the following:

Using Template Parser

This is very simple scenario. We will use the <parse-template ...=""> component as the following:
        
The html template is in the following form:
<html>
    <head>
      <title>#[original_payload.subject]</title>
    </head>
    <body>
      Environment: #[environment]
      Date: #[system_date]
      Integration Case ID: #[original_payload.integrationId]      
      #[original_payload.body]
     
      #[original_payload.footer]
 
    </body>
</html>
In the above html code, the #[environment] is the same as #[flowVars.environment] The flows for using parse-template are shown in the following diagram:

Using Velocity

Apache Velocity Engine is a powerful tool for build complicated html template. Here I only introduce the for loop. For more directives, you may refer the following document.

The html template is shown as the following:

<HTML>
    <HEAD>
      <TITLE>$emailInfo.subject</TITLE>
    </HEAD>
    <BODY>
      <BR>
      Environment: $emailInfo.environment     
      <BR><BR>
      Integration ID: $emailInfo.integrationId
      <BR/>
      <BR/>      
      $emailInfo.body     
      <BR/><BR/>   
      <TABLE width="70% "border = "1" cellspacing="0" cellpadding="2" font="5">
        <TR style="text-align: left; font-size: 14px; font-weight: bold; color: #000000;">
        
        #foreach ($headerCol in $emailInfo.payload.header)
                <TH>$headerCol</TH>
        #end
        
        </TR>
        
        #foreach ($data in $emailInfo.payload.data)
            <TR style="text-align: left; font-size: 13px; font-weight: bold; color: #488AC7;">          
            #foreach ($col in $data)
                <TD>$col</TD>
            #end            
            </TR>
        #end
      </TABLE>
     
     <BR/>
     <BR/>
      
     <I>$emailInfo.footer</I>
          
 
    </BODY>
</HTML>

As you can see that for loop takes the following form:

        
        #foreach ($headerCol in $emailInfo.payload.header)
              <TH>$headerCol</TH>
        #end

Where the emailInfo is a java object in the form of: LinkedHashMap emailInfo. The whole idea is MVC, Model, View, Control. The html is the view page, the mode is and java object. Control is the engine injecting data to the view.

The java code is in the following form:


public class VelocityComponent implements Callable
{
 private static Logger logger = LoggerFactory.getLogger(VelocityComponent.class);

 @SuppressWarnings("unchecked")
 @Override
 public Object onCall(MuleEventContext eventContext) throws Exception {
  LinkedHashMap payload = (LinkedHashMap)eventContext.getMessage().getPayload();
  String emailHtml = this.buildEmailHtml(payload);
  return emailHtml;
 }
 
    public String buildEmailHtml(LinkedHashMap emailInfo) throws Exception
    {
        VelocityEngine ve = new VelocityEngine();
        ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
        ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());

        ve.init();
        
        String environment = System.getProperty("mule.env");
        
        emailInfo.put("environment", environment);

        VelocityContext context = new VelocityContext();
        context.put("emailInfo", emailInfo);

        Template t = ve.getTemplate("email-notification-template-velocity.vm" );

        StringWriter writer = new StringWriter();

        t.merge( context, writer );

        logger.info( writer.toString() );
        
        return writer.toString();
    }
}