comparison Plugins/Engine/OrthancPlugins.cpp @ 2799:6e3a60b85da6

New primitives to access Orthanc peers from plugins
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 22 Aug 2018 16:55:07 +0200
parents ad2c32082653
children 37583cd183ed
comparison
equal deleted inserted replaced
2798:5c83e5cf9d79 2799:6e3a60b85da6
246 IStorageArea* Create() const 246 IStorageArea* Create() const
247 { 247 {
248 return new PluginStorageArea(callbacks_, errorDictionary_); 248 return new PluginStorageArea(callbacks_, errorDictionary_);
249 } 249 }
250 }; 250 };
251
252
253 class OrthancPeers : public boost::noncopyable
254 {
255 private:
256 std::vector<std::string> names_;
257 std::vector<WebServiceParameters> parameters_;
258
259 void CheckIndex(size_t i) const
260 {
261 assert(names_.size() == parameters_.size());
262 if (i >= names_.size())
263 {
264 throw OrthancException(ErrorCode_ParameterOutOfRange);
265 }
266 }
267
268 public:
269 OrthancPeers()
270 {
271 std::set<std::string> peers;
272 Configuration::GetListOfOrthancPeers(peers);
273
274 names_.reserve(peers.size());
275 parameters_.reserve(peers.size());
276
277 for (std::set<std::string>::const_iterator
278 it = peers.begin(); it != peers.end(); ++it)
279 {
280 WebServiceParameters peer;
281 if (Configuration::GetOrthancPeer(peer, *it))
282 {
283 names_.push_back(*it);
284 parameters_.push_back(peer);
285 }
286 }
287 }
288
289 size_t GetPeersCount() const
290 {
291 return names_.size();
292 }
293
294 const std::string& GetPeerName(size_t i) const
295 {
296 CheckIndex(i);
297 return names_[i];
298 }
299
300 const WebServiceParameters& GetPeerParameters(size_t i) const
301 {
302 CheckIndex(i);
303 return parameters_[i];
304 }
305 };
251 } 306 }
252 307
253 308
254 class OrthancPlugins::PImpl 309 class OrthancPlugins::PImpl
255 { 310 {
1830 for (uint32_t i = 0; i < p.headersCount; i++) 1885 for (uint32_t i = 0; i < p.headersCount; i++)
1831 { 1886 {
1832 if (p.headersKeys[i] == NULL || 1887 if (p.headersKeys[i] == NULL ||
1833 p.headersValues[i] == NULL) 1888 p.headersValues[i] == NULL)
1834 { 1889 {
1835 throw OrthancException(ErrorCode_ParameterOutOfRange); 1890 throw OrthancException(ErrorCode_NullPointer);
1836 } 1891 }
1837 1892
1838 client.AddHeader(p.headersKeys[i], p.headersValues[i]); 1893 client.AddHeader(p.headersKeys[i], p.headersValues[i]);
1839 } 1894 }
1840 1895
1896 CopyToMemoryBuffer(*p.answerBody, body); 1951 CopyToMemoryBuffer(*p.answerBody, body);
1897 } 1952 }
1898 } 1953 }
1899 1954
1900 1955
1956 void OrthancPlugins::CallPeerApi(const void* parameters)
1957 {
1958 const _OrthancPluginCallPeerApi& p = *reinterpret_cast<const _OrthancPluginCallPeerApi*>(parameters);
1959 const OrthancPeers& peers = *reinterpret_cast<const OrthancPeers*>(p.peers);
1960
1961 HttpClient client(peers.GetPeerParameters(p.peerIndex), p.uri);
1962 client.SetConvertHeadersToLowerCase(false);
1963
1964 if (p.timeout != 0)
1965 {
1966 client.SetTimeout(p.timeout);
1967 }
1968
1969 for (uint32_t i = 0; i < p.additionalHeadersCount; i++)
1970 {
1971 if (p.additionalHeadersKeys[i] == NULL ||
1972 p.additionalHeadersValues[i] == NULL)
1973 {
1974 throw OrthancException(ErrorCode_NullPointer);
1975 }
1976
1977 client.AddHeader(p.additionalHeadersKeys[i], p.additionalHeadersValues[i]);
1978 }
1979
1980 switch (p.method)
1981 {
1982 case OrthancPluginHttpMethod_Get:
1983 client.SetMethod(HttpMethod_Get);
1984 break;
1985
1986 case OrthancPluginHttpMethod_Post:
1987 client.SetMethod(HttpMethod_Post);
1988 client.GetBody().assign(p.body, p.bodySize);
1989 break;
1990
1991 case OrthancPluginHttpMethod_Put:
1992 client.SetMethod(HttpMethod_Put);
1993 client.GetBody().assign(p.body, p.bodySize);
1994 break;
1995
1996 case OrthancPluginHttpMethod_Delete:
1997 client.SetMethod(HttpMethod_Delete);
1998 break;
1999
2000 default:
2001 throw OrthancException(ErrorCode_ParameterOutOfRange);
2002 }
2003
2004 std::string body;
2005 HttpClient::HttpHeaders headers;
2006
2007 bool success = client.Apply(body, headers);
2008
2009 // The HTTP request has succeeded
2010 *p.httpStatus = static_cast<uint16_t>(client.GetLastStatus());
2011
2012 if (!success)
2013 {
2014 HttpClient::ThrowException(client.GetLastStatus());
2015 }
2016
2017 // Copy the HTTP headers of the answer, if the plugin requested them
2018 if (p.answerHeaders != NULL)
2019 {
2020 Json::Value json = Json::objectValue;
2021
2022 for (HttpClient::HttpHeaders::const_iterator
2023 it = headers.begin(); it != headers.end(); ++it)
2024 {
2025 json[it->first] = it->second;
2026 }
2027
2028 std::string s = json.toStyledString();
2029 CopyToMemoryBuffer(*p.answerHeaders, s);
2030 }
2031
2032 // Copy the body of the answer if it makes sense
2033 if (p.method != OrthancPluginHttpMethod_Delete)
2034 {
2035 CopyToMemoryBuffer(*p.answerBody, body);
2036 }
2037 }
2038
2039
1901 void OrthancPlugins::ConvertPixelFormat(const void* parameters) 2040 void OrthancPlugins::ConvertPixelFormat(const void* parameters)
1902 { 2041 {
1903 const _OrthancPluginConvertPixelFormat& p = *reinterpret_cast<const _OrthancPluginConvertPixelFormat*>(parameters); 2042 const _OrthancPluginConvertPixelFormat& p = *reinterpret_cast<const _OrthancPluginConvertPixelFormat*>(parameters);
1904 const ImageAccessor& source = *reinterpret_cast<const ImageAccessor*>(p.source); 2043 const ImageAccessor& source = *reinterpret_cast<const ImageAccessor*>(p.source);
1905 2044
1957 } 2096 }
1958 else 2097 else
1959 { 2098 {
1960 if (p.instanceId == NULL) 2099 if (p.instanceId == NULL)
1961 { 2100 {
1962 throw OrthancException(ErrorCode_ParameterOutOfRange); 2101 throw OrthancException(ErrorCode_NullPointer);
1963 } 2102 }
1964 2103
1965 std::string content; 2104 std::string content;
1966 2105
1967 { 2106 {
2125 throw OrthancException(ErrorCode_BadRequest); 2264 throw OrthancException(ErrorCode_BadRequest);
2126 } 2265 }
2127 } 2266 }
2128 2267
2129 2268
2130
2131 namespace 2269 namespace
2132 { 2270 {
2133 class DictionaryReadLocker 2271 class DictionaryReadLocker
2134 { 2272 {
2135 private: 2273 private:
2175 p.target->vr = Plugins::Convert(FromDcmtkBridge::Convert(entry->getEVR())); 2313 p.target->vr = Plugins::Convert(FromDcmtkBridge::Convert(entry->getEVR()));
2176 p.target->minMultiplicity = static_cast<uint32_t>(entry->getVMMin()); 2314 p.target->minMultiplicity = static_cast<uint32_t>(entry->getVMMin());
2177 p.target->maxMultiplicity = (entry->getVMMax() == DcmVariableVM ? 0 : static_cast<uint32_t>(entry->getVMMax())); 2315 p.target->maxMultiplicity = (entry->getVMMax() == DcmVariableVM ? 0 : static_cast<uint32_t>(entry->getVMMax()));
2178 } 2316 }
2179 } 2317 }
2180
2181 2318
2182 2319
2183 bool OrthancPlugins::InvokeSafeService(SharedLibrary& plugin, 2320 bool OrthancPlugins::InvokeSafeService(SharedLibrary& plugin,
2184 _OrthancPluginService service, 2321 _OrthancPluginService service,
2185 const void* parameters) 2322 const void* parameters)
2442 } 2579 }
2443 2580
2444 case _OrthancPluginService_FreeImage: 2581 case _OrthancPluginService_FreeImage:
2445 { 2582 {
2446 const _OrthancPluginFreeImage& p = *reinterpret_cast<const _OrthancPluginFreeImage*>(parameters); 2583 const _OrthancPluginFreeImage& p = *reinterpret_cast<const _OrthancPluginFreeImage*>(parameters);
2447 if (p.image == NULL) 2584
2448 { 2585 if (p.image != NULL)
2449 throw OrthancException(ErrorCode_ParameterOutOfRange);
2450 }
2451 else
2452 { 2586 {
2453 delete reinterpret_cast<ImageAccessor*>(p.image); 2587 delete reinterpret_cast<ImageAccessor*>(p.image);
2454 return true; 2588 }
2455 } 2589
2590 return true;
2456 } 2591 }
2457 2592
2458 case _OrthancPluginService_UncompressImage: 2593 case _OrthancPluginService_UncompressImage:
2459 UncompressImage(parameters); 2594 UncompressImage(parameters);
2460 return true; 2595 return true;
2622 case _OrthancPluginService_FreeFindMatcher: 2757 case _OrthancPluginService_FreeFindMatcher:
2623 { 2758 {
2624 const _OrthancPluginFreeFindMatcher& p = 2759 const _OrthancPluginFreeFindMatcher& p =
2625 *reinterpret_cast<const _OrthancPluginFreeFindMatcher*>(parameters); 2760 *reinterpret_cast<const _OrthancPluginFreeFindMatcher*>(parameters);
2626 2761
2627 if (p.matcher == NULL) 2762 if (p.matcher != NULL)
2628 {
2629 throw OrthancException(ErrorCode_ParameterOutOfRange);
2630 }
2631 else
2632 { 2763 {
2633 delete reinterpret_cast<HierarchicalMatcher*>(p.matcher); 2764 delete reinterpret_cast<HierarchicalMatcher*>(p.matcher);
2634 return true; 2765 }
2635 } 2766
2767 return true;
2636 } 2768 }
2637 2769
2638 case _OrthancPluginService_FindMatcherIsMatch: 2770 case _OrthancPluginService_FindMatcherIsMatch:
2639 { 2771 {
2640 const _OrthancPluginFindMatcherIsMatch& p = 2772 const _OrthancPluginFindMatcherIsMatch& p =
2641 *reinterpret_cast<const _OrthancPluginFindMatcherIsMatch*>(parameters); 2773 *reinterpret_cast<const _OrthancPluginFindMatcherIsMatch*>(parameters);
2642 2774
2643 if (p.matcher == NULL) 2775 if (p.matcher == NULL)
2644 { 2776 {
2645 throw OrthancException(ErrorCode_ParameterOutOfRange); 2777 throw OrthancException(ErrorCode_NullPointer);
2646 } 2778 }
2647 else 2779 else
2648 { 2780 {
2649 ParsedDicomFile query(p.dicom, p.size); 2781 ParsedDicomFile query(p.dicom, p.size);
2650 *p.isMatch = reinterpret_cast<const HierarchicalMatcher*>(p.matcher)->Match(query) ? 1 : 0; 2782 *p.isMatch = reinterpret_cast<const HierarchicalMatcher*>(p.matcher)->Match(query) ? 1 : 0;
2651 return true; 2783 return true;
2652 } 2784 }
2653 } 2785 }
2786
2787 case _OrthancPluginService_GetPeers:
2788 {
2789 const _OrthancPluginGetPeers& p =
2790 *reinterpret_cast<const _OrthancPluginGetPeers*>(parameters);
2791 *(p.peers) = reinterpret_cast<OrthancPluginPeers*>(new OrthancPeers);
2792 return true;
2793 }
2794
2795 case _OrthancPluginService_FreePeers:
2796 {
2797 const _OrthancPluginFreePeers& p =
2798 *reinterpret_cast<const _OrthancPluginFreePeers*>(parameters);
2799
2800 if (p.peers != NULL)
2801 {
2802 delete reinterpret_cast<OrthancPeers*>(p.peers);
2803 }
2804
2805 return true;
2806 }
2807
2808 case _OrthancPluginService_GetPeersCount:
2809 {
2810 const _OrthancPluginGetPeersCount& p =
2811 *reinterpret_cast<const _OrthancPluginGetPeersCount*>(parameters);
2812
2813 if (p.peers == NULL)
2814 {
2815 throw OrthancException(ErrorCode_NullPointer);
2816 }
2817 else
2818 {
2819 *(p.target) = reinterpret_cast<const OrthancPeers*>(p.peers)->GetPeersCount();
2820 return true;
2821 }
2822 }
2823
2824 case _OrthancPluginService_GetPeerName:
2825 {
2826 const _OrthancPluginGetPeerProperty& p =
2827 *reinterpret_cast<const _OrthancPluginGetPeerProperty*>(parameters);
2828
2829 if (p.peers == NULL)
2830 {
2831 throw OrthancException(ErrorCode_NullPointer);
2832 }
2833 else
2834 {
2835 *(p.target) = reinterpret_cast<const OrthancPeers*>(p.peers)->GetPeerName(p.peerIndex).c_str();
2836 return true;
2837 }
2838 }
2839
2840 case _OrthancPluginService_GetPeerUrl:
2841 {
2842 const _OrthancPluginGetPeerProperty& p =
2843 *reinterpret_cast<const _OrthancPluginGetPeerProperty*>(parameters);
2844
2845 if (p.peers == NULL)
2846 {
2847 throw OrthancException(ErrorCode_NullPointer);
2848 }
2849 else
2850 {
2851 *(p.target) = reinterpret_cast<const OrthancPeers*>(p.peers)->GetPeerParameters(p.peerIndex).GetUrl().c_str();
2852 return true;
2853 }
2854 }
2855
2856 case _OrthancPluginService_CallPeerApi:
2857 CallPeerApi(parameters);
2858 return true;
2654 2859
2655 default: 2860 default:
2656 return false; 2861 return false;
2657 } 2862 }
2658 } 2863 }