diff --git a/Modules/CppRestSdk/test/mitkRESTClientTest.cpp b/Modules/CppRestSdk/test/mitkRESTClientTest.cpp index 742418edd6..a0dc6c713f 100644 --- a/Modules/CppRestSdk/test/mitkRESTClientTest.cpp +++ b/Modules/CppRestSdk/test/mitkRESTClientTest.cpp @@ -1,253 +1,252 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Testing #include "mitkTestFixture.h" #include "mitkTestingMacros.h" // MITK includes #include "mitkRESTClient.h" // VTK includes #include #include "mitkIRESTManager.h" #include #include #include #include #include #include class mitkRESTClientTestSuite : public mitk::TestFixture, mitk::IRESTObserver { CPPUNIT_TEST_SUITE(mitkRESTClientTestSuite); MITK_TEST(GetRequestValidURI_ReturnsExpectedJSON); MITK_TEST(MultipleGetRequestValidURI_AllTasksFinish); MITK_TEST(PutRequestValidURI_ReturnsExpectedJSON); MITK_TEST(PostRequestValidURI_ReturnsExpectedJSON); MITK_TEST(GetRequestInvalidURI_ThrowsException); MITK_TEST(PutRequestInvalidURI_ThrowsException); MITK_TEST(PostRequestInvalidURI_ThrowsException); CPPUNIT_TEST_SUITE_END(); public: mitk::IRESTManager *m_Service; web::json::value m_Data; web::json::value Notify(const web::uri &uri, const web::json::value &data) override { return m_Data; } /** * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used * members for a new test case. (If the members are not used in a test, the method does not need to be called). */ void setUp() override { m_Data[L"userId"] = web::json::value(1); m_Data[L"id"] = web::json::value(1); m_Data[L"title"] = web::json::value(U("this is a title")); m_Data[L"body"] = web::json::value(U("this is a body")); us::ServiceReference serviceRef = us::GetModuleContext()->GetServiceReference(); if (serviceRef) { m_Service = us::GetModuleContext()->GetService(serviceRef); } if (!m_Service) { CPPUNIT_FAIL("Getting Service in setUp() failed"); } m_Service->ReceiveRequest(L"http://localhost:8080/test", this); } void tearDown() override { m_Service->HandleDeleteObserver(this); } void GetRequestValidURI_ReturnsExpectedJSON() { web::json::value *result = new web::json::value(); m_Service->SendRequest(L"http://localhost:8080/test") .then([=](pplx::task resultTask) { try { *result = resultTask.get(); } catch (const mitk::Exception &exception) { MITK_ERROR << exception.what(); return; } }) .wait(); CPPUNIT_ASSERT_MESSAGE("Result is the expected JSON value", *result == m_Data); } void MultipleGetRequestValidURI_AllTasksFinish() { int *count = new int(0); // Create multiple tasks e.g. as shown below - //TODO: vector konstruktoren anschauen / emplace_back - std::vector> tasks; + std::vector> tasks; for (int i = 0; i < 20; ++i) { pplx::task singleTask = m_Service->SendRequest(L"http://localhost:8080/test") .then([=](pplx::task resultTask) { // Do something when a single task is done try { resultTask.get(); *count +=1; } catch (const mitk::Exception &exception) { MITK_ERROR << exception.what(); return; } }); - tasks.push_back(singleTask); + tasks.emplace_back(singleTask); } // Create a joinTask which includes all tasks you've created auto joinTask = pplx::when_all(begin(tasks), end(tasks)); // Run asynchonously joinTask.then([=](pplx::task resultTask) { // Do something when all tasks are finished try { resultTask.get(); *count += 1; } catch (const mitk::Exception &exception) { MITK_ERROR << exception.what(); return; } }).wait(); CPPUNIT_ASSERT_MESSAGE("Multiple Requests", 21 == *count); } void PutRequestValidURI_ReturnsExpectedJSON() { // optional: link might get invalid or content is changed web::json::value *result = new web::json::value(); m_Service ->SendRequest(L"https://jsonplaceholder.typicode.com/posts/1", mitk::IRESTManager::RequestType::Put, &m_Data) .then([=](pplx::task resultTask) { try { *result = resultTask.get(); } catch (const mitk::Exception &exception) { MITK_ERROR << exception.what(); return; } }) .wait(); CPPUNIT_ASSERT_MESSAGE( "Result is the expected JSON value, check if the link is still valid since this is an optional test", *result == m_Data); } void PostRequestValidURI_ReturnsExpectedJSON() { // optional: link might get invalid or content is changed web::json::value *result = new web::json::value(); web::json::value data; data[L"userId"] = m_Data[L"userId"]; data[L"title"] = m_Data[L"title"]; data[L"body"] = m_Data[L"body"]; m_Service->SendRequest(L"https://jsonplaceholder.typicode.com/posts", mitk::IRESTManager::RequestType::Post, &data) .then([=](pplx::task resultTask) { try { *result = resultTask.get(); } catch (const mitk::Exception &exception) { MITK_ERROR << exception.what(); return; } }) .wait(); data[L"id"] = web::json::value(101); CPPUNIT_ASSERT_MESSAGE( "Result is the expected JSON value, check if the link is still valid since this is an optional test", *result == data); } void GetException() { //Method which makes a get request to an invalid uri web::json::value *result = new web::json::value(); m_Service->SendRequest(L"http://localhost:1234/invalid") .then([=](pplx::task resultTask) { *result = resultTask.get(); }) .wait(); } void GetRequestInvalidURI_ThrowsException() { CPPUNIT_ASSERT_THROW(GetException(), mitk::Exception); } void PutException() { //Method which makes a put request to an invalid uri web::json::value *result = new web::json::value(); m_Service->SendRequest(L"http://localhost:1234/invalid", mitk::IRESTManager::RequestType::Put, &m_Data) .then([=](pplx::task resultTask) { *result = resultTask.get();}) .wait(); } void PutRequestInvalidURI_ThrowsException() { CPPUNIT_ASSERT_THROW(PutException(), mitk::Exception); } void PostException() { //Method which makes a post request to an invalid uri web::json::value *result = new web::json::value(); m_Service->SendRequest(L"http://localhost:1234/invalid", mitk::IRESTManager::RequestType::Post, &m_Data) .then([=](pplx::task resultTask) { *result = resultTask.get(); }) .wait(); } void PostRequestInvalidURI_ThrowsException() { CPPUNIT_ASSERT_THROW(PostException(), mitk::Exception); } }; MITK_TEST_SUITE_REGISTRATION(mitkRESTClient) \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.client/src/internal/QmitkClientView.cpp b/Plugins/org.mitk.gui.qt.client/src/internal/QmitkClientView.cpp index 63d52aad1b..8f08f3c3a4 100644 --- a/Plugins/org.mitk.gui.qt.client/src/internal/QmitkClientView.cpp +++ b/Plugins/org.mitk.gui.qt.client/src/internal/QmitkClientView.cpp @@ -1,269 +1,269 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkClientView.h" #include #include "cpprest/json.h" #include #include #include #include #include #include const std::string QmitkClientView::VIEW_ID = "org.mitk.views.clientview"; QmitkClientView::QmitkClientView() : m_Ui(new Ui::QmitkClientView) { } QmitkClientView::~QmitkClientView() { delete m_Ui; } void QmitkClientView::CreateQtPartControl(QWidget *parent) { m_Ui->setupUi(parent); connect(m_Ui->getMultiplePushButton, &QPushButton::clicked, this, &QmitkClientView::OnGetMultipleButtonClicked); connect(m_Ui->getSinglePushButton, &QPushButton::clicked, this, &QmitkClientView::OnGetSingleButtonClicked); connect(m_Ui->getSavePushButton, &QPushButton::clicked, this, &QmitkClientView::OnGetSaveButtonClicked); connect(m_Ui->putPushButton, &QPushButton::clicked, this, &QmitkClientView::OnPutButtonClicked); connect(m_Ui->postPushButton, &QPushButton::clicked, this, &QmitkClientView::OnPostButtonClicked); connect(this, &QmitkClientView::UpdateProgressBar, this, &QmitkClientView::OnUpdateProgressBar); connect(this, SIGNAL(UpdateLabel(QString)), this, SLOT(OnUpdateLabel(QString))); m_Ui->progressBar->setValue(0); } void QmitkClientView::OnUpdateProgressBar() { m_Ui->progressBar->setValue(m_Ui->progressBar->value() + 5); } void QmitkClientView::OnUpdateLabel(QString text) { m_Ui->responseLabel->setText(text); } void QmitkClientView::SetFocus() {} void QmitkClientView::OnGetMultipleButtonClicked() { m_Ui->progressBar->setValue(0); m_Ui->getMultiplePushButton->setDisabled(true); //Get microservice us::ModuleContext *context = us::ModuleRegistry::GetModule(1)->GetModuleContext(); auto managerRef = context->GetServiceReference(); if (managerRef) { auto managerService = context->GetService(managerRef); if (managerService) { //Create multiple tasks e.g. as shown below std::vector> tasks; for (int i = 0; i < 20; i++) { pplx::task singleTask = managerService->SendRequest(L"http://193.174.48.78:8090/dcm4chee-arc/aets/DCM4CHEE/rs/studies/1.2.840.113654.2.70.1.97144850941324808603541273584489321943/series/1.2.840.113654.2.70.1.15771179684190906938515254678965278540/instances") .then([=](pplx::task resultTask) { //Do something when a single task is done try { resultTask.get(); emit UpdateProgressBar(); } catch (const mitk::Exception &exception) { MITK_ERROR << exception.what(); return; } }); - tasks.push_back(singleTask); + tasks.emplace_back(singleTask); } //Create a joinTask which includes all tasks you've created auto joinTask = pplx::when_all(begin(tasks), end(tasks)); //Run asynchonously joinTask.then([=](pplx::task resultTask) { //Do something when all tasks are finished try { resultTask.get(); emit UpdateLabel("All tasks finished"); } catch (const mitk::Exception &exception) { MITK_ERROR << exception.what(); return; } }); m_Ui->responseLabel->setText("Waiting for change"); } } m_Ui->getMultiplePushButton->setEnabled(true); } void QmitkClientView::OnGetSingleButtonClicked() { m_Ui->putPushButton->setDisabled(true); //Get the micorservice us::ModuleContext *context = us::ModuleRegistry::GetModule(1)->GetModuleContext(); auto managerRef = context->GetServiceReference(); if (managerRef) { auto managerService = context->GetService(managerRef); if (managerService) { //Call the send request method which starts the actual request managerService ->SendRequest(L"http://193.174.48.78:8090/dcm4chee-arc/aets/DCM4CHEE/rs/studies/1.2.840.113654.2.70.1.97144850941324808603541273584489321943/series/1.2.840.113654.2.70.1.15771179684190906938515254678965278540/instances") .then([=](pplx::task resultTask)/*It is important to use task-based continuation*/ { try { //Get the result of the request //This will throw an exception if the ascendent task threw an exception (e.g. invalid URI) web::json::value result = resultTask.get(); //Do something with the result (e.g. convert it to a QSrting to update an UI element) utility::string_t stringT = result.to_string(); std::string stringStd(stringT.begin(), stringT.end()); QString stringQ = QString::fromStdString(stringStd); //Note: if you want to update your UI, do this by using signals and slots. //The UI can't be updated from a Thread different to the Qt main thread emit UpdateLabel(stringQ); } catch (const mitk::Exception &exception) { //Exceptions from ascendent tasks are catched here MITK_ERROR << exception.what(); return; } }); } } m_Ui->putPushButton->setEnabled(true); } void QmitkClientView::OnGetSaveButtonClicked() { m_Ui->putPushButton->setDisabled(true); us::ModuleContext *context = us::ModuleRegistry::GetModule(1)->GetModuleContext(); auto managerRef = context->GetServiceReference(); if (managerRef) { auto managerService = context->GetService(managerRef); if (managerService) { managerService ->SendRequest(L"http://193.174.48.78:8090/dcm4chee-arc/aets/DCM4CHEE/rs/studies/1.2.840.113654.2.70.1.97144850941324808603541273584489321943/series/1.2.840.113654.2.70.1.15771179684190906938515254678965278540/instances", mitk::IRESTManager::RequestType::Get, NULL,L"FileStream.txt") .then([=](pplx::task resultTask) { try { web::json::value result = resultTask.get(); utility::string_t stringT = result.to_string(); std::string stringStd(stringT.begin(), stringT.end()); QString stringQ = QString::fromStdString(stringStd); emit UpdateLabel(stringQ); } catch (const mitk::Exception &exception) { MITK_ERROR << exception.what(); return; } }); m_Ui->responseLabel->setText("Waiting for change"); } } m_Ui->putPushButton->setEnabled(true); } void QmitkClientView::OnPutButtonClicked() { m_Ui->putPushButton->setDisabled(true); us::ModuleContext *context = us::ModuleRegistry::GetModule(1)->GetModuleContext(); auto managerRef = context->GetServiceReference(); if (managerRef) { auto managerService = context->GetService(managerRef); if (managerService) { web::json::value data; data[L"userId"] = web::json::value(1); data[L"id"] = web::json::value(1); data[L"title"] = web::json::value(U("this is a changed title")); data[L"body"] = web::json::value(U("and the body is changed as well")); managerService->SendRequest( L"https://jsonplaceholder.typicode.com/posts/1", mitk::IRESTManager::RequestType::Put, &data) .then([=](pplx::task resultTask) { try { web::json::value result = resultTask.get(); utility::string_t stringT = result.to_string(); std::string stringStd(stringT.begin(), stringT.end()); QString stringQ = QString::fromStdString(stringStd); emit UpdateLabel(stringQ); } catch (const mitk::Exception &exception) { MITK_ERROR << exception.what(); return; } }); } } m_Ui->putPushButton->setEnabled(true); } void QmitkClientView::OnPostButtonClicked() { m_Ui->postPushButton->setDisabled(true); us::ModuleContext *context = us::ModuleRegistry::GetModule(1)->GetModuleContext(); auto managerRef = context->GetServiceReference(); if (managerRef) { auto managerService = context->GetService(managerRef); if (managerService) { web::json::value data; data[L"userId"] = web::json::value(1); data[L"title"] = web::json::value(U("this is a new title")); data[L"body"] = web::json::value(U("this is a new body")); managerService ->SendRequest(L"https://jsonplaceholder.typicode.com/posts", mitk::IRESTManager::RequestType::Post, &data) .then([=](pplx::task resultTask) { try { web::json::value result = resultTask.get(); utility::string_t stringT = result.to_string(); std::string stringStd(stringT.begin(), stringT.end()); QString stringQ = QString::fromStdString(stringStd); emit UpdateLabel(stringQ); } catch (const mitk::Exception &exception) { MITK_ERROR << exception.what(); return; } }); } } m_Ui->postPushButton->setEnabled(true); }