2013-04-28 6 views
6

DBLookup Mediator의 설명서에는 쿼리의 첫 번째 행만 반환되고 다른 결과는 무시됩니다.WSO2 ESB DBLookup 중재자가 여러 행을 쿼리합니다.

여러 레코드를 반환하고 처리하는 쿼리 (SELECT * FROM X)를 실행하는 "최선의 방법"이 있는지 알고 싶습니다. 이제 우리는 축 2 서비스를 구현하고 있습니다. 그러나 wso2 esb에서 제공하는 중개자의 조합을 사용하여 그 요구 사항을 달성하는 또 다른 방법이 있습니까 ??

미리 감사드립니다.

산티아고.

답변

6

예 DBlookup 조정자는 여러 행을 리턴하지 않습니다. 두 가지 대안을 사용할 수 있습니다.

1) WSO2 데이터 서비스 서버를 사용하여 데이터 서비스를 만들고 콜 아웃 조정자를 사용하여 ESB에서 해당 서비스를 호출하십시오.

2) 클래스 중재자를 작성하여 데이터베이스의 데이터를 쿼리 한 다음 페이로드를 생성 한 다음 시퀀스를 통해 보낼 수 있습니다.

+1

셸란에게 감사드립니다. 저는 이것이 매우 일반적인 문제라고 생각합니다. Synapse 또는 WSO2가 대답의 옵션 2 번을 제공하지 않은 이유를 알고 있습니까? 아마도 메시지의 페이로드 (쿼리의 결과가 너무 큼)가 시냅스의 메시지 컨텍스트에 몇 가지 단점을 가질 수 있습니까 ?? 아니면 문제가되지 않습니까? 산티아고에 다시 한 번 감사드립니다. – smontico

+0

예. 결과 집합이 너무 큰 경우 메시지 컨텍스트에 추가하는 것이 문제입니다. 아직이 JIRA 관련 내용은 개방형 상태입니다. https://issues.apache.org/jira/browse/SYNAPSE-533 제공된 솔루션은 훌륭하지 않습니다. –

+0

네, 제가 왜 당신에게 물어 보는 거죠 ... 응답 셸란에게 고마워요! – smontico

2

DB 조회 중재자 단점을 극복하기 위해 다른 서비스를 작성하거나 WS02 데이터 서비스 서버를 완전히 설치하지 않기 위해 기존 중재자를 확장했지만 시간 제약으로 인해 코드를 커뮤니티에 다시 제공하지 않았습니다. 다음은 업데이트 된 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; 
    } 

} 
0

은 단순히 당신이 DBLookUp 중재자를 사용하여 여러 행을 검색 할 수 없습니다 사용하고 JSON 결과

2

을 돌아가려면 여기를 https://github.com/ichakios/dbselect-wso2-mediator 쉽게에서 DBSelect 중재자를 사용합니다. 그러나 데이터 서비스 서버 (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

를 참조하십시오.