template<template<typename ...> class _ProxyClass, template<typename> class _AttributeExtension>
std::shared_ptr<typename DefaultAttributeProxyFactoryHelper<_ProxyClass, _AttributeExtension>::class_t> createProxyWithDefaultAttributeExtension(Factory* specificFactory, const std::string& participantId, const std::string& domain);
+
/**
* \brief The main CommonAPI access class. A factory is responsible for creation and destruction of service objects.
*
*/
class Factory {
public:
+ typedef std::function<void(std::vector<std::string>&) > GetAvailableServiceInstancesCallback;
+ typedef std::function<void(bool)> IsServiceInstanceAliveCallback;
/**
* \brief Creates factory. Don't call manually.
const std::string& serviceName,
const std::string& domain) {
- std::shared_ptr<Proxy> abstractMiddlewareProxy = createProxy(_ProxyClass<_AttributeExtensions...>::getInterfaceId(), participantId, serviceName, domain);
- return std::make_shared<_ProxyClass<_AttributeExtensions...>>(abstractMiddlewareProxy);
+ std::shared_ptr<Proxy> abstractMiddlewareProxy = createProxy(_ProxyClass<_AttributeExtensions...>::getInterfaceId(), participantId, serviceName, domain);
+ return std::make_shared<_ProxyClass<_AttributeExtensions...>>(abstractMiddlewareProxy);
}
/**
* \brief Build a proxy for the specified address
*
* Build a proxy for the specified address.
- * Template this method call for the desired proxy type and attribute extension.
+ * Template this method call for the desired proxy type and attribute extensions.
*
* @param serviceAddress The common API address
* @return a shared pointer to the constructed proxy
std::shared_ptr<_ProxyClass<_AttributeExtensions...> >
buildProxy(const std::string& serviceAddress) {
- std::string domain;
- std::string serviceName;
- std::string participantId;
- if(!splitValidAddress(serviceAddress, domain, serviceName, participantId)) {
- return false;
- }
+ std::string domain;
+ std::string serviceName;
+ std::string participantId;
+ if(!splitValidAddress(serviceAddress, domain, serviceName, participantId)) {
+ return false;
+ }
- return buildProxy<_ProxyClass, _AttributeExtensions...>(participantId, serviceName, domain);
+ return buildProxy<_ProxyClass, _AttributeExtensions...>(participantId, serviceName, domain);
}
/**
* \brief Build a proxy for the specified address with one extension for all attributes
*
* Build a proxy for the specified address with one extension for all attributes
- * Template this method call for the desired proxy type attribute extension.
+ * Template this method call for the desired proxy type and attribute extensions.
*
* @param participantId The participant ID of the common API address (last part)
* @param serviceName The service name of the common API address (middle part)
const std::string& serviceName,
const std::string& domain) {
- std::shared_ptr<Proxy> abstractMiddlewareProxy = createProxy(DefaultAttributeProxyFactoryHelper<_ProxyClass, _AttributeExtension>::class_t::getInterfaceId(), participantId, serviceName, domain);
- return std::make_shared<typename DefaultAttributeProxyFactoryHelper<_ProxyClass, _AttributeExtension>::class_t>(abstractMiddlewareProxy);
+ std::shared_ptr<Proxy> abstractMiddlewareProxy = createProxy(DefaultAttributeProxyFactoryHelper<_ProxyClass, _AttributeExtension>::class_t::getInterfaceId(), participantId, serviceName, domain);
+ return std::make_shared<typename DefaultAttributeProxyFactoryHelper<_ProxyClass, _AttributeExtension>::class_t>(abstractMiddlewareProxy);
}
/**
std::shared_ptr<typename DefaultAttributeProxyFactoryHelper<_ProxyClass, _AttributeExtension>::class_t>
buildProxyWithDefaultAttributeExtension(const std::string& serviceAddress) {
- std::string domain;
- std::string serviceName;
- std::string participantId;
- if(!splitValidAddress(serviceAddress, domain, serviceName, participantId)) {
- return false;
- }
+ std::string domain;
+ std::string serviceName;
+ std::string participantId;
+ if(!splitValidAddress(serviceAddress, domain, serviceName, participantId)) {
+ return false;
+ }
- return buildProxyWithDefaultAttributeExtension<_ProxyClass, _AttributeExtension>(participantId, serviceName, domain);
+ return buildProxyWithDefaultAttributeExtension<_ProxyClass, _AttributeExtension>(participantId, serviceName, domain);
}
/**
/**
* \brief Register a service stub under a specified address
*
- * Register a service stub under a specified address
+ * Register a service stub under a specified address. The service will be registered
+ * with the ServicePublisher that is provided by the runtime which you also retrieved
+ * this factory from. It is recommended to use the ServicePublisher for registering
+ * and unregistering purposes.
*
* @param stub The stub pointer
* @param participantId The participant ID of the common API address (last part)
* @param serviceName The service name of the common API address (middle part)
* @param domain The domain of the common API address (first part)
* @return Was the registration successful
+ *
+ * @deprecated Use CommonAPI::Runtime->getServicePublisher()->registerService() instead.
+ * Purpose for this change is to make service management (esp. deregistering) independent
+ * from factory instances.
*/
template<typename _Stub>
bool registerService(std::shared_ptr<_Stub> stub,
- const std::string& participantId,
- const std::string& serviceName,
- const std::string& domain) {
+ const std::string& participantId,
+ const std::string& serviceName,
+ const std::string& domain) {
- std::shared_ptr<StubBase> stubBase = std::dynamic_pointer_cast<StubBase>(stub);
- return registerAdapter(stubBase, _Stub::StubAdapterType::getInterfaceId(), participantId, serviceName, domain);
+ std::shared_ptr<StubBase> stubBase = std::dynamic_pointer_cast<StubBase>(stub);
+ return registerAdapter(stubBase, _Stub::StubAdapterType::getInterfaceId(), participantId, serviceName, domain);
}
/**
* \brief Register a service stub under a specified address
*
- * Register a service stub under a specified address
+ * Register a service stub under a specified address. The service will be registered
+ * with the ServicePublisher that is provided by the runtime which you also retrieved
+ * this factory from. It is recommended to use the ServicePublisher for registering
+ * and unregistering purposes.
*
* @param stub The stub pointer
* @param serviceAddress The common API address
* @return Was the registration successful
+ *
+ * @deprecated Use CommonAPI::Runtime->getServicePublisher()->registerService() instead.
+ * Purpose for this change is to make service management (esp. deregistering) independent
+ * from factory instances.
*/
template<typename _Stub>
bool registerService(std::shared_ptr<_Stub> stub, const std::string& serviceAddress) {
- std::string domain;
- std::string serviceName;
- std::string participantId;
- if(!splitValidAddress(serviceAddress, domain, serviceName, participantId)) {
- return false;
- }
-
- return registerService<_Stub>(stub, participantId, serviceName, domain);
+ std::string domain;
+ std::string serviceName;
+ std::string participantId;
+ if(!splitValidAddress(serviceAddress, domain, serviceName, participantId)) {
+ return false;
+ }
+
+ return registerService<_Stub>(stub, participantId, serviceName, domain);
}
/**
* \brief Unregister a service stub associated with a specified address
*
- * Unregister a service stub associated with a specified address
+ * Unregister a service stub associated with a specified address.
*
* @param participantId The participant ID of the common API address (last part)
* @param serviceName The service name of the common API address (middle part)
* @param domain The domain of the common API address (first part)
* @return Was the deregistration successful
+ *
+ * @deprecated Use CommonAPI::Runtime->getServicePublisher()->unregisterService() instead.
+ * Purpose for this change is to make service management (esp. deregistering) independent
+ * from factory instances.
*/
virtual bool unregisterService(const std::string& participantId, const std::string& serviceName, const std::string& domain) = 0;
*
* @param serviceAddress The common API address
* @return Was the deregistration successful
+ *
+ * @deprecated Use CommonAPI::Runtime->getServicePublisher()->unregisterService() instead.
+ * Purpose for this change is to make service management (esp. deregistering) independent
+ * from factory instances.
*/
inline bool unregisterService(const std::string& serviceAddress) {
- std::string domain;
- std::string serviceName;
- std::string participantId;
- if(!splitValidAddress(serviceAddress, domain, serviceName, participantId)) {
- return false;
- }
- return unregisterService(participantId, serviceName, domain);
+ std::string domain;
+ std::string serviceName;
+ std::string participantId;
+ if(!splitValidAddress(serviceAddress, domain, serviceName, participantId)) {
+ return false;
+ }
+ return unregisterService(participantId, serviceName, domain);
}
/**
*/
virtual bool isServiceInstanceAlive(const std::string& serviceInstanceID, const std::string& serviceName, const std::string& serviceDomainName = "local") = 0;
+ /**
+ * \brief Get all instances of a specific service name available. Asynchronous call.
+ *
+ * Get all instances of a specific service name available. Asynchronous call.
+ *
+ * @param serviceName The service name of the common API address (middle part)
+ * @param serviceDomainName The domain of the common API address (first part)
+ */
+ virtual void getAvailableServiceInstancesAsync(GetAvailableServiceInstancesCallback callback, const std::string& serviceName, const std::string& serviceDomainName = "local") = 0;
+
+ /**
+ * \brief Tells whether a particular service instance is available. Asynchronous call.
+ *
+ * Tells whether a particular service instance is available. Asynchronous call.
+ *
+ * @param serviceAddress The common API address of the service
+ */
+ virtual void isServiceInstanceAliveAsync(IsServiceInstanceAliveCallback callback, const std::string& serviceAddress) = 0;
+
+ /**
+ * \brief Tells whether a particular service instance is available. Asynchronous call.
+ *
+ * Tells whether a particular service instance is available. Asynchronous call.
+ *
+ * @param serviceInstanceID The participant ID of the common API address (last part) of the service
+ * @param serviceName The service name of the common API address (middle part) of the service
+ * @param serviceDomainName The domain of the common API address (first part) of the service
+ */
+ virtual void isServiceInstanceAliveAsync(IsServiceInstanceAliveCallback callback, const std::string& serviceInstanceID, const std::string& serviceName, const std::string& serviceDomainName = "local") = 0;
+
protected:
virtual std::shared_ptr<Proxy> createProxy(const char* interfaceId, const std::string& participantId, const std::string& serviceName, const std::string& domain) = 0;
- virtual bool registerAdapter(std::shared_ptr<StubBase> stubBase, const char* interfaceId, const std::string& participantId, const std::string& serivceName, const std::string& domain) = 0;
+ virtual bool registerAdapter(std::shared_ptr<StubBase> stubBase, const char* interfaceId, const std::string& participantId, const std::string& serviceName, const std::string& domain) = 0;
private:
std::shared_ptr<Runtime> runtime_;
const MiddlewareInfo* middlewareInfo_;
inline bool splitValidAddress(const std::string& serviceAddress, std::string& domain, std::string& serviceName, std::string& participantId) {
- std::istringstream addressStream(serviceAddress);
- if(!std::getline(addressStream, domain, ':')) {
- return false;
- }
- if(!std::getline(addressStream, serviceName, ':')) {
- return false;
- }
- if(!std::getline(addressStream, participantId, ':')) {
- return false;
- }
- if(std::getline(addressStream, participantId)) {
- return false;
- }
- return true;
+ std::istringstream addressStream(serviceAddress);
+ if(!std::getline(addressStream, domain, ':')) {
+ return false;
+ }
+ if(!std::getline(addressStream, serviceName, ':')) {
+ return false;
+ }
+ if(!std::getline(addressStream, participantId, ':')) {
+ return false;
+ }
+ if(std::getline(addressStream, participantId)) {
+ return false;
+ }
+ return true;
}
};
#include "MiddlewareInfo.h"
-#include "Factory.h"
#include "MainLoopContext.h"
#include <memory>
class Factory;
class Runtime;
class MainLoopContext;
+class ServicePublisher;
/**
* \brief Represents the CommonAPI runtime bindings available.
*/
class Runtime {
public:
-
/**
- * \brief Loads the default runtime
+ * \brief Loads the default runtime.
*
- * Loads the default runtime. This is the only one available, or the default as defined in configuration
+ * Loads the runtime for the default middleware binding. This either is the only binding available,
+ * or the one defined as default in the configuration.
*
- * @return The runtime object for this binding
+ * @return The runtime object for the default binding
*/
static std::shared_ptr<Runtime> load();
+
/**
- * \brief Loads specified runtime
+ * \brief Loads specified runtime.
*
- * Loads specified runtime. This is specified by either the well known name defined by the binding, or configured
+ * Loads the runtime for the specified middleware binding. The given middleware ID can be either
+ * the well known name defined by a binding, or a configured alias for a binding.
*
* @return The runtime object for specified binding
*/
static std::shared_ptr<Runtime> load(const std::string& middlewareId);
+
/**
- * \brief Called by bindings to register their methods. Do not call from applications.
+ * \brief Called by bindings to register their runtime loaders. Do not call from applications.
*
- * Called by bindings to register their methods. Do not call from applications.
+ * Called by bindings to register their runtime loaders. Do not call from applications.
*/
static void registerRuntimeLoader(std::string middlewareName, MiddlewareRuntimeLoadFunction middlewareRuntimeLoadFunction);
* @return A new MainLoopContext object
*/
std::shared_ptr<MainLoopContext> getNewMainLoopContext() const;
+
/**
- * \brief Create a factory for the loaded runtime
+ * \brief Create a factory for the loaded runtime.
*
- * Create a factory for the loaded rluntime
+ * Create a factory for the loaded runtime
*
* @param In case mainloop integration shall be used, a std::shared_ptr<MainLoopContext> can be passed in.
* If no parameter is given, internal threading will handle sending and receiving of messages automatically.
*
- * @return Factory object for the loaded runtime
+ * @return Factory object for this runtime
*/
virtual std::shared_ptr<Factory> createFactory(std::shared_ptr<MainLoopContext> = std::shared_ptr<MainLoopContext>(NULL)) = 0;
+
+ /**
+ * \brief Returns the ServicePublisher object for this runtime.
+ *
+ * Returns the ServicePublisher object for this runtime. Use the interface
+ * provided by the ServicePublisher to publish and de-publish the services that
+ * your application will provide to the outside world over the middleware
+ * represented by this runtime. A ServicePublisher exists once per middleware.
+ *
+ * @return The ServicePublisher object for this runtime
+ */
+ virtual std::shared_ptr<ServicePublisher> getServicePublisher() = 0;
};
--- /dev/null
+/* Copyright (C) 2013 BMW Group
+ * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
+ * Author: Juergen Gehring (juergen.gehring@bmw.de)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef COMMONAPI_SERVICE_PUBLISHER_H_
+#define COMMONAPI_SERVICE_PUBLISHER_H_
+
+
+#include "Factory.h"
+
+
+namespace CommonAPI {
+
+/**
+ * \brief Manages all services that shall be published by the application.
+ *
+ * Stubs for all services that shall be published will be registered here.
+ * This class is defined as singleton per loaded runtime (i.e. per loaded middleware).
+ */
+class ServicePublisher {
+ public:
+ virtual ~ServicePublisher() {}
+
+ /**
+ * \brief Registers and publishes a service.
+ *
+ * Registers and publishes a service. Which service is to be published is defined
+ * by the stub-pointer that is given as parameter. The given factory will be used
+ * to construct all necessary middleware specific objects to do the publishing.
+ *
+ * \note Note that a call to this method will always result in a registration
+ * with the middleware the given factory was instantiated for, not the middleware
+ * that matches the runtime this ServicePublisher was retrieved from. Accordingly,
+ * unregistering the service will have to be done by using the ServicePublisher
+ * that is provided by the runtime matching the middleware that also provided
+ * the given factory.
+ *
+ * @param serviceAddress The CommonAPI address the service shall be reachable at
+ * @param stub The stub that provides an implementation for the service
+ * @param factory The factory that will be used to construct all necessary middleware specific objects
+ *
+ * @return 'true' if the service was published successfully, 'false' if not or if another service that uses
+ * the exact same address already is registered.
+ */
+ template<typename _Stub>
+ bool registerService(std::shared_ptr<_Stub> stub,
+ const std::string& serviceAddress,
+ std::shared_ptr<Factory> factory) {
+ return factory->registerService<_Stub>(stub, serviceAddress);
+ }
+
+ /**
+ * \brief Registers and publishes a service.
+ *
+ * Registers and publishes a service. Which service is to be published is defined
+ * by the stub-pointer that is given as parameter. The given factory will be used
+ * to construct all necessary middleware specific objects to do the publishing.
+ *
+ * \note Note that a call to this method will always result in a registration
+ * with the middleware the given factory was instantiated for, not the middleware
+ * that matches the runtime this ServicePublisher was retrieved from. Accordingly,
+ * unregistering the service will have to be done by using the ServicePublisher
+ * that is provided by the runtime matching the middleware that also provided
+ * the given factory.
+ *
+ * @param participantId The CommonAPI participant ID the service shall be identified with
+ * @param serviceName The CommonAPI service name the service shall provide
+ * @param domain The CommonAPI domain the service shall be reachable at
+ * @param stub The stub that provides an implementation for the service
+ * @param factory The factory that will be used to construct all necessary middleware specific objects
+ *
+ * @return 'true' if the service was published successfully, 'false' if not or if another service that uses
+ * the exact same address already is registered.
+ */
+ template<typename _Stub>
+ bool registerService(std::shared_ptr<_Stub> stub,
+ const std::string& participantId,
+ const std::string& serviceName,
+ const std::string& domain,
+ std::shared_ptr<Factory> factory) {
+
+ return factory->registerService<_Stub>(stub, participantId, serviceName, domain);
+ }
+
+ /**
+ * \brief Unregisters and depublishes the service that was published for the given address.
+ *
+ * Unregisters and depublishes the service that was published for the given CommonAPI address.
+ *
+ * @param The CommonAPI address the service was registered for
+ *
+ * @return 'true' if there was a service for the given address and depublishing
+ * was successful, 'false' otherwise
+ */
+ virtual bool unregisterService(const std::string& serviceAddress) = 0;
+
+ /**
+ * \brief Unregisters and depublishes the service that was published for the given address.
+ *
+ * Unregisters and depublishes the service that was published for the given CommonAPI address.
+ *
+ * @param The CommonAPI participant ID the service was identified with
+ * @param The CommonAPI service name the service provided
+ * @param The CommonAPI domain the service was registered for
+ *
+ * @return 'true' if there was a service for the given address and depublishing
+ * was successful, 'false' otherwise
+ */
+ virtual bool unregisterService(const std::string& participantId, const std::string& serviceName, const std::string& domain) {
+ std::string serviceAddress(participantId + ":" + serviceName + ":"+ domain);
+ return unregisterService(serviceAddress);
+ }
+};
+
+} // namespace CommonAPI
+
+
+#endif /* COMMONAPI_SERVICE_PUBLISHER_H_ */