diff --git a/include/MarketPlaceManger.h b/include/MarketPlaceManger.h new file mode 100644 index 0000000000..d2421b6ff9 --- /dev/null +++ b/include/MarketPlaceManger.h @@ -0,0 +1,200 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef MARKETPLACE_MANAGER_H_ +#define MARKETPLACE_MANAGER_H_ + +#include "MadManager.h" +#include "ActionManager.h" +#include "MarketPlaceManagerDriver.h" + +extern "C" void * marketplace_action_loop(void *arg); + +class MarketPlace; +class MarketPlaceApp; + +class MarketPlaceManager : public MadManager, public ActionListener +{ +public: + + MarketPlaceManager( + time_t _timer_period, + time_t _monitor_period, + std::vector& _mads): + MadManager(_mads), + timer_period(_timer_period), + monitor_period(_monitor_period), + mppool(0), + apppool(0) + { + am.addListener(this); + }; + + ~MarketPlaceManager(){}; + + /** + * This functions starts the associated listener thread, and creates a + * new thread for the MarketPlace Manager. This thread will wait in + * an action loop till it receives ACTION_FINALIZE. + * @return 0 on success. + */ + int start(); + + /** + * Loads the MarketPlace Driver defined in configuration file + * @param uid of the user executing the driver. When uid is 0 the nebula + * identity will be used. Otherwise the Mad will be loaded through the + * sudo application. + */ + int load_mads(int uid=0); + + /** + * Gets the thread identification. + * @return pthread_t for the manager thread (that in the action loop). + */ + pthread_t get_thread_id() const + { + return marektm_thread; + }; + + /** + * Finalizes the Image Manager + */ + void finalize() + { + am.trigger(ACTION_FINALIZE,0); + }; + + /** + * Imports a new app into the marketplace. The marketplace app needs to + * include the ORIGIN attribute so the driver can locate the app. An + * optional template maybe provided to export the app to a cloud. + * @param appid of the app + * @param market_data of the associated marketplace in XML format + * @param error descrition + * + * @return 0 on success + */ + int import_app(int appid, const std::string& market_data, std::string& error); + + /** + * Exports the app to this cloud. If an APPTEMPLATE64 is provided associated + * objects can also be created. + * @param appid of the app + * @param market_data of the associated marketplace in XML format + * @param error descrition + * + * @return 0 on success + */ + int export_app(int appid, const std::string& market_data, std::string& error); + + /** + * Deletes an app from the marketplace. + * @param iid id of image + * @param error_str Error reason, if any + * + * @return 0 on success + */ + int delete_app(int iid, std::string& error_str); + + /** + * Trigger a monitor action for the marketplace . + * @param ds_id id of the datastore to monitor + */ + void monitor_market(int ds_id); + +private: + /** + * Generic name for the marketplace driver + */ + static const char * market_driver_name; + + /** + * Thread id for the MarketPlace Manager + */ + pthread_t marketm_thread; + + /** + * Timer period for the Image Manager. + */ + time_t timer_period; + + /** + * Marketplace monitor interval + */ + time_t monitor_period; + + /** + * Pointer to the marketplace pool + */ + MarketPlacePool * mppool; + + /** + * Pointer to the app pool + */ + MarketPlaceAppPool * apppool; + + /** + * Action engine for the Manager + */ + ActionManager am; + + /** + * Returns a pointer to the marketplace driver. + * @return the marketplace manager driver or 0 in not found + */ + const MarketPlaceManagerDriver * get() + { + std::string name("NAME"); + + return static_cast + (MadManager::get(0, name, market_driver_name)); + }; + + /** + * Function to execute the Manager action loop method within a new pthread + * (requires C linkage) + */ + friend void * marketplace_action_loop(void *arg); + + /** + * The action function executed when an action is triggered. + * @param action the name of the action + * @param arg arguments for the action function + */ + void do_action(const std::string& action, void * arg); + + /** + * Formats an XML message for the MAD + * + * @param app_data marketplace app XML representation + * @param market_data marketplace XML representation + * @param extra_data additional XML formatted data for the driver + * + * @return the XML message + */ + static std::string * format_message( + const std::string& app_data, + const std::string& market_data, + const std::string& extra_data); + /** + * This function is executed periodically to monitor marketplaces.. + */ + void timer_action(); +}; + +#endif /*MARKETPLACE_MANAGER_H*/ + diff --git a/src/market/MarketPlaceManager.cc b/src/market/MarketPlaceManager.cc new file mode 100644 index 0000000000..65b4a52fa6 --- /dev/null +++ b/src/market/MarketPlaceManager.cc @@ -0,0 +1,258 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "MarketPlaceManager.h" +#include "NebulaLog.h" +#include "MarketPlacePool.h" +#include "MarketPlaceAppPool.h" +#include "Nebula.h" + +const char * MarketPlaceManager::market_driver_name = "market_exe"; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +extern "C" void * marketplace_action_loop(void *arg) +{ + MarketPlaceManager * mpm; + + if ( arg == 0 ) + { + return 0; + } + + NebulaLog::log("MKP", Log::INFO, "Marketplace Manager started."); + + mpm = static_cast(arg); + + mpm->am.loop(mpm->timer_period, 0); + + NebulaLog::log("MKP", Log::INFO, "Marketplace Manager stopped."); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int MarketPlaceManager::load_mads(int uid) +{ + MarketPlaceManagerDriver * marketm_mad; + + std::ostringstream oss; + const VectorAttribute * vattr = 0; + + int rc; + + NebulaLog::log("MKP", Log::INFO,"Loading Marketplace Manager driver."); + + if ( mad_conf.size() > 0 ) + { + vattr = static_cast(mad_conf[0]); + } + + if ( vattr == 0 ) + { + NebulaLog::log("MKP", Log::INFO,"Failed to load Marketplace Manager driver."); + return -1; + } + + VectorAttribute market_conf("MARKET_MAD", vattr->value()); + + market_conf.replace("NAME", market_driver_name); + + marketm_mad= new MarketManagerDriver(0, market_conf.value(), false); + + rc = add(marketm_mad); + + if ( rc == 0 ) + { + oss.str(""); + oss << "\tMarketplace Manager loaded"; + + NebulaLog::log("MKP", Log::INFO, oss); + } + + return rc; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int MarketPlaceManager::start() +{ + int rc; + pthread_attr_t pattr; + + rc = MadManager::start(); + + if ( rc != 0 ) + { + return -1; + } + + NebulaLog::log("ImM",Log::INFO,"Starting Marketplace Manager..."); + + pthread_attr_init (&pattr); + pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE); + + rc = pthread_create(&marketm_thread, &pattr, marketplace_action_loop, + (void *) this); + + return rc; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void MarketPlaceManager::do_action(const string &action, void * arg) +{ + if (action == ACTION_TIMER) + { + timer_action(); + } + else if (action == ACTION_FINALIZE) + { + NebulaLog::log("MKP", Log::INFO, "Stopping Marketplace Manager..."); + MadManager::stop(); + } + else + { + std::ostringstream oss; + oss << "Unknown action name: " << action; + + NebulaLog::log("MKP", Log::ERROR, oss); + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void MarketPlaceManager::init_managers() +{ + Nebula& nd = Nebula::instance(); + + mppool = nd.get_mppool(); + appool = nd.get_appool(); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string * MarketPlaceManager::format_message( + const string& app_data, + const string& market_data, + const string& extra_data) +{ + ostringstream oss; + + oss << "" + << app_data + << market_data + << extra_data + << ""; + + return one_util::base64_encode(oss.str()); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void MarketPlaceManager::timer_action() +{ + static int mark = 0; + static int tics = monitor_period; + + mark += timer_period; + tics += timer_period; + + if ( mark >= 600 ) + { + NebulaLog::log("MKP",Log::INFO,"--Mark--"); + mark = 0; + } + + if ( tics < monitor_period ) + { + return; + } + + tics = 0; + + int rc; + + std::vector markets; + std::vector::iterator it; + + rc = mppool->list(markets); + + if ( rc != 0 ) + { + return; + } + + for(it = markets.begin() ; it != markets.end(); it++) + { + monitor_market(*it); + } + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void MarketPlaceManager::monitor_market(int mp_id) +{ + std::string mp_data; + std::string mp_name; + std::string* drv_msg; + + std::ostringstream oss; + + const MarketPlaceManagerDriver* mpmd = get(); + + if ( mpmd == 0 ) + { + oss << "Error getting MarketPlaceManagerDriver"; + + NebulaLog::log("MKP", Log::ERROR, oss); + return; + } + + MarketPlace * mp = mppool->get(mp_id, true); + + if ( ds == 0 ) + { + return; + } + + mp->to_xml(mp_data); + + mp_name = mp->get_name(); + + mp->unlock(); + + drv_msg = MarketPlaceManager::format_message("", mp_data, ""); + + oss << "Monitoring marketplace " << mp_name << " (" << mp_id << ")"; + + NebulaLog::log("MKP", Log::DEBUG, oss); + + mpmd->monitor(mp_id, *drv_msg); + + delete drv_msg; +}