Browse Source

First version that communicates somehow with XIP

In both direction:
ctkHost->xip simple app
xip host->ctkExampleHostedApp
ivowolf 14 years ago
parent
commit
ab03e87f84

+ 1 - 1
Applications/ctkExampleHostedApp/ctkExampleHostedAppMain.cpp

@@ -155,7 +155,7 @@ int main(int argv, char** argc)
 qCritical() << "app about to start 1";
   // setup the communication infrastructure: DicomAppServer and DicomHostService
   ctkDicomAppServer * appServer = new ctkDicomAppServer(QUrl(appURL).port()); // accesses the app-plugin via getService("ctkDicomAppInterface");
-  ctkDicomHostInterface * hostInterface = new ctkDicomHostService(QUrl(hostURL).port());
+  ctkDicomHostInterface * hostInterface = new ctkDicomHostService(QUrl(hostURL).port(), "/HostInterface");
   framework->getPluginContext()->registerService(QStringList("ctkDicomHostInterface"), hostInterface);
 qCritical() << "app about to start 2";
   // install and start the plugin with the business logic and remember pointer to start it later

+ 33 - 1
Plugins/org.commontk.dicom.wg23.app/ctkDicomAppServerPrivate.cpp

@@ -36,6 +36,8 @@ ctkDicomAppServerPrivate::ctkDicomAppServerPrivate(int port) :
 {
   connect(&server, SIGNAL(incomingSoapMessage(QtSoapMessage,QtSoapMessage*)),
           this, SLOT(incomingSoapMessage(QtSoapMessage,QtSoapMessage*)));
+  connect(&server, SIGNAL(incomingWSDLMessage(QString,QString*)),
+          this, SLOT(incomingWSDLMessage(QString,QString*)));
 
   if (!server.listen(QHostAddress::LocalHost, this->port))
   {
@@ -43,6 +45,36 @@ ctkDicomAppServerPrivate::ctkDicomAppServerPrivate(int port) :
   }
 }
 
+void ctkDicomAppServerPrivate::incomingWSDLMessage(
+  const QString& message, QString* reply)
+{
+  if (message == "?wsdl")
+  {
+    QFile wsdlfile(":/dah/ApplicationService.wsdl");
+    wsdlfile.open(QFile::ReadOnly | QFile::Text);
+    if(wsdlfile.isOpen())
+    {
+      QTextStream textstream(&wsdlfile);
+      *reply = textstream.readAll();
+      QString actualURL="http://localhost:";
+      actualURL+=QString::number(port)+"/ApplicationInterface"; // FIXME: has to be replaced by url provided by host
+      reply->replace("REPLACE_WITH_ACTUAL_URL",actualURL);
+      reply->replace("ApplicationService_schema1.xsd",actualURL+"?xsd=1");
+      //reply->replace("<soap:body use=\"literal\"/>","<soap:body use=\"literal\"></soap:body>");
+    }
+  }
+  else if (message == "?xsd=1")
+  {
+    QFile wsdlfile(":/dah/HostService_schema1.xsd");
+    wsdlfile.open(QFile::ReadOnly | QFile::Text);
+    if(wsdlfile.isOpen())
+    {
+      QTextStream textstream(&wsdlfile);
+      *reply = textstream.readAll();
+    }
+  }
+}
+
 void ctkDicomAppServerPrivate::incomingSoapMessage(const QtSoapMessage& message,
                                               QtSoapMessage* reply)
 {
@@ -90,7 +122,7 @@ void ctkDicomAppServerPrivate::processGetState(
 void ctkDicomAppServerPrivate::processSetState(
     const QtSoapMessage &message, QtSoapMessage *reply)
 {
-    const QtSoapType& stateType = message.method()["state"];
+    const QtSoapType& stateType = message.method()[0];//["state"];
     bool result = appInterface->setState(ctkDicomSoapState::getState(stateType));
   
     reply->setMethod("SetState");

+ 1 - 0
Plugins/org.commontk.dicom.wg23.app/ctkDicomAppServerPrivate.h

@@ -45,6 +45,7 @@ public slots:
 
   void incomingSoapMessage(const QtSoapMessage& message,
                            QtSoapMessage* reply);
+  void incomingWSDLMessage(const QString& message, QString* reply);
 
 private:
 

+ 3 - 3
Plugins/org.commontk.dicom.wg23.app/ctkDicomHostService.cpp

@@ -25,8 +25,8 @@
 
 #include "ctkDicomWG23TypesHelper.h"
 
-ctkDicomHostService::ctkDicomHostService(int port)
-  : d_ptr(new ctkDicomServicePrivate(port))
+ctkDicomHostService::ctkDicomHostService(int port, QString path)
+  : d_ptr(new ctkDicomServicePrivate(port, path))
 {
 
 }
@@ -69,7 +69,7 @@ void ctkDicomHostService::notifyStateChanged(ctkDicomWG23::State state)
 {
   Q_D(ctkDicomService);
 
-  QtSoapType* input = new ctkDicomSoapState("state", state);
+  QtSoapType* input = new ctkDicomSoapState("newState", state); // spec would be "state", jave has "newState"
   d->askHost("notifyStateChanged", input);
 }
 

+ 1 - 1
Plugins/org.commontk.dicom.wg23.app/ctkDicomHostService.h

@@ -33,7 +33,7 @@ class org_commontk_dicom_wg23_app_EXPORT ctkDicomHostService : public ctkDicomHo
 {
 
 public:
-  ctkDicomHostService(int port);
+  ctkDicomHostService(int port, QString path);
   ~ctkDicomHostService();
 
   QString generateUID();

+ 2 - 0
Plugins/org.commontk.dicom.wg23.core/Resources/dah_wsdl.qrc

@@ -1,7 +1,9 @@
 <!DOCTYPE RCC><RCC version="1.0">
 <qresource prefix="/dah">
   <file>HostService.wsdl</file>
+  <file>HostService_schema1.xsd</file>
   <file>ApplicationService.wsdl</file>
+  <file>ApplicationService_schema1.xsd</file>
 </qresource>
 </RCC>
 

+ 18 - 7
Plugins/org.commontk.dicom.wg23.core/ctkDicomServicePrivate.cpp

@@ -28,7 +28,10 @@
 
 #include <stdexcept>
 
-ctkDicomServicePrivate::ctkDicomServicePrivate(int port)
+
+#include <iostream>
+
+ctkDicomServicePrivate::ctkDicomServicePrivate(int port, QString path) : path(path)
 {
   connect(&http, SIGNAL(responseReady()), this, SLOT(responseReady()));
 
@@ -42,19 +45,23 @@ void ctkDicomServicePrivate::responseReady()
 
 const QtSoapType & ctkDicomServicePrivate::askHost(const QString& methodName, QtSoapType* soapType )
 {
-  qDebug() << "Submitting request " << methodName << " to path " << "/HostInterface";
+  QString action="\"";
+  //action.append(methodName);
+  action.append("\"");
+  http.setAction(action);
 
-  http.setAction(methodName);
+  std::cout << "Submitting action " << action.toStdString() << " method " << methodName.toStdString() << " to path " << path.toStdString();
 
   QtSoapMessage request;
-  request.setMethod(methodName);
+  request.setMethod(QtSoapQName(methodName,"http://wg23.dicom.nema.org/"));
   if( soapType != NULL )
   {
     request.addMethodArgument(soapType);
-    qDebug() << "  Argument type is " << soapType->typeName();
+    qDebug() << "  Argument type is " << soapType->typeName() << ". Argument name is " << soapType->name().name();
   }
+  qDebug() << request.toXmlString();
 
-  http.submitRequest(request, "/HostInterface");//"/IHostService");
+  http.submitRequest(request, path);;
 
   qDebug() << "Submitted request " << methodName ;
 
@@ -70,7 +77,11 @@ const QtSoapType & ctkDicomServicePrivate::askHost(const QString& methodName, Qt
 
   if (response.isFault())
   {
-    throw std::runtime_error("ctkDicomServicePrivate: server error (response.IsFault())");
+    qCritical() << "ctkDicomServicePrivate: server error (response.IsFault())";
+    qDebug() << response.faultString().toString().toLatin1().constData() << endl;
+    qDebug() << response.toXmlString();
+    return response.returnValue();
+//    throw std::runtime_error("ctkDicomServicePrivate: server error (response.IsFault())");
   }
 
   qDebug() << "Response: " << response.toXmlString();

+ 2 - 1
Plugins/org.commontk.dicom.wg23.core/ctkDicomServicePrivate.h

@@ -33,7 +33,7 @@ class org_commontk_dicom_wg23_core_EXPORT ctkDicomServicePrivate : public QObjec
   Q_OBJECT
 
 public:
-  ctkDicomServicePrivate(int port);
+  ctkDicomServicePrivate(int port, QString path);
 
   const QtSoapType & askHost(const QString& methodName, QtSoapType* soapStruct);
     
@@ -41,6 +41,7 @@ public:
   QtSoapHttpTransport http;
 
   int port;
+  QString path;
 
 private slots:
 

+ 35 - 14
Plugins/org.commontk.dicom.wg23.core/ctkSoapConnectionRunnable.cpp

@@ -36,7 +36,6 @@ ctkSoapConnectionRunnable::~ctkSoapConnectionRunnable()
 
 void ctkSoapConnectionRunnable::run()
 {
-  QTcpSocket tcpSocket;
   if (!tcpSocket.setSocketDescriptor(socketDescriptor))
   {
     // error handling
@@ -56,35 +55,55 @@ void ctkSoapConnectionRunnable::run()
 
 void ctkSoapConnectionRunnable::readClient(QTcpSocket& socket)
 {
-  bool wsdlRequest = false;
+  QString requestType;
+  int contentLength = -1;
   //qDebug() << socket->readAll();
   while (socket.canReadLine()) {
     QString line = socket.readLine();
     qDebug() << line;
     if(line.contains("?wsdl HTTP"))
     {
-      wsdlRequest = true;
+      requestType = "?wsdl";
+    }
+    if(line.contains("?xsd=1"))
+    {
+      requestType = "?xsd=1";
+    }
+    if(line.contains("SoapAction"))
+    {
+      requestType = line;
+    }
+    if(line.contains("Content-Length: "))
+    {
+      contentLength = line.section(':',1).trimmed().toInt();
     }
     if (line.trimmed().isEmpty())
     {
       QString content;
-      if(wsdlRequest)
+      if(requestType.startsWith("?"))
       {
-        wsdlRequest = false;
-        emit incomingWSDLMessage("wsdl", &content);
+        QByteArray body = socket.readAll();
+        emit incomingWSDLMessage(requestType, &content);
       }
       else
       {
         // Read the http body, which contains the soap message
-        QByteArray body = socket.readAll();
-        qDebug() << body;
-
-        if (body.trimmed().isEmpty())
+        int bytesRead = 0;
+        QByteArray body;
+        while(body.size() < contentLength)
         {
-          qDebug() << "Message body empty";
-          content = "";
+          QByteArray bodyPart = socket.read(contentLength);
+          qDebug() << bodyPart;
+          bytesRead += bodyPart.size();
+          body.append(bodyPart);
+          qDebug() << " Expected content-length: " << contentLength << ". Bytes read so far: " << body.size();
+          if (body.size()<contentLength)
+          {
+            qDebug() << " Message body too small. Trying to read more.";
+            tcpSocket.waitForReadyRead(-1);
+          }
         }
-        else
+        if(body.trimmed().isEmpty()==false)
         {
           QtSoapMessage msg;
           if (!msg.setContent(body))
@@ -116,10 +135,12 @@ void ctkSoapConnectionRunnable::readClient(QTcpSocket& socket)
 
       block.append(content);
 
-      //qDebug() << block;
+      qDebug() << block;
 
       socket.write(block);
 
+      requestType = "";
+      contentLength = -1;
     }
   }
 }

+ 2 - 0
Plugins/org.commontk.dicom.wg23.core/ctkSoapConnectionRunnable_p.h

@@ -50,6 +50,8 @@ private:
   void readClient(QTcpSocket& socket);
 
   int socketDescriptor;
+
+  QTcpSocket tcpSocket;
 };
 
 #endif // CTKSOAPCONNECTIONRUNNABLE_P_H

+ 1 - 1
Plugins/org.commontk.dicom.wg23.host/ctkDicomAbstractHost.cpp

@@ -18,7 +18,7 @@ class ctkDicomAbstractHostPrivate
     }
 
     server = new ctkDicomHostServer(hostInterface,hostPort);
-    appService = new ctkDicomAppService(appPort);
+    appService = new ctkDicomAppService(appPort, "/ApplicationInterface");
   }
   ~ctkDicomAbstractHostPrivate()
   {

+ 3 - 3
Plugins/org.commontk.dicom.wg23.host/ctkDicomAppService.cpp

@@ -25,8 +25,8 @@
 
 #include "ctkDicomWG23TypesHelper.h"
 
-ctkDicomAppService::ctkDicomAppService(int port)
-  : d_ptr(new ctkDicomServicePrivate(port))
+ctkDicomAppService::ctkDicomAppService(int port, QString path)
+  : d_ptr(new ctkDicomServicePrivate(port, path))
 {
 
 }
@@ -45,7 +45,7 @@ ctkDicomWG23::State ctkDicomAppService::getState()
 bool ctkDicomAppService::setState(ctkDicomWG23::State newState)
 {
   Q_D(ctkDicomService);
-  QtSoapType* input = new ctkDicomSoapState("state", newState);
+  QtSoapType* input = new ctkDicomSoapState("newState", newState);
   const QtSoapType & result = d->askHost("setState", input);
   return ctkDicomSoapBool::getBool(result);
 }

+ 1 - 1
Plugins/org.commontk.dicom.wg23.host/ctkDicomAppService.h

@@ -33,7 +33,7 @@ class org_commontk_dicom_wg23_host_EXPORT ctkDicomAppService : public ctkDicomAp
 {
 
 public:
-  ctkDicomAppService(int port);
+  ctkDicomAppService(int port, QString path);
   ~ctkDicomAppService();
 
   ctkDicomWG23::State getState();

+ 17 - 4
Plugins/org.commontk.dicom.wg23.host/ctkDicomHostServerPrivate.cpp

@@ -45,7 +45,7 @@ ctkDicomHostServerPrivate::ctkDicomHostServerPrivate(ctkDicomHostInterface* host
 void ctkDicomHostServerPrivate::incomingWSDLMessage(
   const QString& message, QString* reply)
 {
-  if (message == "wsdl")
+  if (message == "?wsdl")
   {
     QFile wsdlfile(":/dah/HostService.wsdl");
     wsdlfile.open(QFile::ReadOnly | QFile::Text);
@@ -53,8 +53,21 @@ void ctkDicomHostServerPrivate::incomingWSDLMessage(
     {
       QTextStream textstream(&wsdlfile);
       *reply = textstream.readAll();
-      reply->replace("REPLACE_WITH_ACTUAL_URL","http://127.0.0.1:8080/HostInterface");
-      reply->replace("HostService_schema1.xsd","http://127.0.0.1:8080/HostInterface?xsd=1");
+      QString actualURL="http://localhost:";
+      actualURL+=QString::number(port)+"/HostInterface"; // FIXME: has to be replaced by url provided by host
+      reply->replace("REPLACE_WITH_ACTUAL_URL",actualURL);
+      reply->replace("HostService_schema1.xsd",actualURL+"?xsd=1");
+      //reply->replace("<soap:body use=\"literal\"/>","<soap:body use=\"literal\"></soap:body>");
+    }
+  }
+  else if (message == "?xsd=1")
+  {
+    QFile wsdlfile(":/dah/HostService_schema1.xsd");
+    wsdlfile.open(QFile::ReadOnly | QFile::Text);
+    if(wsdlfile.isOpen())
+    {
+      QTextStream textstream(&wsdlfile);
+      *reply = textstream.readAll();
     }
   }
 }
@@ -111,7 +124,7 @@ void ctkDicomHostServerPrivate::processGetAvailableScreen(
 void ctkDicomHostServerPrivate::processNotifyStateChanged(
     const QtSoapMessage &message, QtSoapMessage * /* reply */) const
 {
-  const QtSoapType& stateType = message.method()["state"];
+  const QtSoapType& stateType = message.method()[0];//["state"]; java sends ["newState"];
   hostInterface->notifyStateChanged(ctkDicomSoapState::getState(stateType));
 }