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