33 #include <curl/curl.h>
39 #include "rapidjson/writer.h"
40 #include "rapidjson/prettywriter.h"
41 #include "rapidjson/stringbuffer.h"
42 #include "rapidjson/filereadstream.h"
45 #include "BESNotFoundError.h"
46 #include "BESSyntaxUserError.h"
49 #include "BESStopWatch.h"
51 #include "TheBESKeys.h"
52 #include "CurlUtils.h"
54 #include "RemoteResource.h"
57 #include "NgapNames.h"
58 #include "NgapError.h"
62 #define prolog string("NgapApi::").append(__func__).append("() - ")
66 const string NGAP_PROVIDER_KEY(
"providers");
67 const string NGAP_COLLECTIONS_KEY(
"collections");
68 const string NGAP_CONCEPTS_KEY(
"concepts");
69 const string NGAP_GRANULES_KEY(
"granules");
70 const string DEFAULT_CMR_ENDPOINT_URL(
"https://cmr.earthdata.nasa.gov");
71 const string DEFAULT_CMR_SEARCH_ENDPOINT_PATH(
"/search/granules.umm_json_v1_4");
73 const string CMR_PROVIDER(
"provider");
74 const string CMR_ENTRY_TITLE(
"entry_title");
75 const string CMR_COLLECTION_CONCEPT_ID(
"collection_concept_id");
76 const string CMR_GRANULE_UR(
"granule_ur");
77 const string CMR_URL_TYPE_GET_DATA(
"GET DATA");
79 const string RJ_TYPE_NAMES[] = {
89 const string AMS_EXPIRES_HEADER_KEY(
"X-Amz-Expires");
90 const string AWS_DATE_HEADER_KEY(
"X-Amz-Date");
92 const string CLOUDFRONT_EXPIRES_HEADER_KEY(
"Expires");
93 const string INGEST_TIME_KEY(
"ingest_time");
94 const unsigned int REFRESH_THRESHOLD = 3600;
97 NgapApi::NgapApi() : d_cmr_hostname(DEFAULT_CMR_ENDPOINT_URL), d_cmr_search_endpoint_path(DEFAULT_CMR_SEARCH_ENDPOINT_PATH) {
102 d_cmr_hostname = cmr_hostnamer;
105 string cmr_search_endpoint_path;
108 d_cmr_search_endpoint_path = cmr_search_endpoint_path;
114 std::string NgapApi::get_cmr_search_endpoint_url(){
122 NgapApi::build_cmr_query_url(
const std::string &restified_path) {
123 string data_access_url(
"");
125 vector<string> tokens;
127 if (tokens.empty()) {
129 "' failed to tokenize: No tokens were returned.", __FILE__, __LINE__);
131 if(tokens.size()!=6){
133 msg << prolog <<
"The specified NGAP API path '" << restified_path <<
"' was tokenized, but ";
134 msg << tokens.size() <<
" token(s) were found where 6 are required.";
139 if (tokens[0] != NGAP_PROVIDER_KEY ) {
141 msg << prolog <<
"The specified path '" << restified_path <<
"'";
142 msg <<
"does not contain the required path element '" << NGAP_PROVIDER_KEY <<
"'";
146 if ((tokens[2] != NGAP_COLLECTIONS_KEY && tokens[2] != NGAP_CONCEPTS_KEY)) {
148 msg << prolog <<
"The specified path '" << restified_path <<
"'";
149 msg <<
"does not contain the expected path element '" << NGAP_COLLECTIONS_KEY <<
"' or it's alternate, '";
150 msg << NGAP_CONCEPTS_KEY <<
"'. One of these is required";
154 if (tokens[4] != NGAP_GRANULES_KEY) {
156 msg << prolog <<
"The specified path '" << restified_path <<
"'";
157 msg <<
"does not contain the required path element '" << NGAP_GRANULES_KEY <<
"'.";
162 string cmr_url = get_cmr_search_endpoint_url() +
"?";
165 CURL *ceh = curl_easy_init();
166 char *esc_url_content;
169 esc_url_content = curl_easy_escape(ceh, tokens[1].c_str(), tokens[1].size());
170 cmr_url += CMR_PROVIDER +
"=" + esc_url_content +
"&";
171 curl_free(esc_url_content);
173 esc_url_content = curl_easy_escape(ceh, tokens[3].c_str(), tokens[3].size());
174 if (tokens[2] == NGAP_COLLECTIONS_KEY) {
176 cmr_url += CMR_ENTRY_TITLE +
"=" + esc_url_content +
"&";
178 else if(tokens[2] == NGAP_CONCEPTS_KEY){
180 cmr_url += CMR_COLLECTION_CONCEPT_ID +
"=" + esc_url_content +
"&";
184 curl_free(esc_url_content);
186 msg << prolog <<
"The specified path '" << restified_path <<
"'";
187 msg <<
"does not contain the expected path element '" << NGAP_COLLECTIONS_KEY <<
"' or it's alternate '";
188 msg << NGAP_CONCEPTS_KEY <<
"'. One of these is required";
191 curl_free(esc_url_content);
193 esc_url_content = curl_easy_escape(ceh, tokens[5].c_str(), tokens[5].size());
194 cmr_url += CMR_GRANULE_UR +
"=" + esc_url_content;
195 curl_free(esc_url_content);
196 curl_easy_cleanup(ceh);
209 std::string NgapApi::build_cmr_query_url(
const std::string &restified_path) {
210 string PROVIDERS_KEY(
"/providers/");
211 string COLLECTIONS_KEY(
"/collections/");
212 string CONCEPTS_KEY(
"/concepts/");
213 string GRANULES_KEY(
"/granules/");
216 string r_path = ( restified_path[0] !=
'/' ?
"/" :
"") + restified_path;
218 size_t provider_index = r_path.find(PROVIDERS_KEY);
219 if(provider_index == string::npos){
221 msg << prolog <<
"The specified path '" << r_path <<
"'";
222 msg <<
" does not contain the required path element '" << NGAP_PROVIDER_KEY <<
"'";
225 if(provider_index != 0){
227 msg << prolog <<
"The specified path '" << r_path <<
"'";
228 msg <<
" has the path element '" << NGAP_PROVIDER_KEY <<
"' located in the incorrect position (";
229 msg << provider_index <<
") expected 0.";
232 provider_index += PROVIDERS_KEY.length();
234 bool use_collection_concept_id =
false;
235 size_t collection_index = r_path.find(COLLECTIONS_KEY);
236 if(collection_index == string::npos) {
237 size_t concepts_index = r_path.find(CONCEPTS_KEY);
238 if (concepts_index == string::npos) {
240 msg << prolog <<
"The specified path '" << r_path <<
"'";
241 msg <<
" contains neither the '" << COLLECTIONS_KEY <<
"'";
242 msg <<
" nor the '" << CONCEPTS_KEY <<
"'";
243 msg <<
" one must be provided.";
246 collection_index = concepts_index;
247 use_collection_concept_id =
true;
249 if(collection_index <= provider_index+1){
251 msg << prolog <<
"The specified path '" << r_path <<
"'";
252 msg <<
" has the path element '" << (use_collection_concept_id?CONCEPTS_KEY:COLLECTIONS_KEY) <<
"' located in the incorrect position (";
253 msg << collection_index <<
") expected at least " << provider_index+1;
256 string provider = r_path.substr(provider_index,collection_index - provider_index);
257 collection_index += use_collection_concept_id?CONCEPTS_KEY.length():COLLECTIONS_KEY.length();
260 size_t granule_index = r_path.find(GRANULES_KEY);
261 if(granule_index == string::npos){
263 msg << prolog <<
"The specified path '" << r_path <<
"'";
264 msg <<
" does not contain the required path element '" << GRANULES_KEY <<
"'";
267 if(granule_index <= collection_index+1){
269 msg << prolog <<
"The specified path '" << r_path <<
"'";
270 msg <<
" has the path element '" << GRANULES_KEY <<
"' located in the incorrect position (";
271 msg << granule_index <<
") expected at least " << collection_index+1;
274 string collection = r_path.substr(collection_index,granule_index - collection_index);
275 granule_index += GRANULES_KEY.length();
278 string granule = r_path.substr(granule_index);
281 string cmr_url = get_cmr_search_endpoint_url() +
"?";
284 CURL *ceh = curl_easy_init();
285 char *esc_url_content;
288 esc_url_content = curl_easy_escape(ceh, provider.c_str(), provider.size());
289 cmr_url += CMR_PROVIDER +
"=" + esc_url_content +
"&";
290 curl_free(esc_url_content);
292 esc_url_content = curl_easy_escape(ceh, collection.c_str(), collection.size());
293 if(use_collection_concept_id){
295 cmr_url += CMR_COLLECTION_CONCEPT_ID +
"=" + esc_url_content +
"&";
299 cmr_url += CMR_ENTRY_TITLE +
"=" + esc_url_content +
"&";
302 curl_free(esc_url_content);
304 esc_url_content = curl_easy_escape(ceh, granule.c_str(), granule.size());
305 cmr_url += CMR_GRANULE_UR +
"=" + esc_url_content;
306 curl_free(esc_url_content);
308 curl_easy_cleanup(ceh);
324 std::string NgapApi::find_get_data_url_in_granules_umm_json_v1_4(
const std::string &restified_path,
rapidjson::Document &cmr_granule_response)
327 string data_access_url(
"");
330 int hits = val.GetInt();
332 throw BESNotFoundError(
string(
"The specified path '").append(restified_path).append(
333 "' does not identify a granule in CMR."), __FILE__, __LINE__);
337 if (items.IsArray()) {
340 ss <<
"items[" << i <<
"]: " << RJ_TYPE_NAMES[items[i].GetType()] << endl;
342 BESDEBUG(MODULE, prolog <<
"items size: " << items.Size() << endl << ss.str() << endl);
345 rapidjson::GenericMemberIterator<false, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>> mitr = items_obj.FindMember(
349 mitr = umm.FindMember(
"RelatedUrls");
350 if (mitr == umm.MemberEnd()) {
351 throw BESInternalError(
"Error! The umm/RelatedUrls object was not located!", __FILE__, __LINE__);
355 if (!related_urls.IsArray()) {
356 throw BESNotFoundError(
"Error! The RelatedUrls object in the CMR response is not an array!", __FILE__,
360 BESDEBUG(MODULE, prolog <<
" Found RelatedUrls array in CMR response." << endl);
365 mitr = obj.FindMember(
"URL");
366 if (mitr == obj.MemberEnd()) {
368 err <<
"Error! The umm/RelatedUrls[" << i <<
"] does not contain the URL object";
373 mitr = obj.FindMember(
"Type");
374 if (mitr == obj.MemberEnd()) {
376 err <<
"Error! The umm/RelatedUrls[" << i <<
"] does not contain the Type object";
381 noSubtype = obj.FindMember(
"Subtype") == obj.MemberEnd();
383 mitr = obj.FindMember(
"Description");
384 if(mitr == obj.MemberEnd()){
386 err <<
"Error! The umm/RelatedUrls[" << i <<
"] does not contain the Description object";
391 BESDEBUG(MODULE, prolog <<
"RelatedUrl Object:" <<
392 " URL: '" << r_url.GetString() <<
"'" <<
393 " Type: '" << r_type.GetString() <<
"'" <<
394 " SubType: '" << (noSubtype ?
"Absent" :
"Present") <<
"'" << endl);
396 if ((r_type.GetString() == CMR_URL_TYPE_GET_DATA) && noSubtype) {
397 data_access_url = r_url.GetString();
402 if (data_access_url.empty()) {
403 throw BESInternalError(
string(
"ERROR! Failed to locate a data access URL for the path: ") + restified_path,
407 return data_access_url;
434 string NgapApi::convert_ngap_resty_path_to_data_access_url(
435 const std::string &restified_path,
436 const std::string &uid
438 BESDEBUG(MODULE, prolog <<
"BEGIN" << endl);
439 string data_access_url(
"");
441 string cmr_query_url = build_cmr_query_url(restified_path);
443 BESDEBUG(MODULE, prolog <<
"CMR Request URL: " << cmr_query_url << endl);
445 BESDEBUG(MODULE, prolog <<
"Building new RemoteResource." << endl);
449 if (BESISDEBUG(MODULE) ||
BESDebug::IsSet(TIMING_LOG_KEY) || BESLog::TheLog()->is_verbose()){
450 besTimer.
start(
"CMR Query: " + cmr_query_url);
456 data_access_url = find_get_data_url_in_granules_umm_json_v1_4(restified_path, cmr_response);
458 BESDEBUG(MODULE, prolog <<
"END (data_access_url: "<< data_access_url <<
")" << endl);
460 return data_access_url;
466 bool NgapApi::signed_url_is_expired(
const http::url &signed_url)
471 BESDEBUG(MODULE, prolog <<
"now: " << now << endl);
473 time_t expires = now;
476 time_t ingest_time = signed_url.ingest_time();
478 if(!cf_expires.empty()){
479 expires = stoll(cf_expires);
480 BESDEBUG(MODULE, prolog <<
"Using "<< CLOUDFRONT_EXPIRES_HEADER_KEY <<
": " << expires << endl);
482 else if(!aws_expires.empty()){
486 time_t start_time = ingest_time;
490 if(!aws_date.empty()){
491 string date = aws_date;
492 string year = date.substr(0,4);
493 string month = date.substr(4,2);
494 string day = date.substr(6,2);
495 string hour = date.substr(9,2);
496 string minute = date.substr(11,2);
497 string second = date.substr(13,2);
499 BESDEBUG(MODULE, prolog <<
"date: "<< date <<
500 " year: " << year <<
" month: " << month <<
" day: " << day <<
501 " hour: " << hour <<
" minute: " << minute <<
" second: " << second << endl);
503 struct tm *ti = gmtime(&now);
504 ti->tm_year = stoll(year) - 1900;
505 ti->tm_mon = stoll(month) - 1;
506 ti->tm_mday = stoll(day);
507 ti->tm_hour = stoll(hour);
508 ti->tm_min = stoll(minute);
509 ti->tm_sec = stoll(second);
511 BESDEBUG(MODULE, prolog <<
"ti->tm_year: "<< ti->tm_year <<
512 " ti->tm_mon: " << ti->tm_mon <<
513 " ti->tm_mday: " << ti->tm_mday <<
514 " ti->tm_hour: " << ti->tm_hour <<
515 " ti->tm_min: " << ti->tm_min <<
516 " ti->tm_sec: " << ti->tm_sec << endl);
519 start_time = mktime(ti);
520 BESDEBUG(MODULE, prolog <<
"AWS (computed) start_time: "<< start_time << endl);
522 expires = start_time + stoll(aws_expires);
523 BESDEBUG(MODULE, prolog <<
"Using "<< AMS_EXPIRES_HEADER_KEY <<
": " << aws_expires <<
524 " (expires: " << expires <<
")" << endl);
526 time_t remaining = expires - now;
527 BESDEBUG(MODULE, prolog <<
"expires_time: " << expires <<
528 " remaining_time: " << remaining <<
529 " refresh_threshold: " << REFRESH_THRESHOLD << endl);
531 is_expired = remaining < REFRESH_THRESHOLD;
532 BESDEBUG(MODULE, prolog <<
"is_expired: " << (is_expired?
"true":
"false") << endl);
540 string NgapApi::convert_ngap_resty_path_to_data_access_url(
string real_name){
541 string data_access_url(
"");
543 vector<string> tokens;
545 if( tokens[0]!= NGAP_PROVIDER_KEY || tokens[2]!=NGAP_DATASETS_KEY || tokens[4]!=NGAP_GRANULES_KEY){
546 string err = (string)
"The specified path " + real_name
547 +
" does not conform to the NGAP request interface API.";
551 string cmr_url = cmr_granule_search_endpoint_url +
"?";
552 cmr_url += CMR_PROVIDER +
"=" + tokens[1] +
"&";
553 cmr_url += CMR_ENTRY_TITLE +
"=" + tokens[3] +
"&";
554 cmr_url += CMR_GRANULE_UR +
"=" + tokens[5] ;
555 BESDEBUG( MODULE, prolog <<
"CMR Request URL: "<< cmr_url << endl );
559 int hits = val.GetInt();
561 string err = (string)
"The specified path " + real_name
562 +
" does not identify a thing we know about....";
570 ss <<
"items[" << i <<
"]: " << rjtype_names[items[i].GetType()] << endl;
571 BESDEBUG(MODULE,prolog <<
"items size: " << items.Size() << endl << ss.str() << endl);
574 rapidjson::GenericMemberIterator<false, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>> mitr = items_obj.FindMember(
"umm");
577 mitr = umm.FindMember(
"RelatedUrls");
580 if(!related_urls.IsArray()){
581 string err = (string)
"Error! The RelatedUrls object in the CMR response is not an array!";
585 BESDEBUG(MODULE,prolog <<
" Found RelatedUrls array in CMR response." << endl);
591 mitr = obj.FindMember(
"URL");
593 mitr = obj.FindMember(
"Type");
595 noSubtype = ((mitr = obj.FindMember(
"Subtype")) == obj.MemberEnd()) ?
true :
false;
596 mitr = obj.FindMember(
"Description");
598 BESDEBUG(MODULE,prolog <<
"RelatedUrl Object:" <<
599 " URL: '" << r_url.GetString() <<
"'" <<
600 " Type: '" << r_type.GetString() <<
"'" <<
602 " Description: '" << r_desc.GetString() <<
"'" << endl);
604 if( (r_type.GetString() == CMR_URL_TYPE_GET_DATA) && noSubtype ){
605 data_access_url = r_url.GetString();
611 return data_access_url +
".dmrpp";
623 itr = obj.FindMember(
"children");
624 bool result = itr != obj.MemberEnd();
625 string msg = prolog + (result?
"Located":
"FAILED to locate") +
" the value 'children' in the object.";
626 BESDEBUG(MODULE, msg << endl);
628 throw NgapError(msg,__FILE__,__LINE__);
632 result = children.IsArray();
633 msg = prolog +
"The value 'children' is" + (result?
"":
" NOT") +
" an array.";
634 BESDEBUG(MODULE, msg << endl);
636 throw NgapError(msg,__FILE__,__LINE__);
647 bool result = ngap_doc.IsObject();
648 string msg = prolog +
"Json document is" + (result?
"":
" NOT") +
" an object.";
649 BESDEBUG(MODULE, msg << endl);
651 throw NgapError(msg,__FILE__,__LINE__);
656 result = itr != ngap_doc.MemberEnd();
657 msg = prolog + (result?
"Located":
"FAILED to locate") +
" the value 'feed'.";
658 BESDEBUG(MODULE, msg << endl);
660 throw NgapError(msg,__FILE__,__LINE__);
664 result = feed.IsObject();
665 msg = prolog +
"The value 'feed' is" + (result?
"":
" NOT") +
" an object.";
666 BESDEBUG(MODULE, msg << endl);
668 throw NgapError(msg,__FILE__,__LINE__);
684 result = itr != feed.MemberEnd();
685 msg = prolog + (result?
"Located":
"FAILED to locate") +
" the value 'entry'.";
686 BESDEBUG(MODULE, msg << endl);
688 throw NgapError(msg,__FILE__,__LINE__);
692 result = entry.IsArray();
693 msg = prolog +
"The value 'entry' is" + (result?
"":
" NOT") +
" an Array.";
694 BESDEBUG(MODULE, msg << endl);
696 throw NgapError(msg,__FILE__,__LINE__);
714 result = itr != feed.MemberEnd();
715 msg = prolog + (result?
"Located":
"FAILED to locate") +
" the value 'facets'." ;
716 BESDEBUG(MODULE, msg << endl);
718 throw NgapError(msg,__FILE__,__LINE__);
722 result = facets_obj.IsObject();
723 msg = prolog +
"The value 'facets' is" + (result?
"":
" NOT") +
" an object.";
724 BESDEBUG(MODULE, msg << endl);
726 throw NgapError(msg,__FILE__,__LINE__);
733 string facet_title = ru.getStringValue(facet,
"title");
734 string temporal_title(
"Temporal");
735 if(facet_title == temporal_title){
736 msg = prolog +
"Found Temporal object.";
737 BESDEBUG(MODULE, msg << endl);
741 msg = prolog +
"The child of 'facets' with title '"+facet_title+
"' does not match 'Temporal'";
742 BESDEBUG(MODULE, msg << endl);
745 msg = prolog +
"Failed to locate the Temporal facet.";
746 BESDEBUG(MODULE, msg << endl);
747 throw NgapError(msg,__FILE__,__LINE__);
764 string temporal_child_title = rju.getStringValue(temporal_child,
"title");
765 string year_title(
"Year");
766 if(temporal_child_title == year_title){
767 msg = prolog +
"Found Year object.";
768 BESDEBUG(MODULE, msg << endl);
769 return temporal_child;
772 msg = prolog +
"The child of 'Temporal' with title '"+temporal_child_title+
"' does not match 'Year'";
773 BESDEBUG(MODULE, msg << endl);
776 msg = prolog +
"Failed to locate the Year group.";
777 BESDEBUG(MODULE, msg << endl);
778 throw NgapError(msg,__FILE__,__LINE__);
794 string year_title = rju.getStringValue(year_obj,
"title");
795 if(r_year == year_title){
796 msg = prolog +
"Found Year object.";
797 BESDEBUG(MODULE, msg << endl);
802 string title = rju.getStringValue(child,
"title");
803 string month_title(
"Month");
804 if(title == month_title){
805 msg = prolog +
"Found Month object.";
806 BESDEBUG(MODULE, msg << endl);
810 msg = prolog +
"The child of 'Year' with title '"+title+
"' does not match 'Month'";
811 BESDEBUG(MODULE, msg << endl);
816 msg = prolog +
"The child of 'Year' group with title '"+year_title+
"' does not match the requested year ("+r_year+
")";
817 BESDEBUG(MODULE, msg << endl);
820 msg = prolog +
"Failed to locate the Year group.";
821 BESDEBUG(MODULE, msg << endl);
822 throw NgapError(msg,__FILE__,__LINE__);
826 NgapApi::get_month(
const string r_month,
const string r_year,
const rapidjson::Document &ngap_doc){
834 string month_id = rju.getStringValue(month,
"title");
835 if(month_id == r_month){
837 msg << prolog <<
"Located requested month ("<<r_month <<
")";
838 BESDEBUG(MODULE, msg.str() << endl);
843 msg << prolog <<
"The month titled '"<<month_id <<
"' does not match the requested month ("<< r_month <<
")";
844 BESDEBUG(MODULE, msg.str() << endl);
848 msg << prolog <<
"Failed to locate request Year/Month.";
849 BESDEBUG(MODULE, msg.str() << endl);
850 throw NgapError(msg.str(),__FILE__,__LINE__);
854 NgapApi::get_day_group(
const string r_month,
const string r_year,
const rapidjson::Document &ngap_doc){
863 string title = rju.getStringValue(
object,
"title");
864 string day_group_title =
"Day";
865 if(title == day_group_title){
867 msg << prolog <<
"Located Day group for year: " << r_year <<
" month: "<< r_month;
868 BESDEBUG(MODULE, msg.str() << endl);
873 msg << prolog <<
"Failed to locate requested Day year: " << r_year <<
" month: "<< r_month;
874 BESDEBUG(MODULE, msg.str() << endl);
875 throw NgapError(msg.str(),__FILE__,__LINE__);
886 NgapApi::get_years(
string collection_name, vector<string> &years_result){
891 string url =
BESUtil::assemblePath(ngap_search_endpoint_url,
"granules.json") +
"?concept_id="+collection_name +
"&include_facets=v2";
893 rju.getJsonDoc(url,doc);
899 string year = rju.getStringValue(year_obj,
"title");
900 years_result.push_back(year);
914 NgapApi::get_months(
string collection_name,
string r_year, vector<string> &months_result){
920 +
"?concept_id="+collection_name
921 +
"&include_facets=v2"
922 +
"&temporal_facet[0][year]="+r_year;
925 rju.getJsonDoc(url,doc);
926 BESDEBUG(MODULE, prolog <<
"Got JSON Document: "<< endl << rju.jsonDocToString(doc) << endl);
930 if(years.Size() != 1){
932 msg << prolog <<
"We expected to get back one year (" << r_year <<
") but we got back " << years.Size();
933 BESDEBUG(MODULE, msg.str() << endl);
934 throw NgapError(msg.str(),__FILE__,__LINE__);
938 string year_title = rju.getStringValue(year,
"title");
939 if(year_title != r_year){
941 msg << prolog <<
"The returned year (" << year_title <<
") does not match the requested year ("<< r_year <<
")";
942 BESDEBUG(MODULE, msg.str() << endl);
943 throw NgapError(msg.str(),__FILE__,__LINE__);
947 if(year_children.Size() != 1){
949 msg << prolog <<
"We expected to get back one child for the year (" << r_year <<
") but we got back " << years.Size();
950 BESDEBUG(MODULE, msg.str() << endl);
951 throw NgapError(msg.str(),__FILE__,__LINE__);
955 string title = rju.getStringValue(month_group,
"title");
956 if(title !=
string(
"Month")){
958 msg << prolog <<
"We expected to get back a Month object, but we did not.";
959 BESDEBUG(MODULE, msg.str() << endl);
960 throw NgapError(msg.str(),__FILE__,__LINE__);
966 string month_id = rju.getStringValue(month,
"title");
967 months_result.push_back(month_id);
977 NgapApi::get_days(
string collection_name,
string r_year,
string r_month, vector<string> &days_result){
982 +
"?concept_id="+collection_name
983 +
"&include_facets=v2"
984 +
"&temporal_facet[0][year]="+r_year
985 +
"&temporal_facet[0][month]="+r_month;
988 rju.getJsonDoc(url,ngap_doc);
989 BESDEBUG(MODULE, prolog <<
"Got JSON Document: "<< endl << rju.jsonDocToString(ngap_doc) << endl);
991 const rapidjson::Value& day_group = get_day_group(r_month, r_year, ngap_doc);
995 string day_id = rju.getStringValue(day,
"title");
996 days_result.push_back(day_id);
1006 NgapApi::get_granule_ids(
string collection_name,
string r_year,
string r_month,
string r_day, vector<string> &granules_ids){
1011 granule_search(collection_name, r_year, r_month, r_day, ngap_doc);
1016 string day_id = rju.getStringValue(granule,
"id");
1017 granules_ids.push_back(day_id);
1027 NgapApi::granule_count(
string collection_name,
string r_year,
string r_month,
string r_day){
1030 granule_search(collection_name, r_year, r_month, r_day, ngap_doc);
1032 return entries.Size();
1040 NgapApi::granule_search(
string collection_name,
string r_year,
string r_month,
string r_day,
rapidjson::Document &result_doc){
1044 +
"?concept_id="+collection_name
1045 +
"&include_facets=v2"
1046 +
"&page_size=2000";
1049 url +=
"&temporal_facet[0][year]="+r_year;
1051 if(!r_month.empty())
1052 url +=
"&temporal_facet[0][month]="+r_month;
1055 url +=
"&temporal_facet[0][day]="+r_day;
1057 BESDEBUG(MODULE, prolog <<
"ngap Granule Search Request Url: : " << url << endl);
1058 rju.getJsonDoc(url,result_doc);
1059 BESDEBUG(MODULE, prolog <<
"Got JSON Document: "<< endl << rju.jsonDocToString(result_doc) << endl);
1068 NgapApi::get_granules(
string collection_name,
string r_year,
string r_month,
string r_day, vector<Granule *> &granules){
1072 granule_search(collection_name, r_year, r_month, r_day, ngap_doc);
1078 Granule *g =
new Granule(granule_obj);
1079 granules.push_back(g);
1086 NgapApi::get_collection_ids(std::vector<std::string> &collection_ids){
1088 string key = NGAP_COLLECTIONS;
1092 +
"' field has not been configured.", __FILE__, __LINE__);
1099 Granule* NgapApi::get_granule(
string collection_name,
string r_year,
string r_month,
string r_day,
string granule_id)
1101 vector<Granule *> granules;
1102 Granule *result = 0;
1104 get_granules(collection_name, r_year, r_month, r_day, granules);
1105 for(
size_t i=0; i<granules.size() ;i++){
1106 string id = granules[i]->getName();
1107 BESDEBUG(MODULE, prolog <<
"Comparing granule id: " << granule_id <<
" to collection member id: " <<
id << endl);
1108 if(
id == granule_id){
1109 result = granules[i];
static bool IsSet(const std::string &flagName)
see if the debug context flagName is set to true
exception thrown if internal error encountered
error thrown if the resource requested cannot be found
virtual bool start(std::string name)
error thrown if there is a user syntax error in the request or any other user error
static void tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters="/")
static std::string assemblePath(const std::string &firstPart, const std::string &secondPart, bool leadingSlash=false, bool trailingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
(Constant) member iterator for a JSON object value
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()
void get_values(const std::string &s, std::vector< std::string > &vals, bool &found)
Retrieve the values of a given key, if set.
rapidjson::Document get_as_json()
get_as_json() This function returns the cached resource parsed into a JSON document.
virtual std::string query_parameter_value(const std::string &key) const
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)