2012-02-24 21 views
5

मैंने इस प्रश्न को Mirth forum पर भी पूछा है।जेएक्स-डब्ल्यूएस जावा क्लाइंट, डब्ल्यूसीएफ सेवा इंटरऑपरेबिलिटी: "400: खराब अनुरोध"

हम वर्तमान में ओपन सोर्स हेल्थ केयर एकीकरण इंजन मिर्थ का उपयोग कर डब्ल्यूसीएफ सेवा से जुड़ने की कोशिश कर रहे हैं। मिर्थ जावा-आधारित है, आंतरिक रूप से मुले का उपयोग करता है जो जेएक्स-डब्ल्यूएस का उपयोग करता है। डब्ल्यूसीएफ सर्वर HTTP स्टेटस कोड "400: खराब अनुरोध" लौटा रहा है। हमारे पास डब्ल्यूसीएफ सर्वर तक आसान पहुंच नहीं है।

क्लाइंट के साथ संचार सी # में अच्छी तरह से काम करता है। दृश्य स्टूडियो में, में सेवा संदर्भ जोड़ने के लिए, और फिर मुख्य():

PatientRegistryQueryFulfiller.GetDemographicsClient svc = new PatientRegistryQueryFulfiller.GetDemographicsClient(); 
doc.Load(@"C:\MirthTesting\PRPA_EX201307NO_10_PatientReg_GetDemographics.xml"); 
PatientRegistryQueryFulfiller.PRPA_IN201307NO patientRegistryRequest = (PatientRegistryQueryFulfiller.PRPA_IN201307NO)ObjectSerializer.DeserializeObject(doc, typeof(PatientRegistryQueryFulfiller.PRPA_IN201307NO)); 
PatientRegistryQueryFulfiller.PRPA_IN201307NOResponse patientRegistryResponse = svc.GetDemographics(patientRegistryRequest); 
doc = ObjectSerializer.SerializeObject(patientRegistryResponse.Item); 

(WSDL से) स्वत: जनरेट की WCF ग्राहक कि समाप्ति बिंदु के साथ एक app.config है, और इस बंधन:

<bindings> 
    <basicHttpBinding> 
     <binding name="PatientRegistryQueryFulfiller_Binding" closeTimeout="00:01:00" 
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
     allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
     maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
     messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
     useDefaultWebProxy="true"> 
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="655360" 
      maxBytesPerRead="4096" maxNameTableCharCount="655360" /> 
     <security mode="None"> 
     <transport clientCredentialType="None" proxyCredentialType="None" 
      realm="" /> 
     <message clientCredentialType="UserName" algorithmSuite="Default" /> 
     </security> 
    </binding> 
    </basicHttpBinding> 
</bindings> 

डब्ल्यूसीएफ-समाधान में अलग-अलग काम किया गया एकमात्र चीज maxNameTableCharCount और maxArrayLength को प्रश्न में बाध्यकारी के लिए readerQuotas टैग में विस्तारित कर रहा है, बाकी को डिफ़ॉल्ट मानों के साथ छोड़ दिया गया है। हालांकि, मुझे इन्हें मिर्थ में सेट करने का कोई तरीका नहीं मिला है, क्या यह वास्तव में त्रुटि का कारण होना चाहिए।

हम मिर्थ बनाम 2.2.1 (सबसे हालिया चेकआउट) चला रहे हैं, और मिर्थ चैनल दोनों को पढ़ने और एचएल 7 वी 3 दस्तावेज़ भेजने के लिए सेट है। समस्या तब उत्पन्न होती है जब डब्ल्यूसीएफ-सेवा के साथ संवाद करने की कोशिश की जाती है। गंतव्य एक वेब सेवा प्रेषक है, जिसमें सेवा और बंदरगाह दोनों डब्लूएसडीएल से पढ़े जाते हैं। कोई आश्रय नहीं है, और लिफाफा केवल उपलब्ध ऑपरेशन से उत्पन्न होता है। हम एमटीओएम का उपयोग नहीं कर रहे हैं।

हम काफी निश्चित हैं कि यह जेएक्स-डब्ल्यूएस और डब्ल्यूसीएफ इंटरऑपरेबिलिटी से संबंधित है। कोई सामान्य संकेत?

हमने जेएक्स-डब्ल्यूएस कनेक्शन पर गुणों को सेट करने का प्रयास किया है। प्रमोद के आंत में दीप, हम http हिस्सा आकार सेट की कोशिश की है:। dispatch.getRequestContext() डाल (JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192) (WebServiceMessageDispatcher.Java लाइन 140)

स्टैक ट्रेस इस प्रकार है:

ERROR-410: Web Service Connector error 
ERROR MESSAGE: Error connecting to web service. 
com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 400: Bad Request 
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.checkStatusCode(Unknown Source) 
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(Unknown Source) 
at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(Unknown Source) 
at com.sun.xml.internal.ws.transport.DeferredTransportPipe.processRequest(Unknown Source) 
at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Unknown Source) 
at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Unknown Source) 
at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Unknown Source) 
at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Unknown Source) 
at com.sun.xml.internal.ws.client.Stub.process(Unknown Source) 
at com.sun.xml.internal.ws.client.dispatch.DispatchImpl.doInvoke(Unknown Source) 
at com.sun.xml.internal.ws.client.dispatch.DispatchImpl.invoke(Unknown Source) 
at com.mirth.connect.connectors.ws.WebServiceMessageDispatcher.processMessage(WebServiceMessageDispatcher.java:176) 
at com.mirth.connect.connectors.ws.WebServiceMessageDispatcher.doDispatch(WebServiceMessageDispatcher.java:106) 
at com.mirth.connect.connectors.ws.WebServiceMessageDispatcher.doSend(WebServiceMessageDispatcher.java:204) 
at org.mule.providers.AbstractMessageDispatcher.send(AbstractMessageDispatcher.java:164) 
at org.mule.impl.MuleSession.sendEvent(MuleSession.java:191) 
at org.mule.impl.MuleSession.sendEvent(MuleSession.java:130) 
at org.mule.routing.outbound.AbstractOutboundRouter.send(AbstractOutboundRouter.java:85) 
at org.mule.routing.outbound.FilteringMulticastingRouter.route(FilteringMulticastingRouter.java:54) 
at org.mule.routing.outbound.OutboundMessageRouter$1.doInTransaction(OutboundMessageRouter.java:78) 
at org.mule.transaction.TransactionTemplate.execute(TransactionTemplate.java:48) 
at org.mule.routing.outbound.OutboundMessageRouter.route(OutboundMessageRouter.java:82) 
at org.mule.impl.model.DefaultMuleProxy.onCall(DefaultMuleProxy.java:247) 
at org.mule.impl.model.seda.SedaComponent.doSend(SedaComponent.java:209) 
at org.mule.impl.model.AbstractComponent.sendEvent(AbstractComponent.java:277) 
at org.mule.impl.MuleSession.sendEvent(MuleSession.java:201) 
at org.mule.routing.inbound.InboundMessageRouter.send(InboundMessageRouter.java:176) 
at org.mule.routing.inbound.InboundMessageRouter.route(InboundMessageRouter.java:143) 
at org.mule.providers.AbstractMessageReceiver$DefaultInternalMessageListener.onMessage(AbstractMessageReceiver.java:487) 
at org.mule.providers.AbstractMessageReceiver.routeMessage(AbstractMessageReceiver.java:266) 
at org.mule.providers.AbstractMessageReceiver.routeMessage(AbstractMessageReceiver.java:225) 
at com.mirth.connect.connectors.vm.VMMessageReceiver.getMessages(VMMessageReceiver.java:223) 
at org.mule.providers.TransactedPollingMessageReceiver.poll(TransactedPollingMessageReceiver.java:108) 
at org.mule.providers.PollingMessageReceiver.run(PollingMessageReceiver.java:97) 
at org.mule.impl.work.WorkerContext.run(WorkerContext.java:290) 
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061) 
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575) 
at java.lang.Thread.run(Unknown Source) 
+0

है? –

+0

एक और विचार सभी अनइडेड कॉन्फ़िगर बिट्स से छुटकारा पाने के लिए है और केवल उन चीजों को कॉन्फ़िगर करें जिन्हें आप चाहते हैं। स्वत: जेनरेट की गई कॉन्फ़िगरेशन फ़ाइलें अनावश्यक रूप से वर्बोज़ हैं। शायद समस्या का समाधान नहीं होगा, लेकिन वैसे भी मदद कर सकते हैं। –

उत्तर

3

हमें एक समाधान मिला। the Mirth forum पर समाधान का लंबा विवरण।

समस्या यह थी कि वेब सेवाओं ने हमें "400: बुरा अनुरोध" दिया जब हमने इसे एक अनुरोध भेजने की कोशिश की जिसे हमने सोचा था। "400 खराब अनुरोध" एक बहुत ही सामान्य और सूचनात्मक त्रुटि नहीं है।

परीक्षण

यह समाधान डीबग फ़ाइल आधारित परीक्षण दोहन है कि आप समझने के लिए Mirth करता है प्रयोग कर सकते हैं के लिए एक समाधान। यह उत्पादन-गुणवत्ता समाधान नहीं है। YMMV।

  • Mirth
  • स्थापित वेब सेवा (जैसे EncounterManager) की डबल्यूएसडीएल फ़ाइलों को डाउनलोड करें और उन्हें Mirth सर्वर \ public_html \ EncounterManager के घेरे में रखा ताकि Mirth उन्हें होस्ट कर सकते हैं।
  • ऊपर स्थानीय WSDL फ़ाइल में, यह संशोधित करने और यह सुनिश्चित कर लें कि अंत बिंदुओं पर सोप कार्रवाई वास्तविक वेब सेवा करने के लिए:

साबुन: पता स्थान = "http: // अपने -server/HL7Connector/GetDemographicsService30/"/

  • पुनः प्रारंभ Mirth अगर यह पहले से ही शुरू कर रहा है।
  • Mirth कनेक्ट में,
  • बस के परीक्षण के लिए, स्रोत इस चैनल के बनाने के उदाहरण भेजने वाले के लिए, एक नया चैनल बनाने के लिए एक फ़ाइल पाठक कि एक पाठ फ़ाइल से (उदाहरण के लिए एक मरीज पहचानकर्ता में कुछ पढ़ता)। उदाहरण के लिए, इसे सी: \ MirthTesting \ unread पर मतदान करें। फ़ाइल को पर समाप्त करने के बाद फ़ाइल को स्थानांतरित करने के लिए Mirth बताएं: \ MirthTesting \ read
  • नए ट्रांसफॉर्मर के सारांश पृष्ठ पर, "डेटा प्रकार सेट करें" पर क्लिक करें।
  • स्रोत कनेक्टर को सेट डेटा प्रकार भीतर का = पाठ सीमांकित, स्रोत कनेक्टर आउटबाउंड = HL7, गंतव्य 1 आउटबाउंड = पाठ सीमांकित। यह सिर्फ परीक्षण के लिए है, आप बाद में फैंसी एचएल 7 सामान कर सकते हैं।
  • स्रोत में, पर क्लिक करें ट्रांसफॉर्मर संपादित करें।
  • "नया चरण जोड़ें" पर क्लिक करें, नया वैरिएबल नाम "patientIdWanted" दर्ज करें और मैपिंग के लिए दर्ज करें, "messageObject.getRawData()"। यह Mirth जो कुछ भी पाठ फ़ाइल आप "अपठित" निर्देशिका में डाल की सामग्री पढ़ सकते हैं और एक वेब में अपने नए चैनल की गंतव्य बनाओ एक चर है कि आप
  • (चैनल नक्शे में) बाद में उपयोग कर सकते हैं में डाल बनाता है सेवा प्रेषक। स्थानीय डब्लूएसडीएल का यूआरएल दर्ज करें (उदा। http: // localhost: 8080/EncounterManager/EncounterManagerQueryFulfiller.wsdl)
  • ऑपरेशन प्राप्त करें पर क्लिक करें, फिर लिफाफा उत्पन्न करें।
  • एसओएपी लिफाफा बहुत बड़ा है और एचएल 7 गैर-ज्ञान (मेरे लिए) से भरा है। इसे एक साधारण उदाहरण के साथ बदलें जो काम करता है, और सभी अनावश्यक एचएल 7 क्रुफ्ट को हटा दें। आपके प्रदाता को आपको एक कामकाजी उदाहरण देना चाहिए।
  • अब आपको एसओएपी लिफाफे में फ़ाइल रीडर चरण से पढ़ने वाले चर डालने की आवश्यकता है। आपके एसओएपी लिफाफे में "पेलोड" होना चाहिए, उदा। कहीं रोगी पहचानकर्ता। GetDemographics क्वेरी के लिए, ऐसा लगता है (इसका हिस्सा)। ध्यान दें कि $ {patientIdWanted} वह जगह है जहां मिर्थ टेम्पलेट में मान को प्रतिस्थापित करता है, जो भी हम उपरोक्त टेक्स्ट फ़ाइल से चैनल मैप में डालते हैं।
  • अब इस चैनल को सहेजें।
  • पिछले चरण में वेब सेवा आपको प्राप्त करने के लिए एक नया चैनल बनाएं। इसे कॉल करें रिसीवर
  • नए चैनल में, डेटा प्रकारों को सभी "सीमित टेक्स्ट" पर सेट करें। फिर, सिर्फ परीक्षण के लिए।
  • "चैनल पाठक"
  • फ़ाइल लेखक करने के लिए नए चैनल के गंतव्य सेट करने के लिए "रिसीवर" चैनल के स्रोत निर्धारित करें। एक निर्देशिका और एक फ़ाइल नाम दर्ज करें, उदा। सी: \ MirthTesting \ read \ webservice-response.txt पढ़ें। टेम्पलेट में, मिर्थ के पास सबकुछ देखने के लिए $ {message.rawData} दर्ज करें।
  • , वापस भेजने वाले चैनल पर जाएं गंतव्य का चयन करें, प्रतिक्रिया के गंतव्य के रूप में रिसीवर चैनल दर्ज करें।
  • परिवर्तन सहेजें, कनेक्टर को सत्यापित करें, सभी चैनलों को फिर से तैनात करें।
  • अब यह एक रोगी पहचानकर्ता के साथ एक पाठ फ़ाइल बनाने के लिए, और यह सी में डाल दिया: \ MirthTesting \ अपठित
  • Mirth इस फाइल को दिखाया जाएगा (तो "पढ़ें" निर्देशिका में ले जाएं)। आपका पहला चैनल टेक्स्ट फ़ाइल प्राप्त करेगा, सामग्री को चैनल मानचित्र $ {patientIdWanted} में ले जाएं। फिर आपकी वेब सेवा इस रोगी पहचानकर्ता के साथ एसओएपी लिफाफा प्राप्त करेगी। प्रतिक्रिया रिसीवर चैनल पर भेजी जाएगी, और सादा पाठ के रूप में डंप किया जाएगा।

सामग्री है कि उपयोगी

  • महसूस करते हुए कि Mirth एक परमाणु उप है था: शक्तिशाली और रहस्यमय। कोई मैनुअल नहीं!
  • और सी # में कुछ हद तक कुशल होने के नाते जावा
  • HL7 संदेश जो भावना
  • कर सत्यापित करने के लिए है कि हम साथ सादा सी # वेब सेवा से पढ़ सकता है एक शुद्ध सी # ग्राहक उत्पन्न करने के लिए दृश्य स्टूडियो का उपयोग करने के उदाहरण के बाद। (हमने WSDL फ़ाइलों को होस्ट करने के लिए मिर्थ का उपयोग किया था, लेकिन आप आईआईएस का उपयोग कर सकते हैं)
  • जावा क्लाइंट उत्पन्न करने के लिए एक्लिप्स का उपयोग करके यह सत्यापित करने के लिए कि हम जावा के साथ वेब सेवा से पढ़ सकते हैं। हमने एसओएपीयूआई (मिर्थ यूज के समान ही) का उपयोग ग्रहण इंडिगो ईई संस्करण (wsimport.bat का उपयोग कर कमांड लाइन से)
  • स्रोत से मिथ डाउनलोड करना और ग्रहण से इसे चलाने के साथ किया।
  • HTTP डंपिंग (ग्रहण में) चालू करना। "कॉन्फ़िगरेशन चलाएं", वीएम तर्क के तहत दर्ज करें। -Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump = सच

  • एक पूर्व जोड़ें: इससे आपको यह देखने Mirth (या अपने जावा ग्राहक) वेब सेवा के लिए भेजता है कि वास्तव में क्या करने देता है अपने इस चैनल के लिए स्क्रिप्ट -processing देखने के लिए Mirth वास्तव में क्या करता है:

    FileUtil.write('C:/MirthTesting/read/sender_preprocessmessage_in.txt', false, message);return message; 
    
  • अपने इस चैनल में एक के बाद procesing स्क्रिप्ट जोड़ें देखने के लिए क्या Mirth करता है:

    FileUtil.write('C:/MirthTesting/read/dipssender_postprocessmessage.txt', false, message); 
    return; 
    

एक कोड परिवर्तन

वास्तव में यह काम करने के लिए, हमें मिर्थ स्रोत कोड में एक बदलाव करना पड़ा। जेडीके 1.7 के साथ हमने उपयोग किया, मिर्थ वास्तव में एसओएपी कार्रवाई नहीं भेजता था। सर्वर /.../ WebServiceMessageDispatcher में।जावा लाइन 137, हम जोड़ने के लिए किया था:

dispatch.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, true); 

कोई रास्ता नहीं आप सेवा के विन्यास की एक प्रति प्राप्त कर सकते हैं (this blog post से लिया गया)