Mercurial > hg > orthanc
comparison OrthancServer/Sources/OrthancConfiguration.cpp @ 4044:d25f4c0fa160 framework
splitting code into OrthancFramework and OrthancServer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 10 Jun 2020 20:30:34 +0200 |
parents | OrthancServer/OrthancConfiguration.cpp@e3b3af80732d |
children | 05b8fd21089c |
comparison
equal
deleted
inserted
replaced
4043:6c6239aec462 | 4044:d25f4c0fa160 |
---|---|
1 /** | |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU General Public License as | |
9 * published by the Free Software Foundation, either version 3 of the | |
10 * License, or (at your option) any later version. | |
11 * | |
12 * In addition, as a special exception, the copyright holders of this | |
13 * program give permission to link the code of its release with the | |
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
15 * that use the same license as the "OpenSSL" library), and distribute | |
16 * the linked executables. You must obey the GNU General Public License | |
17 * in all respects for all of the code used other than "OpenSSL". If you | |
18 * modify file(s) with this exception, you may extend this exception to | |
19 * your version of the file(s), but you are not obligated to do so. If | |
20 * you do not wish to do so, delete this exception statement from your | |
21 * version. If you delete this exception statement from all source files | |
22 * in the program, then also delete it here. | |
23 * | |
24 * This program is distributed in the hope that it will be useful, but | |
25 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 * General Public License for more details. | |
28 * | |
29 * You should have received a copy of the GNU General Public License | |
30 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31 **/ | |
32 | |
33 | |
34 #include "PrecompiledHeadersServer.h" | |
35 #include "OrthancConfiguration.h" | |
36 | |
37 #include "../Core/HttpServer/HttpServer.h" | |
38 #include "../Core/Logging.h" | |
39 #include "../Core/OrthancException.h" | |
40 #include "../Core/SystemToolbox.h" | |
41 #include "../Core/TemporaryFile.h" | |
42 #include "../Core/Toolbox.h" | |
43 | |
44 #include "ServerIndex.h" | |
45 | |
46 | |
47 static const char* const DICOM_MODALITIES = "DicomModalities"; | |
48 static const char* const DICOM_MODALITIES_IN_DB = "DicomModalitiesInDatabase"; | |
49 static const char* const ORTHANC_PEERS = "OrthancPeers"; | |
50 static const char* const ORTHANC_PEERS_IN_DB = "OrthancPeersInDatabase"; | |
51 static const char* const TEMPORARY_DIRECTORY = "TemporaryDirectory"; | |
52 | |
53 namespace Orthanc | |
54 { | |
55 static void AddFileToConfiguration(Json::Value& target, | |
56 const boost::filesystem::path& path) | |
57 { | |
58 std::map<std::string, std::string> env; | |
59 SystemToolbox::GetEnvironmentVariables(env); | |
60 | |
61 LOG(WARNING) << "Reading the configuration from: " << path; | |
62 | |
63 Json::Value config; | |
64 | |
65 { | |
66 std::string content; | |
67 SystemToolbox::ReadFile(content, path.string()); | |
68 | |
69 content = Toolbox::SubstituteVariables(content, env); | |
70 | |
71 Json::Value tmp; | |
72 Json::Reader reader; | |
73 if (!reader.parse(content, tmp) || | |
74 tmp.type() != Json::objectValue) | |
75 { | |
76 throw OrthancException(ErrorCode_BadJson, | |
77 "The configuration file does not follow the JSON syntax: " + path.string()); | |
78 } | |
79 | |
80 Toolbox::CopyJsonWithoutComments(config, tmp); | |
81 } | |
82 | |
83 if (target.size() == 0) | |
84 { | |
85 target = config; | |
86 } | |
87 else | |
88 { | |
89 // Merge the newly-added file with the previous content of "target" | |
90 Json::Value::Members members = config.getMemberNames(); | |
91 for (Json::Value::ArrayIndex i = 0; i < members.size(); i++) | |
92 { | |
93 if (target.isMember(members[i])) | |
94 { | |
95 throw OrthancException(ErrorCode_BadFileFormat, | |
96 "The configuration section \"" + members[i] + | |
97 "\" is defined in 2 different configuration files"); | |
98 } | |
99 else | |
100 { | |
101 target[members[i]] = config[members[i]]; | |
102 } | |
103 } | |
104 } | |
105 } | |
106 | |
107 | |
108 static void ScanFolderForConfiguration(Json::Value& target, | |
109 const char* folder) | |
110 { | |
111 using namespace boost::filesystem; | |
112 | |
113 LOG(WARNING) << "Scanning folder \"" << folder << "\" for configuration files"; | |
114 | |
115 directory_iterator end_it; // default construction yields past-the-end | |
116 for (directory_iterator it(folder); | |
117 it != end_it; | |
118 ++it) | |
119 { | |
120 if (!is_directory(it->status())) | |
121 { | |
122 std::string extension = boost::filesystem::extension(it->path()); | |
123 Toolbox::ToLowerCase(extension); | |
124 | |
125 if (extension == ".json") | |
126 { | |
127 AddFileToConfiguration(target, it->path().string()); | |
128 } | |
129 } | |
130 } | |
131 } | |
132 | |
133 | |
134 static void ReadConfiguration(Json::Value& target, | |
135 const char* configurationFile) | |
136 { | |
137 target = Json::objectValue; | |
138 | |
139 if (configurationFile != NULL) | |
140 { | |
141 if (!boost::filesystem::exists(configurationFile)) | |
142 { | |
143 throw OrthancException(ErrorCode_InexistentFile, | |
144 "Inexistent path to configuration: " + | |
145 std::string(configurationFile)); | |
146 } | |
147 | |
148 if (boost::filesystem::is_directory(configurationFile)) | |
149 { | |
150 ScanFolderForConfiguration(target, configurationFile); | |
151 } | |
152 else | |
153 { | |
154 AddFileToConfiguration(target, configurationFile); | |
155 } | |
156 } | |
157 else | |
158 { | |
159 #if ORTHANC_STANDALONE == 1 | |
160 // No default path for the standalone configuration | |
161 LOG(WARNING) << "Using the default Orthanc configuration"; | |
162 return; | |
163 | |
164 #else | |
165 // In a non-standalone build, we use the | |
166 // "Resources/Configuration.json" from the Orthanc source code | |
167 | |
168 boost::filesystem::path p = ORTHANC_PATH; | |
169 p /= "Resources"; | |
170 p /= "Configuration.json"; | |
171 | |
172 AddFileToConfiguration(target, p); | |
173 #endif | |
174 } | |
175 } | |
176 | |
177 | |
178 static void CheckAlphanumeric(const std::string& s) | |
179 { | |
180 for (size_t j = 0; j < s.size(); j++) | |
181 { | |
182 if (!isalnum(s[j]) && | |
183 s[j] != '-') | |
184 { | |
185 throw OrthancException(ErrorCode_BadFileFormat, | |
186 "Only alphanumeric and dash characters are allowed " | |
187 "in the names of modalities/peers, but found: " + s); | |
188 } | |
189 } | |
190 } | |
191 | |
192 | |
193 void OrthancConfiguration::LoadModalitiesFromJson(const Json::Value& source) | |
194 { | |
195 modalities_.clear(); | |
196 | |
197 if (source.type() != Json::objectValue) | |
198 { | |
199 throw OrthancException(ErrorCode_BadFileFormat, | |
200 "Bad format of the \"" + std::string(DICOM_MODALITIES) + | |
201 "\" configuration section"); | |
202 } | |
203 | |
204 Json::Value::Members members = source.getMemberNames(); | |
205 | |
206 for (size_t i = 0; i < members.size(); i++) | |
207 { | |
208 const std::string& name = members[i]; | |
209 CheckAlphanumeric(name); | |
210 | |
211 RemoteModalityParameters modality; | |
212 modality.Unserialize(source[name]); | |
213 modalities_[name] = modality; | |
214 } | |
215 } | |
216 | |
217 | |
218 void OrthancConfiguration::LoadPeersFromJson(const Json::Value& source) | |
219 { | |
220 peers_.clear(); | |
221 | |
222 if (source.type() != Json::objectValue) | |
223 { | |
224 throw OrthancException(ErrorCode_BadFileFormat, | |
225 "Bad format of the \"" + std::string(ORTHANC_PEERS) + | |
226 "\" configuration section"); | |
227 } | |
228 | |
229 Json::Value::Members members = source.getMemberNames(); | |
230 | |
231 for (size_t i = 0; i < members.size(); i++) | |
232 { | |
233 const std::string& name = members[i]; | |
234 CheckAlphanumeric(name); | |
235 | |
236 WebServiceParameters peer; | |
237 peer.Unserialize(source[name]); | |
238 peers_[name] = peer; | |
239 } | |
240 } | |
241 | |
242 | |
243 void OrthancConfiguration::LoadModalities() | |
244 { | |
245 if (GetBooleanParameter(DICOM_MODALITIES_IN_DB, false)) | |
246 { | |
247 // Modalities are stored in the database | |
248 if (serverIndex_ == NULL) | |
249 { | |
250 throw Orthanc::OrthancException(ErrorCode_BadSequenceOfCalls); | |
251 } | |
252 else | |
253 { | |
254 std::string property = serverIndex_->GetGlobalProperty(GlobalProperty_Modalities, "{}"); | |
255 | |
256 Json::Reader reader; | |
257 Json::Value modalities; | |
258 if (reader.parse(property, modalities)) | |
259 { | |
260 LoadModalitiesFromJson(modalities); | |
261 } | |
262 else | |
263 { | |
264 throw OrthancException(ErrorCode_InternalError, | |
265 "Cannot unserialize the list of modalities from the Orthanc database"); | |
266 } | |
267 } | |
268 } | |
269 else | |
270 { | |
271 // Modalities are stored in the configuration files | |
272 if (json_.isMember(DICOM_MODALITIES)) | |
273 { | |
274 LoadModalitiesFromJson(json_[DICOM_MODALITIES]); | |
275 } | |
276 else | |
277 { | |
278 modalities_.clear(); | |
279 } | |
280 } | |
281 } | |
282 | |
283 void OrthancConfiguration::LoadPeers() | |
284 { | |
285 if (GetBooleanParameter(ORTHANC_PEERS_IN_DB, false)) | |
286 { | |
287 // Peers are stored in the database | |
288 if (serverIndex_ == NULL) | |
289 { | |
290 throw Orthanc::OrthancException(ErrorCode_BadSequenceOfCalls); | |
291 } | |
292 else | |
293 { | |
294 std::string property = serverIndex_->GetGlobalProperty(GlobalProperty_Peers, "{}"); | |
295 | |
296 Json::Reader reader; | |
297 Json::Value peers; | |
298 if (reader.parse(property, peers)) | |
299 { | |
300 LoadPeersFromJson(peers); | |
301 } | |
302 else | |
303 { | |
304 throw OrthancException(ErrorCode_InternalError, | |
305 "Cannot unserialize the list of peers from the Orthanc database"); | |
306 } | |
307 } | |
308 } | |
309 else | |
310 { | |
311 // Peers are stored in the configuration files | |
312 if (json_.isMember(ORTHANC_PEERS)) | |
313 { | |
314 LoadPeersFromJson(json_[ORTHANC_PEERS]); | |
315 } | |
316 else | |
317 { | |
318 peers_.clear(); | |
319 } | |
320 } | |
321 } | |
322 | |
323 | |
324 void OrthancConfiguration::SaveModalitiesToJson(Json::Value& target) | |
325 { | |
326 target = Json::objectValue; | |
327 | |
328 for (Modalities::const_iterator it = modalities_.begin(); it != modalities_.end(); ++it) | |
329 { | |
330 Json::Value modality; | |
331 it->second.Serialize(modality, true /* force advanced format */); | |
332 | |
333 target[it->first] = modality; | |
334 } | |
335 } | |
336 | |
337 | |
338 void OrthancConfiguration::SavePeersToJson(Json::Value& target) | |
339 { | |
340 target = Json::objectValue; | |
341 | |
342 for (Peers::const_iterator it = peers_.begin(); it != peers_.end(); ++it) | |
343 { | |
344 Json::Value peer; | |
345 it->second.Serialize(peer, | |
346 false /* use simple format if possible */, | |
347 true /* include passwords */); | |
348 | |
349 target[it->first] = peer; | |
350 } | |
351 } | |
352 | |
353 | |
354 void OrthancConfiguration::SaveModalities() | |
355 { | |
356 if (GetBooleanParameter(DICOM_MODALITIES_IN_DB, false)) | |
357 { | |
358 // Modalities are stored in the database | |
359 if (serverIndex_ == NULL) | |
360 { | |
361 throw Orthanc::OrthancException(ErrorCode_BadSequenceOfCalls); | |
362 } | |
363 else | |
364 { | |
365 Json::Value modalities; | |
366 SaveModalitiesToJson(modalities); | |
367 | |
368 Json::FastWriter writer; | |
369 std::string s = writer.write(modalities); | |
370 | |
371 serverIndex_->SetGlobalProperty(GlobalProperty_Modalities, s); | |
372 } | |
373 } | |
374 else | |
375 { | |
376 // Modalities are stored in the configuration files | |
377 if (!modalities_.empty() || | |
378 json_.isMember(DICOM_MODALITIES)) | |
379 { | |
380 SaveModalitiesToJson(json_[DICOM_MODALITIES]); | |
381 } | |
382 } | |
383 } | |
384 | |
385 | |
386 void OrthancConfiguration::SavePeers() | |
387 { | |
388 if (GetBooleanParameter(ORTHANC_PEERS_IN_DB, false)) | |
389 { | |
390 // Peers are stored in the database | |
391 if (serverIndex_ == NULL) | |
392 { | |
393 throw Orthanc::OrthancException(ErrorCode_BadSequenceOfCalls); | |
394 } | |
395 else | |
396 { | |
397 Json::Value peers; | |
398 SavePeersToJson(peers); | |
399 | |
400 Json::FastWriter writer; | |
401 std::string s = writer.write(peers); | |
402 | |
403 serverIndex_->SetGlobalProperty(GlobalProperty_Peers, s); | |
404 } | |
405 } | |
406 else | |
407 { | |
408 // Peers are stored in the configuration files | |
409 if (!peers_.empty() || | |
410 json_.isMember(ORTHANC_PEERS)) | |
411 { | |
412 SavePeersToJson(json_[ORTHANC_PEERS]); | |
413 } | |
414 } | |
415 } | |
416 | |
417 | |
418 OrthancConfiguration& OrthancConfiguration::GetInstance() | |
419 { | |
420 static OrthancConfiguration configuration; | |
421 return configuration; | |
422 } | |
423 | |
424 | |
425 bool OrthancConfiguration::LookupStringParameter(std::string& target, | |
426 const std::string& parameter) const | |
427 { | |
428 if (json_.isMember(parameter)) | |
429 { | |
430 if (json_[parameter].type() != Json::stringValue) | |
431 { | |
432 throw OrthancException(ErrorCode_BadParameterType, | |
433 "The configuration option \"" + parameter + "\" must be a string"); | |
434 } | |
435 else | |
436 { | |
437 target = json_[parameter].asString(); | |
438 return true; | |
439 } | |
440 } | |
441 else | |
442 { | |
443 return false; | |
444 } | |
445 } | |
446 | |
447 | |
448 std::string OrthancConfiguration::GetStringParameter(const std::string& parameter, | |
449 const std::string& defaultValue) const | |
450 { | |
451 std::string value; | |
452 if (LookupStringParameter(value, parameter)) | |
453 { | |
454 return value; | |
455 } | |
456 else | |
457 { | |
458 return defaultValue; | |
459 } | |
460 } | |
461 | |
462 | |
463 int OrthancConfiguration::GetIntegerParameter(const std::string& parameter, | |
464 int defaultValue) const | |
465 { | |
466 if (json_.isMember(parameter)) | |
467 { | |
468 if (json_[parameter].type() != Json::intValue) | |
469 { | |
470 throw OrthancException(ErrorCode_BadParameterType, | |
471 "The configuration option \"" + parameter + "\" must be an integer"); | |
472 } | |
473 else | |
474 { | |
475 return json_[parameter].asInt(); | |
476 } | |
477 } | |
478 else | |
479 { | |
480 return defaultValue; | |
481 } | |
482 } | |
483 | |
484 | |
485 unsigned int OrthancConfiguration::GetUnsignedIntegerParameter( | |
486 const std::string& parameter, | |
487 unsigned int defaultValue) const | |
488 { | |
489 int v = GetIntegerParameter(parameter, defaultValue); | |
490 | |
491 if (v < 0) | |
492 { | |
493 throw OrthancException(ErrorCode_ParameterOutOfRange, | |
494 "The configuration option \"" + parameter + "\" must be a positive integer"); | |
495 } | |
496 else | |
497 { | |
498 return static_cast<unsigned int>(v); | |
499 } | |
500 } | |
501 | |
502 | |
503 bool OrthancConfiguration::LookupBooleanParameter(bool& target, | |
504 const std::string& parameter) const | |
505 { | |
506 if (json_.isMember(parameter)) | |
507 { | |
508 if (json_[parameter].type() != Json::booleanValue) | |
509 { | |
510 throw OrthancException(ErrorCode_BadParameterType, | |
511 "The configuration option \"" + parameter + | |
512 "\" must be a Boolean (true or false)"); | |
513 } | |
514 else | |
515 { | |
516 target = json_[parameter].asBool(); | |
517 return true; | |
518 } | |
519 } | |
520 else | |
521 { | |
522 return false; | |
523 } | |
524 } | |
525 | |
526 | |
527 bool OrthancConfiguration::GetBooleanParameter(const std::string& parameter, | |
528 bool defaultValue) const | |
529 { | |
530 bool value; | |
531 if (LookupBooleanParameter(value, parameter)) | |
532 { | |
533 return value; | |
534 } | |
535 else | |
536 { | |
537 return defaultValue; | |
538 } | |
539 } | |
540 | |
541 | |
542 void OrthancConfiguration::Read(const char* configurationFile) | |
543 { | |
544 // Read the content of the configuration | |
545 configurationFileArg_ = configurationFile; | |
546 ReadConfiguration(json_, configurationFile); | |
547 | |
548 // Adapt the paths to the configurations | |
549 defaultDirectory_ = boost::filesystem::current_path(); | |
550 configurationAbsolutePath_ = ""; | |
551 | |
552 if (configurationFile) | |
553 { | |
554 if (boost::filesystem::is_directory(configurationFile)) | |
555 { | |
556 defaultDirectory_ = boost::filesystem::path(configurationFile); | |
557 configurationAbsolutePath_ = boost::filesystem::absolute(configurationFile).parent_path().string(); | |
558 } | |
559 else | |
560 { | |
561 defaultDirectory_ = boost::filesystem::path(configurationFile).parent_path(); | |
562 configurationAbsolutePath_ = boost::filesystem::absolute(configurationFile).string(); | |
563 } | |
564 } | |
565 else | |
566 { | |
567 #if ORTHANC_STANDALONE != 1 | |
568 // In a non-standalone build, we use the | |
569 // "Resources/Configuration.json" from the Orthanc source code | |
570 | |
571 boost::filesystem::path p = ORTHANC_PATH; | |
572 p /= "Resources"; | |
573 p /= "Configuration.json"; | |
574 configurationAbsolutePath_ = boost::filesystem::absolute(p).string(); | |
575 #endif | |
576 } | |
577 } | |
578 | |
579 | |
580 void OrthancConfiguration::LoadModalitiesAndPeers() | |
581 { | |
582 LoadModalities(); | |
583 LoadPeers(); | |
584 } | |
585 | |
586 | |
587 void OrthancConfiguration::RegisterFont(ServerResources::FileResourceId resource) | |
588 { | |
589 std::string content; | |
590 ServerResources::GetFileResource(content, resource); | |
591 fontRegistry_.AddFromMemory(content); | |
592 } | |
593 | |
594 | |
595 void OrthancConfiguration::GetDicomModalityUsingSymbolicName( | |
596 RemoteModalityParameters& modality, | |
597 const std::string& name) const | |
598 { | |
599 Modalities::const_iterator found = modalities_.find(name); | |
600 | |
601 if (found == modalities_.end()) | |
602 { | |
603 throw OrthancException(ErrorCode_InexistentItem, | |
604 "No modality with symbolic name: " + name); | |
605 } | |
606 else | |
607 { | |
608 modality = found->second; | |
609 } | |
610 } | |
611 | |
612 | |
613 bool OrthancConfiguration::LookupOrthancPeer(WebServiceParameters& peer, | |
614 const std::string& name) const | |
615 { | |
616 Peers::const_iterator found = peers_.find(name); | |
617 | |
618 if (found == peers_.end()) | |
619 { | |
620 LOG(ERROR) << "No peer with symbolic name: " << name; | |
621 return false; | |
622 } | |
623 else | |
624 { | |
625 peer = found->second; | |
626 return true; | |
627 } | |
628 } | |
629 | |
630 | |
631 void OrthancConfiguration::GetListOfDicomModalities(std::set<std::string>& target) const | |
632 { | |
633 target.clear(); | |
634 | |
635 for (Modalities::const_iterator | |
636 it = modalities_.begin(); it != modalities_.end(); ++it) | |
637 { | |
638 target.insert(it->first); | |
639 } | |
640 } | |
641 | |
642 | |
643 void OrthancConfiguration::GetListOfOrthancPeers(std::set<std::string>& target) const | |
644 { | |
645 target.clear(); | |
646 | |
647 for (Peers::const_iterator it = peers_.begin(); it != peers_.end(); ++it) | |
648 { | |
649 target.insert(it->first); | |
650 } | |
651 } | |
652 | |
653 | |
654 bool OrthancConfiguration::SetupRegisteredUsers(HttpServer& httpServer) const | |
655 { | |
656 httpServer.ClearUsers(); | |
657 | |
658 if (!json_.isMember("RegisteredUsers")) | |
659 { | |
660 return false; | |
661 } | |
662 | |
663 const Json::Value& users = json_["RegisteredUsers"]; | |
664 if (users.type() != Json::objectValue) | |
665 { | |
666 throw OrthancException(ErrorCode_BadFileFormat, "Badly formatted list of users"); | |
667 } | |
668 | |
669 bool hasUser = false; | |
670 Json::Value::Members usernames = users.getMemberNames(); | |
671 for (size_t i = 0; i < usernames.size(); i++) | |
672 { | |
673 const std::string& username = usernames[i]; | |
674 std::string password = users[username].asString(); | |
675 httpServer.RegisterUser(username.c_str(), password.c_str()); | |
676 hasUser = true; | |
677 } | |
678 | |
679 return hasUser; | |
680 } | |
681 | |
682 | |
683 std::string OrthancConfiguration::InterpretStringParameterAsPath( | |
684 const std::string& parameter) const | |
685 { | |
686 return SystemToolbox::InterpretRelativePath(defaultDirectory_.string(), parameter); | |
687 } | |
688 | |
689 | |
690 void OrthancConfiguration::GetListOfStringsParameter(std::list<std::string>& target, | |
691 const std::string& key) const | |
692 { | |
693 target.clear(); | |
694 | |
695 if (!json_.isMember(key)) | |
696 { | |
697 return; | |
698 } | |
699 | |
700 const Json::Value& lst = json_[key]; | |
701 | |
702 if (lst.type() != Json::arrayValue) | |
703 { | |
704 throw OrthancException(ErrorCode_BadFileFormat, "Badly formatted list of strings"); | |
705 } | |
706 | |
707 for (Json::Value::ArrayIndex i = 0; i < lst.size(); i++) | |
708 { | |
709 target.push_back(lst[i].asString()); | |
710 } | |
711 } | |
712 | |
713 | |
714 bool OrthancConfiguration::IsSameAETitle(const std::string& aet1, | |
715 const std::string& aet2) const | |
716 { | |
717 if (GetBooleanParameter("StrictAetComparison", false)) | |
718 { | |
719 // Case-sensitive matching | |
720 return aet1 == aet2; | |
721 } | |
722 else | |
723 { | |
724 // Case-insensitive matching (default) | |
725 std::string tmp1, tmp2; | |
726 Toolbox::ToLowerCase(tmp1, aet1); | |
727 Toolbox::ToLowerCase(tmp2, aet2); | |
728 return tmp1 == tmp2; | |
729 } | |
730 } | |
731 | |
732 | |
733 bool OrthancConfiguration::LookupDicomModalityUsingAETitle(RemoteModalityParameters& modality, | |
734 const std::string& aet) const | |
735 { | |
736 for (Modalities::const_iterator it = modalities_.begin(); it != modalities_.end(); ++it) | |
737 { | |
738 if (IsSameAETitle(aet, it->second.GetApplicationEntityTitle())) | |
739 { | |
740 modality = it->second; | |
741 return true; | |
742 } | |
743 } | |
744 | |
745 return false; | |
746 } | |
747 | |
748 | |
749 bool OrthancConfiguration::IsKnownAETitle(const std::string& aet, | |
750 const std::string& ip) const | |
751 { | |
752 RemoteModalityParameters modality; | |
753 | |
754 if (!LookupDicomModalityUsingAETitle(modality, aet)) | |
755 { | |
756 LOG(WARNING) << "Modality \"" << aet | |
757 << "\" is not listed in the \"DicomModalities\" configuration option"; | |
758 return false; | |
759 } | |
760 else if (!GetBooleanParameter("DicomCheckModalityHost", false) || | |
761 ip == modality.GetHost()) | |
762 { | |
763 return true; | |
764 } | |
765 else | |
766 { | |
767 LOG(WARNING) << "Forbidding access from AET \"" << aet | |
768 << "\" given its hostname (" << ip << ") does not match " | |
769 << "the \"DicomModalities\" configuration option (" | |
770 << modality.GetHost() << " was expected)"; | |
771 return false; | |
772 } | |
773 } | |
774 | |
775 | |
776 RemoteModalityParameters | |
777 OrthancConfiguration::GetModalityUsingSymbolicName(const std::string& name) const | |
778 { | |
779 RemoteModalityParameters modality; | |
780 GetDicomModalityUsingSymbolicName(modality, name); | |
781 | |
782 return modality; | |
783 } | |
784 | |
785 | |
786 RemoteModalityParameters | |
787 OrthancConfiguration::GetModalityUsingAet(const std::string& aet) const | |
788 { | |
789 RemoteModalityParameters modality; | |
790 | |
791 if (LookupDicomModalityUsingAETitle(modality, aet)) | |
792 { | |
793 return modality; | |
794 } | |
795 else | |
796 { | |
797 throw OrthancException(ErrorCode_InexistentItem, | |
798 "Unknown modality for AET: " + aet); | |
799 } | |
800 } | |
801 | |
802 | |
803 void OrthancConfiguration::UpdateModality(const std::string& symbolicName, | |
804 const RemoteModalityParameters& modality) | |
805 { | |
806 CheckAlphanumeric(symbolicName); | |
807 | |
808 modalities_[symbolicName] = modality; | |
809 SaveModalities(); | |
810 } | |
811 | |
812 | |
813 void OrthancConfiguration::RemoveModality(const std::string& symbolicName) | |
814 { | |
815 modalities_.erase(symbolicName); | |
816 SaveModalities(); | |
817 } | |
818 | |
819 | |
820 void OrthancConfiguration::UpdatePeer(const std::string& symbolicName, | |
821 const WebServiceParameters& peer) | |
822 { | |
823 CheckAlphanumeric(symbolicName); | |
824 | |
825 peer.CheckClientCertificate(); | |
826 | |
827 peers_[symbolicName] = peer; | |
828 SavePeers(); | |
829 } | |
830 | |
831 | |
832 void OrthancConfiguration::RemovePeer(const std::string& symbolicName) | |
833 { | |
834 peers_.erase(symbolicName); | |
835 SavePeers(); | |
836 } | |
837 | |
838 | |
839 void OrthancConfiguration::Format(std::string& result) const | |
840 { | |
841 Json::StyledWriter w; | |
842 result = w.write(json_); | |
843 } | |
844 | |
845 | |
846 void OrthancConfiguration::SetDefaultEncoding(Encoding encoding) | |
847 { | |
848 SetDefaultDicomEncoding(encoding); | |
849 | |
850 // Propagate the encoding to the configuration file that is | |
851 // stored in memory | |
852 json_["DefaultEncoding"] = EnumerationToString(encoding); | |
853 } | |
854 | |
855 | |
856 bool OrthancConfiguration::HasConfigurationChanged() const | |
857 { | |
858 Json::Value current; | |
859 ReadConfiguration(current, configurationFileArg_); | |
860 | |
861 Json::FastWriter writer; | |
862 std::string a = writer.write(json_); | |
863 std::string b = writer.write(current); | |
864 | |
865 return a != b; | |
866 } | |
867 | |
868 | |
869 void OrthancConfiguration::SetServerIndex(ServerIndex& index) | |
870 { | |
871 serverIndex_ = &index; | |
872 } | |
873 | |
874 | |
875 void OrthancConfiguration::ResetServerIndex() | |
876 { | |
877 serverIndex_ = NULL; | |
878 } | |
879 | |
880 | |
881 TemporaryFile* OrthancConfiguration::CreateTemporaryFile() const | |
882 { | |
883 if (json_.isMember(TEMPORARY_DIRECTORY)) | |
884 { | |
885 return new TemporaryFile(InterpretStringParameterAsPath(GetStringParameter(TEMPORARY_DIRECTORY, ".")), ""); | |
886 } | |
887 else | |
888 { | |
889 return new TemporaryFile; | |
890 } | |
891 } | |
892 | |
893 | |
894 std::string OrthancConfiguration::GetDefaultPrivateCreator() const | |
895 { | |
896 // New configuration option in Orthanc 1.6.0 | |
897 return GetStringParameter("DefaultPrivateCreator", ""); | |
898 } | |
899 } |