Mercurial > hg > orthanc
comparison OrthancFramework/Sources/RestApi/RestApi.cpp @ 4413:22a1352a0823
cont openapi
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 28 Dec 2020 13:08:00 +0100 |
parents | 68b96234fbd6 |
children | d928dfcacb4b |
comparison
equal
deleted
inserted
replaced
4412:68b96234fbd6 | 4413:22a1352a0823 |
---|---|
423 { | 423 { |
424 private: | 424 private: |
425 class Path | 425 class Path |
426 { | 426 { |
427 private: | 427 private: |
428 std::string tag_; | |
429 bool hasGet_; | 428 bool hasGet_; |
430 bool hasPost_; | 429 bool hasPost_; |
431 bool hasDelete_; | 430 bool hasDelete_; |
432 bool hasPut_; | 431 bool hasPut_; |
432 std::string getTag_; | |
433 std::string postTag_; | |
434 std::string deleteTag_; | |
435 std::string putTag_; | |
433 std::string summary_; | 436 std::string summary_; |
434 HttpMethod summaryOrigin_; | 437 HttpMethod summaryOrigin_; |
435 | 438 |
436 public: | 439 public: |
437 Path() : | 440 Path() : |
441 hasPut_(false), | 444 hasPut_(false), |
442 summaryOrigin_(HttpMethod_Get) // Dummy initialization | 445 summaryOrigin_(HttpMethod_Get) // Dummy initialization |
443 { | 446 { |
444 } | 447 } |
445 | 448 |
446 void AddMethod(HttpMethod method) | 449 void AddMethod(HttpMethod method, |
450 const std::string& tag) | |
447 { | 451 { |
448 switch (method) | 452 switch (method) |
449 { | 453 { |
450 case HttpMethod_Get: | 454 case HttpMethod_Get: |
455 if (hasGet_) | |
456 { | |
457 throw OrthancException(ErrorCode_InternalError); | |
458 } | |
459 | |
451 hasGet_ = true; | 460 hasGet_ = true; |
461 getTag_ = tag; | |
452 break; | 462 break; |
453 | 463 |
454 case HttpMethod_Post: | 464 case HttpMethod_Post: |
465 if (hasPost_) | |
466 { | |
467 throw OrthancException(ErrorCode_InternalError); | |
468 } | |
469 | |
455 hasPost_ = true; | 470 hasPost_ = true; |
471 postTag_ = tag; | |
456 break; | 472 break; |
457 | 473 |
458 case HttpMethod_Delete: | 474 case HttpMethod_Delete: |
475 if (hasDelete_) | |
476 { | |
477 throw OrthancException(ErrorCode_InternalError); | |
478 } | |
479 | |
459 hasDelete_ = true; | 480 hasDelete_ = true; |
481 deleteTag_ = tag; | |
460 break; | 482 break; |
461 | 483 |
462 case HttpMethod_Put: | 484 case HttpMethod_Put: |
485 if (hasPut_) | |
486 { | |
487 throw OrthancException(ErrorCode_InternalError); | |
488 } | |
489 | |
463 hasPut_ = true; | 490 hasPut_ = true; |
491 putTag_ = tag; | |
464 break; | 492 break; |
465 | 493 |
466 default: | 494 default: |
467 throw OrthancException(ErrorCode_ParameterOutOfRange); | 495 throw OrthancException(ErrorCode_ParameterOutOfRange); |
468 } | 496 } |
469 } | 497 } |
470 | 498 |
471 bool HasSummary() const | 499 void SetSummary(const std::string& summary, |
472 { | |
473 return !summary_.empty(); | |
474 } | |
475 | |
476 const std::string& GetTag() const | |
477 { | |
478 return tag_; | |
479 } | |
480 | |
481 void SetSummary(const std::string& tag, | |
482 const std::string& summary, | |
483 HttpMethod newOrigin) | 500 HttpMethod newOrigin) |
484 { | 501 { |
485 if (!tag_.empty() && | |
486 !tag.empty() && | |
487 tag_ != tag) | |
488 { | |
489 printf("===================================================================================\n"); | |
490 throw OrthancException(ErrorCode_InternalError, "Mismatch between HTTP methods in the tag: \"" + | |
491 tag + "\" vs. \"" + tag_ + "\""); | |
492 } | |
493 | |
494 if (tag_.empty()) | |
495 { | |
496 tag_ = tag; | |
497 } | |
498 | |
499 if (!summary.empty()) | 502 if (!summary.empty()) |
500 { | 503 { |
501 bool replace; | 504 bool replace; |
502 | 505 |
503 if (summary_.empty()) | 506 if (summary_.empty()) |
542 summaryOrigin_ = newOrigin; | 545 summaryOrigin_ = newOrigin; |
543 } | 546 } |
544 } | 547 } |
545 } | 548 } |
546 | 549 |
547 bool HasGet() const | |
548 { | |
549 return hasGet_; | |
550 } | |
551 | |
552 bool HasPost() const | |
553 { | |
554 return hasPost_; | |
555 } | |
556 | |
557 bool HasDelete() const | |
558 { | |
559 return hasDelete_; | |
560 } | |
561 | |
562 bool HasPut() const | |
563 { | |
564 return hasPut_; | |
565 } | |
566 | |
567 const std::string& GetSummary() const | 550 const std::string& GetSummary() const |
568 { | 551 { |
569 return summary_; | 552 return summary_; |
570 } | 553 } |
554 | |
555 static std::string FormatTag(const std::string& tag) | |
556 { | |
557 if (tag.empty()) | |
558 { | |
559 return tag; | |
560 } | |
561 else | |
562 { | |
563 std::string s; | |
564 s.reserve(tag.size()); | |
565 s.push_back(tag[0]); | |
566 | |
567 for (size_t i = 1; i < tag.size(); i++) | |
568 { | |
569 if (tag[i] == ' ') | |
570 { | |
571 s.push_back('-'); | |
572 } | |
573 else if (isupper(tag[i]) && | |
574 tag[i - 1] == ' ') | |
575 { | |
576 s.push_back(tolower(tag[i])); | |
577 } | |
578 else | |
579 { | |
580 s.push_back(tag[i]); | |
581 } | |
582 } | |
583 | |
584 return s; | |
585 } | |
586 } | |
587 | |
588 std::string Format(const std::string& openApiUrl, | |
589 HttpMethod method, | |
590 const std::string& uri) const | |
591 { | |
592 std::string p = uri; | |
593 boost::replace_all(p, "/", "~1"); | |
594 | |
595 switch (method) | |
596 { | |
597 case HttpMethod_Get: | |
598 if (hasGet_) | |
599 { | |
600 if (openApiUrl.empty()) | |
601 { | |
602 return "GET"; | |
603 } | |
604 else | |
605 { | |
606 return ("`GET <" + openApiUrl + "#tag/" + FormatTag(getTag_) + "/paths/" + p + "/get>`__"); | |
607 } | |
608 } | |
609 break; | |
610 | |
611 case HttpMethod_Post: | |
612 if (hasPost_) | |
613 { | |
614 if (openApiUrl.empty()) | |
615 { | |
616 return "POST"; | |
617 } | |
618 else | |
619 { | |
620 return ("`POST <" + openApiUrl + "#tag/" + FormatTag(postTag_) + "/paths/" + p + "/post>`__"); | |
621 } | |
622 } | |
623 break; | |
624 | |
625 case HttpMethod_Delete: | |
626 if (hasDelete_) | |
627 { | |
628 if (openApiUrl.empty()) | |
629 { | |
630 return "DELETE"; | |
631 } | |
632 else | |
633 { | |
634 return ("`DELETE <" + openApiUrl + "#tag/" + FormatTag(deleteTag_) + "/paths/" + p + "/delete>`__"); | |
635 } | |
636 } | |
637 break; | |
638 | |
639 case HttpMethod_Put: | |
640 if (hasPut_) | |
641 { | |
642 if (openApiUrl.empty()) | |
643 { | |
644 return "GET"; | |
645 } | |
646 else | |
647 { | |
648 return ("`PUT <" + openApiUrl + "#tag/" + FormatTag(putTag_) + "/paths/" + p + "/put>`__"); | |
649 } | |
650 } | |
651 break; | |
652 | |
653 default: | |
654 throw OrthancException(ErrorCode_InternalError); | |
655 } | |
656 | |
657 return ""; | |
658 } | |
571 }; | 659 }; |
572 | 660 |
573 typedef std::map<std::string, Path> Paths; | 661 typedef std::map<std::string, Path> Paths; |
574 | 662 |
575 Paths paths_; | 663 Paths paths_; |
576 | |
577 static std::string FormatTag(const std::string& tag) | |
578 { | |
579 if (tag.empty()) | |
580 { | |
581 return tag; | |
582 } | |
583 else | |
584 { | |
585 std::string s; | |
586 s.reserve(tag.size()); | |
587 s.push_back(tag[0]); | |
588 | |
589 for (size_t i = 1; i < tag.size(); i++) | |
590 { | |
591 if (tag[i] == ' ') | |
592 { | |
593 s.push_back('-'); | |
594 } | |
595 else if (isupper(tag[i]) && | |
596 tag[i - 1] == ' ') | |
597 { | |
598 s.push_back(tolower(tag[i])); | |
599 } | |
600 else | |
601 { | |
602 s.push_back(tag[i]); | |
603 } | |
604 } | |
605 | |
606 return s; | |
607 } | |
608 } | |
609 | |
610 std::string FormatUrl(const std::string& openApiUrl, | |
611 bool hasMethod, | |
612 const std::string& tag, | |
613 const std::string& uri, | |
614 const std::string& method) const | |
615 { | |
616 if (hasMethod) | |
617 { | |
618 std::string title; | |
619 Toolbox::ToUpperCase(title, method); | |
620 | |
621 if (openApiUrl.empty()) | |
622 { | |
623 return title; | |
624 } | |
625 else | |
626 { | |
627 std::string p = uri; | |
628 boost::replace_all(p, "/", "~1"); | |
629 | |
630 return ("`" + title + " <" + openApiUrl + "#tag/" + | |
631 FormatTag(tag) + "/paths/" + p + "/" + method + ">`__"); | |
632 } | |
633 } | |
634 else | |
635 { | |
636 return ""; | |
637 } | |
638 } | |
639 | 664 |
640 protected: | 665 protected: |
641 virtual bool HandleCall(RestApiCall& call, | 666 virtual bool HandleCall(RestApiCall& call, |
642 const std::set<std::string> uriArgumentsNames) ORTHANC_OVERRIDE | 667 const std::set<std::string> uriArgumentsNames) ORTHANC_OVERRIDE |
643 { | 668 { |
644 Path& path = paths_[ Toolbox::FlattenUri(call.GetFullUri()) ]; | 669 Path& path = paths_[ Toolbox::FlattenUri(call.GetFullUri()) ]; |
645 | 670 |
646 path.AddMethod(call.GetMethod()); | 671 path.AddMethod(call.GetMethod(), call.GetDocumentation().GetTag()); |
647 | 672 |
648 if (call.GetDocumentation().HasSummary()) | 673 if (call.GetDocumentation().HasSummary()) |
649 { | 674 { |
650 path.SetSummary(call.GetDocumentation().GetTag(), call.GetDocumentation().GetSummary(), call.GetMethod()); | 675 path.SetSummary(call.GetDocumentation().GetSummary(), call.GetMethod()); |
651 } | 676 } |
652 | 677 |
653 return true; | 678 return true; |
654 } | 679 } |
655 | 680 |
664 { | 689 { |
665 target += "Path,GET,POST,DELETE,PUT,Summary\n"; | 690 target += "Path,GET,POST,DELETE,PUT,Summary\n"; |
666 for (Paths::const_iterator it = paths_.begin(); it != paths_.end(); ++it) | 691 for (Paths::const_iterator it = paths_.begin(); it != paths_.end(); ++it) |
667 { | 692 { |
668 target += "``" + it->first + "``,"; | 693 target += "``" + it->first + "``,"; |
669 target += FormatUrl(openApiUrl, it->second.HasGet(), it->second.GetTag(), it->first, "get") + ","; | 694 target += it->second.Format(openApiUrl, HttpMethod_Get, it->first) + ","; |
670 target += FormatUrl(openApiUrl, it->second.HasPost(), it->second.GetTag(), it->first, "post") + ","; | 695 target += it->second.Format(openApiUrl, HttpMethod_Post, it->first) + ","; |
671 target += FormatUrl(openApiUrl, it->second.HasDelete(), it->second.GetTag(), it->first, "delete") + ","; | 696 target += it->second.Format(openApiUrl, HttpMethod_Delete, it->first) + ","; |
672 target += FormatUrl(openApiUrl, it->second.HasPut(), it->second.GetTag(), it->first, "put") + ","; | 697 target += it->second.Format(openApiUrl, HttpMethod_Put, it->first) + ","; |
673 target += it->second.GetSummary() + "\n"; | 698 target += it->second.GetSummary() + "\n"; |
674 } | 699 } |
675 } | 700 } |
676 }; | 701 }; |
677 } | 702 } |