45#include "BESCatalogUtils.h"
46#include "BESCatalogEntry.h"
50#include "BESContainerStorageList.h"
51#include "BESFileContainerStorage.h"
54#include "BESInternalError.h"
55#include "BESForbiddenError.h"
56#include "BESNotFoundError.h"
57#include "BESSyntaxUserError.h"
59#include "TheBESKeys.h"
62#include "CatalogNode.h"
63#include "CatalogItem.h"
67#include "CmrCatalog.h"
72#define prolog std::string("CmrCatalog::").append(__func__).append("() - ")
91 throw BESInternalError(
string(
"The CMR module must define at least one collection name using the key; '") + CMR_COLLECTIONS_KEY
92 +
"'", __FILE__, __LINE__);
98 throw BESInternalError(
string(
"The CMR module must define at least one facet name using the key; '") + CMR_COLLECTIONS_KEY
99 +
"'", __FILE__, __LINE__);
110 node->set_lmt(epoch_time);
111 node->set_catalog_name(CMR_CATALOG_NAME);
112 map<string, unique_ptr<Provider>> providers;
114 for (
const auto &provider : providers ) {
116 collection->set_name(provider.second->id());
117 collection->set_description(provider.second->description_of_holding());
118 collection->set_type(CatalogItem::node);
119 node->add_node(collection);
125bes::CatalogNode *CmrCatalog::get_collections_node(
const string &path,
const string &provider_id)
const
131 map<string, unique_ptr<Collection>> collections;
132 cmrApi.get_opendap_collections(provider_id, collections);
133 if(collections.empty()){
135 msg <<
"The provider " << provider_id <<
" does contain any OPeNDAP enabled collections.";
136 throw BESNotFoundError(msg.str(),__FILE__,__LINE__);
139 auto *catalog_node =
new CatalogNode(path);
140 catalog_node->set_lmt(epoch_time);
141 catalog_node->set_catalog_name(CMR_CATALOG_NAME);
142 for (
const auto &collection : collections ) {
143 auto *catalog_item =
new CatalogItem();
144 catalog_item->set_name(collection.second->id());
145 catalog_item->set_description(collection.second->abstract());
146 catalog_item->set_type(CatalogItem::node);
147 catalog_node->add_node(catalog_item);
153CmrCatalog::get_facets_node(
const std::string &path,
const std::string &collection_id)
const {
154 BESDEBUG(MODULE, prolog <<
"Building facet list for collection: " << collection_id << endl);
156 auto node =
new CatalogNode(path);
157 node->set_lmt(epoch_time);
158 node->set_catalog_name(CMR_CATALOG_NAME);
159 for(
const auto & d_facet : d_facets){
160 auto *catalogItem =
new CatalogItem();
161 catalogItem->set_name(d_facet);
162 catalogItem->set_type(CatalogItem::node);
163 catalogItem->set_lmt(epoch_time);
164 BESDEBUG(MODULE, prolog <<
"Adding facet: " << d_facet << endl);
165 node->add_node(catalogItem);
171CmrCatalog::get_temporal_facet_nodes(
const string &path,
const vector<string> &path_elements,
const string &collection_id)
const
173 BESDEBUG(MODULE, prolog <<
"Found Temporal Facet"<< endl);
176 auto node =
new CatalogNode(path);
177 node->set_lmt(epoch_time);
178 node->set_catalog_name(CMR_CATALOG_NAME);
181 switch( path_elements.size()){
185 vector<string> years;
187 BESDEBUG(MODULE, prolog <<
"Getting year nodes for collection: " << collection_id<< endl);
188 cmrApi.get_years(collection_id, years);
189 for(
const auto & year : years){
190 auto *catalogItem =
new CatalogItem();
191 catalogItem->set_type(CatalogItem::node);
192 catalogItem->set_name(year);
193 catalogItem->set_is_data(
false);
194 catalogItem->set_lmt(epoch_time);
195 catalogItem->set_size(0);
196 node->add_node(catalogItem);
203 const string &year = path_elements[0];
205 vector<string> months;
207 BESDEBUG(MODULE, prolog <<
"Getting month nodes for collection: " << collection_id <<
" year: " << year << endl);
208 cmrApi.get_months(collection_id, year, months);
209 for(
const auto & month : months){
210 auto *catalogItem =
new CatalogItem();
211 catalogItem->set_type(CatalogItem::node);
212 catalogItem->set_name(month);
213 catalogItem->set_is_data(
false);
214 catalogItem->set_lmt(epoch_time);
215 catalogItem->set_size(0);
216 node->add_node(catalogItem);
223 const string &year = path_elements[0];
224 const string &month = path_elements[1];
227 BESDEBUG(MODULE, prolog <<
"Getting day nodes for collection: " << collection_id <<
" year: " << year <<
" month: " << month << endl);
228 cmrApi.get_days(collection_id, year, month, days);
229 for(
const auto &day : days){
230 auto *catalogItem =
new CatalogItem();
231 catalogItem->set_type(CatalogItem::node);
232 catalogItem->set_name(day);
233 catalogItem->set_is_data(
false);
234 catalogItem->set_lmt(epoch_time);
235 catalogItem->set_size(0);
236 node->add_node(catalogItem);
243 const string &year = path_elements[0];
244 const string &month = path_elements[1];
245 const string &day = path_elements[2];
246 BESDEBUG(MODULE, prolog <<
"Getting granule leaves for collection: " << collection_id <<
" year: " << year <<
" month: " << month <<
" day: " << day << endl);
247 vector<unique_ptr<GranuleUMM>> granules;
248 cmrApi.get_granules_umm(collection_id, year, month, day, granules);
249 for(
const auto &granule : granules){
262 const string &year = path_elements[0];
263 const string &month = path_elements[1];
264 const string &day = path_elements[2];
265 const string &granule_id = path_elements[3];
266 BESDEBUG(MODULE, prolog <<
"Request resolved to leaf granule/dataset name, collection: " << collection_id <<
" year: " << year
267 <<
" month: " << month <<
" day: " << day <<
" granule: " << granule_id << endl);
268 auto granule = cmrApi.get_granule(collection_id,year,month,day,granule_id);
270 auto *granuleItem =
new CatalogItem();
271 granuleItem->set_type(CatalogItem::leaf);
272 granuleItem->set_name(granule->getName());
273 granuleItem->set_is_data(
true);
274 granuleItem->set_lmt(granule->getLastModifiedStr());
275 granuleItem->set_size(granule->getSize());
276 node->set_leaf(granuleItem);
279 throw BESNotFoundError(
"No such resource: "+path,__FILE__,__LINE__);
286 throw BESSyntaxUserError(
"CmrCatalog: The path '"+path+
"' does not describe a valid temporal facet search.",__FILE__,__LINE__);
311 BESDEBUG(MODULE, prolog <<
"path: '" << path <<
"' path_elements.size(): " << path_elements.size() << endl);
316 for (
auto & path_element : path_elements) {
317 if (path_element ==
"-")
322 string collection_id;
324 switch(path_elements.size()){
327 return get_providers_node();
331 provider_id = path_elements[0];
332 return get_collections_node(path, provider_id);
344 provider_id = path_elements[0];
345 path_elements.erase(path_elements.begin());
347 collection_id = path_elements[0];
348 path_elements.erase(path_elements.begin());
359 return get_temporal_facet_nodes(path, path_elements,collection_id);
376CmrCatalog::get_node_OLD(
const string &ppath)
const
380 BESDEBUG(MODULE, prolog <<
"path: '" << path <<
"' path_elements.size(): " << path_elements.size() << endl);
387 if(path_elements.empty()){
389 node->set_lmt(epoch_time);
390 node->set_catalog_name(CMR_CATALOG_NAME);
391 for(
const auto & d_collection : d_collections){
393 collection->set_name(d_collection);
394 collection->set_type(CatalogItem::node);
395 node->add_node(collection);
399 for(
auto & path_element : path_elements){
400 if(path_element==
"-")
404 string collection = path_elements[0];
405 BESDEBUG(MODULE, prolog <<
"Checking for collection: " << collection <<
" d_collections.size(): " << d_collections.size() << endl);
406 bool valid_collection =
false;
407 for(
size_t i=0; i<d_collections.size() && !valid_collection ; i++){
408 if(collection == d_collections[i])
409 valid_collection =
true;
411 if(!valid_collection){
412 throw BESNotFoundError(
"The CMR catalog does not contain a collection named '"+collection+
"'",__FILE__,__LINE__);
414 BESDEBUG(MODULE, prolog <<
"Collection " << collection <<
" is valid." << endl);
415 if(path_elements.size() >1){
416 string facet = path_elements[1];
417 bool valid_facet =
false;
418 for(
size_t i=0; i<d_facets.size() && !valid_facet ; i++){
419 if(facet == d_facets[i])
423 throw BESNotFoundError(
"The CMR collection '"+collection+
"' does not contain a facet named '"+facet+
"'",__FILE__,__LINE__);
426 if(facet==
"temporal"){
427 BESDEBUG(MODULE, prolog <<
"Found Temporal Facet"<< endl);
428 node =
new CatalogNode(path);
429 node->set_lmt(epoch_time);
430 node->set_catalog_name(CMR_CATALOG_NAME);
433 switch( path_elements.size()){
437 vector<string> years;
439 BESDEBUG(MODULE, prolog <<
"Getting year nodes for collection: " << collection<< endl);
440 cmrApi.get_years(collection, years);
441 for(
auto & year : years){
442 auto *catalogItem =
new CatalogItem();
443 catalogItem->set_type(CatalogItem::node);
444 catalogItem->set_name(year);
445 catalogItem->set_is_data(
false);
446 catalogItem->set_lmt(epoch_time);
447 catalogItem->set_size(0);
448 node->add_node(catalogItem);
455 string year = path_elements[2];
458 vector<string> months;
460 BESDEBUG(MODULE, prolog <<
"Getting month nodes for collection: " << collection <<
" year: " << year << endl);
462 for(
auto & month : months){
463 auto *catalogItem =
new CatalogItem();
464 catalogItem->set_type(CatalogItem::node);
465 catalogItem->set_name(month);
466 catalogItem->set_is_data(
false);
467 catalogItem->set_lmt(epoch_time);
468 catalogItem->set_size(0);
469 node->add_node(catalogItem);
476 string year = path_elements[2];
477 string month = path_elements[3];
481 BESDEBUG(MODULE, prolog <<
"Getting day nodes for collection: " << collection <<
" year: " << year <<
" month: " << month << endl);
482 cmrApi.
get_days(collection, year, month, days);
483 for(
auto & day : days){
484 auto *catalogItem =
new CatalogItem();
485 catalogItem->set_type(CatalogItem::node);
486 catalogItem->set_name(day);
487 catalogItem->set_is_data(
false);
488 catalogItem->set_lmt(epoch_time);
489 catalogItem->set_size(0);
490 node->add_node(catalogItem);
497 string year = path_elements[2];
498 string month = path_elements[3];
499 string day = path_elements[4];
500 BESDEBUG(MODULE, prolog <<
"Getting granule leaves for collection: " << collection <<
" year: " << year <<
" month: " << month <<
" day: " << day << endl);
501 vector<Granule *> granules;
502 cmrApi.
get_granules(collection, year, month, day, granules);
503 for(
auto & granule : granules){
511 string year = path_elements[2];
512 string month = path_elements[3];
513 string day = path_elements[4];
514 string granule_id = path_elements[5];
515 BESDEBUG(MODULE, prolog <<
"Request resolved to leaf granule/dataset name, collection: " << collection <<
" year: " << year
516 <<
" month: " << month <<
" day: " << day <<
" granule: " << granule_id << endl);
517 Granule *granule = cmrApi.get_granule(collection,year,month,day,granule_id);
519 auto *granuleItem =
new CatalogItem();
520 granuleItem->set_type(CatalogItem::leaf);
521 granuleItem->set_name(granule->getName());
522 granuleItem->set_is_data(
true);
523 granuleItem->set_lmt(granule->getLastModifiedStr());
524 granuleItem->set_size(granule->getSize());
525 node->set_leaf(granuleItem);
528 throw BESNotFoundError(
"No such resource: "+path,__FILE__,__LINE__);
535 throw BESSyntaxUserError(
"CmrCatalog: The path '"+path+
"' does not describe a valid temporal facet search.",__FILE__,__LINE__);
542 throw BESNotFoundError(
"The CMR catalog only supports temporal faceting.",__FILE__,__LINE__);
546 BESDEBUG(MODULE, prolog <<
"Building facet list for collection: " << collection << endl);
547 node =
new CatalogNode(path);
548 node->set_lmt(epoch_time);
549 node->set_catalog_name(CMR_CATALOG_NAME);
550 for(
const auto & d_facet : d_facets){
551 auto *catalogItem =
new CatalogItem();
552 catalogItem->set_name(d_facet);
553 catalogItem->set_type(CatalogItem::node);
554 catalogItem->set_lmt(epoch_time);
555 BESDEBUG(MODULE, prolog <<
"Adding facet: " << d_facet << endl);
556 node->add_node(catalogItem);
575 strm << BESIndent::LMarg << prolog <<
"(" << (
void *)
this <<
")" << endl;
578 strm << BESIndent::LMarg <<
"catalog utilities: " << endl;
581 BESIndent::UnIndent();
582 BESIndent::UnIndent();
virtual void dump(std::ostream &strm) const
dump the contents of this object to the specified ostream
virtual BESCatalogUtils * get_catalog_utils() const
Get a pointer to the utilities, customized for this catalog.
exception thrown if internal error encountered
static std::vector< std::string > split(const std::string &s, char delim='/', bool skip_empty=true)
Splits the string s into the return vector of tokens using the delimiter delim and skipping empty val...
static std::string normalize_path(const std::string &path, bool leading_separator, bool trailing_separator, std::string separator="/")
Removes duplicate separators and provides leading and trailing separators as directed.
static std::string get_time(bool use_local_time=false)
static TheBESKeys * TheKeys()
Access to the singleton.
void get_values(const std::string &s, std::vector< std::string > &vals, bool &found)
Retrieve the values of a given key, if set.
void get_opendap_providers(std::map< std::string, std::unique_ptr< cmr::Provider > > &providers) const
void get_granules(const std::string &collection_name, const std::string &r_year, const std::string &r_month, const std::string &r_day, std::vector< std::unique_ptr< cmr::Granule > > &granule_objs) const
void get_days(const std::string &collection_name, const std::string &r_year, const std::string &r_month, std::vector< std::string > &days_result) const
void get_months(const std::string &collection_name, const std::string &year, std::vector< std::string > &months_result) const
bes::CatalogNode * get_node(const std::string &path) const override
CmrCatalog(const std::string &name=CMR_CATALOG_NAME)
A catalog based on NASA's CMR system.
void dump(std::ostream &strm) const override
dumps information about this object