Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Types | Public Member Functions | Static Public Attributes | Protected Attributes | Private Member Functions | Private Attributes | Friends
Arc::MCCLoader Class Reference

Creator of Message Component Chains (MCC). More...

#include <MCCLoader.h>

Inheritance diagram for Arc::MCCLoader:
Inheritance graph
[legend]
Collaboration diagram for Arc::MCCLoader:
Collaboration graph
[legend]

List of all members.

Public Types

typedef std::map< std::string,
MCC * > 
mcc_container_t
typedef std::map< std::string,
Service * > 
service_container_t
typedef std::map< std::string,
ArcSec::SecHandler * > 
sechandler_container_t
typedef std::map< std::string,
Plexer * > 
plexer_container_t

Public Member Functions

 MCCLoader ()
 MCCLoader (Config &cfg)
 Constructor that takes whole XML configuration and creates component chains.
 ~MCCLoader ()
 Destructor destroys all components created by constructor.
MCCoperator[] (const std::string &id)
 Access entry MCCs in chains.
MCCoperator[] (const char *id)
 operator bool (void)
bool operator! (void)

Static Public Attributes

static Logger logger

Protected Attributes

PluginsFactoryfactory_
 Link to Factory responsible for loading and creation of Plugin and derived objects.

Private Member Functions

bool make_elements (Config &cfg, int level=0, mcc_connectors_t *mcc_connectors=NULL, plexer_connectors_t *plexer_connectors=NULL)
 Internal method which performs whole stuff specific to creation of Message Chains.

Private Attributes

bool valid_
mcc_container_t mccs_
 Set of labeled MCC objects.
mcc_container_t mccs_exposed_
 Set of MCC objects exposed to external interface.
service_container_t services_
 Set of labeled Service objects.
sechandler_container_t sechandlers_
 Set of labeled security handlers.
plexer_container_t plexers_
 Set of labeled Plexer objects.
ChainContextcontext_

Friends

class ChainContext

Detailed Description

Creator of Message Component Chains (MCC).

This class processes XML configration and creates message chains. Accepted configuration is defined by XML schema mcc.xsd. Supported components are of types MCC, Service and Plexer. MCC and Service are loaded from dynamic libraries. For Plexer only internal implementation is supported. This object is also a container for loaded componets. All components and chains are destroyed if this object is destroyed. Chains are created in 2 steps. First all components are loaded and corresponding objects are created. Constructors are supplied with corresponding configuration subtrees. During next step components are linked together by calling their Next() methods. Each call creates labeled link to next component in a chain. 2 step method has an advantage over single step because it allows loops in chains and makes loading procedure more simple. But that also means during short period of time components are only partly configured. Components in such state must produce proper error response if Message arrives. Note: Current implementation requires all components and links to be labeled. All labels must be unique. Future implementation will be able to assign labels automatically.

Definition at line 46 of file MCCLoader.h.


Member Typedef Documentation

typedef std::map<std::string, MCC*> Arc::MCCLoader::mcc_container_t

Definition at line 49 of file MCCLoader.h.

typedef std::map<std::string, Plexer*> Arc::MCCLoader::plexer_container_t

Definition at line 52 of file MCCLoader.h.

Definition at line 51 of file MCCLoader.h.

typedef std::map<std::string, Service*> Arc::MCCLoader::service_container_t

Definition at line 50 of file MCCLoader.h.


Constructor & Destructor Documentation

Definition at line 85 of file MCCLoader.h.

:valid_(false) {};

Constructor that takes whole XML configuration and creates component chains.

Definition at line 12 of file MCCLoader.cpp.

                                 :Loader(cfg),valid_(false) {
    context_ = new ChainContext(*this);
    valid_ = make_elements(cfg);
    if(!valid_)
      MCCLoader::logger.msg(ERROR, "Chain(s) configuration failed");
  }

Here is the call graph for this function:

Destructor destroys all components created by constructor.

Definition at line 19 of file MCCLoader.cpp.

                            {
    // TODO: stop any processing on those MCCs or mark them for
    // self-destruction or break links first or use semaphors in
    // MCC destructors
    // Unlink all objects
    for(mcc_container_t::iterator mcc_i = mccs_.begin();
        mcc_i != mccs_.end(); ++mcc_i) {
      MCC* mcc = mcc_i->second;
      if(mcc) mcc->Unlink();
    }
    for(plexer_container_t::iterator plexer_i = plexers_.begin();
        plexer_i != plexers_.end(); ++plexer_i) {
      Plexer* plexer = plexer_i->second;
      if(plexer) plexer->Unlink();
    }
    // Destroy all objects
    for(mcc_container_t::iterator mcc_i = mccs_.begin();
        mcc_i != mccs_.end(); mcc_i = mccs_.begin()) {
      MCC* mcc = mcc_i->second;
      mccs_.erase(mcc_i);
      if(mcc) delete mcc;
    }
    for(service_container_t::iterator service_i = services_.begin();
        service_i != services_.end(); service_i = services_.begin()) {
      Service* service = service_i->second;
      services_.erase(service_i);
      if(service) delete service;
    }
    for(plexer_container_t::iterator plexer_i = plexers_.begin();
        plexer_i != plexers_.end(); plexer_i = plexers_.begin()) {
      Plexer* plexer = plexer_i->second;
      plexers_.erase(plexer_i);
      if(plexer) delete plexer;
    }
    for(sechandler_container_t::iterator sechandler_i = sechandlers_.begin();
        sechandler_i != sechandlers_.end();
        sechandler_i = sechandlers_.begin()) {
      ArcSec::SecHandler* sechandler = sechandler_i->second;
      sechandlers_.erase(sechandler_i);
      if(sechandler) delete sechandler;
    }

    if(context_) delete context_;
  }

Here is the call graph for this function:


Member Function Documentation

bool Arc::MCCLoader::make_elements ( Config cfg,
int  level = 0,
mcc_connectors_t mcc_connectors = NULL,
plexer_connectors_t plexer_connectors = NULL 
) [private]

Internal method which performs whole stuff specific to creation of Message Chains.

It is taken out from constructor to make it easier to reconfigure chains in a future. Returns true if all objects were succesfully initialized and all links created.

Definition at line 162 of file MCCLoader.cpp.

                                                                        {
    bool success = true;
    if(mcc_connectors == NULL) mcc_connectors = new mcc_connectors_t;
    if(plexer_connectors == NULL) plexer_connectors = new plexer_connectors_t;
    // 1st stage - creating all elements.
    // Configuration is parsed recursively - going deeper at ArcConfig
    // and Chain elements
    for(int n = 0;; ++n) {
      XMLNode cn = cfg.Child(n);
      if(!cn) break;
      Config cfg_(cn, cfg.getFileName());

      if(MatchXMLName(cn, "ArcConfig")) {
        if(!make_elements(cfg_, level + 1, mcc_connectors, plexer_connectors))
          success = false;
        continue;
      }

      if(MatchXMLName(cn, "Chain")) {
        if(!make_elements(cfg_, level + 1, mcc_connectors, plexer_connectors))
          success = false;
        continue;
      }

      if(MatchXMLName(cn, "Component")) {
        // Create new MCC
        std::string name = cn.Attribute("name");
        if(name.empty()) {
          logger.msg(ERROR, "Component has no name attribute defined");
          success = false;
          continue;
        }
        std::string id = cn.Attribute("id");
        if(id.empty()) {
          logger.msg(ERROR, "Component has no id attribute defined");
          success = false;
          continue;
        }
        MCCPluginArgument arg(&cfg_,context_);
        Plugin* plugin = factory_->get_instance(MCCPluginKind ,name, &arg);
        MCC* mcc = plugin?dynamic_cast<MCC*>(plugin):NULL;
        if(!mcc) {
          logger.msg(ERROR, "Component %s(%s) could not be created", name, id);
          success = false;
          continue;
        }
        mccs_[id] = mcc;

        // Configure security plugins
        XMLNode an = cn["SecHandler"];
        for(int n = 0;; ++n) {
          XMLNode can = an[n];
          if(!can) break;
          ArcSec::SecHandler* sechandler = MakeSecHandler(cfg, context_,
                                        sechandlers_, factory_, can);
          if(!sechandler) {
            success = false;
            continue;
          };
          std::string event = can.Attribute("event");
          mcc->AddSecHandler(&cfg_, sechandler, event);
        }

        // Add to chain list
        std::string entry = cn.Attribute("entry");
        if(!entry.empty()) mccs_exposed_[entry] = mcc;
        mcc_connector_t mcc_connector(mccs_.find(id));
        for(int nn = 0;; ++nn) {
          XMLNode cnn = cn["next"][nn];
          if(!cnn) break;
          std::string nid = cnn.Attribute("id");
          if(nid.empty()) {
            logger.msg(ERROR, "Component's %s(%s) next has no id "
                 "attribute defined", name, id);
            success = false;
            continue;
          }
          std::string label = cnn;
          mcc_connector.nexts[label] = nid;
        }
        mcc_connector.name = name;
        mcc_connectors->push_back(mcc_connector);
        logger.msg(INFO, "Loaded MCC %s(%s)", name, id);
        continue;
      }

      if(MatchXMLName(cn, "Plexer")) {
        std::string id = cn.Attribute("id");
        if(id.empty()) id = "plexer";
        Plexer* plexer = new Plexer(&cfg_);
        plexers_[id] = plexer;
        plexer_connector_t plexer_connector(plexers_.find(id));
        for(int nn = 0;; ++nn) {
          XMLNode cnn = cn["next"][nn];
          if(!cnn) break;
          std::string nid = cnn.Attribute("id");
          if(nid.empty()) {
            logger.msg(ERROR, "Plexer's (%s) next has no id "
                 "attribute defined", id);
            success = false;
            continue;
          }
          std::string label = cnn;
          plexer_connector.nexts[label] = nid;
        }
        plexer_connectors->push_back(plexer_connector);
        logger.msg(INFO, "Loaded Plexer %s", id);
        continue;
      }

      if(MatchXMLName(cn, "Service")) {
        std::string name = cn.Attribute("name");
        if(name.empty()) {
          logger.msg(ERROR, "Service has no name attribute defined");
          success = false;
          continue;
        }
        std::string id = cn.Attribute("id");
        if(id.empty()) {
          logger.msg(ERROR, "Service has no id attribute defined");
          success = false;
          continue;
        }
        ServicePluginArgument arg(&cfg_,context_);
        Plugin* plugin = factory_->get_instance(ServicePluginKind, name, &arg);
              Service* service = plugin?dynamic_cast<Service*>(plugin):NULL;
        if(!service) {
          logger.msg(ERROR, "Service %s(%s) could not be created", name, id);
          success = false;
          continue;
        }
        services_[id] = service;
        logger.msg(INFO, "Loaded Service %s(%s)", name, id);

        // Configure security plugins
        XMLNode an;

        an = cn["SecHandler"];
        for(int n = 0;; ++n) {
          XMLNode can = an[n];
          if(!can) break;
          ArcSec::SecHandler* sechandler = MakeSecHandler(cfg, context_,
                                        sechandlers_, factory_, can);
          if(!sechandler) {
            success = false;
            continue;
          }
          std::string event = can.Attribute("event");
          service->AddSecHandler(&cfg_, sechandler, event);
        }
        continue;
      }

      // Configuration processing is split to multiple functions - hence
      // ignoring all unknown elements.
      //logger.msg(WARNING, "Unknown element \"%s\" - ignoring", cn.Name());
    }

    if(level != 0) return true;

    // 2nd stage - making links between elements.

    // Making links from MCCs
    for(mcc_connectors_t::iterator mcc = mcc_connectors->begin();
        mcc != mcc_connectors->end(); ++mcc) {
      for(std::map<std::string, std::string>::iterator next =
          mcc->nexts.begin();
          next != mcc->nexts.end(); next = mcc->nexts.begin()) {
        std::string label = next->first;
        std::string id = next->second;
        mcc_container_t::iterator mcc_l = mccs_.find(id);
        if(mcc_l != mccs_.end()) {
          // Make link MCC->MCC
          mcc->mcc->second->Next(mcc_l->second, label);
          logger.msg(INFO, "Linking MCC %s(%s) to MCC (%s) under %s",
               mcc->name, mcc->mcc->first, id, label);
          mcc->nexts.erase(next);
          continue;
        }
        service_container_t::iterator service_l = services_.find(id);
        if(service_l != services_.end()) {
          // Make link MCC->Service
          mcc->mcc->second->Next(service_l->second, label);
          logger.msg(INFO, "Linking MCC %s(%s) to Service (%s) under %s",
               mcc->name, mcc->mcc->first, id, label);
          mcc->nexts.erase(next);
          continue;
        }
        plexer_container_t::iterator plexer_l = plexers_.find(id);
        if(plexer_l != plexers_.end()) {
          // Make link MCC->Plexer
          mcc->mcc->second->Next(plexer_l->second, label);
          logger.msg(INFO, "Linking MCC %s(%s) to Plexer (%s) under %s",
               mcc->name, mcc->mcc->first, id, label);
          mcc->nexts.erase(next);
          continue;
        }
        logger.msg(ERROR, "MCC %s(%s) - next %s(%s) has no target",
                   mcc->name, mcc->mcc->first, label, id);
        success = false;
        mcc->nexts.erase(next);
      }
    }
    // Making links from Plexers
    for(plexer_connectors_t::iterator plexer = plexer_connectors->begin();
        plexer != plexer_connectors->end(); ++plexer) {
      for(std::map<std::string, std::string>::iterator next =
          plexer->nexts.begin();
          next != plexer->nexts.end(); next = plexer->nexts.begin()) {
        std::string label = next->first;
        std::string id = next->second;
        mcc_container_t::iterator mcc_l = mccs_.find(id);
        if(mcc_l != mccs_.end()) {
          // Make link Plexer->MCC
          plexer->plexer->second->Next(mcc_l->second, label);
          logger.msg(INFO, "Linking Plexer %s to MCC (%s) under %s",
               plexer->plexer->first, id, label);
          plexer->nexts.erase(next);
          continue;
        }
        service_container_t::iterator service_l = services_.find(id);
        if(service_l != services_.end()) {
          // Make link Plexer->Service
          plexer->plexer->second->Next(service_l->second, label);
          logger.msg(INFO, "Linking Plexer %s to Service (%s) under %s",
               plexer->plexer->first, id, label);
          plexer->nexts.erase(next);
          continue;
        }
        plexer_container_t::iterator plexer_l = plexers_.find(id);
        if(plexer_l != plexers_.end()) {
          // Make link Plexer->Plexer
          plexer->plexer->second->Next(plexer_l->second, label);
          logger.msg(INFO, "Linking Plexer %s to Plexer (%s) under %s",
               plexer->plexer->first, id, label);
          plexer->nexts.erase(next);
          continue;
        }

        logger.msg(ERROR, "Plexer (%s) - next %s(%s) has no target",
                   plexer->plexer->first, label, id);
        success = false;
        plexer->nexts.erase(next);
      }
    }
    if(mcc_connectors) delete mcc_connectors;
    if(plexer_connectors) delete plexer_connectors;
    return success;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Arc::MCCLoader::operator bool ( void  ) [inline]

Definition at line 97 of file MCCLoader.h.

{ return valid_; };
bool Arc::MCCLoader::operator! ( void  ) [inline]

Definition at line 98 of file MCCLoader.h.

{ return !valid_; };
MCC * Arc::MCCLoader::operator[] ( const std::string &  id)

Access entry MCCs in chains.

Those are components exposed for external access using 'entry' attribute

Definition at line 414 of file MCCLoader.cpp.

                                                {
    mcc_container_t::iterator mcc = mccs_exposed_.find(id);
    if(mcc != mccs_exposed_.end()) return mcc->second;
    return NULL;
  }
MCC* Arc::MCCLoader::operator[] ( const char *  id) [inline]

Definition at line 95 of file MCCLoader.h.

{ return operator[](std::string(id)); };

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

friend class ChainContext [friend]

Definition at line 47 of file MCCLoader.h.


Member Data Documentation

Definition at line 82 of file MCCLoader.h.

PluginsFactory* Arc::Loader::factory_ [protected, inherited]

Link to Factory responsible for loading and creation of Plugin and derived objects.

Definition at line 23 of file Loader.h.

Logger Arc::Loader::logger [static, inherited]

Definition at line 18 of file Loader.h.

Set of labeled MCC objects.

Definition at line 58 of file MCCLoader.h.

Set of MCC objects exposed to external interface.

Definition at line 61 of file MCCLoader.h.

Set of labeled Plexer objects.

Definition at line 70 of file MCCLoader.h.

Set of labeled security handlers.

Definition at line 67 of file MCCLoader.h.

Set of labeled Service objects.

Definition at line 64 of file MCCLoader.h.

bool Arc::MCCLoader::valid_ [private]

Definition at line 55 of file MCCLoader.h.


The documentation for this class was generated from the following files: