2013-04-28 12 views
6

DBLookupメディエータのドキュメントでは、問合せの最初の行のみが戻され、他の結果がある場合は無視されます。WSO2 ESB DBLookupメディエータ問合せ複数行

複数のレコードを戻して処理するクエリ(SELECT * FROM X)を実行する「最良の方法」があるかどうかを知りたいと思います。今はaxis2サービスを実装している日ですが、wso2 esbによって提供されるメディエーターの組み合わせを使用してその要件を達成する別の方法がありますか?

ありがとうございます。

サンティアゴ。

答えて

6

はいDBlookupメディエーターは複数の行を戻しません。 2つの選択肢を使用できます。

1)WSO2データサービスサーバーを使用してデータサービスを作成し、コールアウトメディエータを使用してESBからそのサービスを呼び出します。

2)クラスメディエータを作成してデータベースからデータをクエリし、それからペイロードを作成し、それをシーケンスに送信することができます。

+1

アンワースのためにシェランに感謝します。私はそれが非常に一般的な問題だと思うのですが、なぜSynapseやWSO2があなたの答えのオプション番号2をすぐに提供しなかったのか知っていますか?おそらく、メッセージのペイロード(クエリの結果が大きすぎる)がシナプスのメッセージコンテキストにいくつかの欠点を持つ可能性がありますか?それとも問題はない? サンティアゴに感謝します。 – smontico

+0

はい。結果セットが大きすぎる場合、それらをメッセージ・コンテキストに追加することは問題です。提供されたソリューションがエレガントではないので、これに関連するこのJIRAはオープン状態のままです。https://issues.apache.org/jira/browse/SYNAPSE-533 –

+0

はい私はそれを参照してください、なぜ私はあなたに尋ねることです...応答シェランのためにたくさんありがとう! – smontico

2

DB検索メディエータの欠点を克服するために、別のサービスを作成したり、WSO2 Data Services Serverを完全に設定することを避けるために、既存のメディエータを拡張しましたが、時間制約のためにコードをコミュニティに戻すことはできませんでした。更新されたorg.apache.synapse.mediators.db.DBLookupMediatorのコードは次のとおりです。

基本的に、ResultSetをXML形式に変換し、その結果をDB_SEARCH_RESULTプロパティに設定します。それはおそらく競争条件についても研磨とテストを必要とするでしょう。

package org.apache.synapse.mediators.db; 

import org.apache.synapse.MessageContext; 
import org.apache.synapse.SynapseException; 
import org.apache.synapse.SynapseLog; 
import org.w3c.dom.Attr; 
import org.w3c.dom.Document; 
import org.w3c.dom.Element; 

import java.io.StringWriter; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.ResultSetMetaData; 
import java.sql.SQLException; 
import java.sql.Connection; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.transform.OutputKeys; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

/** 
* Simple database table lookup mediator. Designed only for read/lookup 
*/ 
public class DBLookupMediator extends AbstractDBMediator { 

    public static final String DB_SEARCH_RESULTS_PROPERTY_NAME = "DB_SEARCH_RESULT"; 

    protected void processStatement(Statement stmnt, MessageContext msgCtx) { 

     SynapseLog synLog = getLog(msgCtx); 

     // execute the prepared statement, and extract the first result row and 
     // set as message context properties, any results that have been specified 
     Connection con = null; 
     ResultSet rs = null; 
     try { 
      PreparedStatement ps = getPreparedStatement(stmnt, msgCtx); 
      con = ps.getConnection(); 
      rs = ps.executeQuery(); 

      // convert RS to XML 
      String rsXML = convertRSToXML(rs); 

      // add result XML to the Message Context 
      msgCtx.setProperty(DB_SEARCH_RESULTS_PROPERTY_NAME, rsXML); 

      // rollback to the beginning of ResultSet to allow standard processing 
      rs = ps.executeQuery(); 

      if (rs.next()) { 
       if (synLog.isTraceOrDebugEnabled()) { 
        synLog.traceOrDebug(
         "Processing the first row returned : " + stmnt.getRawStatement()); 
       } 

       for (String propName : stmnt.getResultsMap().keySet()) { 

        String columnStr = stmnt.getResultsMap().get(propName); 
        Object obj; 
        try { 
         int colNum = Integer.parseInt(columnStr); 
         obj = rs.getObject(colNum); 
        } catch (NumberFormatException ignore) { 
         obj = rs.getObject(columnStr); 
        } 

        if (obj != null) { 
         if (synLog.isTraceOrDebugEnabled()) { 
          synLog.traceOrDebug("Column : " + columnStr + 
            " returned value : " + obj + 
            " Setting this as the message property : " + propName); 
         } 
         msgCtx.setProperty(propName, obj.toString()); 
        } else { 
         if (synLog.isTraceOrDebugEnabled()) { 
          synLog.traceOrDebugWarn("Column : " + columnStr + 
            " returned null Skip setting message property : " + propName); 
         } 
        } 
       } 
      } else { 
       if (synLog.isTraceOrDebugEnabled()) { 
        synLog.traceOrDebug("Statement : " 
         + stmnt.getRawStatement() + " returned 0 rows"); 
       } 
      } 

     } catch (SQLException e) { 
      handleException("Error executing statement : " + stmnt.getRawStatement() + 
       " against DataSource : " + getDSName(), e, msgCtx); 
     } finally { 
      if (rs != null) { 
       try { 
        rs.close(); 
       } catch (SQLException e) {} 
      } 
      if (con != null) { 
       try { 
        con.close(); 
       } catch (SQLException ignore) {} 
      } 
     } 
    } 

    private String convertRSToXML(ResultSet rs) throws SQLException { 
     ResultSetMetaData rsmd = rs.getMetaData(); 

     // create XML document 
     DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder docBuilder; 
     Document doc = null; 
     try { 
      docBuilder = dbfac.newDocumentBuilder(); 
      doc = docBuilder.newDocument(); 
     } catch (ParserConfigurationException pce) { 
      throw new SynapseException("Failed to transform Resultset to XML", pce); 
     } 

     // create Root element 
     Element rootElement = doc.createElement("table"); 
     doc.appendChild(rootElement); 

     while (rs.next()) { 
      // add Record element 
      Element recordElement = doc.createElement("record"); 
      rootElement.appendChild(recordElement); 

      for (int i = 1; i <= rsmd.getColumnCount(); i++) { 
       String columnName = rsmd.getColumnName(i); 
       String columnValue = rs.getObject(i).toString(); 

       // add Field element 
       Element fieldElement = doc.createElement("field"); 
       fieldElement.appendChild(doc.createTextNode(columnValue)); 

       // set Name attribute to Field element 
       Attr nameAttr = doc.createAttribute("name"); 
       nameAttr.setValue(columnName); 
       fieldElement.setAttributeNode(nameAttr);     

       // add Field to Record 
       recordElement.appendChild(fieldElement);        
      } 
     } 

     //Output the XML 
     String xmlString = null; 

     try { 
      //set up a transformer 
      TransformerFactory transfac = TransformerFactory.newInstance(); 
      Transformer trans = transfac.newTransformer(); 
      trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
      trans.setOutputProperty(OutputKeys.INDENT, "yes"); 

      //create string from XML tree 
      StringWriter sw = new StringWriter(); 
      StreamResult result = new StreamResult(sw); 
      DOMSource source = new DOMSource(doc); 
      trans.transform(source, result); 
      xmlString = sw.toString();  
     } catch (javax.xml.transform.TransformerException te) { 
      throw new SynapseException("Failed to transform Resultset to XML", te); 
     } 

     return xmlString; 
    } 

} 
2

からは、DbSelectのメディエータを使用してください。しかし、Data Services Server(DSS)を使用してクエリを作成することができます。その後、コールメディエーターまたはメディエーターを使用してそれらを呼び出すことができます。 WSO2 EIでは、DSSも利用可能です。データは(DSS運転中)またはSOAP(DSSリソースに)RESTとして公開することができますドキュメントここ

https://docs.wso2.com/display/EI611/Generating+a+Data+Service https://docs.wso2.com/display/EI611/Exposing+Data+as+a+REST+Resource

を参照してください。

関連する問題