00001 #ifndef __ARC_ENDPOINTRETRIEVER_H__
00002 #define __ARC_ENDPOINTRETRIEVER_H__
00003 
00004 #include <list>
00005 #include <map>
00006 #include <string>
00007 
00008 #include <arc/ArcConfig.h>
00009 #include <arc/client/Endpoint.h>
00010 #include <arc/UserConfig.h>
00011 #include <arc/Utils.h>
00012 #include <arc/client/EndpointQueryingStatus.h>
00013 #include <arc/client/ExecutionTarget.h>
00014 #include <arc/loader/Loader.h>
00015 #include <arc/loader/FinderLoader.h>
00016 
00017 namespace Arc {
00018 
00019 class Logger;
00020 class SharedMutex;
00021 class SimpleCondition;
00022 class SimpleCounter;
00023 class ThreadedPointer<class Endpoint>;
00024 class UserConfig;
00025 
00026 template<typename T>
00027 class EndpointQueryOptions {
00028 public:
00029   EndpointQueryOptions(std::list<std::string> preferredInterfaceNames = std::list<std::string>()) : preferredInterfaceNames(preferredInterfaceNames) {}
00030   std::list<std::string>& getPreferredInterfaceNames() { return preferredInterfaceNames; }
00031 private:
00032   std::list<std::string> preferredInterfaceNames;
00033 };
00034 
00035 template<>
00036 class EndpointQueryOptions<Endpoint> {
00037 public:
00038   EndpointQueryOptions(bool recursive = false,
00039                        const std::list<std::string>& capabilityFilter = std::list<std::string>(),
00040                        const std::list<std::string>& rejectedServices = std::list<std::string>() )
00041     : recursive(recursive), capabilityFilter(capabilityFilter), rejectedServices(rejectedServices) {}
00042 
00043   bool recursiveEnabled() const { return recursive; }
00044   const std::list<std::string>& getCapabilityFilter() const { return capabilityFilter; }
00045   const std::list<std::string>& getRejectedServices() const { return rejectedServices; }
00046   std::list<std::string>& getPreferredInterfaceNames() { return preferredInterfaceNames; }
00047 
00048 private:
00049   bool recursive;
00050   std::list<std::string> capabilityFilter;
00051   std::list<std::string> rejectedServices;
00052   std::list<std::string> preferredInterfaceNames;
00053 };
00054 
00055 template<typename T>
00056 class EntityRetrieverPlugin : public Plugin {
00057 protected:
00058   EntityRetrieverPlugin(PluginArgument* parg): Plugin(parg) {};
00059 public:
00060   virtual const std::list<std::string>& SupportedInterfaces() const { return supportedInterfaces; };
00061   virtual bool isEndpointNotSupported(const Endpoint&) const = 0;
00062   virtual EndpointQueryingStatus Query(const UserConfig&, const Endpoint& rEndpoint, std::list<T>&, const EndpointQueryOptions<T>& options) const = 0;
00063 
00064   static const std::string kind;
00065 
00066 protected:
00067   std::list<std::string> supportedInterfaces;
00068 };
00069 
00070 template<typename T>
00071 class EntityRetrieverPluginLoader : public Loader {
00072 public:
00073   EntityRetrieverPluginLoader() : Loader(BaseConfig().MakeConfig(Config()).Parent()) {}
00074   ~EntityRetrieverPluginLoader();
00075 
00076   EntityRetrieverPlugin<T>* load(const std::string& name);
00077   static std::list<std::string> getListOfPlugins();
00078   const std::map<std::string, EntityRetrieverPlugin<T> *>& GetTargetInformationRetrieverPlugins() const { return plugins; }
00079 
00080 protected:
00081   std::map<std::string, EntityRetrieverPlugin<T> *> plugins;
00082 
00083   static Logger logger;
00084 };
00085 
00086 template<typename T>
00087 class EntityConsumer {
00088 public:
00089   virtual ~EntityConsumer() {}
00090   virtual void addEntity(const T&) = 0;
00091 };
00092 
00093 template<typename T>
00094 class EntityContainer : public EntityConsumer<T>, public std::list<T> {
00095 public:
00096   virtual ~EntityContainer() {}
00097   virtual void addEntity(const T& t) { push_back(t); }
00098 };
00099 
00100 template<typename T>
00101 class EntityRetriever : public EntityConsumer<T> {
00102 public:
00103   EntityRetriever(const UserConfig&, const EndpointQueryOptions<T>& options = EndpointQueryOptions<T>());
00104   ~EntityRetriever() { common->deactivate(); }
00105 
00106   void wait() const { result.wait(); };
00107   
00108   bool isDone() const { return result.wait(0); };
00109 
00110   void addConsumer(EntityConsumer<T>& c) { consumerLock.lock(); consumers.push_back(&c); consumerLock.unlock(); };
00111   void removeConsumer(const EntityConsumer<T>&);
00112 
00113   EndpointQueryingStatus getStatusOfEndpoint(const Endpoint&) const;
00114   bool setStatusOfEndpoint(const Endpoint&, const EndpointQueryingStatus&, bool overwrite = true);
00115 
00116   virtual void addEntity(const T&);
00117   virtual void addEndpoint(const Endpoint&);
00118 
00119 protected:
00120   static void queryEndpoint(void *arg_);
00121 
00122   
00123   class Common : public EntityRetrieverPluginLoader<T> {
00124   public:
00125     Common(EntityRetriever* t, const UserConfig& u) : EntityRetrieverPluginLoader<T>(),
00126       mutex(), t(t), uc(u) {};
00127     void deactivate(void) {
00128       mutex.lockExclusive();
00129       t = NULL;
00130       mutex.unlockExclusive();
00131     }
00132     bool lockExclusiveIfValid(void) {
00133       mutex.lockExclusive();
00134       if(t) return true;
00135       mutex.unlockExclusive();
00136       return false;
00137     }
00138     void unlockExclusive(void) { mutex.unlockExclusive(); }
00139     bool lockSharedIfValid(void) {
00140       mutex.lockShared();
00141       if(t) return true;
00142       mutex.unlockShared();
00143       return false;
00144     }
00145     void unlockShared(void) { mutex.unlockShared(); }
00146 
00147     operator const UserConfig&(void) const { return uc; }
00148     const std::list<std::string>& getAvailablePlugins(void) const { return availablePlugins; }
00149     void setAvailablePlugins(const std::list<std::string>& newAvailablePlugins) { availablePlugins = newAvailablePlugins; }
00150     EntityRetriever* operator->(void) { return t; }
00151     EntityRetriever* operator*(void) { return t; }
00152   private:
00153     SharedMutex mutex;
00154     EntityRetriever* t;
00155     const UserConfig uc;
00156     std::list<std::string> availablePlugins;
00157   };
00158   ThreadedPointer<Common> common;
00159 
00160   
00161   
00162   
00163   
00164   
00165   class Result: private ThreadedPointer<SimpleCounter>  {
00166   public:
00167     
00168     Result(bool one_success = false):
00169       ThreadedPointer<SimpleCounter>(new SimpleCounter),
00170       success(false),need_one_success(one_success) { };
00171     
00172     Result(const Result& r):
00173       ThreadedPointer<SimpleCounter>(r),
00174       success(false),need_one_success(r.need_one_success) {
00175       Ptr()->inc();
00176     };
00177     
00178     ~Result(void) {
00179       if(need_one_success && success) {
00180         Ptr()->set(0);
00181       } else {
00182         Ptr()->dec();
00183       };
00184     };
00185     
00186     void setSuccess(void) { success = true; };
00187     
00188     bool wait(int t = -1) const { return Ptr()->wait(t); };
00189   private:
00190     bool success;
00191     bool need_one_success;
00192   };
00193   Result result;
00194 
00195   class ThreadArg {
00196   public:
00197     ThreadArg(const ThreadedPointer<Common>& common, Result& result, const Endpoint& endpoint, const EndpointQueryOptions<T>& options) : common(common), result(result), endpoint(endpoint), options(options) {};
00198     ThreadArg(const ThreadArg& v, Result& result) : common(v.common), result(result), endpoint(v.endpoint), pluginName(v.pluginName), options(options) {};
00199     
00200     ThreadedPointer<Common> common;
00201     Result result;
00202     
00203     Endpoint endpoint;
00204     std::string pluginName;
00205     EndpointQueryOptions<T> options;
00206   };
00207 
00208   std::map<Endpoint, EndpointQueryingStatus> statuses;
00209 
00210   static Logger logger;
00211   const UserConfig& uc;
00212   std::list< EntityConsumer<T>* > consumers;
00213   EndpointQueryOptions<T> options;
00214 
00215   mutable SimpleCondition consumerLock;
00216   mutable SimpleCondition statusLock;
00217   std::map<std::string, std::string> interfacePluginMap;
00218 };
00219 
00220 
00221 typedef EntityRetriever<Endpoint>             ServiceEndpointRetriever;
00222 typedef EntityRetrieverPlugin<Endpoint>       ServiceEndpointRetrieverPlugin;
00223 typedef EntityRetrieverPluginLoader<Endpoint> ServiceEndpointRetrieverPluginLoader;
00224 
00225 typedef EntityRetriever<ComputingServiceType>             TargetInformationRetriever;
00226 typedef EntityRetrieverPlugin<ComputingServiceType>       TargetInformationRetrieverPlugin;
00227 typedef EntityRetrieverPluginLoader<ComputingServiceType> TargetInformationRetrieverPluginLoader;
00228 
00229 typedef EntityRetriever<Job>             JobListRetriever;
00230 typedef EntityRetrieverPlugin<Job>       JobListRetrieverPlugin;
00231 typedef EntityRetrieverPluginLoader<Job> JobListRetrieverPluginLoader;
00232 
00233 } 
00234 
00235 #endif // __ARC_ENDPOINTRETRIEVER_H__
00236