Mercurial > hg > orthanc
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 } |