そごうソフトウェア研究所

SOA、開発プロセス、ITアーキテクチャなどについて書いています。Twitterやってます@rsogo

Mule ESBのフロー定義中にでGroovyスクリプトでカスタムのロジックを埋め込む

そういえば、Salesforce.comによるMulesoftの買収が発表されましたね。今後、どのようになっていくのか注目したいと思います。

www.mulesoft.com

さて、今回はMuleのフロー定義にGroovyのスクリプトを埋め込んでみたいと思います。 これができるとMuleで予め用意されたメッセージの変換ルール関数以外の独自処理をスクリプトで行うことができます。 Groovy以外にもJavaScriptなどのスクリプトを呼び出せます。

フロー定義

全体像

HTTPのGETリクエストを受け取り、URLのPATHのlxに置き換えるという処理をしています。 処理は<scripting:transformer>の中でやっています。名前空間http://www.mulesoft.org/schema/mule/scriptingを使うためにhttp://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd"を宣言に追加しています。

<mule
  xmlns="http://www.mulesoft.org/schema/mule/core"
  xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
  xmlns:http="http://www.mulesoft.org/schema/mule/http"
  xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd">

  <http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8086" basePath="groovy" doc:name="HTTP Listener Configuration"/>

  <!-- GET -->
  <flow name="GetFlow">
    <http:listener config-ref="HTTP_Listener_Configuration" path="/*" doc:name="Recieve HTTP request" allowedMethods="GET">
      <http:response-builder reasonPhrase="#[flowVars['reason']]" statusCode="#[flowVars['statusCode']]"/>
    </http:listener>
    <logger doc:name="Log the payload" level="INFO" message="GET is called."/>

    <set-variable variableName="VarTableName"
                  value="#[message.inboundProperties['http.request.path']]"
                  doc:name="Variable"/>
                  
    <scripting:transformer name="stringReplaceWithParams">
      <scripting:script engine="groovy">
        <property key="oldStr" value="l" />
        <property key="newStr" value="x" />
        <scripting:text>
          return VarTableName.toString().replaceAll("$oldStr", "$newStr")
        </scripting:text>
      </scripting:script>
    </scripting:transformer>
  </flow>
</mule>

ステップバイステップで見ていきます。

HTTPリクエストのリッスン

8086ポートで、URLのベースのパスとして/groovyに来たリクエストを受け取る設定になっています。

<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8086" basePath="groovy" doc:name="HTTP Listener Configuration"/>

GETメソッドで呼び出されたときに、下記のフローが動作します。

  <flow name="GetFlow">
    <http:listener config-ref="HTTP_Listener_Configuration" path="/*" doc:name="Recieve HTTP request" allowedMethods="GET">

URLパスの取り出し

HTTPリクエストのパス(ホスト名、ポート名は含まず、それ以降)を取り出し、VarTableNameという変数に入れています。

    <set-variable variableName="VarTableName"
                  value="#[message.inboundProperties['http.request.path']]"
                  doc:name="Variable"/>

Groovyのスクリプトで文字列操作

    <scripting:transformer name="stringReplaceWithParams">
      <!-- scriptのエンジンとして、groovyを指定 -->
      <scripting:script engine="groovy">
        <!-- 変数に値を設定 -->
        <property key="oldStr" value="l" />
        <property key="newStr" value="x" />
        <!-- 実際のGroovyのコード。replaceAllでURLパスの文字列を変換して、応答として返す -->
        <scripting:text>
          return VarTableName.toString().replaceAll("$oldStr", "$newStr")
        </scripting:text>
      </scripting:script>
    </scripting:transformer>

テストしてみましょう

リクエス

次のURLに対して、GETメソッドのリクエストを出します

http://localhost:8086/groovy/helloworld

レスポンス

URLのパス(/groovy/helloworld)のうち、lxに置換した結果が返ってきています。

/groovy/hexxoworxd

curlコマンドで確認したら、こんな感じ。

$ curl http://localhost:8086/groovy/helloworld
/groovy/hexxoworxd

うまくいきましたね。