diff options
Diffstat (limited to 'TAO/orbsvcs/examples')
383 files changed, 31897 insertions, 0 deletions
diff --git a/TAO/orbsvcs/examples/CosEC/Factory/CosEC_Factory.mpc b/TAO/orbsvcs/examples/CosEC/Factory/CosEC_Factory.mpc new file mode 100644 index 00000000000..2ff7ecdb1d7 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Factory/CosEC_Factory.mpc @@ -0,0 +1,36 @@ +// -*- MPC -*- +// $Id$ + +project(*idl) : orbsvcslib { + + IDL_Files { + CosEventChannelFactory.idl + } + + custom_only = 1 +} + +project(*Client) : orbsvcsexe, event, event_skel, naming { + after += *idl + exename = FactoryClient + source_files { + FactoryClient.cpp + CosEventChannelFactoryC.cpp + } + IDL_Files { + } +} + +project(*Server) : orbsvcsexe, event, event_serv, naming { + after += *idl + exename = FactoryServer + source_files { + main.cpp + FactoryDriver.cpp + CosEventChannelFactory_i.cpp + CosEventChannelFactoryS.cpp + CosEventChannelFactoryC.cpp + } + IDL_Files { + } +} diff --git a/TAO/orbsvcs/examples/CosEC/Factory/CosEventChannelFactory.idl b/TAO/orbsvcs/examples/CosEC/Factory/CosEventChannelFactory.idl new file mode 100644 index 00000000000..9e68302b882 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Factory/CosEventChannelFactory.idl @@ -0,0 +1,83 @@ +// $Id$ + +// ============================================================================ +// +// = FILENAME +// CosEventChannelFactory.idl +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_COSEVENTCHANNELFACTORY_IDL +#define TAO_COSEVENTCHANNELFACTORY_IDL + +#include "orbsvcs/CosEventChannelAdmin.idl" + +module CosEventChannelFactory +{ + // = TITLE + // Module that describes the Channel Factory. + // + exception DuplicateChannel + { + // = TITLE + // This exception is raised to indicate that a specified + // channel already exists. + }; + + exception NoSuchChannel + { + // = TITLE + // This exception is raised to indicate that a specified + // channel does not exist. + }; + + exception BindFailed + { + // = TITLE + // This exception is raised to indicate that the EventChannel + // could not be registered with the naming service. + }; + + interface ChannelFactory + { + // = TITLE + // Interface definition of the ChannelFactory. + // + // = DESCRIPTION + // The ChannelFactory is used to create,destroy and + // locate CosEventChannels. + + CosEventChannelAdmin::EventChannel create ( + in string channel_id, + in boolean store_in_naming_service) raises (DuplicateChannel, BindFailed); + // Creates a CosEventChannel given a channel id. + // The DuplicateChannel exception is raised if the channel + // already exists. + // BindFailed is raised if we failed to register the newly created channel + // with the naming service. + + void destroy ( + in string channel_id, + in boolean unbind_from_naming_service) raises (NoSuchChannel); + // Destroys the channel specified by the channel id. + // If the channel does not exist then the NoSuchChannel exception + // is raised. + + CosEventChannelAdmin::EventChannel find ( + in string channel_id) raises (NoSuchChannel); + // Finds an EventChannel given the channel id. + // If the channel does not exist then the NoSuchChannel exception + // is raised. + + string find_channel_id ( + in CosEventChannelAdmin::EventChannel channel) raises (NoSuchChannel); + // Returns a channel id given a reference to it. + // If the channel does not exist then the NoSuchChannel exception + // is raised. + }; +}; + +#endif /* TAO_COSEVENTCHANNELFACTORY_IDL */ diff --git a/TAO/orbsvcs/examples/CosEC/Factory/CosEventChannelFactory_i.cpp b/TAO/orbsvcs/examples/CosEC/Factory/CosEventChannelFactory_i.cpp new file mode 100644 index 00000000000..78b17a2bac9 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Factory/CosEventChannelFactory_i.cpp @@ -0,0 +1,327 @@ +// -*- C++ -*- +// $Id$ + +#include "CosEventChannelFactory_i.h" +#include "orbsvcs/CosEvent/CEC_EventChannel.h" +#include "tao/PortableServer/PortableServer.h" +#include "ace/Auto_Ptr.h" + +TAO_CosEventChannelFactory_i::TAO_CosEventChannelFactory_i (void) + :poa_ (PortableServer::POA::_nil ()), + naming_ (CosNaming::NamingContext::_nil ()) +{ +} + +TAO_CosEventChannelFactory_i::~TAO_CosEventChannelFactory_i (void) +{ +#if 0 + ACE_DEBUG ((LM_DEBUG, + "in TAO_CosEventChannelFactory_i dtor")); +#endif + // No-Op. +} + +int +TAO_CosEventChannelFactory_i::init (PortableServer::POA_ptr poa, + const char* child_poa_name, + CosNaming::NamingContext_ptr naming + ACE_ENV_ARG_DECL) +{ + // Check if we have a parent poa. + if (CORBA::is_nil (poa)) + return -1; + + this->naming_ = CosNaming::NamingContext::_duplicate (naming); + // Save the naming context. + + // Create a UNIQUE_ID and USER_ID policy because we want the POA + // to detect duplicates for us. + PortableServer::IdUniquenessPolicy_var idpolicy = + poa->create_id_uniqueness_policy (PortableServer::UNIQUE_ID + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + PortableServer::IdAssignmentPolicy_var assignpolicy = + poa->create_id_assignment_policy (PortableServer::USER_ID + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Create a PolicyList + CORBA::PolicyList policy_list; + policy_list.length (2); + policy_list [0] = + PortableServer::IdUniquenessPolicy::_duplicate (idpolicy.in ()); + policy_list [1] = + PortableServer::IdAssignmentPolicy::_duplicate (assignpolicy.in ()); + + PortableServer::POAManager_ptr manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + // @@ Pradeep : TODO - find a way to destroy the policy_list if we return here. + + // Create the child POA. + this->poa_ = poa->create_POA (child_poa_name, + manager, + policy_list + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + idpolicy->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + assignpolicy->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + //this->poa_ = PortableServer::POA::_duplicate (poa); + // uncomment this if we want to use the parent poa for some reason. + return 0; +} + +CosEventChannelAdmin::EventChannel_ptr +TAO_CosEventChannelFactory_i::create (const char * channel_id, + CORBA::Boolean store_in_naming_service + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventChannelFactory::DuplicateChannel, + CosEventChannelFactory::BindFailed + )) +{ + ACE_ASSERT (!CORBA::is_nil (this->poa_.in ())); + + CosEventChannelAdmin::EventChannel_var ec_return; + + ACE_TRY + { + PortableServer::ObjectId_var oid = + PortableServer::string_to_ObjectId (channel_id); + + // let all those contained in FactoryEC use the default POA. + // We only need the FactoryEC's to be unique! + PortableServer::POA_ptr defPOA = this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + TAO_CEC_EventChannel_Attributes attr (defPOA, defPOA); + + TAO_CEC_EventChannel *impl = 0; + ACE_NEW_THROW_EX (impl, + TAO_CEC_EventChannel (attr, 0, 0), + CORBA::NO_MEMORY ()); + ACE_TRY_CHECK; + + auto_ptr <TAO_CEC_EventChannel> ec (impl); + + impl->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->poa_->activate_object_with_id (oid.in (), + ec.get () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ec.release (); + + CORBA::Object_var obj = + this->poa_->id_to_reference (oid.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (store_in_naming_service && + !CORBA::is_nil (this->naming_.in ())) + { + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (channel_id); + + this->naming_->rebind (name, + obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + ec_return = CosEventChannelAdmin::EventChannel::_narrow (obj.in ()); + } + ACE_CATCH (PortableServer::POA::ServantAlreadyActive, sa_ex) + { + ACE_THROW_RETURN (CosEventChannelFactory::DuplicateChannel (), + ec_return._retn ()); + } + ACE_CATCH (PortableServer::POA::ObjectAlreadyActive, oaa_ex) + { + ACE_THROW_RETURN (CosEventChannelFactory::DuplicateChannel (), + ec_return._retn ()); + } + ACE_CATCH (PortableServer::POA::WrongPolicy, wp_ex) + { + ACE_THROW_RETURN (CORBA::UNKNOWN (), + ec_return._retn ()); + } + ACE_CATCH (PortableServer::POA::ObjectNotActive, ona_ex) + { + ACE_THROW_RETURN (CosEventChannelFactory::BindFailed (), + ec_return._retn ()); + } + ACE_CATCH (CosNaming::NamingContext::NotFound, nf_ex) + { + ACE_THROW_RETURN (CosEventChannelFactory::BindFailed (), + ec_return._retn ()); + } + ACE_CATCH (CosNaming::NamingContext::CannotProceed, cp_ex) + { + ACE_THROW_RETURN (CosEventChannelFactory::BindFailed (), + ec_return._retn ()); + } + ACE_CATCH (CosNaming::NamingContext::InvalidName, in_ex) + { + ACE_THROW_RETURN (CosEventChannelFactory::BindFailed (), + ec_return._retn ()); + } + ACE_CATCH (CosNaming::NamingContext::AlreadyBound, ab) + { + ACE_THROW_RETURN (CosEventChannelFactory::BindFailed (), + ec_return._retn ()); + } + ACE_ENDTRY; + ACE_CHECK_RETURN (ec_return._retn ()); + + return ec_return._retn (); +} + +void +TAO_CosEventChannelFactory_i::destroy +( + const char * channel_id, + CORBA::Boolean unbind_from_naming_service + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventChannelFactory::NoSuchChannel + )) +{ + ACE_ASSERT (!CORBA::is_nil (this->poa_.in ())); + + ACE_TRY + { + // Get hold of the objectid first. + PortableServer::ObjectId_var oid = + PortableServer::string_to_ObjectId (channel_id); + + CORBA::Object_var obj = + this->poa_->id_to_reference (oid.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosEventChannelAdmin::EventChannel_var fact_ec = + CosEventChannelAdmin::EventChannel::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + fact_ec->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Remove from the naming service. + if (unbind_from_naming_service && + !CORBA::is_nil (this->naming_.in ())) + { + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (channel_id); + + this->naming_->unbind (name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + } + ACE_CATCH (CosNaming::NamingContext::NotFound, nf_ex) + { + return; // don't bother the user with exceptions if unbind fails. + } + ACE_CATCH (CosNaming::NamingContext::CannotProceed, cp_ex) + { + return; // don't bother the user with exceptions if unbind fails. + } + ACE_CATCH (CosNaming::NamingContext::InvalidName, in_ex) + { + return; // don't bother the user with exceptions if unbind fails. + } + ACE_CATCH (CORBA::UserException, ue) // Translate any other user exception. + { + ACE_THROW (CosEventChannelFactory::NoSuchChannel ()); + } + ACE_ENDTRY; + ACE_CHECK; +} + +CosEventChannelAdmin::EventChannel_ptr +TAO_CosEventChannelFactory_i::find +( + const char * channel_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventChannelFactory::NoSuchChannel + )) +{ + ACE_ASSERT (!CORBA::is_nil (this->poa_.in ())); + + CosEventChannelAdmin::EventChannel_var ec_return; + + ACE_TRY + { + PortableServer::ObjectId_var oid = + PortableServer::string_to_ObjectId (channel_id); + + CORBA::Object_var obj = + this->poa_->id_to_reference (oid.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ec_return = CosEventChannelAdmin::EventChannel::_narrow (obj.in ()); + } + ACE_CATCH (CORBA::UserException, ue) // Translate any user exception. + { + ACE_THROW_RETURN (CosEventChannelFactory::NoSuchChannel (), + ec_return._retn ()); + } + ACE_ENDTRY; + ACE_CHECK_RETURN (ec_return._retn ()); + + return ec_return._retn (); +} + +char* +TAO_CosEventChannelFactory_i::find_channel_id +( + CosEventChannelAdmin::EventChannel_ptr channel + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventChannelFactory::NoSuchChannel + )) +{ + ACE_ASSERT (!CORBA::is_nil (this->poa_.in ())); + + CORBA::String_var str_return; + ACE_TRY + { + PortableServer::ObjectId_var oid = + this->poa_->reference_to_id (channel + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + str_return = PortableServer::ObjectId_to_string (oid.in ()); + } + ACE_CATCH (CORBA::UserException, ue) // Translate any user exception. + { + ACE_THROW_RETURN (CosEventChannelFactory::NoSuchChannel (), + str_return._retn ()); + } + ACE_ENDTRY; + ACE_CHECK_RETURN (str_return._retn ()); + + return str_return._retn (); +} + diff --git a/TAO/orbsvcs/examples/CosEC/Factory/CosEventChannelFactory_i.h b/TAO/orbsvcs/examples/CosEC/Factory/CosEventChannelFactory_i.h new file mode 100644 index 00000000000..f1a137b5372 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Factory/CosEventChannelFactory_i.h @@ -0,0 +1,119 @@ +// -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/orbsvcs/examples/CosEC/Factory +// +// = FILENAME +// CosEventChannelFactory_i.h +// +// = DESCRIPTION +// This class implements the CosEventChannelFactory +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_COSEVENTCHANNELFACTORY_I_H +#define TAO_COSEVENTCHANNELFACTORY_I_H + +#include /**/ "ace/pre.h" + +#include "CosEventChannelFactoryS.h" +#include "orbsvcs/CosNamingC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class TAO_CosEventChannelFactory_i : + public virtual POA_CosEventChannelFactory::ChannelFactory +{ + public: + // = Initialization and termination code. + TAO_CosEventChannelFactory_i (void); + // Constructor. + + ~TAO_CosEventChannelFactory_i (void); + // Destructor. + + int init (PortableServer::POA_ptr poa, + const char* child_poa_name, + CosNaming::NamingContext_ptr naming = CosNaming::NamingContext::_nil () + ACE_ENV_ARG_DECL_WITH_DEFAULTS); + // This method creates a child poa with <poa> as the + // parent. It also accepts a Naming_Context which is used to register + // the event channels if specified. + // Returns -1 on error, 0 on success. + // @@ Pradeep: this looks OK. I wonder if it would be a good idea to + // raise exceptions, but I'm undecided. + // @@ Pradeep: when is the child poa destroyed? Maybe we should add + // a destroy() method to the factory interface (in IDL). + // @@ Carlos: if we add a <destroy> to the factory, any client will be + // able to destroy the factory! + // @@ Pradeep: it could be a method of the Factory_i class, it + // doesn't have to be exposed through the IDL interface. Anyway, + // there must be a way to cleanup any resources created by the + // factory, and you must avoid CORBA calls in the destructor, + // first because you won't have an ACE_ENV_SINGLE_ARG_PARAMETER and second because + // exceptions in destructors are evil. + // @@ Pradeep: anyway you can just use exceptions and not return -1? + + // = CosEventChannelFactory::ChannelFactory methods. + virtual CosEventChannelAdmin::EventChannel_ptr create + ( + const char * channel_id, + CORBA::Boolean store_in_naming_service + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventChannelFactory::DuplicateChannel, + CosEventChannelFactory::BindFailed + )); + + virtual void destroy + ( + const char * channel_id, + CORBA::Boolean unbind_from_naming_service + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventChannelFactory::NoSuchChannel + )); + + virtual CosEventChannelAdmin::EventChannel_ptr find + ( + const char * channel_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventChannelFactory::NoSuchChannel + )); + + virtual char * find_channel_id + ( + CosEventChannelAdmin::EventChannel_ptr channel + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventChannelFactory::NoSuchChannel + )); + protected: + + PortableServer::POA_var poa_; + // The Poa with which we activate all the Event Channels. + + CosNaming::NamingContext_var naming_; + // The naming context to use. +}; + +#include /**/ "ace/post.h" + +#endif /* TAO_COSEVENTCHANNELFACTORY_I_H */ diff --git a/TAO/orbsvcs/examples/CosEC/Factory/FactoryClient.cpp b/TAO/orbsvcs/examples/CosEC/Factory/FactoryClient.cpp new file mode 100644 index 00000000000..72c9ebc763b --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Factory/FactoryClient.cpp @@ -0,0 +1,418 @@ +// -*- C++ -*- +// $Id$ + +#include "CosEventChannelFactoryC.h" +#include "orbsvcs/CosNamingC.h" +#include "ace/Log_Msg.h" + +class FactoryClient +{ + // = TITLE + // A simple client to test the CosEC factory + // + // = DESCRIPTION + // Test Client for the CosEC factory. + +public: + // Initialization and termination methods + FactoryClient (void); + // constructor. + + virtual ~FactoryClient (void); + // destructor. + + void init_ORB (int argc, char *argv [] ACE_ENV_ARG_DECL); + // Initializes the ORB. + + void resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL); + // Try to get hold of a running naming service. + + void resolve_factory (ACE_ENV_SINGLE_ARG_DECL); + // Try to resolve the factory from the Naming service. + + CosEventChannelFactory::ChannelFactory_ptr + create_factory (ACE_ENV_SINGLE_ARG_DECL); + // Create a local Factory and also set the <factory_>. + + virtual void run_test (ACE_ENV_SINGLE_ARG_DECL); + // Runs a couple of tests to check if the factory behaves correctly. + +protected: + CosEventChannelAdmin::EventChannel_ptr + create_channel (const char *channel_id, + CosEventChannelFactory::ChannelFactory_ptr factory + ACE_ENV_ARG_DECL); + // Create a channel. + + void destroy_channel (const char *channel_id + ACE_ENV_ARG_DECL); + // Destroy the channel. + + void find_channel (const char* channel_id + ACE_ENV_ARG_DECL); + // Find a channel. + + void find_channel_id (CosEventChannelAdmin::EventChannel_ptr channel + ACE_ENV_ARG_DECL); + // Find a channel. + + // = Protected Data members. + const char* factory_name_; + // The name of the factory registered with the naming service. + + CORBA::ORB_var orb_; + // The ORB that we use. + + CosNaming::NamingContext_var naming_context_; + // Handle to the name service. + + CosEventChannelFactory::ChannelFactory_var factory_; + // object from naming service. + + int use_naming_service; + // flag to indicate if the naming service should be used. +}; + +FactoryClient::FactoryClient (void) + :factory_name_ ("CosEC_Factory"), + use_naming_service (0) +{ + // No-Op. +} + +FactoryClient::~FactoryClient (void) +{ + // No-Op. +} + +void +FactoryClient::init_ORB (int argc, + char *argv [] + ACE_ENV_ARG_DECL) +{ + this->orb_ = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +FactoryClient::resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL) +{ + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW (CORBA::UNKNOWN ()); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->use_naming_service = 1; +} + +void +FactoryClient::resolve_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_ASSERT (this->use_naming_service == 1); + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (this->factory_name_); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->factory_ = + CosEventChannelFactory::ChannelFactory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +CosEventChannelFactory::ChannelFactory_ptr +FactoryClient::create_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_THROW_RETURN (CORBA::UNKNOWN (), + CosEventChannelFactory::ChannelFactory::_nil ()); +} + +CosEventChannelAdmin::EventChannel_ptr +FactoryClient::create_channel (const char *channel_id, + CosEventChannelFactory::ChannelFactory_ptr factory + ACE_ENV_ARG_DECL) +{ + ACE_DEBUG ((LM_DEBUG, + "Trying to create channel %s\n", channel_id)); + + CosEventChannelAdmin::EventChannel_var ec = + CosEventChannelAdmin::EventChannel::_nil (); + + ACE_TRY + { + ec = factory->create (channel_id, + this->use_naming_service + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ASSERT (!CORBA::is_nil (ec.in ())); + + ACE_DEBUG ((LM_DEBUG, + "Created Cos Event Channel \"%s \"\n", + channel_id)); + } + ACE_CATCH (CORBA::UserException, ue) + { + ACE_PRINT_EXCEPTION (ue, + "User Exception in createChannel: "); + return CosEventChannelAdmin::EventChannel::_nil (); + } + ACE_CATCH (CORBA::SystemException, se) + { + ACE_PRINT_EXCEPTION (se, + "System Exception in createChannel: "); + return CosEventChannelAdmin::EventChannel::_nil (); + } + ACE_ENDTRY; + + return ec._retn (); +} + +void +FactoryClient::destroy_channel (const char *channel_id + ACE_ENV_ARG_DECL) +{ + ACE_DEBUG ((LM_DEBUG, + "Destroying Cos Event Channel \"%s \"\n", + channel_id)); + + this->factory_->destroy (channel_id, + use_naming_service + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +FactoryClient::find_channel (const char* channel_id + ACE_ENV_ARG_DECL) +{ + ACE_TRY + { + ACE_DEBUG ((LM_DEBUG, + "trying to find the Channel \"%s \"\n", + channel_id)); + + CosEventChannelAdmin::EventChannel_var channel = + this->factory_->find (channel_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + CORBA::String_var str = + orb_->object_to_string (channel.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Find returned - %s \n", + str.in ())); + + this->find_channel_id (channel.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::UserException, ue) + { + ACE_PRINT_EXCEPTION (ue, + "User Exception in findchannel: "); + } + ACE_CATCH (CORBA::SystemException, se) + { + ACE_PRINT_EXCEPTION (se, + "System Exception in findchannel: "); + } + ACE_ENDTRY; +} + +void +FactoryClient::find_channel_id (CosEventChannelAdmin::EventChannel_ptr channel + ACE_ENV_ARG_DECL) +{ + CORBA::String_var str = + orb_->object_to_string (channel + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "trying to find the Channel %s \n", + str.in ())); + + char *channel_id = + this->factory_->find_channel_id (channel + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "find returned %s\n", channel_id)); +} + +/* + * excercise the factory: create 3 Channels and test the factory. + */ + +void +FactoryClient::run_test (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->factory_.in ())); + + const char *channel_id [3] = {"cosec1", "cosec2", "cosec3"}; + CosEventChannelAdmin::EventChannel_var cosec [3]; + + // create the first cosec + cosec[0] = this->create_channel (channel_id[0], + this->factory_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // create the second cosec + cosec[1] = this->create_channel (channel_id[1], + this->factory_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // create the third cosec + cosec[2] = this->create_channel (channel_id[2], + this->factory_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // see it we can destroy this one.. + this->destroy_channel (channel_id[2] + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // see if we can find it? + this->find_channel_id (cosec[2].in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // see if we can create it again? + cosec[2] = this->create_channel (channel_id[2], + this->factory_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // try and find a channel that does not exist. + this->find_channel ("areyouthere?" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // see if it can detect duplicates. + this->create_channel (channel_id[2], + this->factory_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // see if it can give us the id? + this->find_channel_id (cosec[0].in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->find_channel_id (cosec[1].in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->find_channel_id (cosec[2].in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // check if we can get the channels from the id. + this->find_channel (channel_id[0] + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->find_channel (channel_id[1] + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->find_channel (channel_id[2] + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + //destroy them all. + this->destroy_channel (channel_id[0] + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->destroy_channel (channel_id[1] + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->destroy_channel (channel_id[2] + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // end of testing. + ACE_DEBUG ((LM_DEBUG, + "Factory testing complete\n")); +} + +int +main (int argc, char *argv []) +{ + ACE_DEBUG ((LM_DEBUG, + "The FactoryClient will test the Cos Event Channel Factory\n")); + ACE_TRY_NEW_ENV + { + FactoryClient ft; + + ft.init_ORB (argc, + argv + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_TRY_EX (naming) + { + ft.resolve_naming_service (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK_EX (naming); + + ft.resolve_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK_EX (naming); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Failed to resolve the naming service"); + ACE_DEBUG ((LM_DEBUG, + "Creating a local Factory\n")); + // TBD: + ft.create_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_ENDTRY; + + ft.run_test (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::UserException, ue) + { + ACE_PRINT_EXCEPTION (ue, + "test failed: User Exception in FactoryClient: "); + return 1; + } + ACE_CATCH (CORBA::SystemException, se) + { + ACE_PRINT_EXCEPTION (se, + "test failed: System Exception in FactoryClient: "); + return 1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/CosEC/Factory/FactoryDriver.cpp b/TAO/orbsvcs/examples/CosEC/Factory/FactoryDriver.cpp new file mode 100644 index 00000000000..845ee110d77 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Factory/FactoryDriver.cpp @@ -0,0 +1,168 @@ +// -*- C++ -*- +// $Id$ + +#include "FactoryDriver.h" +#include "tao/debug.h" +#include "ace/Get_Opt.h" + +FactoryDriver::FactoryDriver (const char* name) + :factoryName_ (name), + child_poa_name_ ("CosEC_ChildPOA"), + factory_servant_ (0) +{ + //No-Op. +} + +FactoryDriver::~FactoryDriver (void) +{ + //No-Op. +} + +int +FactoryDriver::parse_args (int argc, char *argv []) +{ + ACE_Get_Opt get_opts (argc, argv, "dr:"); + int c = 0; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'd': // debug flag. + TAO_debug_level++; + break; + + case 'r': + factoryName_ = get_opts.opt_arg (); + break; + + case '?': // display help for use of the server. + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s" + " [-r] <Factory Name>" + "\n", + argv [0]), + -1); + } + + // Indicates successful parsing of command line. + return 0; +} + +int +FactoryDriver::start (int argc, char *argv []) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + orb_ = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (this->parse_args (argc, argv) == -1) + return -1; + + // Ref counted servants are on the heap.. + ACE_NEW_RETURN (factory_servant_, + TAO_CosEventChannelFactory_i (), + -1); + + CORBA::Object_var poa_object = + orb_->resolve_initial_references("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + -1); + + root_poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POAManager_var poa_manager = + root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + + ACE_TRY_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + + ACE_TRY_CHECK; + + // Initialization of the naming service. + if (naming_client_.init (orb_.in ()) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) Unable to initialize " + "the TAO_Naming_Client. \n"), + 1); + + CosNaming::NamingContext_var context = + naming_client_.get_context (); + + if (factory_servant_->init (root_poa_.in (), + child_poa_name_, + context.in () + ACE_ENV_ARG_PARAMETER) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) Unable to initialize " + "the factory. \n"), + 1); + + // activate the factory in the root poa. + factory_ = factory_servant_->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Give the ownership to the POA. + factory_servant_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + + ACE_TRY_CHECK; + CORBA::String_var + str = orb_->object_to_string (factory_.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "CosEvent_Service: The Cos Event Channel Factory IOR is <%s>\n", + str.in ())); + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (factoryName_); + naming_client_->rebind (name, + factory_.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Registered with the naming service as %s\n", factoryName_)); + + orb_->run (); + } + ACE_CATCH (CORBA::UserException, ue) + { + ACE_PRINT_EXCEPTION (ue, + "cosecfactory: "); + return 1; + } + ACE_CATCH (CORBA::SystemException, se) + { + ACE_PRINT_EXCEPTION (se, + "cosecfactory: "); + return 1; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (1); + + return 0; +} + +int +FactoryDriver::stop (void) +{ + orb_->shutdown (); + return 0; +} diff --git a/TAO/orbsvcs/examples/CosEC/Factory/FactoryDriver.h b/TAO/orbsvcs/examples/CosEC/Factory/FactoryDriver.h new file mode 100644 index 00000000000..97d837a7c2e --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Factory/FactoryDriver.h @@ -0,0 +1,80 @@ + +// -*- C++ -*- +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/orbsvcs/examples/CosEC/Factory +// +// = FILENAME +// FactoryDriver.h +// +// = DESCRIPTION +// This class implements the Factory driver. +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_FACTORYDRIVER_H +#define TAO_FACTORYDRIVER_H + +#include "CosEventChannelFactory_i.h" +#include "orbsvcs/Naming/Naming_Client.h" + +// @@ Pradeep: I know this is just an example, but could you talk to +// Vishal about making this a service that could be bootstraped +// using the -ORBInitRef mechanisms? That way we can run this +// stuff without the naming service running. + +class FactoryDriver +{ + // = TITLE + // Driver class for the CosEventChannel Factory. + // = DESCRIPTION + // creates a CosEventChannel Factory and registers it with the + // naming service. + // + public: + // = Initialization and termination code. + FactoryDriver (const char* factory = "CosEC_Factory"); + // Constructor. + + ~FactoryDriver (void); + // Destructor. + + int start (int argc, char *argv []); + // Start the driver. + + int stop (void); + //Stop the driver. + + protected: + int parse_args (int argc, char *argv []); + // Parse the command-line arguments and set options. + + const char* factoryName_; + // The name of the factory registered with the naming service. + + const char* child_poa_name_; + // The name of the Child POA. + + CORBA::ORB_var orb_; + // The ORB that we use. + + TAO_CosEventChannelFactory_i *factory_servant_; + // The factory servant. + + PortableServer::POA_var root_poa_; + // Reference to the root poa. + + CosEventChannelFactory::ChannelFactory_var factory_; + // The corba object after activation. + + TAO_Naming_Client naming_client_; + // Use a naming client. + +}; +#endif /* TAO_FACTORYDRIVER_H */ diff --git a/TAO/orbsvcs/examples/CosEC/Factory/Makefile.am b/TAO/orbsvcs/examples/CosEC/Factory/Makefile.am new file mode 100644 index 00000000000..9eeb947e9d0 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Factory/Makefile.am @@ -0,0 +1,139 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_IDL = ACE_ROOT=$(ACE_ROOT) TAO_ROOT=$(TAO_ROOT) $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDL_DEP = $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDLFLAGS = -Ge 1 -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -I$(TAO_ROOT) -I$(srcdir) -g $(ACE_BUILDDIR)/apps/gperf/src/gperf +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.CosEC_Factory_Idl.am + +BUILT_SOURCES = \ + CosEventChannelFactoryC.cpp \ + CosEventChannelFactoryC.h \ + CosEventChannelFactoryC.inl \ + CosEventChannelFactoryS.cpp \ + CosEventChannelFactoryS.h \ + CosEventChannelFactoryS.inl \ + CosEventChannelFactoryS_T.cpp \ + CosEventChannelFactoryS_T.h \ + CosEventChannelFactoryS_T.inl + +CLEANFILES = \ + CosEventChannelFactory-stamp \ + CosEventChannelFactoryC.cpp \ + CosEventChannelFactoryC.h \ + CosEventChannelFactoryC.inl \ + CosEventChannelFactoryS.cpp \ + CosEventChannelFactoryS.h \ + CosEventChannelFactoryS.inl \ + CosEventChannelFactoryS_T.cpp \ + CosEventChannelFactoryS_T.h \ + CosEventChannelFactoryS_T.inl + +CosEventChannelFactoryC.cpp CosEventChannelFactoryC.h CosEventChannelFactoryC.inl CosEventChannelFactoryS.cpp CosEventChannelFactoryS.h CosEventChannelFactoryS.inl CosEventChannelFactoryS_T.cpp CosEventChannelFactoryS_T.h CosEventChannelFactoryS_T.inl: CosEventChannelFactory-stamp + +CosEventChannelFactory-stamp: $(srcdir)/CosEventChannelFactory.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -I$(TAO_ROOT)/orbsvcs -GT $(srcdir)/CosEventChannelFactory.idl + @touch $@ + + +noinst_HEADERS = \ + CosEventChannelFactory.idl + +## Makefile.CosEC_Factory_Client.am + +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += FactoryClient + +FactoryClient_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +FactoryClient_SOURCES = \ + CosEventChannelFactoryC.cpp \ + FactoryClient.cpp \ + CosEventChannelFactory_i.h \ + FactoryDriver.h + +FactoryClient_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA + +## Makefile.CosEC_Factory_Server.am + +if BUILD_CORBA_MESSAGING +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += FactoryServer + +FactoryServer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +FactoryServer_SOURCES = \ + CosEventChannelFactoryC.cpp \ + CosEventChannelFactoryS.cpp \ + CosEventChannelFactory_i.cpp \ + FactoryDriver.cpp \ + main.cpp \ + CosEventChannelFactory_i.h \ + FactoryDriver.h + +FactoryServer_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/tao/libTAO_IFR_Client.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicInterface.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/CosEC/Factory/README b/TAO/orbsvcs/examples/CosEC/Factory/README new file mode 100644 index 00000000000..29104ea2b9f --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Factory/README @@ -0,0 +1,45 @@ +// $Id$ + CosEventChannelFactory + ====================================================== + +The CosEventChannelFactory is a factory for creating COS Event +Channels. The ChannelFactory interface allows a client to create, +destroy and locate factories. + +IMPLEMENTATION +============== + +The TAO_CosEventChannelFactory_i class implements the C++ servant for +the ChannelFactory interface. The FactoryDriver class activates the +ChannelFactory servant with the ORB. During initialization the +ChannelFactory creates a child POA which is used to activate all the +CosEC servants.The ChannelFactory uses the CosEC_ServantBase class to +create the CosEvent Channels. + +The Makefile in this directory generates 2 executables: factory and +factoryclient. + +FACTORY +======= + +To allow client applications to obtain a reference to the factory, a +Naming service must be started prior to running the factory. + +The factory options are: + + -r <FactoryName> : specifies under what name the factory should be + +registered with the Naming Service. The default is "CosEC_Factory" + +FACTORYCLIENT +============= + +The factory client is a test driver for the factory. It exercises all +the features of the factory. A Naming Service and a factory must be +running prior to running the factoryclient. factoryclient does not +take any command line options. + +AUTHOR +====== + +Pradeep Gore <pradeep@cs.wustl.edu> diff --git a/TAO/orbsvcs/examples/CosEC/Factory/main.cpp b/TAO/orbsvcs/examples/CosEC/Factory/main.cpp new file mode 100644 index 00000000000..2ca49905292 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Factory/main.cpp @@ -0,0 +1,14 @@ +// -*- C++ -*- +// $Id$ + +#include "FactoryDriver.h" +#include "orbsvcs/CosEvent/CEC_Default_Factory.h" + +int +main (int argc, char *argv []) +{ + TAO_CEC_Default_Factory::init_svcs (); + FactoryDriver driver; + driver.start (argc, argv); + return 0; +} diff --git a/TAO/orbsvcs/examples/CosEC/Makefile.am b/TAO/orbsvcs/examples/CosEC/Makefile.am new file mode 100644 index 00000000000..fc83f662130 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + Factory \ + RtEC_Based \ + Simple \ + TypedSimple + diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/Makefile.am b/TAO/orbsvcs/examples/CosEC/RtEC_Based/Makefile.am new file mode 100644 index 00000000000..8c8daad071b --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/Makefile.am @@ -0,0 +1,15 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + lib \ + bin \ + tests + diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/README b/TAO/orbsvcs/examples/CosEC/RtEC_Based/README new file mode 100644 index 00000000000..a90ec511868 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/README @@ -0,0 +1,7 @@ +# $Id$ + + This directory contains a partial implementation of the COS +Event Service, using TAO's RT Event Service as the backend. It is +preserved for historical reasons, most applications are better served +by the full implementation of the COS Event Service included with TAO +or by the standard Notification Service. diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/CosEC_RtEC_Based_bin.mpc b/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/CosEC_RtEC_Based_bin.mpc new file mode 100644 index 00000000000..d74001a0687 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/CosEC_RtEC_Based_bin.mpc @@ -0,0 +1,15 @@ +// -*- MPC -*- +// $Id$ + +project : orbsvcsexe, rtevent_serv, event_skel, naming { + after += CosEC_RtEC_Based_lib + libs += CosEC_RtEC_Based + + specific (automake) { + includes += $(srcdir)/../lib + } else { + includes += ../lib + } + + libpaths += ../lib +} diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/Makefile.am b/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/Makefile.am new file mode 100644 index 00000000000..74f7f1dd02d --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/Makefile.am @@ -0,0 +1,67 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.CosEC_RtEC_Based_bin.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS = RtEC_Based_CosEC + +RtEC_Based_CosEC_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(srcdir)/../lib \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +RtEC_Based_CosEC_SOURCES = \ + RtEC_Based_CosEC.cpp \ + RtEC_Based_CosEC.h + +RtEC_Based_CosEC_LDADD = \ + $(top_builddir)/orbsvcs/examples/CosEC/RtEC_Based/lib/libCosEC_RtEC_Based.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/README b/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/README new file mode 100644 index 00000000000..9f9ac585a75 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/README @@ -0,0 +1,82 @@ + CORBA COS Event Service + ----------------------- + +The CosEvent_Service is a COS compilant Event Service. + +The service is registered with the naming service with the name +"CosEventService" . It exposes the <EventChannel> interface which can be +used by suppliers and consumers to send and receive events. + +WARNING: In TAO 1.0.14 we introduced a new implementation of the COS +Event Service, this new implementation supports both the push and pull +models, and does not use the Real-time Event Service as its backend. +Both implementations are useful, for example, the native +implementation is more efficient and fully featured, but cannot +exploit the features in the RTEC, such as filtering and multicast +based federations. + +To run the Event Channel: +------------------------ +1. you should have a running Naming Service. + if not, start one at $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service + +2. if you want to use the -t option you should have a running + Real Time Event Channel. + if not, start one at $TAO_ROOT/orbsvcs/Event_Service/Event_Service + +3. execute the CosEvent_Service. + +Command line parameters: +------------------------ + -n <COS Event Service name> + specifies the name with which to register the Event Service. + + -r + specifies that a local Real Time Event Channel (Rtec) should be + created and used. + + -t <Real Time Event Service name> + specifies the name with which to *look* for the RtEC.This option is + only useful along with the -r option. + +The next 3 options are used to introduce a filtering mechanism for the +Event Channel based on event types and source ids. + + -e ["EventType_1 EventType_2..."] + specifies the event types for the ConsumerQOS.When the Rtec is being + setup, the ConsumerQOS is specified. + The event types should start at >= ACE_ES_EVENT_UNDEFINED = 16. + e.g. -e "17 20 40" specifies that event types with ids 17, 20 and 40 + should be passed to the consumers. + + -o ["EventSourceID_1 EventSourceID_2.."] + specifies the source ids for the ConsumerQOS. + + -p ["sourceID EventTypeID"] + specifies a pair of sourceid and event type for the Supplier QOS. + + +Running the native COS Event Channel +------------------------------------ + + The native implementation of the COS Event Channel is run +using: + +$ CosEvent_Service_Native + + on top of the regular -ORB arguments and the service +configurator parameters described in: + +$TAO_ROOT/docs/cec_options.html + + this implementation also understands the following arguments: + + -n name Use <name> when binding the object + reference in the naming service + -r Use rebind() to store the object + reference in the naming service + -x do not use the naming service + +Author: +------- +Pradeep Gore <pradeep@cs.wustl.edu> diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/RtEC_Based_CosEC.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/RtEC_Based_CosEC.cpp new file mode 100644 index 00000000000..68f393240e7 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/RtEC_Based_CosEC.cpp @@ -0,0 +1,311 @@ +// $Id$ + +#include "RtEC_Based_CosEC.h" +#include "orbsvcs/Event/EC_Default_Factory.h" +#include "ace/Get_Opt.h" + +RtEC_Based_CosEC::RtEC_Based_CosEC (void) + : service_name ("CosEventService"), + rt_service_name ("EventService"), + remote_rtec_ (0) +{ + // No-Op. +} + +RtEC_Based_CosEC::~RtEC_Based_CosEC (void) +{ + // No-Op. +} + +void +RtEC_Based_CosEC::init_ORB (int& argc, char *argv [] + ACE_ENV_ARG_DECL) +{ + this->orb_ = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +int +RtEC_Based_CosEC::parse_args (int argc, char *argv []) +{ + ACE_Get_Opt get_opt (argc, argv, "t:n:e:o:p:r"); + int opt; + + while ((opt = get_opt ()) != EOF) + { + switch (opt) + { + case 'n': + this->service_name = get_opt.opt_arg (); + break; + + case 't': + this->rt_service_name = get_opt.opt_arg (); + break; + + case 'r': + this->remote_rtec_ = 1; + break; + + case 'e': + this->eventTypeIds_ = get_opt.opt_arg (); + break; + + case 'o': + this->eventSourceIds_ = get_opt.opt_arg (); + break; + + case 'p': + this->source_type_pairs_ = get_opt.opt_arg (); + break; + + case '?': + default: + ACE_DEBUG ((LM_DEBUG, + "Usage: %s " + "\n\t-n <COS Event Service name>" + "\n\t-t <RealTime Event Service name>" + "\n\t-r" // creates the RtEC locally. + "\n\t-e [\"EventType_1, EventType_2...\"] for ConsumerQOS." + "\n\t-o [\"EventSourceID_1, [EventSourceID_2...\"] for ConsumerQOS." + "\n\t-p [\"Source, Event\" pairs] for SupplierQOS." + "\n", + argv[0])); + return -1; + } + } + + return 0; +} + +void +RtEC_Based_CosEC::startup (int argc, char *argv[] + ACE_ENV_ARG_DECL) +{ + ACE_DEBUG ((LM_DEBUG, + "Starting up the CosEvent Service...\n")); + + // initalize the ORB. + this->init_ORB (argc, argv + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (this->parse_args (argc, argv) == -1) + ACE_THROW (CORBA::BAD_PARAM ()); + + this->resolve_naming_service (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->init (this->poa_.in (), + this->poa_.in (), + this->eventTypeIds_, + this->eventSourceIds_, + this->source_type_pairs_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Register ourselves with the naming service. + ACE_ASSERT(!CORBA::is_nil (this->naming_.in ())); + + CORBA::Object_var obj = + this->poa_->servant_to_reference (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::String_var str = + this->orb_->object_to_string (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "The CosEC IOR is <%s>\n", str.in ())); + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (this->service_name); + + this->naming_->rebind (name, + obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Registered with the naming service as: %s\n", + this->service_name)); +} + +POA_RtecEventChannelAdmin::EventChannel_ptr +RtEC_Based_CosEC::create_rtec (ACE_ENV_SINGLE_ARG_DECL) +{ + // see if the user wants a local RtEC.. + if (this->remote_rtec_ == 0) + return CosEC_ServantBase::create_rtec (ACE_ENV_SINGLE_ARG_PARAMETER); + else + return 0; +} + +void +RtEC_Based_CosEC::activate_rtec (ACE_ENV_SINGLE_ARG_DECL) +{ + // see if the user wants to use a local RtEC.. + if (this->remote_rtec_ == 0) + { + CosEC_ServantBase::activate_rtec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } + else + { + // Try to locate a remote rtec. + this->locate_rtec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Use the return value to check success. + if (CORBA::is_nil (this->rtec_.in ())) + ACE_DEBUG ((LM_DEBUG, + "Could not locate a RT EventChannel.Please start one and try again\n")); + } +} + +void +RtEC_Based_CosEC::deactivate_rtec (ACE_ENV_SINGLE_ARG_DECL) +{ + // Check if the local rtec is to be deactivated. + if (this->remote_rtec_ == 0) + { + CosEC_ServantBase::deactivate_rtec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } +} + +void +RtEC_Based_CosEC::locate_rtec (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNaming::Name ref_name (1); + ref_name.length (1); + ref_name[0].id = + CORBA::string_dup (this->rt_service_name); + + CORBA::Object_var obj = + this->naming_->resolve (ref_name + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->rtec_ = + RtecEventChannelAdmin::EventChannel::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +RtEC_Based_CosEC::resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL) +{ + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW (CORBA::UNKNOWN ()); + + this->naming_ = + CosNaming::NamingContext::_narrow (naming_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +int +RtEC_Based_CosEC::run (void) +{ + ACE_DEBUG ((LM_DEBUG, "%s: Running the CosEventService\n", __FILE__)); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->orb_->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "run"), 1); + } + ACE_ENDTRY; + + return 0; +} + +void +RtEC_Based_CosEC::shutdown (ACE_ENV_SINGLE_ARG_DECL) +{ + // Deactivate. + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Unbind from the naming service. + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (this->service_name); + + this->naming_->unbind (name + ACE_ENV_ARG_PARAMETER); + + // shutdown the ORB. + if (!CORBA::is_nil (this->orb_.in ())) + this->orb_->shutdown (); +} + +int +main (int argc, char *argv[]) +{ + TAO_EC_Default_Factory::init_svcs (); + + RtEC_Based_CosEC service; + + ACE_TRY_NEW_ENV + { + service.startup (argc, + argv + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (service.run () == -1) + { + service.shutdown (); + ACE_ERROR_RETURN ((LM_ERROR, + "Failed to run the CosEventService.\n"), + 1); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Failed to start CosEventService"); + return 1; + } + ACE_ENDTRY; + + service.shutdown (); + + return 0; +} diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/RtEC_Based_CosEC.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/RtEC_Based_CosEC.h new file mode 100644 index 00000000000..72f1bd8224f --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/bin/RtEC_Based_CosEC.h @@ -0,0 +1,106 @@ +/* -*- C++ -*- */ +// $Id$ +// ============================================================================ +// +// = FILENAME +// RtEC_Based_CosEC.h +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// The COS Event Channel service. +// +// ============================================================================ + +#ifndef RTEC_BASED_COSEC_H +#define RTEC_BASED_COSEC_H + +#include "CosEvent_Utilities.h" +#include "orbsvcs/CosNamingC.h" + +#if defined (_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +class RtEC_Based_CosEC : public CosEC_ServantBase +{ + // = TITLE + // RtEC_Based_CosEC + // + // = DESCRIPTION + // Implementation of the COS Event Service. + + public: + // = Initialization and termination methods. + RtEC_Based_CosEC (void); + // Constructor. + + virtual ~RtEC_Based_CosEC (void); + // Destructor. + + int parse_args (int argc, char *argv []); + // Parses the command line arguments. + + void startup (int argc, char *argv[] + ACE_ENV_ARG_DECL); + // Initializes the COS Event Service. + // Returns 0 on success, -1 on error. + + int run (void); + // run the COS Event Service. + // Returns 0 on success, -1 on error. + + void shutdown (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS); + // Shutdown the COS Event Service. + // Returns 0 on success, -1 on error. + +protected: + // = Methods from CosEC_ServantBase + virtual POA_RtecEventChannelAdmin::EventChannel_ptr + create_rtec (ACE_ENV_SINGLE_ARG_DECL); + // Create a local rtec. + + virtual void activate_rtec (ACE_ENV_SINGLE_ARG_DECL); + // Activates the rtec. + + virtual void deactivate_rtec (ACE_ENV_SINGLE_ARG_DECL); + // Deactivates the rtec. + + void init_ORB (int& argc, char *argv [] + ACE_ENV_ARG_DECL); + // initialize the ORB. + + void resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL); + // Resolve the naming service. + + void locate_rtec (ACE_ENV_SINGLE_ARG_DECL); + // Locate a rtec. + + // = Data members + const char* service_name; + // The name we use to register with the Naming Service. + + const char* rt_service_name; + // The name of the Real Time Event Service. + + CORBA::ORB_var orb_; + // The ORB that we use. + + PortableServer::POA_var poa_; + // Reference to the root poa. + + CosNaming::NamingContext_var naming_; + // A naming context. + + CORBA::Boolean remote_rtec_; + // Flag to indicate if the RtEC is local/remote, + // 0 => local, 1 => remote, default is local. +}; + +#if defined (_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#endif /* RTEC_BASED_COSEC_H */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ConsumerAdmin_i.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ConsumerAdmin_i.cpp new file mode 100644 index 00000000000..8aa8fcdb042 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ConsumerAdmin_i.cpp @@ -0,0 +1,68 @@ +// $Id$ + +#include "ConsumerAdmin_i.h" +#include "ace/Auto_Ptr.h" + +TAO_CosEC_ConsumerAdmin_i::TAO_CosEC_ConsumerAdmin_i (void) + : qos_ (), + rtec_consumeradmin_ (RtecEventChannelAdmin::ConsumerAdmin::_nil ()) +{ + // No-Op. +} + +TAO_CosEC_ConsumerAdmin_i::~TAO_CosEC_ConsumerAdmin_i (void) +{ + // No-Op. +} + +int +TAO_CosEC_ConsumerAdmin_i::init (const RtecEventChannelAdmin::ConsumerQOS &consumerqos, + RtecEventChannelAdmin::ConsumerAdmin_ptr rtec_consumeradmin) +{ + this->qos_ = consumerqos; + this->rtec_consumeradmin_ = + RtecEventChannelAdmin::ConsumerAdmin::_duplicate (rtec_consumeradmin); + return 0; +} + +CosEventChannelAdmin::ProxyPushSupplier_ptr +TAO_CosEC_ConsumerAdmin_i::obtain_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CosEventChannelAdmin::ProxyPushSupplier_ptr proxysupplier_nil = + CosEventChannelAdmin::ProxyPushSupplier::_nil (); + + RtecEventChannelAdmin::ProxyPushSupplier_var rtecproxypushsupplier = + this->rtec_consumeradmin_->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxysupplier_nil); + + TAO_CosEC_ProxyPushSupplier_i *proxypushsupplier; + + ACE_NEW_RETURN (proxypushsupplier, + TAO_CosEC_ProxyPushSupplier_i (this->qos_, + rtecproxypushsupplier.in ()), + proxysupplier_nil); + + auto_ptr<TAO_CosEC_ProxyPushSupplier_i> + auto_proxysupplier (proxypushsupplier); + + CosEventChannelAdmin::ProxyPushSupplier_ptr proxy_obj = + auto_proxysupplier.get ()->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxysupplier_nil); + + // give the ownership to the POA. + auto_proxysupplier.get ()->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxysupplier_nil); + + auto_proxysupplier.release (); + return proxy_obj; +} + +CosEventChannelAdmin::ProxyPullSupplier_ptr +TAO_CosEC_ConsumerAdmin_i::obtain_pull_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // TODO: implement this. + return CosEventChannelAdmin::ProxyPullSupplier::_nil (); +} + diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ConsumerAdmin_i.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ConsumerAdmin_i.h new file mode 100644 index 00000000000..e6142c993ef --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ConsumerAdmin_i.h @@ -0,0 +1,69 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO services +// +// = FILENAME +// ConsumerAdmin_i +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// This has the implementation of the +// CosEventChannelAdmin::ConsumerAdmin interface. +// +// ============================================================================ + +#ifndef CONSUMERADMIN_I_H +#define CONSUMERADMIN_I_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "ProxyPushSupplier_i.h" + +class TAO_RTEC_COSEC_Export TAO_CosEC_ConsumerAdmin_i : + public virtual POA_CosEventChannelAdmin::ConsumerAdmin +{ + // = TITLE + // class TAO_CosEC_ConsumerAdmin_i implements the ConsumerAdmin interface. + // + // = DESCRIPTION + // This implementation of the ConsumerAdmin uses the + // RtecEventChannelAdmin::ConsumerAdmin. +public: + // = Initialization and termination methods. + TAO_CosEC_ConsumerAdmin_i (void); + // Constructor. + + ~TAO_CosEC_ConsumerAdmin_i (void); + // Destructor. + + int init (const RtecEventChannelAdmin::ConsumerQOS &consumerqos, + RtecEventChannelAdmin::ConsumerAdmin_ptr rtec_consumeradmin); + + virtual CosEventChannelAdmin::ProxyPushSupplier_ptr + obtain_push_supplier(ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Returns a new ProxyPushSupplier_ptr. + + virtual CosEventChannelAdmin::ProxyPullSupplier_ptr + obtain_pull_supplier(ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Returns a new ProxyPullSupplier_ptr. + +private: + RtecEventChannelAdmin::ConsumerQOS qos_; + // The ConsumerQOS specified by the user of this class. + + RtecEventChannelAdmin::ConsumerAdmin_var rtec_consumeradmin_; + // The RtecEventChannelAdmin::ConsumerAdmin specified by the user of + // this class. +}; + +#include /**/ "ace/post.h" +#endif /* CONSUMERADMIN_I_H */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/CosEC_RtEC_Based_lib.mpc b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/CosEC_RtEC_Based_lib.mpc new file mode 100644 index 00000000000..8d6627c4a00 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/CosEC_RtEC_Based_lib.mpc @@ -0,0 +1,8 @@ +// -*- MPC -*- +// $Id$ + +project : orbsvcslib, event_skel, rtevent_serv { + sharedname = CosEC_RtEC_Based + dynamicflags += TAO_RTEC_COSEC_BUILD_DLL +} + diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/CosEvent_Utilities.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/CosEvent_Utilities.cpp new file mode 100644 index 00000000000..543fb669bf8 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/CosEvent_Utilities.cpp @@ -0,0 +1,443 @@ +// -*- C++ -*- +// $Id$ + +#include "CosEvent_Utilities.h" +#include "orbsvcs/Event/EC_Event_Channel.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "EventChannel_i.h" +#include "ace/Auto_Ptr.h" +#include "ace/OS_NS_string.h" + +CosEC_ServantBase::CosEC_ServantBase (void) + :poa_ (PortableServer::POA::_nil ()), + rtec_servant_ (0), + cosec_servant_ (0), + rtec_ (RtecEventChannelAdmin::EventChannel::_nil ()), + cosec_ (CosEventChannelAdmin::EventChannel::_nil ()), + eventTypeIds_ (0), + eventSourceIds_ (0), + source_type_pairs_ (0) +{ + // No-Op. +} + +CosEC_ServantBase::~CosEC_ServantBase (void) +{ + // No-Op. +#if 0 + ACE_DEBUG ((LM_DEBUG, "in cosec servant base %d \n", this)); +#endif +} + +void +CosEC_ServantBase::init (PortableServer::POA_ptr thispoa, + PortableServer::POA_ptr poa, + char *, + char *, + char * + ACE_ENV_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (thispoa)); + ACE_ASSERT (!CORBA::is_nil (poa)); + + // Save the POA refs. + this->thispoa_ = PortableServer::POA::_duplicate (thispoa); + this->poa_ = PortableServer::POA::_duplicate (poa); + + auto_ptr<POA_RtecEventChannelAdmin::EventChannel> + auto_rtec_servant_ (this->create_rtec (ACE_ENV_SINGLE_ARG_PARAMETER)); + ACE_CHECK; + + auto_ptr<TAO_CosEC_EventChannel_i> + auto_cosec_servant_ (this->create_cosec (ACE_ENV_SINGLE_ARG_PARAMETER)); + ACE_CHECK; + + // if all the servants were allocated then set the class pointers. + this->rtec_servant_ = auto_rtec_servant_.release (); + this->cosec_servant_ = auto_cosec_servant_.release (); +} + +int +CosEC_ServantBase::activate (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->poa_.in ())); + ACE_ASSERT (!CORBA::is_nil (this->thispoa_.in ())); + + // Activate the Rtec + this->activate_rtec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Activate the CosEC + int retval = this->activate_cosec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (retval != 0) + return -1; + + // Activate ourselves.. + // Note that the POA is <thispoa_> + + PortableServer::ObjectId_var oid = + this->thispoa_->activate_object (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CORBA::Object_var obj = + this->thispoa_->id_to_reference (oid.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + return 0; // success. +} + +int +CosEC_ServantBase::activate (const char* servant_id + ACE_ENV_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->poa_.in ())); + ACE_ASSERT (!CORBA::is_nil (this->thispoa_.in ())); + + // Activate the Rtec + this->activate_rtec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Activate the CosEC + int retval = this->activate_cosec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (retval != 0) + return -1; + + PortableServer::ObjectId_var oid = + PortableServer::string_to_ObjectId (servant_id); + + // Activate ourselves. + // Note that the POA is <thispoa_> + this->thispoa_->activate_object_with_id (oid.in (), + this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CORBA::Object_var obj = + this->thispoa_->id_to_reference (oid.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + return 0; // success. +} + +void +CosEC_ServantBase::activate_rtec (ACE_ENV_SINGLE_ARG_DECL) +{ + // Activate the Rtec + PortableServer::ObjectId_var oid = + this->poa_->activate_object (this->rtec_servant_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->rtec_servant_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var obj = + this->poa_->id_to_reference (oid.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->rtec_ = + RtecEventChannelAdmin::EventChannel::_narrow (obj.in ()); +} + +int +CosEC_ServantBase::activate_cosec (ACE_ENV_SINGLE_ARG_DECL) +{ + // Initialize the CosEC servant. + RtecBase::handle_t supp_handle = 0; + + this->init_SupplierQOS (supp_handle, + this->supplier_qos_, + this->source_type_pairs_); + + RtecBase::handle_t cons_handle = 0; + + this->init_ConsumerQOS (cons_handle, + this->consumer_qos_, + this->eventTypeIds_, + this->eventSourceIds_); + + const RtecEventChannelAdmin::ConsumerQOS &consumerqos = + this->consumer_qos_.get_ConsumerQOS (); + + const RtecEventChannelAdmin::SupplierQOS &supplierqos = + this->supplier_qos_.get_SupplierQOS (); + + if (this->cosec_servant_->init (consumerqos, + supplierqos, + this->rtec_.in () + ACE_ENV_ARG_PARAMETER) != 0) + return -1; + ACE_CHECK_RETURN (-1); + + // Activate the CosEC + PortableServer::ObjectId_var oid = + this->poa_->activate_object (this->cosec_servant_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->cosec_servant_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CORBA::Object_var obj = + this->poa_->id_to_reference (oid.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->cosec_ = + CosEventChannelAdmin::EventChannel::_narrow (obj.in ()); + return 0; // success +} + +void +CosEC_ServantBase::deactivate (ACE_ENV_SINGLE_ARG_DECL) +{ + // Deactivate all those we control... + this->deactivate_rtec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->deactivate_cosec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Finally we go away.. + PortableServer::ObjectId_var oid = + this->thispoa_->servant_to_id (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // deactivate from the poa. + this->thispoa_->deactivate_object (oid.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +CosEC_ServantBase::deactivate_rtec (ACE_ENV_SINGLE_ARG_DECL) +{ + // Deactivate the rtec. + PortableServer::ObjectId_var oid = + this->poa_->servant_to_id (this->rtec_servant_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // deactivate from the poa. + this->poa_->deactivate_object (oid.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +CosEC_ServantBase::deactivate_cosec (ACE_ENV_SINGLE_ARG_DECL) +{ + // Deactivate the cosec. + PortableServer::ObjectId_var oid = + this->poa_->servant_to_id (this->cosec_servant_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // deactivate from the poa. + this->poa_->deactivate_object (oid.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +CosEventChannelAdmin::ConsumerAdmin_ptr +CosEC_ServantBase::for_consumers (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return this->cosec_->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +CosEventChannelAdmin::SupplierAdmin_ptr +CosEC_ServantBase::for_suppliers (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return this->cosec_->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +CosEC_ServantBase::destroy (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Deactivate all the contained servants and ourselves. + // The poa will "destroy" the ref counted servants. + + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +POA_RtecEventChannelAdmin::EventChannel_ptr +CosEC_ServantBase::create_rtec (ACE_ENV_SINGLE_ARG_DECL) +{ + // Create the RtEC servant. + TAO_EC_Event_Channel_Attributes attr (this->poa_.in (), + this->poa_.in ()); + TAO_EC_Event_Channel* _rtec_servant; + ACE_NEW_THROW_EX (_rtec_servant, + TAO_EC_Event_Channel (attr), + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (0); + + return _rtec_servant; +} + +TAO_CosEC_EventChannel_i* +CosEC_ServantBase::create_cosec (ACE_ENV_SINGLE_ARG_DECL) +{ + // Create the CosEC servant. + TAO_CosEC_EventChannel_i* _cosec_servant; + ACE_NEW_THROW_EX (_cosec_servant, + TAO_CosEC_EventChannel_i (), + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (0); + + return _cosec_servant; +} + +void +CosEC_ServantBase::init_SupplierQOS (RtecBase::handle_t supp_handle, + ACE_SupplierQOS_Factory &supplier_qos, + char *source_type_pairs) +{ + // @@ Pradeep: It is very important that you make the type of + // events generated by the CosEC an option. + // I know this is not very well documented, but the type should + // be >= ACE_ES_EVENT_UNDEFINED = 16 + // Something else: please make the EventSourceID for the + // supplier also an option... + + const char *c = " "; // space + char *tok = 0; + + // if nothing was specified on the command line use defaults.. + if (source_type_pairs == 0) + supplier_qos.insert (1, + ACE_ES_EVENT_ANY, + supp_handle, + 1); + else // parse the event types.. + { + tok = ACE_OS::strtok (source_type_pairs, c); + if (tok == 0) // error + { + ACE_DEBUG ((LM_DEBUG, "error parsing source,event pairs for SupplierQOS, defaulting to source id = 1, eventid = ACE_ES_EVENT_ANY")); + + supplier_qos.insert (1, + ACE_ES_EVENT_ANY, + supp_handle, + 1); + } + else + // we just use 1 source-type pair in the event channel. + // so scan for the 1st pair only. + { + int source_val = 0, type_val = 0; + source_val = ACE_OS::atoi (tok); + + tok = ACE_OS::strtok (0, c); + + if (tok != 0) + type_val = ACE_OS::atoi (tok); + + ACE_DEBUG ((LM_DEBUG, "supplier_qos::insert (%d, %d)\n", + source_val, type_val)); + + // Setup the QOS params.. + supplier_qos.insert (source_val, + type_val, + supp_handle, + 1); + } + } +} + +void +CosEC_ServantBase::init_ConsumerQOS (RtecBase::handle_t cons_handle, + ACE_ConsumerQOS_Factory &consumer_qos, + char *eventTypeIds, + char *eventSourceIds + ) +{ + // @@ Pradeep: ditto here, make the set of sources (and/or type) + // a parameter, and make sure the user can specify multiple of + // them (just call insert_source() or insert_type() in the + // parse_args routine). + + const char *c = " "; // space + char *tok = 0; + + consumer_qos.start_disjunction_group (); + + // insert the event ids first.. + + // if nothing was specified on the command line use defaults.. + if (eventTypeIds == 0) + { + //consumer_qos.insert_type (ACE_ES_EVENT_ANY, // default + // cons_handle); + // @@ if i uncomment this line then the Rtec displays the message + // "Consumer tried to register for allevents! This is not implemented." + // whenever a consumer tries to register with it. + } + else // parse the event types.. + { + tok = ACE_OS::strtok (eventTypeIds, c); + if (tok == 0) // error + { + ACE_DEBUG ((LM_DEBUG, "error parsing eventIds for ConsumerQOS, defaulting to 1")); + consumer_qos.insert_type (ACE_ES_EVENT_ANY, + cons_handle); + } + else + do + { + int type_val = ACE_OS::atoi (tok); + ACE_DEBUG ((LM_DEBUG, "consumer_qos::insert_type (%d)\n", + type_val)); + consumer_qos.insert_type (type_val, + cons_handle); + tok = ACE_OS::strtok (0, c); + } + while (tok != 0); + } + + // repeat for source ids.. + + // if nothing was specified on the command line use defaults.. + if (eventSourceIds == 0) + consumer_qos.insert_source (1, // default = 1 + cons_handle); + else // parse the event types.. + { + tok = ACE_OS::strtok (eventSourceIds, c); + if (tok == 0) // error + { + ACE_DEBUG ((LM_DEBUG, "error parsing sourceIds for ConsumerQOS, defaulting to 1")); + consumer_qos.insert_source (1, // default = 1 + cons_handle); + } + else + do + { + int source_val = ACE_OS::atoi (tok); + ACE_DEBUG ((LM_DEBUG, "consumer_qos::insert_source (%d)\n", + source_val)); + consumer_qos.insert_type (source_val, + cons_handle); + tok = ACE_OS::strtok (0, c); + } + while (tok != 0); + } +} + diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/CosEvent_Utilities.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/CosEvent_Utilities.h new file mode 100644 index 00000000000..2738ff890fe --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/CosEvent_Utilities.h @@ -0,0 +1,157 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/orbsvcs/orbsvcs +// +// = FILENAME +// CosEvent_Utilities.h +// +// = DESCRIPTION +// A few utility classes to make it easier to write EC applications. +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_COSEVENT_UTILITIES_H +#define TAO_COSEVENT_UTILITIES_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/RtecBaseC.h" +#include "orbsvcs/RtecEventChannelAdminS.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "orbsvcs/Event_Utilities.h" +#include "rtec_cosec_export.h" + +class TAO_CosEC_EventChannel_i; + +class TAO_RTEC_COSEC_Export CosEC_ServantBase : + public virtual POA_CosEventChannelAdmin::EventChannel +{ + // = TITLE + // A generic servant base class. + // = DESCRIPTION + // This class contains all the member data and methods required to + // create and manage a CosEC servant. + // Clients can derive from this class and create servants. + public: + // = Initialization method. + CosEC_ServantBase (void); + // Constructor. + + virtual ~CosEC_ServantBase (void); + // Destructor. + + virtual void init (PortableServer::POA_ptr thispoa, + PortableServer::POA_ptr poa, + char *eventTypeIds, + char *eventSourceIds, + char *source_type_pairs + ACE_ENV_ARG_DECL); + // This method creates a local scheduler, rtec and cosec. + // The POA <poa> specified here is used when <activate> is called to + // activate the contained servants. + // The POA <thispoa> is used to activate this. + + int activate (ACE_ENV_SINGLE_ARG_DECL); + // Activates the CosEC with <thispoa_> and friends with the <poa_> + + int activate (const char* servant_id ACE_ENV_ARG_DECL); + // If the servant_id is not nil then it is used to supply the object id + // for <this> servant. + + void deactivate (ACE_ENV_SINGLE_ARG_DECL); + // Deactivates the CosEC and friends with the POA. + + // = POA_CosEventChannelAdmin::EventChannel methods. + virtual CosEventChannelAdmin::ConsumerAdmin_ptr for_consumers (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CosEventChannelAdmin::SupplierAdmin_ptr for_suppliers (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void destroy (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Destroys this Event Channel object. + + protected: + // = RtEC creation, activation and deactivation methods. + virtual POA_RtecEventChannelAdmin::EventChannel_ptr + create_rtec (ACE_ENV_SINGLE_ARG_DECL); + // Create a local rtec. + + virtual void activate_rtec (ACE_ENV_SINGLE_ARG_DECL); + // Activates the rtec. + + virtual void deactivate_rtec (ACE_ENV_SINGLE_ARG_DECL); + // Deactivates the rtec. + + // = CosEC creation, activation and deactivation methods. + TAO_CosEC_EventChannel_i* + create_cosec (ACE_ENV_SINGLE_ARG_DECL); + // Create a local cosec. + + int activate_cosec (ACE_ENV_SINGLE_ARG_DECL); + // Activates the cosec. + + void deactivate_cosec (ACE_ENV_SINGLE_ARG_DECL); + // Deactivates the cosec. + + void init_SupplierQOS (RtecBase::handle_t supp_handle, + ACE_SupplierQOS_Factory &supplier_qos, + char *source_type_pairs); + // Initialize the SupplierQOS Factory. + + + void init_ConsumerQOS (RtecBase::handle_t cons_handle, + ACE_ConsumerQOS_Factory &consumer_qos, + char *eventTypeIds, + char *eventSourceIds); + // Initialize the ConsumerQOS Factory. + + // = Protected Data members. + + PortableServer::POA_var thispoa_; + // The poa that we use to activate ourselves. + + PortableServer::POA_var poa_; + // The poa that we use to activate others + + POA_RtecEventChannelAdmin::EventChannel_ptr rtec_servant_; + // The Event Channel servant. + + TAO_CosEC_EventChannel_i *cosec_servant_; + // The servant object of the COS Event Channel. + + RtecEventChannelAdmin::EventChannel_var rtec_; + // Ref to the Rtec. + + CosEventChannelAdmin::EventChannel_var cosec_; + // Ref to the cosec. + + ACE_ConsumerQOS_Factory consumer_qos_; + // The Consumer QOS. + + ACE_SupplierQOS_Factory supplier_qos_; + // The Supplier QOS. + + char *eventTypeIds_; + // The list of EventTypeIDs (for ConsumerQOS) seperated by spaces. + // e.g. "1 2 3 4" + + char *eventSourceIds_; + // The list of EventSourceIDs (for ConsumerQOS) seperated by spaces. + // e.g. "1 2 3 4" + + char *source_type_pairs_; + // The pairs of Source and EventType Ids (for the SupplierQOS). + // e.g "1 4 2 5 3 6" where (1,4) (2,5) and (3,6) from source id, + // event id pairs. +}; + +#include /**/ "ace/post.h" +#endif /* TAO_COSEVENT_UTILITIES_H */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/EventChannel_i.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/EventChannel_i.cpp new file mode 100644 index 00000000000..e5dd9fb0348 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/EventChannel_i.cpp @@ -0,0 +1,124 @@ +// $Id$ +#include "EventChannel_i.h" +#include "ace/Auto_Ptr.h" + +TAO_CosEC_EventChannel_i::TAO_CosEC_EventChannel_i (void) + : consumer_admin_ (0), + supplier_admin_ (0), + consumeradmin_ (CosEventChannelAdmin::ConsumerAdmin::_nil ()), + supplieradmin_ (CosEventChannelAdmin::SupplierAdmin::_nil ()) +{ + // No-Op. +} + +TAO_CosEC_EventChannel_i::~TAO_CosEC_EventChannel_i (void) +{ + //No-Op. +} + +int +TAO_CosEC_EventChannel_i::init (const RtecEventChannelAdmin::ConsumerQOS &consumerqos, + const RtecEventChannelAdmin::SupplierQOS &supplierqos, + RtecEventChannelAdmin::EventChannel_ptr rtec + ACE_ENV_ARG_DECL) +{ + // Allocate the admins.. + TAO_CosEC_ConsumerAdmin_i *consumer_; + ACE_NEW_RETURN (consumer_, + TAO_CosEC_ConsumerAdmin_i (), + -1); + + auto_ptr <TAO_CosEC_ConsumerAdmin_i> auto_consumer_ (consumer_); + + TAO_CosEC_SupplierAdmin_i *supplier_; + ACE_NEW_RETURN (supplier_, + TAO_CosEC_SupplierAdmin_i (), + -1); + + auto_ptr <TAO_CosEC_SupplierAdmin_i> auto_supplier_ (supplier_); + + RtecEventChannelAdmin::ConsumerAdmin_ptr rtec_consumeradmin = + rtec->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (auto_consumer_.get ()->init (consumerqos, + rtec_consumeradmin) == -1) + return -1; + + this->consumeradmin_ = + auto_consumer_.get ()->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // give the ownership to the POA. + auto_consumer_.get ()->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + RtecEventChannelAdmin::SupplierAdmin_ptr rtec_supplieradmin = + rtec->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (auto_supplier_.get ()->init (supplierqos, + rtec_supplieradmin) == -1) + return -1; + + this->supplieradmin_ = + auto_supplier_.get ()->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // give the ownership to the POA. + auto_supplier_.get ()->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->consumer_admin_ = auto_consumer_.release (); + this->supplier_admin_ = auto_supplier_.release (); + + return 0; +} + +CosEventChannelAdmin::ConsumerAdmin_ptr +TAO_CosEC_EventChannel_i::for_consumers (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // @@ Pradeep: you must make a copy here, because the caller is + // responsible of removing this object. + return + CosEventChannelAdmin::ConsumerAdmin::_duplicate (this->consumeradmin_.in()); +} + +CosEventChannelAdmin::SupplierAdmin_ptr +TAO_CosEC_EventChannel_i::for_suppliers (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // @@ Pradeep: you must make a copy here, because the caller is + // responsible of removing this object, same here.. + return + CosEventChannelAdmin::SupplierAdmin::_duplicate (this->supplieradmin_.in ()); +} + +void +TAO_CosEC_EventChannel_i::destroy (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Deactivate the CosEventChannel + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ObjectId_var id = poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + poa->deactivate_object (id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->supplieradmin_ = CosEventChannelAdmin::SupplierAdmin::_nil (); + this->consumeradmin_ = CosEventChannelAdmin::ConsumerAdmin::_nil (); +} + +void +TAO_CosEC_EventChannel_i::shutdown (ACE_ENV_SINGLE_ARG_DECL) +{ + this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); +} + diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/EventChannel_i.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/EventChannel_i.h new file mode 100644 index 00000000000..74f25ca3ec2 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/EventChannel_i.h @@ -0,0 +1,92 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO services +// +// = FILENAME +// EventChannel_i +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// This has the implementation of the +// CosEventChannelAdmin::EventChannel interface. +// +// ============================================================================ + +#ifndef EVENTCHANNEL_I_H +#define EVENTCHANNEL_I_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/CosEventChannelAdminC.h" +#include "ConsumerAdmin_i.h" +#include "SupplierAdmin_i.h" + +class TAO_RTEC_COSEC_Export TAO_CosEC_EventChannel_i : + public virtual POA_CosEventChannelAdmin::EventChannel +{ + // = TITLE + // class TAO_CosEC_EventChannel_i implements the standard Cos EventChannel + // interface. + // + // = DESCRIPTION + // This Cos EventChannel implementation is based on TAO's + // Real-time Event Channel. This TAO_CosEC_EventChannel_i implementation + // delegates all its responsibility to corresponding objects from + // the real-time implementation. + // +public: + // = Initialization and termination methods. + TAO_CosEC_EventChannel_i (void); + // Constructor. + + ~TAO_CosEC_EventChannel_i (void); + // Destructor. + + int init (const RtecEventChannelAdmin::ConsumerQOS &consumerqos, + const RtecEventChannelAdmin::SupplierQOS &supplierqos, + RtecEventChannelAdmin::EventChannel_ptr rtec + ACE_ENV_ARG_DECL); + // Activates the ConsumerAdmin and SupplierAdmin servants. Returns + // -1 on error, 0 on success. + + virtual CosEventChannelAdmin::ConsumerAdmin_ptr for_consumers (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The for_consumers method will return the same ConsumerAdmin_ptr + // everytime its called. + + virtual CosEventChannelAdmin::SupplierAdmin_ptr for_suppliers (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The for_suppliers method will return the same SupplierAdmin_ptr + // everytime its called. + + virtual void destroy (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Destroys this Event Channel object. + + void shutdown (ACE_ENV_SINGLE_ARG_DECL); + // destroys this Event Channel object and <delete>s this object. + +private: + TAO_CosEC_ConsumerAdmin_i* consumer_admin_; + // ConsumerAdmin servant object. + + TAO_CosEC_SupplierAdmin_i* supplier_admin_; + // SupplierAdmin servant object. + + CosEventChannelAdmin::ConsumerAdmin_var consumeradmin_; + // The reference to the ConsumerAdmin interface returned after + // activating the servant in the ORB. + + CosEventChannelAdmin::SupplierAdmin_var supplieradmin_; + // The reference to the SupplierAdmin interface returned after + // activating the servant in the ORB. +}; + +#include /**/ "ace/post.h" +#endif /* EVENTCHANNEL_I_H */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/Makefile.am b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/Makefile.am new file mode 100644 index 00000000000..fd3d67b82b3 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/Makefile.am @@ -0,0 +1,62 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.CosEC_RtEC_Based_lib.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_LTLIBRARIES = libCosEC_RtEC_Based.la + +libCosEC_RtEC_Based_la_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL \ + -DTAO_RTEC_COSEC_BUILD_DLL + +libCosEC_RtEC_Based_la_SOURCES = \ + ConsumerAdmin_i.cpp \ + CosEvent_Utilities.cpp \ + EventChannel_i.cpp \ + ProxyPushConsumer_i.cpp \ + ProxyPushSupplier_i.cpp \ + SupplierAdmin_i.cpp + +noinst_HEADERS = \ + ConsumerAdmin_i.h \ + CosEvent_Utilities.h \ + EventChannel_i.h \ + ProxyPushConsumer_i.h \ + ProxyPushSupplier_i.h \ + SupplierAdmin_i.h \ + rtec_cosec_export.h + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushConsumer_i.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushConsumer_i.cpp new file mode 100644 index 00000000000..5870b6c33c7 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushConsumer_i.cpp @@ -0,0 +1,207 @@ +/* -*- C++ -*- */ +// $Id$ + +#include "orbsvcs/Event_Utilities.h" +#include "orbsvcs/CosEventChannelAdminC.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "orbsvcs/RtecEventCommS.h" +#include "orbsvcs/CosEventCommS.h" +#include "ProxyPushConsumer_i.h" +#include "ace/Auto_Ptr.h" + +#if defined(_MSC_VER) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +class TAO_CosEC_PushSupplierWrapper : + public virtual POA_RtecEventComm::PushSupplier +{ + // = TITLE + // A Wrapper for the Rtec PushSupplier. + // + // = DESCRIPTION + // The Rtec ProxyPushConsumer uses a Rtec PushSupplier. This + // class wraps the Cos PushSupplier to make it look like a Rtec + // PushSupplier. +public: + // = Initialization and termination methods. + TAO_CosEC_PushSupplierWrapper (CosEventComm::PushSupplier_ptr supplier); + // Constructor. + + ~TAO_CosEC_PushSupplierWrapper (void); + // Destructor. + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Disconnects the push supplier. + +private: + // @@ Pradeep: are you sure you want to go through the CORBA + // interface? Maybe the implementation (ProxyPushConsumer_i) is good + // enough at this point? The tradeoff is flexibility (your scheme + // can use remote CosPushSuppliers), but suffers some performance + // penalty: do you need the extra flexibility? Can you use it? [I + // suspect the answers are "not" for both] + CosEventComm::PushSupplier_var supplier_; + // The Cos PushSupplier that we're proxying for. +}; + +#if defined(_MSC_VER) +#pragma warning(default:4250) +#endif /* _MSC_VER */ + +TAO_CosEC_PushSupplierWrapper::TAO_CosEC_PushSupplierWrapper +(CosEventComm::PushSupplier_ptr supplier) + : supplier_ (CosEventComm::PushSupplier::_duplicate (supplier)) +{ + // No-Op. +} + +TAO_CosEC_PushSupplierWrapper::~TAO_CosEC_PushSupplierWrapper (void) +{ + // No-Op. +} + +void +TAO_CosEC_PushSupplierWrapper::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->supplier_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Deactivate the supplier proxy + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ObjectId_var id = + poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + poa->deactivate_object (id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // @@ If we keep a list remember to remove this object from the + // list. +} + +TAO_CosEC_ProxyPushConsumer_i::TAO_CosEC_ProxyPushConsumer_i (const RtecEventChannelAdmin::SupplierQOS &qos, + RtecEventChannelAdmin::ProxyPushConsumer_ptr proxypushconsumer) + : qos_ (qos), + proxypushconsumer_ (RtecEventChannelAdmin::ProxyPushConsumer::_duplicate (proxypushconsumer)), + wrapper_ (0) +{ + // No-Op. +} + +TAO_CosEC_ProxyPushConsumer_i::~TAO_CosEC_ProxyPushConsumer_i (void) +{ + // No-Op. +} + +void +TAO_CosEC_ProxyPushConsumer_i::push (const CORBA::Any &data + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + RtecEventComm::Event buffer[1]; + // Create an event set that does not own the buffer.... + RtecEventComm::EventSet events (1, 1, buffer, 0); + events.length (1); + + RtecEventComm::Event &e = events[0]; + RtecEventComm::Event eqos = + qos_.publications[0].event; + + // @@ what if i initialize the entire <EventSet> with corresponding + // publications entries. + + // NOTE: we initialize the <EventHeader> field using the 1st + // <publications> from the <SupplierQOS>.so we assume that + // publications[0] is initialized. + e.header.source = eqos.header.source; + e.header.ttl = eqos.header.ttl; + e.header.type = eqos.header.type; + + ACE_hrtime_t t = ACE_OS::gethrtime (); + + ORBSVCS_Time::hrtime_to_TimeT (e.header.creation_time, + t); +#if !defined(TAO_LACKS_EVENT_CHANNEL_TIMESTAMPS) + e.header.ec_recv_time = ORBSVCS_Time::zero (); + e.header.ec_send_time = ORBSVCS_Time::zero (); +#endif /* TAO_LACKS_EVENT_CHANNEL_TIMESTAMPS */ + + e.data.any_value = data; + + this->proxypushconsumer_->push (events + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_CosEC_ProxyPushConsumer_i::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->proxypushconsumer_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Deactivate the ProxyPushConsumer + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ObjectId_var id = + poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + poa->deactivate_object (id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_CosEC_ProxyPushConsumer_i::connect_push_supplier (CosEventComm::PushSupplier_ptr push_supplier + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventChannelAdmin::AlreadyConnected)) +{ + if (this->connected ()) + ACE_THROW (CosEventChannelAdmin::AlreadyConnected ()); + + TAO_CosEC_PushSupplierWrapper *wrapper; + + ACE_NEW_THROW_EX (wrapper, + TAO_CosEC_PushSupplierWrapper (push_supplier), + CORBA::NO_MEMORY ()); + ACE_CHECK; + + auto_ptr <TAO_CosEC_PushSupplierWrapper> + auto_wrapper (wrapper); + + RtecEventComm::PushSupplier_ptr rtecpushsupplier + = auto_wrapper.get ()->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // give the ownership to the POA. + auto_wrapper.get ()->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->proxypushconsumer_->connect_push_supplier + (rtecpushsupplier, + this->qos_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->wrapper_ = auto_wrapper.release (); +} + +int +TAO_CosEC_ProxyPushConsumer_i::connected (void) +{ + return this->wrapper_ == 0 ? 0 : 1; +} + diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushConsumer_i.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushConsumer_i.h new file mode 100644 index 00000000000..b780b88d90a --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushConsumer_i.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ +// $Id$ + +// ================================================================ +// +// = LIBRARY +// TAO services +// +// = FILENAME +// ProxyPushConsumer_i +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// This has the implementation of the +// CosEventChannelAdmin::ProxyPushConsumer interface. +// +// ================================================================ + +#ifndef _PROXYPUSHCONSUMER_I_H +#define _PROXYPUSHCONSUMER_I_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/RtecEventChannelAdminS.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "rtec_cosec_export.h" + +class TAO_CosEC_PushSupplierWrapper; + +class TAO_RTEC_COSEC_Export TAO_CosEC_ProxyPushConsumer_i : + public virtual POA_CosEventChannelAdmin::ProxyPushConsumer +{ + // = TITLE + // class TAO_CosEC_ProxyPushConsumer_i implements the ProxyPushConsumer + // interface. + // + // = DESCRIPTION + // This implementation of the ProxyPushConsumer uses the + // RtecEventChannelAdmin::ProxyPushConsumer. + // + // NOTE: RtecEventChannelAdmin::ProxyPushConsumer::push method is + // passed a RtecEventComm::EventSet.The <EventHeader> field in that is + // initialized using the the 1st <publications> from the <SupplierQOS>. + // so we assume that publications[0] is initialized. + // +public: + // = Initialization and termination methods. + TAO_CosEC_ProxyPushConsumer_i (const RtecEventChannelAdmin::SupplierQOS &qos, + RtecEventChannelAdmin::ProxyPushConsumer_ptr proxypushconsumer); + // Constructor. + + ~TAO_CosEC_ProxyPushConsumer_i (void); + // Destructor. + + virtual void push (const CORBA::Any &data + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Suppliers call this method to pass data to connected consumers. + + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Disconnects the supplier from the event communication. + + virtual void connect_push_supplier(CosEventComm::PushSupplier_ptr push_supplier + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventChannelAdmin::AlreadyConnected)); + // Connects a push supplier. + +private: + int connected (void); + // Returns 0 if a push_supplier is already connected to this + // ProxyPushConsumer, otherwise it returns a 1. + + const RtecEventChannelAdmin::SupplierQOS &qos_; + // The SupplierQOS specified by the user of this class. + + RtecEventChannelAdmin::ProxyPushConsumer_var proxypushconsumer_; + // The Rtec ProxyPushConsumer specified by the user of this class. + + TAO_CosEC_PushSupplierWrapper *wrapper_; + // The Rtec PushSupplier wrapper used by the Rtec ProxyPushConsumer. +}; + +#include /**/ "ace/post.h" +#endif /* _PROXYPUSHCONSUMER_I_H */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushSupplier_i.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushSupplier_i.cpp new file mode 100644 index 00000000000..866c8a9e1a3 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushSupplier_i.cpp @@ -0,0 +1,194 @@ +// $Id$ +// +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/CosEventChannelAdminC.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "orbsvcs/CosEventCommS.h" +#include "orbsvcs/RtecEventCommS.h" +#include "ProxyPushSupplier_i.h" +#include "ace/Auto_Ptr.h" + +#if defined(_MSC_VER) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +class TAO_CosEC_PushConsumerWrapper : + public POA_RtecEventComm::PushConsumer +{ + // = TITLE + // Wrapper class for the Rtec PushConsumer. + // + // = DESCRIPTION + // The Rtec ProxyPushSupplier uses a Rtec PushConsumer. This + // class wraps the Cos PushConsumer to make it look like a Rtec + // PushConsumer. +public: + // = Initialization and termination methods. + TAO_CosEC_PushConsumerWrapper (CosEventComm::PushConsumer_ptr consumer); + // Constructor. + + ~TAO_CosEC_PushConsumerWrapper (void); + // Destructor. + + virtual void push (const RtecEventComm::EventSet & data + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // This method is called by the RTEvent Channel to supply data. + + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Disconnects the consumer from the event channel. + +private: + CosEventComm::PushConsumer_var consumer_; + // The Cos PushConsumer that we're proxying for. +}; + +#if defined(_MSC_VER) +#pragma warning(default:4250) +#endif /* _MSC_VER */ + +TAO_CosEC_PushConsumerWrapper::TAO_CosEC_PushConsumerWrapper +(CosEventComm::PushConsumer_ptr consumer) + : consumer_ (CosEventComm::PushConsumer::_duplicate (consumer)) +{ + // No-Op. +} + +TAO_CosEC_PushConsumerWrapper::~TAO_CosEC_PushConsumerWrapper () +{ + // No-Op. +} + +void +TAO_CosEC_PushConsumerWrapper::push (const RtecEventComm::EventSet& set + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + for (CORBA::ULong i = 0; + i < set.length (); + ++i) + { + ACE_TRY + { + this->consumer_->push (set[i].data.any_value + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // Ignore the exception... + } + ACE_ENDTRY; + } +} + +void +TAO_CosEC_PushConsumerWrapper::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Deactivate the supplier proxy. + this->consumer_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ObjectId_var id = + poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + poa->deactivate_object (id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // @@ If we keep a list remember to remove this object from the + // list. +} + +TAO_CosEC_ProxyPushSupplier_i::TAO_CosEC_ProxyPushSupplier_i +(const RtecEventChannelAdmin::ConsumerQOS &qos, + RtecEventChannelAdmin::ProxyPushSupplier_ptr pps) + : qos_ (qos), + pps_ (RtecEventChannelAdmin::ProxyPushSupplier::_duplicate (pps)), + wrapper_ (0) +{ + // No-Op. +} + +TAO_CosEC_ProxyPushSupplier_i::~TAO_CosEC_ProxyPushSupplier_i (void) +{ + // No-Op. +} + +void +TAO_CosEC_ProxyPushSupplier_i::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->pps_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Deactivate the supplier proxy + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ObjectId_var id = + poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + poa->deactivate_object (id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // @@ If we keep a list remember to remove this object from the + // list. +} + +void +TAO_CosEC_ProxyPushSupplier_i::connect_push_consumer (CosEventComm::PushConsumer_ptr push_consumer + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventChannelAdmin::AlreadyConnected, + CosEventChannelAdmin::TypeError)) +{ + if (this->connected ()) + ACE_THROW (CosEventChannelAdmin::AlreadyConnected ()); + + if (push_consumer == CosEventComm::PushConsumer::_nil()) + ACE_THROW (CORBA::BAD_PARAM ()); + + TAO_CosEC_PushConsumerWrapper *wrapper; + ACE_NEW_THROW_EX (wrapper, + TAO_CosEC_PushConsumerWrapper (push_consumer), + CORBA::NO_MEMORY ()); + ACE_CHECK; + + auto_ptr <TAO_CosEC_PushConsumerWrapper> auto_wrapper (wrapper); + + // @@ This code is not exception safe. + RtecEventComm::PushConsumer_ptr rtecpushconsumer = + auto_wrapper.get ()->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // give the ownership to the POA. + auto_wrapper.get ()->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->pps_->connect_push_consumer (rtecpushconsumer, + this->qos_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->wrapper_ = auto_wrapper.release (); +} + +int +TAO_CosEC_ProxyPushSupplier_i::connected (void) +{ + return this->wrapper_ == 0 ? 0 : 1; +} + diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushSupplier_i.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushSupplier_i.h new file mode 100644 index 00000000000..199a596c0bf --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/ProxyPushSupplier_i.h @@ -0,0 +1,76 @@ +/* -*- C++ -*- */ +// $Id$ + +// ================================================================ +// +// = LIBRARY +// TAO services +// +// = FILENAME +// ProxyPushSupplier_i +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// This has the implementation of the +// CosEventChannelAdmin::ProxyPushSupplier interface. +// +// ================================================================ + +#ifndef _PROXYPUSHSUPPLIER_H +#define _PROXYPUSHSUPPLIER_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/CosEventChannelAdminC.h" +#include "rtec_cosec_export.h" + +class TAO_CosEC_PushConsumerWrapper; + +class TAO_RTEC_COSEC_Export TAO_CosEC_ProxyPushSupplier_i : + public POA_CosEventChannelAdmin::ProxyPushSupplier +{ + // = TITLE + // class ProxyPushSupplier-i implements the ProxyPushConsumer interface. + // + // = DESCRIPTION + // This implementation of the ProxyPushSupplier uses the + // RtecEventChannelAdmin::ProxyPushSupplier. +public: + // = Initialization and termination methods. + TAO_CosEC_ProxyPushSupplier_i (const RtecEventChannelAdmin::ConsumerQOS &qos, + RtecEventChannelAdmin::ProxyPushSupplier_ptr pps); + // Constructor. + + ~TAO_CosEC_ProxyPushSupplier_i (void); + // Destructor. + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Ends the event communication and disposes this object. + + virtual void connect_push_consumer(CosEventComm::PushConsumer_ptr push_consumer + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventChannelAdmin::AlreadyConnected, + CosEventChannelAdmin::TypeError)); + // Connects the <push_consumer> to the Event Channel. + +private: + int connected (void); + // Returns 0 if a push_consumer is already connected to this + // ProxyPushSupplier, otherwise it returns a 1. + + const RtecEventChannelAdmin::ConsumerQOS &qos_; + // The ConsumerQOS specified by the user of this class. + + RtecEventChannelAdmin::ProxyPushSupplier_var pps_; + // The Rtec ProxyPushSupplier specified by the user of this class. + + TAO_CosEC_PushConsumerWrapper *wrapper_; + // The Rtec PushConsumer wrapper used by the Rtec ProxyPushSupplier. +}; + +#include /**/ "ace/post.h" +#endif /* _PROXYPUSHSUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/SupplierAdmin_i.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/SupplierAdmin_i.cpp new file mode 100644 index 00000000000..97af59df51a --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/SupplierAdmin_i.cpp @@ -0,0 +1,67 @@ +// $Id$ + +#include "SupplierAdmin_i.h" +#include "ace/Auto_Ptr.h" + +TAO_CosEC_SupplierAdmin_i::TAO_CosEC_SupplierAdmin_i (void) + : qos_ (), + rtec_supplieradmin_ (RtecEventChannelAdmin::SupplierAdmin::_nil ()) +{ + // No-Op. +} + +TAO_CosEC_SupplierAdmin_i::~TAO_CosEC_SupplierAdmin_i (void) +{ + // No-Op. +} + +int +TAO_CosEC_SupplierAdmin_i::init (const RtecEventChannelAdmin::SupplierQOS &supplierqos, + RtecEventChannelAdmin::SupplierAdmin_ptr rtec_supplieradmin) +{ + this->qos_ = supplierqos; + this->rtec_supplieradmin_ = + RtecEventChannelAdmin::SupplierAdmin::_duplicate (rtec_supplieradmin); + return 0; +} + +CosEventChannelAdmin::ProxyPushConsumer_ptr +TAO_CosEC_SupplierAdmin_i::obtain_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CosEventChannelAdmin::ProxyPushConsumer_ptr proxyconsumer_nil = + CosEventChannelAdmin::ProxyPushConsumer::_nil (); + + RtecEventChannelAdmin::ProxyPushConsumer_var rtecproxypushconsumer = + this->rtec_supplieradmin_->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxyconsumer_nil); + + TAO_CosEC_ProxyPushConsumer_i *proxypushconsumer; + + ACE_NEW_RETURN (proxypushconsumer, + TAO_CosEC_ProxyPushConsumer_i (this->qos_, + rtecproxypushconsumer.in ()), + proxyconsumer_nil); + auto_ptr <TAO_CosEC_ProxyPushConsumer_i> + auto_proxyconsumer (proxypushconsumer); + + CosEventChannelAdmin::ProxyPushConsumer_ptr proxy_obj = + auto_proxyconsumer.get ()->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxyconsumer_nil); + + // give the ownership to the POA. + auto_proxyconsumer.get ()->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (proxyconsumer_nil); + + auto_proxyconsumer.release (); + return proxy_obj; +} + +CosEventChannelAdmin::ProxyPullConsumer_ptr +TAO_CosEC_SupplierAdmin_i::obtain_pull_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // TODO: implement this. + return CosEventChannelAdmin::ProxyPullConsumer::_nil (); +} + diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/SupplierAdmin_i.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/SupplierAdmin_i.h new file mode 100644 index 00000000000..7642b282601 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/SupplierAdmin_i.h @@ -0,0 +1,71 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO services +// +// = FILENAME +// SupplierAdmin_i.h +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// This has the implementation of the +// CosEventChannelAdmin::SupplierAdmin interface. +// +// ============================================================================ + +#ifndef SUPPLIER_ADMIN_I_H +#define SUPPLIER_ADMIN_I_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/CosEventChannelAdminC.h" +#include "ProxyPushConsumer_i.h" + +class TAO_RTEC_COSEC_Export TAO_CosEC_SupplierAdmin_i : + public virtual POA_CosEventChannelAdmin::SupplierAdmin +{ + // = TITLE + // class TAO_CosEC_SupplierAdmin_i implements the SupplierAdmin interface. + // + // = DESCRIPTION + // This COS-compliant implementation of the SupplierAdmin uses + // TAO's RtecEventChannelAdmin::SupplierAdmin. +public: + // = Initialization and termination methods. + TAO_CosEC_SupplierAdmin_i (void); + // Constructor. + + ~TAO_CosEC_SupplierAdmin_i (void); + // Destructor. + + int init (const RtecEventChannelAdmin::SupplierQOS &supplierqos, + RtecEventChannelAdmin::SupplierAdmin_ptr rtec_supplieradmin); + // Initializes the SupplierAdmin. Returns 0 on success, -1 on + // error. + + virtual CosEventChannelAdmin::ProxyPushConsumer_ptr + obtain_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Returns a new ProxyPushConsumer_ptr. + + virtual CosEventChannelAdmin::ProxyPullConsumer_ptr + obtain_pull_consumer(ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Returns a new ProxyPullConsumer_ptr. + +private: + RtecEventChannelAdmin::SupplierQOS qos_; + // The SupplierQOS specified by the user of this class. + + RtecEventChannelAdmin::SupplierAdmin_var rtec_supplieradmin_; + // The RtecEventChannelAdmin::SupplierAdmin specified by the user of + // this class. +}; + +#include /**/ "ace/post.h" +#endif /* SUPPLIER_ADMIN_I_H */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/rtec_cosec_export.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/rtec_cosec_export.h new file mode 100644 index 00000000000..4d2cbe378d2 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib/rtec_cosec_export.h @@ -0,0 +1,40 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl +// ------------------------------ +#ifndef TAO_RTEC_COSEC_EXPORT_H +#define TAO_RTEC_COSEC_EXPORT_H + +#include "ace/config-all.h" + +#if defined (TAO_AS_STATIC_LIBS) +# if !defined (TAO_RTEC_COSEC_HAS_DLL) +# define TAO_RTEC_COSEC_HAS_DLL 0 +# endif /* ! TAO_RTEC_COSEC_HAS_DLL */ +#else +# if !defined (TAO_RTEC_COSEC_HAS_DLL) +# define TAO_RTEC_COSEC_HAS_DLL 1 +# endif /* ! TAO_RTEC_COSEC_HAS_DLL */ +#endif + +#if defined (TAO_RTEC_COSEC_HAS_DLL) && (TAO_RTEC_COSEC_HAS_DLL == 1) +# if defined (TAO_RTEC_COSEC_BUILD_DLL) +# define TAO_RTEC_COSEC_Export ACE_Proper_Export_Flag +# define TAO_RTEC_COSEC_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TAO_RTEC_COSEC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* TAO_RTEC_COSEC_BUILD_DLL */ +# define TAO_RTEC_COSEC_Export ACE_Proper_Import_Flag +# define TAO_RTEC_COSEC_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TAO_RTEC_COSEC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* TAO_RTEC_COSEC_BUILD_DLL */ +#else /* TAO_RTEC_COSEC_HAS_DLL == 1 */ +# define TAO_RTEC_COSEC_Export +# define TAO_RTEC_COSEC_SINGLETON_DECLARATION(T) +# define TAO_RTEC_COSEC_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* TAO_RTEC_COSEC_HAS_DLL == 1 */ + +#endif /* TAO_RTEC_COSEC_EXPORT_H */ + +// End of auto generated file. diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Basic.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Basic.cpp new file mode 100644 index 00000000000..bd0b2585f86 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Basic.cpp @@ -0,0 +1,176 @@ +/* -*- C++ -*- */ +// $Id$ + +#include "Basic.h" +#include "CosEvent_Utilities.h" + +int +main (int argc, char *argv []) +{ + Basic basic; + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + basic.init (argc, argv ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + basic.run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + basic.shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::UserException, ue) + { + ACE_PRINT_EXCEPTION (ue, + "CosEC_Basic user exception: "); + return 1; + } + ACE_CATCH (CORBA::SystemException, se) + { + ACE_PRINT_EXCEPTION (se, + "CosEC_Basic system exception: "); + return 1; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (1); + + return 0; +} + +Basic::Basic (void) +{ + // No-Op. +} + +Basic::~Basic (void) +{ + // No-Op. +} + +void +Basic::init (int argc, char *argv[] + ACE_ENV_ARG_DECL) +{ + this->init_ORB (argc, argv ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->init_CosEC (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Basic::init_ORB (int argc, char *argv [] + ACE_ENV_ARG_DECL) +{ + this->orb_ = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n")); + + root_poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::POAManager_var poa_manager = + root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Basic::init_CosEC (ACE_ENV_SINGLE_ARG_DECL) +{ + CosEC_ServantBase *ec = 0; + + ACE_NEW_THROW_EX (ec, + CosEC_ServantBase (), + CORBA::NO_MEMORY ()); + ACE_CHECK; + + PortableServer::ServantBase_var ec_var (ec); + + ec->init (this->root_poa_.in(), + this->root_poa_.in(), + 0,0,0 + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + int retval = ec->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + if (retval == -1) + ACE_THROW (CORBA::UNKNOWN ()); + // @@ look for more descriptive exception to throw here + + CORBA::Object_var obj = + this->root_poa_->servant_to_reference (ec ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->cos_ec_ = + CosEventChannelAdmin::EventChannel::_narrow (obj._retn () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Basic::run (ACE_ENV_SINGLE_ARG_DECL) +{ + // Create an Any type to pass to the Cos EC. + CORBA::Any any; + any <<= (CORBA::Long)50; + + this->consumer_.open (this->cos_ec_.in (), + this->orb_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->consumer_.connect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_.open (this->cos_ec_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_.connect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_.send_event (any + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // this->orb_->run (); + // @@ commenting out the run-shutdown mechanism for now because it gives + // an poa "unknown location" exception otherwise. + + // wait here. + // When the consumer gets the event we pushed, it will shutdown the ORB. + // We will return from <run> then. +} + +void +Basic::shutdown (ACE_ENV_SINGLE_ARG_DECL) +{ + this->supplier_.close (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->consumer_.close (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->cos_ec_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Basic.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Basic.h new file mode 100644 index 00000000000..df713f5766f --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Basic.h @@ -0,0 +1,75 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = FILENAME +// Basic.h +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// This is a simple test class for the standard Cos Event Channel. +// +// ============================================================================ + +#ifndef COSECBASIC_H +#define COSECBASIC_H + +#include "Consumer.h" +#include "Supplier.h" + +class Basic +{ + // = TITLE + // class Basic + // + // = DESCRIPTION + // Creates a CORBA Standard Event Channel (COSEC) implemented with + // TAO's Real-time Event Channel (RtEC) and sends an event across. +public: + // = Initialization and termination methods. + Basic (void); + // Constructor. + + ~Basic (void); + // Destructor. + + void init (int argc, char *argv[] ACE_ENV_ARG_DECL); + // Starts up an ORB and the CosEC. + // Returns 0 on success, -1 on error. + + void run (ACE_ENV_SINGLE_ARG_DECL); + // Connects a consumer and a supplier to the CosEC and sends 1 event + // across. + + void shutdown (ACE_ENV_SINGLE_ARG_DECL); + // Closes down the CosEC. + +private: + void init_ORB (int argc, char *argv[] ACE_ENV_ARG_DECL); + // initializes the ORB. + // Returns 0 on success, -1 on error. + + void init_CosEC (ACE_ENV_SINGLE_ARG_DECL); + // initializes the COS EC. + // Returns 0 on success, -1 on error. + + CORBA::ORB_var orb_; + // The ORB that we use. + + PortableServer::POA_var root_poa_; + // The root poa. + + CosEventChannelAdmin::EventChannel_var cos_ec_; + // Reference to the CosEC returned after activating it in the ORB. + + Consumer consumer_; + // The Cos Consumer that will receive the event. + + Supplier supplier_; + // The Cos Supplier that will supply the event. +}; + +#endif /* COSECBASIC_H */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Consumer.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Consumer.cpp new file mode 100644 index 00000000000..03259f3a123 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Consumer.cpp @@ -0,0 +1,96 @@ +/* -*- C++ -*- */ +// $Id$ + +#include "Consumer.h" + +void +Consumer::open (CosEventChannelAdmin::EventChannel_ptr event_channel, + CORBA::ORB_ptr orb + ACE_ENV_ARG_DECL) +{ + this->orb_ = orb; + + // = Connect as a consumer. + this->consumer_admin_ = + event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Consumer::close (ACE_ENV_SINGLE_ARG_DECL) +{ + this->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->consumer_admin_ = + CosEventChannelAdmin::ConsumerAdmin::_nil (); +} + +void +Consumer::connect (ACE_ENV_SINGLE_ARG_DECL) +{ + if (CORBA::is_nil (this->consumer_admin_.in ())) + return; + + CosEventComm::PushConsumer_var objref = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_proxy_ = + this->consumer_admin_->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_proxy_->connect_push_consumer (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + if (CORBA::is_nil (this->supplier_proxy_.in ()) + || CORBA::is_nil (this->consumer_admin_.in ())) + return; + + this->supplier_proxy_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_proxy_ = + CosEventChannelAdmin::ProxyPushSupplier::_nil (); +} + +void +Consumer::push (const CORBA::Any & + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )) +{ + ACE_DEBUG ((LM_DEBUG, + "in Consumer::push\n")); + // this->orb_->shutdown (); + // @@ read comment in run +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + // Deactivate this object. + + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ObjectId_var id = + poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + poa->deactivate_object (id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Consumer.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Consumer.h new file mode 100644 index 00000000000..c1ced5cbc08 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Consumer.h @@ -0,0 +1,75 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = FILENAME +// Consumer.h +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// Defines a simple Push Consumer. +// +// ============================================================================ + +#ifndef COSECCONSUMER_H_ +#define COSECCONSUMER_H_ + +#include "orbsvcs/CosEventCommC.h" +#include "orbsvcs/CosEventChannelAdminC.h" +#include "orbsvcs/CosEventCommS.h" +#include "orbsvcs/CosEventChannelAdminS.h" + +class Consumer : public POA_CosEventComm::PushConsumer +{ + // = TITLE + // Consumer + // + // = DESCRIPTION + // The Consumer is a simple PushConsumer that connects to the + // CosEC and receives events from it. + +public: + void open (CosEventChannelAdmin::EventChannel_ptr event_channel, + CORBA::ORB_ptr orb + ACE_ENV_ARG_DECL); + // This method connects the consumer to the EC. + + void close (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the EC. + + void connect (ACE_ENV_SINGLE_ARG_DECL); + // Connect the Consumer to the EventChannel. + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the supplier, but do not forget about it or close + // it. + + virtual void push (const CORBA::Any &data + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )); + // push the event to the consumer. + + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + // disconnect the consumer from the EC. + +private: + CORBA::ORB_var orb_; + // The orb that we as using. + + CosEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_; + // We talk to the EC using this proxy. + + CosEventChannelAdmin::ConsumerAdmin_var consumer_admin_; + // We talk to the EC using this proxy. +}; + +#endif /* COSECCONSUMER_H_ */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/CosEC_RtEC_Based_tests_Basic.mpc b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/CosEC_RtEC_Based_tests_Basic.mpc new file mode 100644 index 00000000000..d3d306ab424 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/CosEC_RtEC_Based_tests_Basic.mpc @@ -0,0 +1,15 @@ +// -*- MPC -*- +// $Id$ + +project(*Client) : orbsvcsexe, event, event_skel, rtevent_serv, rtsched { + after += CosEC_RtEC_Based_lib + libs += CosEC_RtEC_Based + + specific (automake) { + includes += $(srcdir)/../../lib + } else { + includes += ../../lib + } + + libpaths += ../../lib +} diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Makefile.am b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Makefile.am new file mode 100644 index 00000000000..cd377c8edb7 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Makefile.am @@ -0,0 +1,72 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.CosEC_RtEC_Based_Tests_Basic_Client.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS = Basic + +Basic_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(srcdir)/../../lib \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Basic_SOURCES = \ + Basic.cpp \ + Consumer.cpp \ + Supplier.cpp \ + Basic.h \ + Consumer.h \ + Supplier.h + +Basic_LDADD = \ + $(top_builddir)/orbsvcs/examples/CosEC/RtEC_Based/lib/libCosEC_RtEC_Based.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTSched.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/README b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/README new file mode 100644 index 00000000000..291ec0fa208 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/README @@ -0,0 +1,26 @@ +$Id$ + +The Cos_ECBasic test shows how to: + + . Create a standard Cos Event Channel, + . Write simple COS compliant consumers and suppliers, + . Connect consumers and suppliers to the COSEC, + . Send and receive events form the EC. + +For initialization, the CosEC_Basic test first creates and initializes +a TAO real-time EC (Rtec). Then, it initializes QOS parameters for +the Supplier and Consumers and then initializes a COSEC (Corba Object +Service compliant Event Channel). + +To test the COSEC the test initializes a Supplier and a Consumer , +connects them to the COSEC. The Supplier then sends an event to the +channel which is delivered to the Consumer via the <push> method. +This method then prints a message to show that an event was delivered +to the Consumer. + +Finally the Rtec and COSEC are shutdown to finish the test. + +NOTE: please do not attempt to compile this test till I've integrated +the COSEC code into orbsvcs. + +- Pradeep <pradeep@cs.wustl.edu> diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Supplier.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Supplier.cpp new file mode 100644 index 00000000000..59cfc9cd251 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Supplier.cpp @@ -0,0 +1,86 @@ +/* -*- C++ -*- */ +// $Id$ + +#include "Supplier.h" + +void +Supplier::open (CosEventChannelAdmin::EventChannel_ptr event_channel + ACE_ENV_ARG_DECL) +{ + // = Connect as a consumer. + this->supplier_admin_ = + event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::close (ACE_ENV_SINGLE_ARG_DECL) +{ + this->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_admin_ = + CosEventChannelAdmin::SupplierAdmin::_nil (); +} + +void +Supplier::connect (ACE_ENV_SINGLE_ARG_DECL) +{ + if (CORBA::is_nil (this->supplier_admin_.in ())) + return; + + this->consumer_proxy_ = + this->supplier_admin_->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosEventComm::PushSupplier_var objref = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->consumer_proxy_->connect_push_supplier (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + if (CORBA::is_nil (this->consumer_proxy_.in ()) + || CORBA::is_nil (this->supplier_admin_.in ())) + return; + + this->consumer_proxy_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->consumer_proxy_ = + CosEventChannelAdmin::ProxyPushConsumer::_nil (); +} + +void +Supplier::send_event (const CORBA::Any & data + ACE_ENV_ARG_DECL) +{ + this->consumer_proxy_->push (data ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + // Deactivate this object. + + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ObjectId_var id = + poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + poa->deactivate_object (id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Supplier.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Supplier.h new file mode 100644 index 00000000000..413244fc4f4 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Basic/Supplier.h @@ -0,0 +1,64 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = FILENAME +// Supplier.h +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// Defines a simple Push Supplier. +// +// ============================================================================ + +#ifndef COSECSUPPLIER_H_ +#define COSECSUPPLIER_H_ + +#include "orbsvcs/CosEventCommC.h" +#include "orbsvcs/CosEventChannelAdminC.h" +#include "orbsvcs/CosEventCommS.h" +#include "orbsvcs/CosEventChannelAdminS.h" + +class Supplier : public POA_CosEventComm::PushSupplier +{ + // = TITLE + // Supplier + // + // = DESCRIPTION + // The Supplier is a simple Push Supplier that connects to + // the CosEC and sends events to it. +public: + void open (CosEventChannelAdmin::EventChannel_ptr event_channel + ACE_ENV_ARG_DECL); + // This method connects the supplier to the EC. + + void close (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the EC. + + void connect (ACE_ENV_SINGLE_ARG_DECL); + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the EC, but do not forget about it or close it. + + void send_event (const CORBA::Any &data + ACE_ENV_ARG_DECL); + // Send one event. + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + // The POA_CosEventComm::PushSupplier method. + +private: + CosEventChannelAdmin::ProxyPushConsumer_var consumer_proxy_; + // We talk to the EC using this proxy. + + CosEventChannelAdmin::SupplierAdmin_var supplier_admin_; + // We talk to the EC using this proxy. +}; + +#endif /* COSECSUPPLIER_H_ */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Makefile.am b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Makefile.am new file mode 100644 index 00000000000..6e509ce0f24 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Makefile.am @@ -0,0 +1,14 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + Basic \ + Multiple + diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Consumer.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Consumer.cpp new file mode 100644 index 00000000000..9cdb697eff1 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Consumer.cpp @@ -0,0 +1,197 @@ +/* -*- C++ -*- */ +// $Id$ + +#include "Consumer.h" +#include "ace/Get_Opt.h" + +Consumer::Consumer () + :event_count_ (1) +{ + // No-Op. +} + +int +Consumer::parse_args (int argc, char *argv []) +{ + ACE_Get_Opt get_opt (argc, argv, "n:c:"); + int opt; + + while ((opt = get_opt ()) != EOF) + { + switch (opt) + { + case 'n': + this->service_name = get_opt.opt_arg (); + break; + + case 'c': + this->event_count_ = ACE_OS::atoi (get_opt.opt_arg ()); + break; + + case '?': + default: + ACE_DEBUG ((LM_DEBUG, + "Usage: %s " + " -n <COS Event Service name>" + " -c event_count" + " \n", + argv[0])); + return -1; + } + } + + return 0; +} + +void +Consumer::open (CosEventChannelAdmin::EventChannel_ptr event_channel + ACE_ENV_ARG_DECL) +{ + // = Connect as a consumer. + this->consumer_admin_ = + event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Consumer::close (ACE_ENV_SINGLE_ARG_DECL) +{ + this->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->consumer_admin_ = + CosEventChannelAdmin::ConsumerAdmin::_nil (); +} + +void +Consumer::connect (ACE_ENV_SINGLE_ARG_DECL) +{ + if (CORBA::is_nil (this->consumer_admin_.in ())) + return; + + CosEventComm::PushConsumer_var objref = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_proxy_ = + this->consumer_admin_->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_proxy_->connect_push_consumer (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + if (CORBA::is_nil (this->supplier_proxy_.in ()) + || CORBA::is_nil (this->consumer_admin_.in ())) + return; + + this->supplier_proxy_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_proxy_ = + CosEventChannelAdmin::ProxyPushSupplier::_nil (); +} + +void +Consumer::push (const CORBA::Any & + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )) +{ + ACE_DEBUG ((LM_DEBUG, + "(%P):%s\n", + " - In Consumer::push")); + + ACE_DEBUG ((LM_DEBUG, + "Event count = %d\n", + this->event_count_)); + + this->event_count_ = this->event_count_ - 1; + // decrement the count + + if (this->event_count_ == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P):%s\n", + "exiting the consumer.")); + + this->close (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->shutdown (); + } +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + // Deactivate this object. + + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ObjectId_var id = + poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + poa->deactivate_object (id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +int +Consumer::init_Consumer (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->open (this->cos_ec_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->connect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Exception in Consumer::connect (void)\n"); + return -1; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (-1); + + return 0; +} + +int +main (int argc, char *argv[]) +{ + Consumer cons; + + if (cons.init (argc, argv) == -1) + return 1; + + if (cons.init_Consumer () == -1) + return 1; + + ACE_DEBUG ((LM_DEBUG, + "(%P): %s\n", "Started the consumer..")); + + cons.runORB (); + + cons.shutdown (); + + return 0; +} diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Consumer.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Consumer.h new file mode 100644 index 00000000000..ce523fed960 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Consumer.h @@ -0,0 +1,86 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = FILENAME +// Consumer.h +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// Defines a simple Push Consumer. +// +// ============================================================================ + +#ifndef COSECCONSUMER_H_ +#define COSECCONSUMER_H_ + +#include "orbsvcs/CosEventCommC.h" +#include "orbsvcs/CosEventChannelAdminC.h" +#include "orbsvcs/CosEventCommS.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "Multiple.h" + +class Consumer : public POA_CosEventComm::PushConsumer, public Multiple +{ + // = TITLE + // Consumer + // + // = DESCRIPTION + // The Consumer is a simple PushConsumer that connects to the + // CosEC and receives events from it. + +public: + // = Initializatiopn and termination methods. + Consumer (); + // Constructor. + + int init_Consumer (void); + // Initialize the Consumer. + + void open (CosEventChannelAdmin::EventChannel_ptr event_channel + ACE_ENV_ARG_DECL); + // This method connects the consumer to the EC. + + void close (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the EC. + + void connect (ACE_ENV_SINGLE_ARG_DECL); + // Connect the Consumer to the EventChannel. + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the supplier, but do not forget about it or close + // it. + + virtual void push (const CORBA::Any &data + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )); + // push the event to the consumer. + + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + // disconnect the consumer from the EC. + + // = CosEC_Multiple methods. + virtual int parse_args (int argc, char *argv []); + // Parse the command line options. + +private: + CosEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_; + // We talk to the EC using this proxy. + + CosEventChannelAdmin::ConsumerAdmin_var consumer_admin_; + // We talk to the EC using this proxy. + + int event_count_; + // The number of Events to receive before switching off. +}; + +#endif /* COSECCONSUMER_H_ */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/CosEC_RtEC_Based_Mult.mpc b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/CosEC_RtEC_Based_Mult.mpc new file mode 100644 index 00000000000..8b13ff7e584 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/CosEC_RtEC_Based_Mult.mpc @@ -0,0 +1,36 @@ +// -*- MPC -*- +// $Id$ + +project(*Cons) : orbsvcsexe, event, event_skel, rtevent, rtsched, rtevent_serv { + after += CosEC_RtEC_Based_lib + libs += CosEC_RtEC_Based + libpaths += ../../lib + + specific (automake) { + includes += $(srcdir)/../../lib + } else { + includes += ../../lib + } + + source_files { + Consumer.cpp + Multiple.cpp + } +} + +project(*Supp) : orbsvcsexe, event, event_skel, rtevent, rtsched, rtevent_serv { + after += CosEC_RtEC_Based_lib + libs += CosEC_RtEC_Based + libpaths += ../../lib + + specific (automake) { + includes += $(srcdir)/../../lib + } else { + includes += ../../lib + } + + source_files { + Supplier.cpp + Multiple.cpp + } +} diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Makefile.am b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Makefile.am new file mode 100644 index 00000000000..40a10fb6254 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Makefile.am @@ -0,0 +1,118 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.CosEC_RtEC_Based_Mult_Cons.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Consumer + +Consumer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(srcdir)/../../lib \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Consumer_SOURCES = \ + Consumer.cpp \ + Multiple.cpp \ + Consumer.h \ + Multiple.h + +Consumer_LDADD = \ + $(top_builddir)/orbsvcs/examples/CosEC/RtEC_Based/lib/libCosEC_RtEC_Based.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTSched.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Makefile.CosEC_RtEC_Based_Mult_Supp.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Supplier + +Supplier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(srcdir)/../../lib \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Supplier_SOURCES = \ + Multiple.cpp \ + Supplier.cpp \ + Multiple.h \ + Supplier.h + +Supplier_LDADD = \ + $(top_builddir)/orbsvcs/examples/CosEC/RtEC_Based/lib/libCosEC_RtEC_Based.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTSched.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Multiple.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Multiple.cpp new file mode 100644 index 00000000000..4af0b93b9aa --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Multiple.cpp @@ -0,0 +1,151 @@ +// $Id$ + +#include "Multiple.h" + +Multiple::Multiple (void) + : cos_ec_ (CosEventChannelAdmin::EventChannel::_nil ()), + service_name ("CosEventService"), + orb_ (CORBA::ORB::_nil ()) +{ + // No-Op. +} + + +Multiple::~Multiple (void) +{ + // No-Op. +} + +int +Multiple::init (int argc, char *argv[]) +{ + if (init_ORB (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "init_ORB returned error.\n"), + -1); + + if (this->parse_args (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "parse error returned error.\n"), + -1); + + if (init_CosEC () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "init_CosEC returned error.\n"), + -1); + return 0; +} + +int +Multiple::init_ORB (int argc, char *argv []) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->orb_ = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + -1); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Exception in Multiple::init_ORB\n"); + return -1; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (-1); + + return 0; +} + +int +Multiple::init_CosEC (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // Initialization of the naming service. + if (this->naming_client_.init (this->orb_.in ()) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) Unable to initialize " + "the TAO_Naming_Client. \n"), + -1); + + CosNaming::Name ec_ref_name (1); + ec_ref_name.length (1); + ec_ref_name[0].id = + CORBA::string_dup (this->service_name); + + CORBA::Object_var EC_obj = + this->naming_client_->resolve (ec_ref_name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The CORBA::Object_var object is downcast to + // CosEventChannelAdmin::EventChannel + // using the <_narrow> method. + this->cos_ec_ = + CosEventChannelAdmin::EventChannel::_narrow (EC_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Exception in Multiple::init_ORB\n"); + return -1; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (-1); + + return 0; +} + +int +Multiple::runORB (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->orb_->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "run"), 1); + } + ACE_ENDTRY; + + return 0; +} + +void +Multiple::shutdown (void) +{ + if (!this->orb_->_nil ()) + this->orb_->shutdown (); +} diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Multiple.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Multiple.h new file mode 100644 index 00000000000..3248946ce78 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Multiple.h @@ -0,0 +1,79 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = FILENAME +// Multiple.h +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// This is a test class for the Cos Event Service. +// +// ============================================================================ + +#ifndef COSECMULTIPLE_H +#define COSECMULTIPLE_H + +#include "orbsvcs/Naming/Naming_Client.h" +#include "orbsvcs/Naming/Naming_Server.h" +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/CosEventChannelAdminC.h" + +class Multiple +{ + public: + // = TITLE + // class Multiple + // + // = DESCRIPTION + // Base class for suppliers and consumers to send/receive events + // via the Cos Event Service. + public: + // = Initialization and termination methods. + Multiple (void); + // Constructor. + + virtual ~Multiple (void); + // Destructor. + + int init (int argc, char *argv[]); + // Calls parse_args, Starts up an ORB, gets hold of the Event Service. + // Returns 0 on success, -1 on error. + + int runORB (void); + // Calls the ORB's <run> method. + + void shutdown (void); + // Closes down the ORB and exits. + + protected: + virtual int parse_args (int argc, char *argv []) = 0; + // Parse the command line arguments. + + CosEventChannelAdmin::EventChannel_ptr cos_ec_; + // Reference to a running Event Service. + + const char* service_name; +// The name with which to locate the Event Service. + + private: + int init_ORB (int argc, char *argv[]); + // initializes the ORB. + // Returns 0 on success, -1 on error. + + int init_CosEC (void); + // initializes the COS EC. + // Returns 0 on success, -1 on error. + + CORBA::ORB_var orb_; + // The ORB that we use. + + TAO_Naming_Client naming_client_; + // An instance of the name client used for resolving the factory + // objects. +}; + +#endif /* COSECMULTIPLE_H */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/README b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/README new file mode 100644 index 00000000000..6b6d90cb706 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/README @@ -0,0 +1,77 @@ + CosEC_Multiple +------------------------------------------------------------------------ +This test for the Cos Event Service has 2 executables - one for suppliers +and the other for consumers. +Both connect to a running Event Service. + +To run a test manually: +1. Start one or more consumers. +2. Run a Supplier, the consumer displays the data received. + +The command line parameters for the Supplier are: + -n <Name of the Event Service>,the default name is "CosEventService" + + -c <event_count>, number of events to send to the CosEC. + +The command line parameters for the Consumer are: + -n <Name of the Event Service>,the default name is "CosEventService" + + -c <event_count>, number of events to receive from the CosEC. + +------------------------------------------------------------------------ +Test Scripts: + +run_test.pl - Event filtering using the RtEC. + +This test starts up 2 CosEC's connected to one RtEC as shown.. + + --------- + | RtEC | + --------- + | + | + ________|____________ + | | + ____|____ ____|____ + | CosEC1 | | CosEC2 | + "cosec1" _________ _________ "cosec2" + | | + _____|________ _____|_______ + | | | | + consumerA supplierB consumerB supplierA + +The CosEC1 (see fig.) is setup with these parameters: +# cos event service name = "cosec1" +# for ConsumerQOS: EventID = 21, SourceID = 6 +# for SupplierQOS: EventID = 20, SourceID = 5 + +The CosEC2 (see fig.) is setup with these parameters: +# cos event service name = "cosec2" +# for ConsumerQOS: EventID = 20, SourceID = 5 +# for SupplierQOS: EventID = 21, SourceID = 6 + +This setup configures the CosEC's such that consumerA connected to CosEC1 receives events from supplierA connected to CosEC2. +similarly, consumerB and supplierB form the other pair. + +Parameters: + +-e event_count, The number of events supplied by each supplier + and also the number of events that a consumer will count + before shutting down. + +To execute this test, run the run_test.pl script. + +------------------------------------------------------------------------ +run_test2.pl: demostrates multiple consumers and suppliers connected +to one CosEC. +This test has the following params - + +-e event_count, The number of events supplied by each supplier + and also the number of events that a consumer will count + before shutting down. + +-c consumers, The number of consumers to connect the Event service. + +-s suppliers, The number of suppliers to connect the Event service. + +------------------------------------------------------------------------ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Supplier.cpp b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Supplier.cpp new file mode 100644 index 00000000000..7d9a03c9261 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Supplier.cpp @@ -0,0 +1,185 @@ +/* -*- C++ -*- */ +// $Id$ + +#include "Supplier.h" +#include "ace/Get_Opt.h" + +Supplier::Supplier () + : event_count_ (1) +{ + // No-Op. +} + +int +Supplier::parse_args (int argc, char *argv []) +{ + ACE_Get_Opt get_opt (argc, argv, "n:c:"); + int opt; + + while ((opt = get_opt ()) != EOF) + { + switch (opt) + { + case 'n': + this->service_name = get_opt.opt_arg (); + break; + + case 'c': + this->event_count_ = ACE_OS::atoi (get_opt.opt_arg ()); + break; + + case '?': + default: + ACE_DEBUG ((LM_DEBUG, + "Usage: %s " + " -n <COS Event Service name>" + " \n", + argv[0])); + return -1; + } + } + + return 0; +} + +void +Supplier::open (CosEventChannelAdmin::EventChannel_ptr event_channel + ACE_ENV_ARG_DECL) +{ + // = Connect as a consumer. + this->supplier_admin_ = + event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::close (ACE_ENV_SINGLE_ARG_DECL) +{ + this->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_admin_ = + CosEventChannelAdmin::SupplierAdmin::_nil (); +} + +void +Supplier::connect (ACE_ENV_SINGLE_ARG_DECL) +{ + if (CORBA::is_nil (this->supplier_admin_.in ())) + return; + + this->consumer_proxy_ = + this->supplier_admin_->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosEventComm::PushSupplier_var objref = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->consumer_proxy_->connect_push_supplier (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + if (CORBA::is_nil (this->consumer_proxy_.in ()) + || CORBA::is_nil (this->supplier_admin_.in ())) + return; + + this->consumer_proxy_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->consumer_proxy_ = + CosEventChannelAdmin::ProxyPushConsumer::_nil (); +} + +void +Supplier::send_event (const CORBA::Any & data + ACE_ENV_ARG_DECL) +{ + this->consumer_proxy_->push (data ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + // Deactivate this object. + + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ObjectId_var id = + poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + poa->deactivate_object (id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::run (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // Create an Any type to pass to the Cos EC. + CORBA::Any any; + any <<= CORBA::Long (50); + + this->open (this->cos_ec_ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->connect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "(%P):sending %d events...\n", + this->event_count_)); + + for (int count = this->event_count_; + count != 0; + count--) + { + this->send_event (any + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + ACE_DEBUG ((LM_DEBUG, + "(%P):Done!. exiting now..\n")); + + this->close (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Exception in CosEC_Multiple::run\n"); + } + ACE_ENDTRY; + ACE_CHECK; +} + +int +main (int argc, char *argv[]) +{ + Supplier supp; + + if (supp.init (argc, argv) == -1) + return 1; + + supp.run (); + + supp.shutdown (); + + return 0; +} diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Supplier.h b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Supplier.h new file mode 100644 index 00000000000..29b213cd31f --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/Supplier.h @@ -0,0 +1,79 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = FILENAME +// Supplier.h +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// = DESCRIPTION +// Defines a simple Push Supplier. +// +// ============================================================================ + +#ifndef COSECSUPPLIER_H_ +#define COSECSUPPLIER_H_ + +#include "orbsvcs/CosEventCommC.h" +#include "orbsvcs/CosEventChannelAdminC.h" +#include "orbsvcs/CosEventCommS.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "Multiple.h" + +class Supplier : public POA_CosEventComm::PushSupplier, + public Multiple +{ + // = TITLE + // Supplier + // + // = DESCRIPTION + // The Supplier is a simple Push Supplier that connects to + // the CosEC and sends events to it. +public: + // = Initializatiopn and termination methods. + Supplier (); + // Constructor. + + void open (CosEventChannelAdmin::EventChannel_ptr event_channel + ACE_ENV_ARG_DECL); + // This method connects the supplier to the EC. + + void close (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the EC. + + void connect (ACE_ENV_SINGLE_ARG_DECL); + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the EC, but do not forget about it or close it. + + void send_event (const CORBA::Any &data + ACE_ENV_ARG_DECL); + // Send one event. + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + // The POA_CosEventComm::PushSupplier method. + + void run (void); + // Sends the events to the EC. + + // = Multiple methods. + virtual int parse_args (int argc, char *argv []); + // Parses the command line arguments. +private: + CosEventChannelAdmin::ProxyPushConsumer_var consumer_proxy_; + // We talk to the EC using this proxy. + + CosEventChannelAdmin::SupplierAdmin_var supplier_admin_; + // We talk to the EC using this proxy. + + int event_count_; + // The number of Events to send to the EC. +}; + +#endif /* COSECSUPPLIER_H_ */ diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/run_test.pl b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/run_test.pl new file mode 100755 index 00000000000..6e98ae48afb --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/run_test.pl @@ -0,0 +1,178 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "../../../../../../../bin"; +use PerlACE::Run_Test; + +#event count +$ev_count = 20; +$status = 0; + +# setup CosEC params such that.. +# cos event service name = "cosec1" +# for ConsumerQOS: EventID = 21, SourceID = 6 +# for SupplierQOS: EventID = 20, SourceID = 5. +$CosEC1_params = "-n cosec1 -e 21 -o 6 -p \"5 20\""; + +# setup another CosEC params such that.. +# cos event service name = "cosec2" +# for ConsumerQOS: EventID = 20, SourceID = 5 +# for SupplierQOS: EventID = 21, SourceID = 6. +$CosEC2_params = "-n cosec2 -e 20 -o 5 -p \"6 21\""; + +$nsior = PerlACE::LocalFile ("ns.ior"); + +unlink $nsior; + +# Parse the arguments + +for ($i = 0; $i <= $#ARGV; $i++) { + if ($ARGV[$i] eq "-h" || $ARGV[$i] eq "-?") { + print "usage: run_test.pl -e event_count -h help\n"; + exit; + } + elsif ($ARGV[$i] eq "-e") { + $ev_count = $ARGV[$i + 1]; + $i++; + } +} + +$NS = new PerlACE::Process ("../../../../../Naming_Service/Naming_Service", + "-o $nsior"); + +$EC = new PerlACE::Process ("../../../../../Event_Service/Event_Service", + "-t new -ORBInitRef NameService=file://$nsior"); + +$CE1 = new PerlACE::Process ("../../bin/RtEC_Based_CosEC", + "-ORBInitRef NameService=file://$nsior $CosEC1_params"); + +$CE2 = new PerlACE::Process ("../../bin/RtEC_Based_CosEC", + "-ORBInitRef NameService=file://$nsior $CosEC2_params"); + +$CO1 = new PerlACE::Process ("Consumer", + "-ORBInitRef NameService=file://$nsior -n cosec1 -c $ev_count"); + +$SU1 = new PerlACE::Process ("Supplier", + "-ORBInitRef NameService=file://$nsior -n cosec2 -c $ev_count"); + +$CO2 = new PerlACE::Process ("Consumer", + "-ORBInitRef NameService=file://$nsior -n cosec2 -c $ev_count"); + +$SU2 = new PerlACE::Process ("Supplier", + "-ORBInitRef NameService=file://$nsior -n cosec1 -c $ev_count"); + +# first start the Naming service.. +$NS->Spawn (); + +sleep 10; + +# now start the Rt EC.. +$EC->Spawn (); + +sleep 10; + +# now start the CosEC1.. +$CE1->Spawn (); + +sleep 10; + +# now start the CosEC2.. +$CE2->Spawn (); + +sleep 10; + +# start 1 consumer that uses CosEC1 to receive events +$CO1->Spawn (); + +sleep 10; + +# start 1 supplier that uses CosEC2 to send events +$SU1->Spawn (); + +sleep 10; + +# wait for the supplier to finish +$supplier = $SU1->WaitKill (60); + +if ($supplier != 0) { + print STDERR "ERROR: supplier returned $supplier\n"; + $status = 1; +} + +# wait for the consumer to finish +$consumer = $CO1->WaitKill (60); + +if ($consumer != 0) { + print STDERR "ERROR: consumer returned $consumer\n"; + $status = 1; +} + +#---------- + +# start 1 consumer that uses CosEC1 to receive events +$CO2->Spawn (); + +sleep 10; + +# start 1 supplier that uses CosEC2 to send events +$SU2->Spawn (); + +sleep 10; + +# wait for the supplier to finish +$supplier = $SU2->WaitKill (60); + +if ($supplier != 0) { + print STDERR "ERROR: supplier returned $supplier\n"; + $status = 1; +} + +# wait for the consumer to finish + +$consumer = $CO2->WaitKill (60); + +if ($consumer != 0) { + print STDERR "ERROR: consumer returned $consumer\n"; + $status = 1; +} + + +#---------- + +# cleanup.. + +$server = $CE2->TerminateWaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: CosEC2 returned $server\n"; + $status = 1; +} + +$CE1->TerminateWaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: CosEC1 returned $server\n"; + $status = 1; +} + +$EC->TerminateWaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: EC returned $server\n"; + $status = 1; +} + +$NS->TerminateWaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: NS returned $server\n"; + $status = 1; +} + +unlink $nsior; + +exit $status; diff --git a/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/run_test2.pl b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/run_test2.pl new file mode 100755 index 00000000000..90852c11c68 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/RtEC_Based/tests/Multiple/run_test2.pl @@ -0,0 +1,133 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "../../../../../../../bin"; +use PerlACE::Run_Test; + +$con_count = 10; +$sup_count = 10; +$ev_count = 8; +$status = 0; + +$nsior = PerlACE::LocalFile ("ns.ior"); + +unlink $nsior; + +# Parse the arguments + +for ($i = 0; $i <= $#ARGV; $i++) { + if ($ARGV[$i] eq "-h" || $ARGV[$i] eq "-?") { + print "usage: run_test2.pl -e event_count -c consumers -s suppliers -h help\n"; + exit; + } + elsif ($ARGV[$i] eq "-e") { + $ev_count = $ARGV[$i + 1]; + $i++; + } + elsif ($ARGV[$i] eq "-c") { + $con_count = $ARGV[$i + 1]; + $i++; + } + elsif ($ARGV[$i] eq "-s") { + $sup_count = $ARGV[$i + 1]; + $i++; + } +} + +$NS = new PerlACE::Process ("../../../../../Naming_Service/Naming_Service", + "-o $nsior"); + +$EC = new PerlACE::Process ("../../../../../Event_Service/Event_Service", + "-t new -ORBInitRef NameService=file://$nsior"); + +$CE1 = new PerlACE::Process ("../../bin/RtEC_Based_CosEC", + "-ORBInitRef NameService=file://$nsior"); + +for ($cntr1 = 0; $cntr1 < $con_count ; ++$cntr1) { + push @CONS, (new PerlACE::Process ("Consumer", "-ORBInitRef NameService=file://$nsior -c $ev_count")); +} + +for ($cntr2 = 0; $cntr2 < $con_count ; ++$cntr2) { + push @SUPS, (new PerlACE::Process ("Supplier", "-ORBInitRef NameService=file://$nsior -c $ev_count")); +} + +# first start the Naming service.. +$NS->Spawn (); + +sleep 10; + +# now start the Rt EC.. +$EC->Spawn (); + +sleep 10; + +# now start the CosEC1.. +$CE1->Spawn (); + +sleep 10; + +# now start the consumers +foreach $co (@CONS) { + print "creating consumer# $cntr1\n"; + $co->Spawn (); + sleep 10; +} + +# now start the suppliers +foreach $su (@SUPS) { + print "creating supplier# $cntr2\n"; + $su->Spawn (); + sleep 10; +} + +print "waiting for the suppliers to finish\n"; +foreach $su (@SUPS) { + $supplier = $su->WaitKill (60); + + if ($supplier != 0) { + print STDERR "ERROR: A supplier returned $supplier\n"; + $status = 1; + } +} + + +print "waiting for the last consumer to finish\n"; +foreach $co (@CONS) { + $consumer = $co->WaitKill (60); + + if ($consumer != 0) { + print STDERR "ERROR: A consumer returned $consumer\n"; + $status = 1; + } +} + +print "cleanup...\n"; +$CE1->TerminateWaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: CosEC1 returned $server\n"; + $status = 1; +} + +$EC->TerminateWaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: EC returned $server\n"; + $status = 1; +} + +$NS->TerminateWaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: NS returned $server\n"; + $status = 1; +} +print "done!.\n"; + +unlink $nsior; + +exit $status; diff --git a/TAO/orbsvcs/examples/CosEC/Simple/Consumer.cpp b/TAO/orbsvcs/examples/CosEC/Simple/Consumer.cpp new file mode 100644 index 00000000000..bcf4fcfc551 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Simple/Consumer.cpp @@ -0,0 +1,130 @@ +// $Id$ + +#include "Consumer.h" +#include "orbsvcs/CosEventChannelAdminS.h" + +ACE_RCSID (CosEC_Examples, + Consumer, + "$Id$") + +int +main (int argc, char* argv[]) +{ + Consumer consumer; + + return consumer.run (argc, argv); +} + +// **************************************************************** + +Consumer::Consumer (void) + : event_count_ (0) +{ +} + +int +Consumer::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Do *NOT* make a copy because we don't want the ORB to outlive + // the Consumer object. + this->orb_ = orb.in (); + + if (argc <= 1) + { + ACE_ERROR ((LM_ERROR, + "Usage: Consumer <event_channel_ior>\n")); + return 1; + } + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel, we could use a naming service, a + // command line argument or resolve_initial_references(), but + // this is simpler... + object = + orb->string_to_object (argv[1] ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosEventChannelAdmin::EventChannel_var event_channel = + CosEventChannelAdmin::EventChannel::_narrow (object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The canonical protocol to connect to the EC + CosEventChannelAdmin::ConsumerAdmin_var consumer_admin = + event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosEventChannelAdmin::ProxyPushSupplier_var supplier = + consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosEventComm::PushConsumer_var consumer = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + supplier->connect_push_consumer (consumer.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Wait for events, using work_pending()/perform_work() may help + // or using another thread, this example is too simple for that. + orb->run (); + + // We don't do any cleanup, it is hard to do it after shutdown, + // and would complicate the example; plus it is almost + // impossible to do cleanup after ORB->run() because the POA is + // in the holding state. Applications should use + // work_pending()/perform_work() to do more interesting stuff. + // Check the supplier for the proper way to do cleanup. + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Consumer::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Consumer::push (const CORBA::Any & + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->event_count_ ++; + if (this->event_count_ % 100 == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t): %d events received\n", + this->event_count_)); + } +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // In this example we shutdown the ORB when we disconnect from the + // EC (or rather the EC disconnects from us), but this doesn't have + // to be the case.... + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} + diff --git a/TAO/orbsvcs/examples/CosEC/Simple/Consumer.h b/TAO/orbsvcs/examples/CosEC/Simple/Consumer.h new file mode 100644 index 00000000000..7156353e483 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Simple/Consumer.h @@ -0,0 +1,59 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS COS Event Channel examples +// +// = FILENAME +// Consumer +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef CONSUMER_H +#define CONSUMER_H + +#include "orbsvcs/CosEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Consumer : public POA_CosEventComm::PushConsumer +{ + // = TITLE + // Simple consumer object + // + // = DESCRIPTION + // This class is a consumer of events. + // +public: + Consumer (void); + // Constructor + + int run (int argc, char* argv[]); + // Run the test + + // = The CosEventComm::PushConsumer methods + + virtual void push (const CORBA::Any &event + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: + CORBA::ULong event_count_; + // Keep track of the number of events received. + + CORBA::ORB_ptr orb_; + // The orb, just a pointer because the ORB does not outlive the + // run() method... +}; + +#endif /* CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/CosEC/Simple/CosEC_Simple.mpc b/TAO/orbsvcs/examples/CosEC/Simple/CosEC_Simple.mpc new file mode 100644 index 00000000000..7a91454ad07 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Simple/CosEC_Simple.mpc @@ -0,0 +1,20 @@ +// -*- MPC -*- +// $Id$ + +project(*Service) : orbsvcsexe, event, event_serv, naming { + Source_Files { + Service.cpp + } +} + +project(*Consumer) : orbsvcsexe, event, event_skel { + Source_Files { + Consumer.cpp + } +} + +project(*Supplier) : orbsvcsexe, event, event_skel { + Source_Files { + Supplier.cpp + } +} diff --git a/TAO/orbsvcs/examples/CosEC/Simple/Makefile.am b/TAO/orbsvcs/examples/CosEC/Simple/Makefile.am new file mode 100644 index 00000000000..9938d9c430d --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Simple/Makefile.am @@ -0,0 +1,123 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.CosEC_Simple_Consumer.am + +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Consumer + +Consumer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Consumer_SOURCES = \ + Consumer.cpp \ + Consumer.h + +Consumer_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA + +## Makefile.CosEC_Simple_Service.am + +if BUILD_CORBA_MESSAGING +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Service + +Service_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Service_SOURCES = \ + Service.cpp \ + Consumer.h \ + Supplier.h + +Service_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/tao/libTAO_IFR_Client.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicInterface.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif BUILD_CORBA_MESSAGING + +## Makefile.CosEC_Simple_Supplier.am + +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Supplier + +Supplier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Supplier_SOURCES = \ + Supplier.cpp \ + Supplier.h + +Supplier_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/CosEC/Simple/README b/TAO/orbsvcs/examples/CosEC/Simple/README new file mode 100644 index 00000000000..6090cd7419e --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Simple/README @@ -0,0 +1,15 @@ +# $Id$ + + This directory contains what possibly is the simplest example +for a COS Event Service. It contains three executables; a consumer, +supplier and a program to create the event channel itself. + + To test is use the run_test.pl script, or: + +$ ./Service -o ec.ior +$ ./Consumer file://ec.ior +$ ./Supplier file://ec.ior + + more advanced tests are located in: + +$TAO_ROOT/orbsvcs/tests/CosEvent diff --git a/TAO/orbsvcs/examples/CosEC/Simple/Service.cpp b/TAO/orbsvcs/examples/CosEC/Simple/Service.cpp new file mode 100644 index 00000000000..07a78aea874 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Simple/Service.cpp @@ -0,0 +1,124 @@ +// $Id$ + +#include "orbsvcs/CosEvent/CEC_EventChannel.h" +#include "orbsvcs/CosEvent/CEC_Default_Factory.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID (CosEC_Simple, + Service, + "$Id$") + +const char *ior_output_file = "ec.ior"; + +int parse_args (int argc, char *argv[]); + +int +main (int argc, char* argv[]) +{ + TAO_CEC_Default_Factory::init_svcs (); + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) == -1) + { + ACE_ERROR ((LM_ERROR, + "Usage: Service [-o IOR_file_name]\n")); + return 1; + } + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + TAO_CEC_EventChannel_Attributes attributes (poa.in (), + poa.in ()); + + TAO_CEC_EventChannel ec_impl (attributes); + ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosEventChannelAdmin::EventChannel_var event_channel = + ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::String_var ior = + orb->object_to_string (event_channel.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "Activated as <%s>\n", ior.in ())); + + // If the ior_output_file exists, output the ior to it + if (ior_output_file != 0) + { + FILE *output_file= ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing IOR: %s", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + } + + // Wait for events, using work_pending()/perform_work() may help + // or using another thread, this example is too simple for that. + orb->run (); + + // We don't do any cleanup, it is hard to do it after shutdown, + // and would complicate the example; plus it is almost + // impossible to do cleanup after ORB->run() because the POA is + // in the holding state. Applications should use + // work_pending()/perform_work() to do more interesting stuff. + // Check the supplier for the proper way to do cleanup. + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +// **************************************************************** + +int parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-o <iorfile>" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/examples/CosEC/Simple/Supplier.cpp b/TAO/orbsvcs/examples/CosEC/Simple/Supplier.cpp new file mode 100644 index 00000000000..3886f6d085a --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Simple/Supplier.cpp @@ -0,0 +1,129 @@ +// $Id$ + +#include "Supplier.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID (CosEC_Examples, + Supplier, + "$Id$") + +int +main (int argc, char* argv[]) +{ + Supplier supplier; + + return supplier.run (argc, argv); +} + +// **************************************************************** + +Supplier::Supplier (void) +{ +} + +int +Supplier::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (argc <= 1) + { + ACE_ERROR ((LM_ERROR, + "Usage: Supplier <event_channel_ior>\n")); + return 1; + } + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel, we could use a naming service, a + // command line argument or resolve_initial_references(), but + // this is simpler... + object = + orb->string_to_object (argv[1] ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosEventChannelAdmin::EventChannel_var event_channel = + CosEventChannelAdmin::EventChannel::_narrow (object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The canonical protocol to connect to the EC + CosEventChannelAdmin::SupplierAdmin_var supplier_admin = + event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosEventChannelAdmin::ProxyPushConsumer_var consumer = + supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosEventComm::PushSupplier_var supplier = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + consumer->connect_push_supplier (supplier.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Push the events... + ACE_Time_Value sleep_time (0, 10000); // 10 milliseconds + + CORBA::Any event; + event <<= CORBA::ULong (10); + + for (int i = 0; i != 2000; ++i) + { + consumer->push (event ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_OS::sleep (sleep_time); + } + + // Disconnect from the EC + consumer->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the EC.... + event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Deactivate this object... + PortableServer::ObjectId_var id = + poa->servant_to_id (this ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the POA + poa->destroy (1, 0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Supplier::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/examples/CosEC/Simple/Supplier.h b/TAO/orbsvcs/examples/CosEC/Simple/Supplier.h new file mode 100644 index 00000000000..4fdc39bfa08 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Simple/Supplier.h @@ -0,0 +1,50 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS COS Event Channel examples +// +// = FILENAME +// Supplier +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef SUPPLIER_H +#define SUPPLIER_H + +#include "orbsvcs/CosEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Supplier : public POA_CosEventComm::PushSupplier +{ + // = TITLE + // Simple supplier object + // + // = DESCRIPTION + // This class is a supplier of events. + // +public: + Supplier (void); + // Constructor + + int run (int argc, char* argv[]); + // Run the test + + // = The CosEventComm::PushSupplier methods + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: +}; + +#endif /* SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/CosEC/Simple/run_test.pl b/TAO/orbsvcs/examples/CosEC/Simple/run_test.pl new file mode 100755 index 00000000000..704c4dd8b3a --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/Simple/run_test.pl @@ -0,0 +1,56 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../../bin'; +use PerlACE::Run_Test; + +$status = 0; + +$iorfile = PerlACE::LocalFile ("ec.ior"); + +unlink $iorfile; + +$T = new PerlACE::Process ("Service", "-o $iorfile"); +$C = new PerlACE::Process ("Consumer", "file://$iorfile"); +$S = new PerlACE::Process ("Supplier", "file://$iorfile"); + +$T->Spawn (); + +if (PerlACE::waitforfile_timed ($iorfile, 15) == -1) { + print STDERR "ERROR: cannot find file <$iorfile>\n"; + $T->Kill (); + exit 1; +} + +$C->Spawn (); + +sleep 5; + +$supplier = $S->SpawnWaitKill (120); + +if ($supplier != 0) { + print STDERR "ERROR: supplier returned $supplier\n"; + $status = 1; +} + +$consumer = $C->WaitKill (15); + +if ($consumer != 0) { + print STDERR "ERROR: consumer returned $consumer\n"; + $status = 1; +} + +$service = $T->TerminateWaitKill (5); + +if ($service != 0) { + print STDERR "ERROR: service returned $service\n"; + $status = 1; +} + +unlink $iorfile; + +exit $status; diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/Consumer.cpp b/TAO/orbsvcs/examples/CosEC/TypedSimple/Consumer.cpp new file mode 100644 index 00000000000..db6437a39bd --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/Consumer.cpp @@ -0,0 +1,114 @@ +// $Id$ + +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/CosTypedEventChannelAdminC.h" +#include "Country_i.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID (CosEC_Examples, + Consumer, + "$Id$") + +int +main (int argc, char* argv[]) +{ + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var poa_obj = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (poa_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel using the Naming Service. + CORBA::Object_var nam_obj = + orb->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + + CosNaming::NamingContext_var root_context = + CosNaming::NamingContext::_narrow(nam_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name channel_name (1); + channel_name.length (1); + channel_name[0].id = CORBA::string_dup ("CountryEventChannel"); + + CORBA::Object_var ec_obj = + root_context->resolve(channel_name); + ACE_TRY_CHECK; + + // Downcast the object reference to a TypedEventChannel reference + CosTypedEventChannelAdmin::TypedEventChannel_var typed_event_channel = + CosTypedEventChannelAdmin::TypedEventChannel::_narrow(ec_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Initialise the Country Impl + Country_i country (orb.in ()); + Country_var typed_consumer = country._this(); + + // Connect to the typed channel + CosTypedEventChannelAdmin::TypedConsumerAdmin_var typed_consumer_admin = + typed_event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosEventChannelAdmin::ProxyPushSupplier_var proxy_push_supplier = + typed_consumer_admin->obtain_typed_push_supplier (_tc_Country->id() + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + proxy_push_supplier->connect_push_consumer (typed_consumer.in () ); + + CORBA::String_var str = + orb->object_to_string (typed_consumer.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + const char* ior_file_name = "Consumer.ior"; + FILE *output_file= + ACE_OS::fopen (ACE_TEXT_CHAR_TO_TCHAR(ior_file_name), + ACE_LIB_TEXT("w")); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing IOR: %s", + ior_file_name), + 1); + ACE_OS::fprintf (output_file, "%s", str.in ()); + ACE_OS::fclose (output_file); + + // Wait for events. + ACE_DEBUG ((LM_DEBUG, "Waiting on orb->run for events...\n")); + orb->run (); + + ACE_DEBUG ((LM_DEBUG, "...ORB shutdown\n")); + + // Destroy the POA + poa->destroy (1, 0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the ORB + orb->destroy (); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "main"); + return 1; + } + ACE_ENDTRY; + return 0; +} + diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/CosEC_TypedSimple.mpc b/TAO/orbsvcs/examples/CosEC/TypedSimple/CosEC_TypedSimple.mpc new file mode 100644 index 00000000000..cddcd128801 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/CosEC_TypedSimple.mpc @@ -0,0 +1,21 @@ +// -*- MPC -*- +// $Id$ + +project(*Consumer) : event_skel, orbsvcsexe, portableserver, naming { + requires += ec_typed_events + source_files { + Consumer.cpp + Country_i.cpp + } +} + +project(*Supplier) : event_skel, orbsvcsexe, portableserver, naming { + requires += ec_typed_events + after += CosEC_TypedSimple_Consumer + idl_files { + } + source_files { + CountryC.cpp + Supplier.cpp + } +} diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/Country.idl b/TAO/orbsvcs/examples/CosEC/TypedSimple/Country.idl new file mode 100644 index 00000000000..00424bfa608 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/Country.idl @@ -0,0 +1,16 @@ +// $Id$ + +//IDL + +#ifndef TAO_COUNTRY_IDL +#define TAO_COUNTRY_IDL + +#include "orbsvcs/CosTypedEventComm.idl" + +interface Country : ::CosTypedEventComm::TypedPushConsumer +{ + void update_population (in string country, + in long population); +}; + +#endif /* TAO_COUNTRY_IDL */ diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/Country.idl.for_ifr b/TAO/orbsvcs/examples/CosEC/TypedSimple/Country.idl.for_ifr new file mode 100644 index 00000000000..220d3c09aa0 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/Country.idl.for_ifr @@ -0,0 +1,16 @@ +// $Id$ + +//IDL + +#ifndef TAO_COUNTRY_IDL +#define TAO_COUNTRY_IDL + +//#include "orbsvcs/CosEventComm.idl" + +interface Country //: ::CosTypedEventComm::TypedPushConsumer +{ + void update_population (in string country, + in long population); +}; + +#endif /* TAO_COUNTRY_IDL */ diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/Country_i.cpp b/TAO/orbsvcs/examples/CosEC/TypedSimple/Country_i.cpp new file mode 100644 index 00000000000..bbf4b03a030 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/Country_i.cpp @@ -0,0 +1,80 @@ +// -*- C++ -*- +// +// $Id$ + +#include "Country_i.h" + +// Implementation skeleton constructor +Country_i::Country_i (CORBA::ORB_ptr orb) : + orb_ (CORBA::ORB::_duplicate (orb)) +{ +} + +// Implementation skeleton destructor +Country_i::~Country_i (void) +{ +} + +void Country_i::update_population (const char * country, + CORBA::Long population + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) + +{ + //Add your implementation here + ACE_DEBUG ((LM_DEBUG, "Country %s has population %d\n", + country, population)); +} + +CORBA::Object_ptr +Country_i::get_typed_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) + +{ + //Add your implementation here + ACE_DEBUG ((LM_DEBUG, "Country_i::get_typed_consumer called...\n")); + + Country_var ret = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + ACE_DEBUG ((LM_DEBUG, "...returning CORBA::Object_ptr for Country_i\n")); + + return Country::_duplicate(ret.in ()); +} + +void +Country_i::push (const CORBA::Any & /* data */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)) + +{ + //Add your implementation here +} + +void +Country_i::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) + +{ + //Add your implementation here + ACE_DEBUG ((LM_DEBUG, "Country_i::disconnect_push_consumer called...\n")); + + // Deactivate the impl + PortableServer::POA_var t_poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::ObjectId_var t_id = + t_poa->servant_to_id (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + t_poa->deactivate_object (t_id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Country_i::disconnect_push_consumer, ") + ACE_TEXT ("calling ORB shutdown...\n"))); + orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/Country_i.h b/TAO/orbsvcs/examples/CosEC/TypedSimple/Country_i.h new file mode 100644 index 00000000000..3d658086c47 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/Country_i.h @@ -0,0 +1,45 @@ +// -*- C++ -*- +// +// $Id$ + +#ifndef COUNTRYI_H_ +#define COUNTRYI_H_ + +#include "CountryS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +//Class Country_i +class Country_i : public virtual POA_Country +{ +public: + //Constructor + Country_i (CORBA::ORB_ptr orb); + + //Destructor + virtual ~Country_i (void); + + virtual void update_population (const char * country, + CORBA::Long population + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Object_ptr get_typed_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void push (const CORBA::Any & data + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)); + + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + /// The ORB + CORBA::ORB_var orb_; +}; + +#endif /* COUNTRYI_H_ */ diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/Makefile.am b/TAO/orbsvcs/examples/CosEC/TypedSimple/Makefile.am new file mode 100644 index 00000000000..615cd3440e0 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/Makefile.am @@ -0,0 +1,130 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_IDL = ACE_ROOT=$(ACE_ROOT) TAO_ROOT=$(TAO_ROOT) $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDL_DEP = $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDLFLAGS = -Ge 1 -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -I$(TAO_ROOT) -I$(srcdir) -g $(ACE_BUILDDIR)/apps/gperf/src/gperf +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.CosEC_TypedSimple_Consumer.am + +if BUILD_EC_TYPED_EVENTS +if !BUILD_MINIMUM_CORBA + +BUILT_SOURCES = \ + CountryC.cpp \ + CountryC.h \ + CountryC.inl \ + CountryS.cpp \ + CountryS.h \ + CountryS.inl \ + CountryS_T.cpp \ + CountryS_T.h \ + CountryS_T.inl + +CLEANFILES = \ + Country-stamp \ + CountryC.cpp \ + CountryC.h \ + CountryC.inl \ + CountryS.cpp \ + CountryS.h \ + CountryS.inl \ + CountryS_T.cpp \ + CountryS_T.h \ + CountryS_T.inl + +CountryC.cpp CountryC.h CountryC.inl CountryS.cpp CountryS.h CountryS.inl CountryS_T.cpp CountryS_T.h CountryS_T.inl: Country-stamp + +Country-stamp: $(srcdir)/Country.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -I$(TAO_ROOT)/orbsvcs -GT $(srcdir)/Country.idl + @touch $@ + +noinst_PROGRAMS += Consumer + +Consumer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Consumer_SOURCES = \ + Consumer.cpp \ + CountryC.cpp \ + CountryS.cpp \ + Country_i.cpp \ + CountryC.h \ + CountryC.inl \ + CountryS.h \ + CountryS.inl \ + CountryS_T.h \ + CountryS_T.inl \ + Country_i.h + +Consumer_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif BUILD_EC_TYPED_EVENTS + +## Makefile.CosEC_TypedSimple_Supplier.am + +if BUILD_EC_TYPED_EVENTS +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Supplier + +Supplier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Supplier_SOURCES = \ + CountryC.cpp \ + Supplier.cpp \ + Country_i.h + +Supplier_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif BUILD_EC_TYPED_EVENTS + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/README b/TAO/orbsvcs/examples/CosEC/TypedSimple/README new file mode 100644 index 00000000000..d722b0a9e0c --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/README @@ -0,0 +1,18 @@ +# $Id$ + + This directory contains an example for a COS Event Service, +using a typed channel. +It contains two executables; a consumer and a supplier. + + To test it use : + +# rm Country.ifr +# IFR_Service -p -b Country.ifr -ORBEndPoint iiop://localhost:12345 +# tao_ifr -ORBInitRef InterfaceRepository=corbaloc:iiop:localhost:12345/InterfaceRepository -I$TAO_ROOT/orbsvcs Country.idl +# Naming_Service -ORBEndPoint iiop://localhost:8000 +# CosEvent_Service -n CountryEventChannel -r -t -d -ORBInitRef InterfaceRepository=corbaloc:iiop:localhost:12345/InterfaceRepository -ORBInitRef NameService=corbaloc:iiop:localhost:8000/NameService +# consumer -ORBInitRef NameService=corbaloc:iiop:localhost:8000/NameService +# supplier -ORBInitRef NameService=corbaloc:iiop:localhost:8000/NameService + +Note: If the tao_ifr fails, use the Country.idl.for_ifr file to upload the idl into the IFR. + Please also report the problem in the usual manner. diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/Supplier.cpp b/TAO/orbsvcs/examples/CosEC/TypedSimple/Supplier.cpp new file mode 100644 index 00000000000..d384fad33cf --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/Supplier.cpp @@ -0,0 +1,93 @@ +// $Id$ + +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/CosTypedEventChannelAdminC.h" +#include "CountryC.h" + +ACE_RCSID(CosEC_Examples, Supplier, "$Id:") + +int +main (int argc, char* argv[]) +{ + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel using the Naming Service. + CORBA::Object_var nam_obj = + orb->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + + CosNaming::NamingContext_var root_context = + CosNaming::NamingContext::_narrow(nam_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name channel_name (1); + channel_name.length (1); + channel_name[0].id = CORBA::string_dup ("CountryEventChannel"); + + CORBA::Object_var ec_obj = + root_context->resolve(channel_name); + ACE_TRY_CHECK; + + // Downcast the object reference to a TypedEventChannel reference + CosTypedEventChannelAdmin::TypedEventChannel_var typed_event_channel = + CosTypedEventChannelAdmin::TypedEventChannel::_narrow(ec_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Connect to the typed channel + CosTypedEventChannelAdmin::TypedSupplierAdmin_var typed_supplier_admin = + typed_event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosTypedEventChannelAdmin::TypedProxyPushConsumer_var typed_proxy_push_consumer = + typed_supplier_admin->obtain_typed_push_consumer (_tc_Country->id() + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + typed_proxy_push_consumer->connect_push_supplier (CosEventComm::PushSupplier::_nil() + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the interface from the event channel + CORBA::Object_var typed_consumer = + typed_proxy_push_consumer->get_typed_consumer(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Narrow the interface + Country_var typed_supplier = Country::_narrow(typed_consumer.in () ); + ACE_TRY_CHECK; + + // Invoke the events... + for (int i = 0; i != 100; ++i) + { + typed_supplier->update_population ("England", i ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + // Disconnect from the EC + typed_proxy_push_consumer->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the EC.... + typed_event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "main"); + return 1; + } + ACE_ENDTRY; + return 0; +} + + + diff --git a/TAO/orbsvcs/examples/CosEC/TypedSimple/run_test.pl b/TAO/orbsvcs/examples/CosEC/TypedSimple/run_test.pl new file mode 100755 index 00000000000..d6d585ce8a9 --- /dev/null +++ b/TAO/orbsvcs/examples/CosEC/TypedSimple/run_test.pl @@ -0,0 +1,118 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../../bin'; +use PerlACE::Run_Test; + +$status = 0; + +$nsiorfile = PerlACE::LocalFile ("ns.ior"); +$ifriorfile = PerlACE::LocalFile ("ifr.ior"); +$eciorfile = PerlACE::LocalFile ("ec.ior"); +$consiorfile = PerlACE::LocalFile ("Consumer.ior"); + +unlink $nsiorfile; +unlink $ifriorfile; +unlink $eciorfile; +unlink $consiorfile; + + +$IF = new PerlACE::Process ($ENV{"TAO_ROOT"}."/orbsvcs/IFR_Service/IFR_Service", + "-o $ifriorfile"); +$TI = new PerlACE::Process ($ENV{"ACE_ROOT"}."/bin/tao_ifr", + "-ORBInitRef InterfaceRepository=file://$ifriorfile " . + "-I".$ENV{"TAO_ROOT"}."/orbsvcs Country.idl"); +$NS = new PerlACE::Process ($ENV{"TAO_ROOT"}."/orbsvcs/Naming_Service/Naming_Service", + "-o $nsiorfile"); +$CE = new PerlACE::Process ($ENV{"TAO_ROOT"}."/orbsvcs/CosEvent_Service/CosEvent_Service", + "-n CountryEventChannel -r -t -d -o $eciorfile " . + "-ORBInitRef InterfaceRepository=file://$ifriorfile " . + "-ORBInitRef NameService=file://$nsiorfile "); +$C = new PerlACE::Process ("Consumer", "-ORBInitRef NameService=file://$nsiorfile "); +$S = new PerlACE::Process ("Supplier", "-ORBInitRef NameService=file://$nsiorfile "); + +$IF->Spawn (); + +if (PerlACE::waitforfile_timed ($ifriorfile, 15) == -1) { + print STDERR "ERROR: cannot find file <$ifriorfile>\n"; + $IF->Kill (); + exit 1; +} + +$TI->SpawnWaitKill (60); + +$NS->Spawn (); + +if (PerlACE::waitforfile_timed ($nsiorfile, 15) == -1) { + print STDERR "ERROR: cannot find file <$nsiorfile>\n"; + $IF->Kill (); + $NS->Kill (); + exit 1; +} + +$CE->Spawn (); + +if (PerlACE::waitforfile_timed ($eciorfile, 15) == -1) { + print STDERR "ERROR: cannot find file <$eciorfile>\n"; + $IF->Kill (); + $NS->Kill (); + $CE->Kill (); + exit 1; +} + +$C->Spawn (); + +if (PerlACE::waitforfile_timed ($consiorfile, 15) == -1) { + print STDERR "ERROR: cannot find file <$consiorfile>\n"; + $IF->Kill (); + $NS->Kill (); + $CE->Kill (); + $C->Kill (); + exit 1; +} + +$supplier = $S->SpawnWaitKill (120); + +if ($supplier != 0) { + print STDERR "ERROR: supplier returned $supplier\n"; + $status = 1; +} + +$server = $C->WaitKill (15); + +if ($server != 0) { + print STDERR "ERROR: consumer returned $server\n"; + $status = 1; +} + +$server = $CE->WaitKill (15); + +if ($server != 0) { + print STDERR "ERROR: CosEvent_Service returned $server\n"; + $status = 1; +} + +$server = $NS->TerminateWaitKill (15); + +if ($server != 0) { + print STDERR "ERROR: name service returned $server\n"; + $status = 1; +} + +$server = $IF->TerminateWaitKill (15); + +if ($server != 0) { + print STDERR "ERROR: IFR_Service returned $server\n"; + $status = 1; +} + +unlink $nsiorfile; +unlink $ifriorfile; +unlink $eciorfile; +unlink $consiorfile; + +exit $status; diff --git a/TAO/orbsvcs/examples/FaultTolerance/Makefile.am b/TAO/orbsvcs/examples/FaultTolerance/Makefile.am new file mode 100644 index 00000000000..8dd0d109288 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/Makefile.am @@ -0,0 +1,13 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + RolyPoly + diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.cpp new file mode 100644 index 00000000000..19fed3a32ea --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.cpp @@ -0,0 +1,7 @@ +// file : RolyPoly/CrashPoint.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "CrashPoint.h" + +short crash_point = 0; diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.h new file mode 100644 index 00000000000..69f2e1a0044 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.h @@ -0,0 +1,19 @@ +// file : RolyPoly/CrashPoint.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef CRASH_POINT_H +#define CRASH_POINT_H + +// Valid crash-point values: +// +// 0 no crash (default) +// +// 1 crash before logging the reply +// +// 2 crash after logging the reply but before replying to the client +// + +extern short crash_point; + +#endif // CRASH_POINT_H diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Log.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Log.h new file mode 100644 index 00000000000..a83d966dd69 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Log.h @@ -0,0 +1,10 @@ +// file : RolyPoly/Log.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef LOG_HPP +#define LOG_HPP + +#include "LogACE_RB_Tree.h" + +#endif // LOG_HPP diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogACE_RB_Tree.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogACE_RB_Tree.h new file mode 100644 index 00000000000..9b54d353315 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogACE_RB_Tree.h @@ -0,0 +1,66 @@ +// file : RolyPoly/LogACE_RB_Tree.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef LOG_ACE_RB_TREE_H +#define LOG_ACE_RB_TREE_H + +#include <ace/RB_Tree.h> +#include <ace/Synch.h> + +template <typename RI, typename RV> +class Log +{ +public: + typedef RI RecordIdType; + typedef RV RecordValueType; + +private: + typedef + ACE_RB_Tree <RecordIdType, + RecordValueType, + ACE_Less_Than<RecordIdType>, + ACE_Null_Mutex> + Map_; + +public: + class Duplicate {}; + class NotFound {}; + + void + insert (RecordIdType const& ri, RecordValueType const& rv) + throw (Duplicate) + { + if (map_.bind (ri, rv) != 0) throw Duplicate (); + } + + bool + contains (RecordIdType const& ri) const + { + // Guess what: ACE_RB_Tree::find() is not const. + // + Map_& m = const_cast<Map_&> (map_); + + RecordValueType tmp; + + return m.find (ri, tmp) == 0; + } + + + RecordValueType const& + lookup (RecordIdType const& ri) const throw (NotFound) + { + Map_& m = const_cast<Map_&> (map_); + + typename Map_::ENTRY* entry; + + if (m.find (ri, entry) != 0) throw NotFound (); + + return entry->item (); + } + +private: + Map_ map_; +}; + +#endif // LOG_ACE_RB_TREE_H diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogStdMap.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogStdMap.h new file mode 100644 index 00000000000..29a5ff2be65 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogStdMap.h @@ -0,0 +1,56 @@ +// file : RolyPoly/LogStdMap.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef LOG_STD_MAP_H +#define LOG_STD_MAP_H + +#include <map> + +template <typename RI, typename RV> +class Log +{ +public: + typedef RI RecordIdType; + typedef RV RecordValueType; + +private: + typedef + std::map <RecordIdType, RecordValueType> + Map_; + +public: + class Duplicate {}; + class NotFound {}; + + void + insert (RecordIdType const& ri, RecordValueType const& rv) + throw (Duplicate) + { + if (!map_.insert (std::make_pair (ri, rv)).second) + { + throw Duplicate (); + } + } + + bool + contains (RecordIdType const& ri) const + { + return map_.count (ri) != 0; + } + + + RecordValueType const& + lookup (RecordIdType const& ri) const throw (NotFound) + { + typename Map_::const_iterator i = map_.find (ri); + + if (i != map_.end ()) return i->second; + else throw NotFound (); + } + +private: + Map_ map_; +}; + +#endif // LOG_STD_MAP_H diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Makefile.am b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Makefile.am new file mode 100644 index 00000000000..a25dd5aeef2 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Makefile.am @@ -0,0 +1,179 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_IDL = ACE_ROOT=$(ACE_ROOT) TAO_ROOT=$(TAO_ROOT) $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDL_DEP = $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDLFLAGS = -Ge 1 -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -I$(TAO_ROOT) -I$(srcdir) -g $(ACE_BUILDDIR)/apps/gperf/src/gperf +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.RolyPoly_Idl.am + +BUILT_SOURCES = \ + RolyPolyC.cpp \ + RolyPolyC.h \ + RolyPolyC.inl \ + RolyPolyS.cpp \ + RolyPolyS.h \ + RolyPolyS.inl + +CLEANFILES = \ + RolyPoly-stamp \ + RolyPolyC.cpp \ + RolyPolyC.h \ + RolyPolyC.inl \ + RolyPolyS.cpp \ + RolyPolyS.h \ + RolyPolyS.inl + +RolyPolyC.cpp RolyPolyC.h RolyPolyC.inl RolyPolyS.cpp RolyPolyS.h RolyPolyS.inl: RolyPoly-stamp + +RolyPoly-stamp: $(srcdir)/RolyPoly.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -Sa -St $(srcdir)/RolyPoly.idl + @touch $@ + + +noinst_HEADERS = \ + RolyPoly.idl + +## Makefile.RolyPoly_Client.am + +if BUILD_ACE_UUID +if BUILD_CORBA_MESSAGING +if BUILD_EXCEPTIONS +if BUILD_INTERCEPTORS +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +client_SOURCES = \ + RolyPolyC.cpp \ + client.cpp \ + CrashPoint.h \ + Log.h \ + LogACE_RB_Tree.h \ + LogStdMap.h \ + ORB_Initializer.h \ + ReplicaController.h \ + RolyPoly_i.h \ + StateUpdate.h + +client_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_FaultTolerance.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_FT_ServerORB.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI_Server.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_FT_ClientORB.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_FTORB_Utils.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_PortableGroup.la \ + $(TAO_BUILDDIR)/tao/libTAO_IORManip.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_INTERCEPTORS +endif BUILD_EXCEPTIONS +endif BUILD_CORBA_MESSAGING +endif BUILD_ACE_UUID + +## Makefile.RolyPoly_Server.am + +if BUILD_ACE_UUID +if BUILD_CORBA_MESSAGING +if BUILD_EXCEPTIONS +if BUILD_INTERCEPTORS +if BUILD_THREADS +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(ACE_ROOT)/protocols \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +server_SOURCES = \ + CrashPoint.cpp \ + ORB_Initializer.cpp \ + ReplicaController.cpp \ + RolyPolyC.cpp \ + RolyPolyS.cpp \ + RolyPoly_i.cpp \ + server.cpp \ + CrashPoint.h \ + ORB_Initializer.h \ + ReplicaController.h \ + RolyPoly_i.h + +server_LDADD = \ + $(ACE_BUILDDIR)/protocols/ace/TMCast/libACE_TMCast.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_FaultTolerance.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_FT_ServerORB.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI_Server.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_FT_ClientORB.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_FTORB_Utils.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_PortableGroup.la \ + $(TAO_BUILDDIR)/tao/libTAO_IORManip.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_THREADS +endif BUILD_INTERCEPTORS +endif BUILD_EXCEPTIONS +endif BUILD_CORBA_MESSAGING +endif BUILD_ACE_UUID + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.cpp new file mode 100644 index 00000000000..ed3b767e2f4 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.cpp @@ -0,0 +1,56 @@ +// file : RolyPoly/ORB_Initializer.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "ace/Auto_Ptr.h" +#include "tao/corba.h" +#include "tao/PI/ORBInitInfo.h" +#include "tao/ORB_Core.h" + +#include "ORB_Initializer.h" +#include "ReplicaController.h" + +void +ORB_Initializer::pre_init (PortableInterceptor::ORBInitInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +ORB_Initializer::post_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Allocate slot id. + // + state_slot_id (info->allocate_slot_id ()); + + // Register replica controller as server request interceptor. + // + TAO_ORBInitInfo* tao_info = dynamic_cast<TAO_ORBInitInfo*> (info); + + CORBA::ORB_var orb (tao_info->orb_core ()->orb ()); + + PortableInterceptor::ServerRequestInterceptor_var interceptor; + + { + PortableInterceptor::ServerRequestInterceptor *tmp_interceptor = 0; + + ACE_NEW_THROW_EX (tmp_interceptor, + ReplicaController (orb.in ()), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + + ACE_CHECK; + + interceptor = tmp_interceptor; + } + + info->add_server_request_interceptor (interceptor.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.h new file mode 100644 index 00000000000..d11b2a41aa2 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.h @@ -0,0 +1,28 @@ +// file : RolyPoly/ORB_Initializer.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef ORB_INITIALIZER_H +#define ORB_INITIALIZER_H + +#include "tao/LocalObject.h" +#include "tao/PI/PI.h" + +class ORB_Initializer : + public virtual PortableInterceptor::ORBInitializer, + public virtual TAO_Local_RefCounted_Object +{ +public: + + virtual void + pre_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void + post_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); +}; + +#endif /* ORB_INITIALIZER_H */ diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/README b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/README new file mode 100644 index 00000000000..786b42a81d9 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/README @@ -0,0 +1,105 @@ + + +Overview + +RolyPoly is a simple example that shows how to increase application +reliability by using replication to tolerate faults. It allows you +to start two replicas of the same object which are logically seen as +one object by a client. Furthermore, you can terminate one of the +replicas without interrupting the service provided by the object. + +RolyPoly is using request/reply logging to suppress repeated +requests (thus guaranteeing exactly-once semantic) and state +synchronization (to ensure all replicas are in a consistent +state). Since replicas are generally distributed across multiple +nodes in the network, logging and state synchronizations are +done using multicast group communication protocol. + +In order to make it illustrative, each replica can be set to +fail in one of the predefined places called crash points. The +following crash point numbers are defined: + +0 - no crash point (default). + +1 - fail before reply logging/state synchronization. + +2 - fail after reply logging/state synchronization but before + returning reply to the client. + +Essential difference between crash point 1 and 2 is that in +the second case there should be reply replay while in the +first case request is simply re-executed (this can be observed +in the trace messages of the replicas). + + +Execution Scenario + +In this example scenario we will start three replicas. For one +of them (let us call it primary) we will specify a crash point +other than 0. Then we will start a client to execute requests +on the resulting object. After a few requests, primary will +fail and we will be able to observe transparent shifting of +client to the other replica. Also we will be able to make sure +that, after this shifting, object is still in expected state +(i.e. the sequence of returned numbers is not interrupted and +that, in case of the crash point 2, request is not re-executed). + +Note, due to the underlying group communication architecture, +the group with only one member (replica in our case) can only +exist for a very short period of time. This, in turn, means +that we need to start first two replicas virtually at the same +time. This is also a reason why we need three replicas instead +of two - if one replica is going to fail then the other one +won't live very long alone. For more information on the reasons +why it works this way please see documentation for TMCast +available at $(ACE_ROOT)/ace/TMCast/README. + +Suppose we have node0, node1 and node2 on which we are going +to start our replicas (it could be the same node). Then, to +start our replicas we can execute the following commands: + +node0$ ./server -o replica-0.ior -c 2 +node1$ ./server -o replica-1.ior +node2$ ./server -o replica-2.ior + +When all replicas are up we can start the client: + +$ ./client -k file://replica-0.ior -k file://replica-1.ior + +In this scenario, after executing a few requests, replica-0 +will fail in crash point 2. After that, replica-1 will continue +executing client requests. You can see what's going on with +replicas by looking at various trace messages printed during +execution. + + +Architecture + +The biggest part of the replication logic is carried out by +the ReplicaController. In particular it performs the +following tasks: + +* management of distributed request/reply log + +* state synchronization + +* repeated request suppression + + +Object implementation (interface RolyPoly in our case) can use +two different strategies for delivering state update to the +ReplicaController: + +* push model: client calls Checkpointable::associate_state + to associate the state update with current request. + +* pull model: ReplicaController will call Checkpointable::get_state + implemented by the servant. + +This two model can be used simultaneously. In RolyPoly interface +implementation you can comment out corresponding piece of code to +chose one of the strategies. + +-- +Boris Kolpackov <boris@dre.vanderbilt.edu> + diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.cpp new file mode 100644 index 00000000000..210009bf339 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.cpp @@ -0,0 +1,540 @@ +// file : RolyPoly/ReplicaController.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "tao/AnyTypeCode/Any_Impl.h" +#include "tao/AnyTypeCode/DynamicC.h" +#include "tao/PortableServer/Servant_Base.h" +#include "tao/PI/PI.h" + +#include "orbsvcs/FT_CORBA_ORBC.h" + +#include "ace/UUID.h" +#include "ace/Thread_Manager.h" +#include "ace/TMCast/Group.hpp" + +#include "CrashPoint.h" +#include "StateUpdate.h" +#include "ReplicaController.h" + + +// State slot. +// +// + +namespace +{ + PortableInterceptor::SlotId state_slot_id_; +} + +PortableInterceptor::SlotId +state_slot_id () +{ + return state_slot_id_; +} + +void +state_slot_id (PortableInterceptor::SlotId slot_id) +{ + state_slot_id_ = slot_id; +} + +Checkpointable:: +~Checkpointable () +{ +} + +CORBA::Any* Checkpointable:: +get_state () +{ + return 0; +} + +void Checkpointable:: +associate_state (CORBA::ORB_ptr orb, CORBA::Any const& state) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var pic_obj = + orb->resolve_initial_references ("PICurrent" ACE_ENV_ARG_PARAMETER); + + ACE_TRY_CHECK; + + PortableInterceptor::Current_var pic = + PortableInterceptor::Current::_narrow ( + pic_obj.in () ACE_ENV_ARG_PARAMETER); + + ACE_TRY_CHECK; + + pic->set_slot (state_slot_id (), state ACE_ENV_ARG_PARAMETER); + + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Caught exception:"); + } + ACE_ENDTRY; +} + +// ReplyLogger +// +// + +ReplicaController:: +~ReplicaController () +{ +} + +ReplicaController:: +ReplicaController (CORBA::ORB_ptr orb) + : orb_ (CORBA::ORB::_duplicate (orb)) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var poa_object = + orb_->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + root_poa_ = PortableServer::POA::_narrow ( + poa_object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Caught exception:"); + ACE_OS::abort (); + } + ACE_ENDTRY; + + // Generate member id + ACE_Utils::UUID uuid; + ACE_Utils::UUID_GENERATOR::instance ()->init (); + ACE_Utils::UUID_GENERATOR::instance ()->generateUUID (uuid); + + ACE_INET_Addr address (10000, "239.255.0.1"); + + ACE_DEBUG ((LM_DEBUG, "Becoming a member with id %s\n", + uuid.to_string ()->c_str ())); + + ACE_AUTO_PTR_RESET (group_, new ACE_TMCast::Group (address, uuid.to_string ()->c_str ()), ACE_TMCast::Group); + + int r = ACE_Thread_Manager::instance ()->spawn ( + &ReplicaController::listener_thunk, this); + + if (r < 0) + { + orb_->shutdown (0); + } +} + +void ReplicaController:: +listener () +{ + try + { + for (char buffer[1024];;) + { + size_t n = group_->recv (buffer, sizeof (buffer)); + + ACE_HEX_DUMP ((LM_DEBUG, buffer, n)); + + TAO_InputCDR cdr (buffer, n); + + CORBA::OctetSeq object_id; + PortableInterceptor::AdapterName adapter_name; + CORBA::String_var client_id; + CORBA::Long retention_id; + CORBA::OctetSeq reply; + CORBA::Any state; + + cdr >> object_id; + cdr >> adapter_name; + cdr >> client_id.out (); + cdr >> retention_id; + cdr >> reply; + cdr >> state; + + if (!cdr.good_bit ()) + { + ACE_DEBUG ((LM_DEBUG, "CDR failed\n")); + //@@ what to do? + } + + ACE_DEBUG ((LM_DEBUG, + "Received log for %s with rid %i\n", + client_id.in (), + retention_id)); + + + RecordId rid (client_id.in (), retention_id); + + CORBA::OctetSeq_var tmp (new CORBA::OctetSeq (reply)); + log_.insert (rid, tmp); + + // Update state. + CORBA::TypeCode_var tc = state.type (); + + if (tc->kind () != CORBA::tk_null) + { + PortableServer::POA_var poa = resolve_poa (adapter_name); + + PortableServer::ServantBase_var servant = + poa->id_to_servant (object_id); + + Checkpointable* target = + dynamic_cast<Checkpointable*> (servant.in ()); + + if (target) target->set_state (state); + } + } + } + catch (ACE_TMCast::Group::Failed const&) + { + ACE_DEBUG ((LM_DEBUG, + "Group failure. Perhaps, I am alone in the group.\n")); + } + catch (ACE_TMCast::Group::InsufficienSpace const&) + { + ACE_DEBUG ((LM_DEBUG, "Group::InsufficienSpace\n")); + } + + orb_->shutdown (0); +} + +PortableServer::POA_ptr ReplicaController:: +resolve_poa (PortableInterceptor::AdapterName const&) +{ + //@@ Assume for now it's a root poa. + return PortableServer::POA::_duplicate (root_poa_.in ()); +} + + +ACE_THR_FUNC_RETURN ReplicaController:: +listener_thunk (void* p) +{ + ReplicaController* obj = reinterpret_cast<ReplicaController*> (p); + obj->listener(); + return 0; +} + +namespace +{ + FT::FTRequestServiceContext* + extract_context ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException)); +} + +#if TAO_HAS_EXTENDED_FT_INTERCEPTORS == 1 +void +ReplicaController::tao_ft_interception_point ( + PortableInterceptor::ServerRequestInfo_ptr ri, + CORBA::OctetSeq_out ocs + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ + FT::FTRequestServiceContext_var ftr ( + extract_context (ri ACE_ENV_ARG_PARAMETER)); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Received request from %s with rid %i\n", + ftr->client_id.in (), + ftr->retention_id)); + + // Check if this request is eligible for replay. + + RecordId rid (ftr->client_id.in (), ftr->retention_id); + + if (log_.contains (rid)) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Replaying reply for %s with rid %i\n", + ftr->client_id.in (), + ftr->retention_id)); + + CORBA::OctetSeq_var copy (log_.lookup (rid)); // make a copy + + ocs = copy._retn (); + } + + return; +} + +#endif /*TAO_HAS_EXTENDED_FT_INTERCEPTORS*/ + +void +ReplicaController::send_reply ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + FT::FTRequestServiceContext_var ftr ( + extract_context (ri ACE_ENV_ARG_PARAMETER)); + + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Sending reply for %s with rid %i\n", + ftr->client_id.in (), + ftr->retention_id)); + + + // Prepare reply for logging. + + CORBA::Any_var result = + ri->result (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + TAO_OutputCDR cdr; + result->impl ()->marshal_value (cdr); + + Dynamic::ParameterList_var pl = + ri->arguments (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CORBA::ULong len = pl->length (); + + for (CORBA::ULong index = 0; index != len ; ++index) + { + //@@ No chance for PARAM_OUT + if ((*pl)[index].mode == CORBA::PARAM_INOUT) + { + (*pl)[index].argument.impl ()->marshal_value (cdr); + } + } + + CORBA::OctetSeq_var reply; + + ACE_NEW (reply.out (), CORBA::OctetSeq (cdr.total_length ())); + + reply->length (cdr.total_length ()); + + CORBA::Octet* buf = reply->get_buffer (); + + // @@ What if this throws an exception?? We don't have any way to + // check whether this succeeded + for (ACE_Message_Block const* mb = cdr.begin (); + mb != 0; + mb = mb->cont ()) + { + ACE_OS::memcpy (buf, mb->rd_ptr (), mb->length ()); + buf += mb->length (); + } + + // Logging the reply and state update. + // + + // First send message to members. + // + { + // Extract state update. + + CORBA::OctetSeq_var oid = ri->object_id (); + PortableInterceptor::AdapterName_var an = ri->adapter_name (); + + CORBA::Any_var state = ri->get_slot (state_slot_id ()); + + CORBA::TypeCode_var tc = state->type (); + + if (tc->kind () == CORBA::tk_null) + { + ACE_DEBUG ((LM_DEBUG, "Slot update is void\n")); + + PortableServer::POA_var poa = resolve_poa (an.in ()); + + PortableServer::ServantBase_var servant = + poa->id_to_servant (oid.in ()); + + Checkpointable* target = + dynamic_cast<Checkpointable*> (servant.in ()); + + if (target) + { + CORBA::Any_var tmp = target->get_state (); + + if (tmp.ptr () != 0) state = tmp._retn (); + } + } + + TAO_OutputCDR cdr; + + cdr << oid.in (); + cdr << an.in (); + cdr << ftr->client_id.in (); + cdr << ftr->retention_id; + cdr << reply.in (); + cdr << state.in (); + + size_t size = cdr.total_length (); + + CORBA::OctetSeq_var msg; + + ACE_NEW (msg.out (), CORBA::OctetSeq (size)); + + msg->length (size); + + { + CORBA::Octet* buf = msg->get_buffer (); + + for (ACE_Message_Block const* mb = cdr.begin (); + mb != 0; + mb = mb->cont ()) + { + ACE_OS::memcpy (buf, mb->rd_ptr (), mb->length ()); + buf += mb->length (); + } + } + + CORBA::Octet* buf = msg->get_buffer (); + + // Crash point 1. + // + if (crash_point == 1 && ftr->retention_id > 2) exit (1); + + try + { + while (true) + { + try + { + group_->send (buf, size); + ACE_DEBUG ((LM_DEBUG, "Sent log record of length %i\n", size)); + break; + } + catch (ACE_TMCast::Group::Aborted const&) + { + ACE_DEBUG ((LM_DEBUG, "Retrying to send log record.\n")); + } + } + } + catch (ACE_TMCast::Group::Failed const&) + { + ACE_DEBUG ((LM_DEBUG, + "Group failure. Perhaps, I am alone in the group.\n")); + } + } + + + // Now perform local logging. + // + RecordId rid (ftr->client_id.in (), ftr->retention_id); + + // This is slow but eh-safe ;-). + // + log_.insert (rid, reply); + + + // Crash point 2. + // + if (crash_point == 2 && ftr->retention_id > 2) exit (1); +} + + +namespace +{ + FT::FTRequestServiceContext* + extract_context (PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + IOP::ServiceContext_var svc = + ri->get_request_service_context (IOP::FT_REQUEST + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + TAO_InputCDR cdr (reinterpret_cast<const char*> (svc->context_data.get_buffer ()), + svc->context_data.length ()); + + CORBA::Boolean byte_order; + + if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0) + { + //@@ what to throw? + ACE_THROW (CORBA::BAD_CONTEXT ()); + } + + cdr.reset_byte_order (static_cast<int> (byte_order)); + + // Funny, the following two lines should normally translate + // just to one ctor call. But because we have to use this + // ACE_NEW macro hackery we have a default ctor call plus + // assignment operator call. Yet another example how the + // majority is being penalized by some broken platforms. + // + FT::FTRequestServiceContext_var req; + + //@@ completed status maybe wrong + // + ACE_NEW_THROW_EX (req, + FT::FTRequestServiceContext, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + + cdr >> *req; + + if (!cdr.good_bit ()) + { + //@@ what to throw? + ACE_THROW (CORBA::UNKNOWN ()); + } + + return req._retn (); + } +} + + +char* +ReplicaController::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::string_dup ("ReplicaController"); +} + +void +ReplicaController::send_exception ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +ReplicaController::send_other ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +ReplicaController::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +ReplicaController::receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ + +} + +void +ReplicaController::receive_request ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.h new file mode 100644 index 00000000000..6c7bcadb647 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.h @@ -0,0 +1,138 @@ +// file : RolyPoly/ReplicaController.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef REPLICA_CONTROLLER_H +#define REPLICA_CONTROLLER_H + +#include "ace/TMCast/GroupFwd.hpp" + +#include "tao/LocalObject.h" +#include "tao/PortableInterceptorC.h" +#include "tao/PI_Server/PI_Server.h" +#include "tao/PortableServer/PortableServer.h" + +#include "Log.h" + +// State management +// +// + +PortableInterceptor::SlotId +state_slot_id (); + +void +state_slot_id (PortableInterceptor::SlotId slot_id); + +// ReplicaController +// +// + +class ReplicaController + : public virtual PortableInterceptor::ServerRequestInterceptor, + public virtual TAO_Local_RefCounted_Object +{ +public: + virtual + ~ReplicaController (); + + ReplicaController (CORBA::ORB_ptr orb); + +public: + virtual char * + name (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void + destroy (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + +#if TAO_HAS_EXTENDED_FT_INTERCEPTORS == 1 + virtual void + tao_ft_interception_point ( + PortableInterceptor::ServerRequestInfo_ptr ri, + CORBA::OctetSeq_out ocs + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); +#endif /*TAO_HAS_EXTENDED_FT_INTERCEPTORS*/ + + virtual void + receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void + receive_request ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void + send_reply ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void + send_exception ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void + send_other ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + +private: + static ACE_THR_FUNC_RETURN + listener_thunk (void* p); + + void + listener (); + + PortableServer::POA_ptr + resolve_poa (PortableInterceptor::AdapterName const& name); + +private: + + class RecordId + { + public: + RecordId (char const* client_id, CORBA::Long retention_id) + : client_id_ (CORBA::string_dup (client_id)), + retention_id_ (retention_id) + { + } + + friend bool + operator< (RecordId const& a, RecordId const& b) + { + int r (ACE_OS::strcmp (a.client_id_.in (), b.client_id_.in ())); + + return (r < 0) || (r == 0 && a.retention_id_ < b.retention_id_); + } + + private: + CORBA::String_var client_id_; + CORBA::Long retention_id_; + }; + + typedef + Log<RecordId, CORBA::OctetSeq_var> + Log_; + + Log_ log_; + CORBA::ORB_var orb_; + PortableServer::POA_var root_poa_; + auto_ptr<ACE_TMCast::Group> group_; +}; + +#endif /* REPLICA_CONTROLLER_H */ diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly.idl b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly.idl new file mode 100644 index 00000000000..7ab87e6d98d --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly.idl @@ -0,0 +1,15 @@ +// file : RolyPoly/RolyPoly.idl +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +interface RolyPoly +{ + exception E + { + string s; + }; + + short number (inout string m) raises (E); + + oneway void shutdown (); +}; diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly.mpc b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly.mpc new file mode 100644 index 00000000000..dea14f4a82c --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly.mpc @@ -0,0 +1,32 @@ +// $Id$ +project(*idl): taoidldefaults { + IDL_Files { + RolyPoly.idl + } + custom_only = 1 +} + +project(*Server): orbsvcsexe, fault_tolerance, tmcast, pi_server, interceptors { + after += *idl + Source_Files { + RolyPolyS.cpp + RolyPolyC.cpp + RolyPoly_i.cpp + ORB_Initializer.cpp + ReplicaController.cpp + CrashPoint.cpp + server.cpp + } + IDL_Files { + } +} + +project(*Client): taoclient, fault_tolerance, exceptions { + after += *idl + Source_Files { + RolyPolyC.cpp + client.cpp + } + IDL_Files { + } +} diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.cpp new file mode 100644 index 00000000000..d3c4a92cde6 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.cpp @@ -0,0 +1,72 @@ +// file : RolyPoly/RolyPoly_i.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "RolyPoly_i.h" +#include "StateUpdate.h" +#include "tao/AnyTypeCode/Any.h" + +RolyPoly_i::RolyPoly_i (CORBA::ORB_ptr orb) + : number_ (0) + , orb_ (CORBA::ORB::_duplicate (orb)) +{ +} + +RolyPoly_i::~RolyPoly_i (void) +{ +} + +CORBA::Any* RolyPoly_i:: +get_state () +{ + /* + CORBA::Any_var state (new CORBA::Any); + + *state <<= this->number_; + + return state._retn (); + */ + + return 0; +} + + +void RolyPoly_i:: +set_state (CORBA::Any const& state) +{ + state >>= this->number_; +} + + +CORBA::Short +RolyPoly_i::number (char *&str + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, RolyPoly::E)) +{ + CORBA::string_free (str); + + str = CORBA::string_dup ("Greetings from RolyPoly."); + + ++this->number_; + + + // Preppare state update. + // + + CORBA::Any a; + + a <<= this->number_; + + associate_state (orb_.in (), a); + + return this->number_; +} + +void +RolyPoly_i::shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, "Server is shutting down.\n")); + + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.h new file mode 100644 index 00000000000..86098f033e9 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.h @@ -0,0 +1,44 @@ +// file : RolyPoly/RolyPoly_i.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef ROLY_POLY_I_H +#define ROLY_POLY_I_H + +#include "RolyPolyS.h" +#include "StateUpdate.h" + +class RolyPoly_i : public virtual POA_RolyPoly, + public virtual Checkpointable +{ +public: + RolyPoly_i (CORBA::ORB_ptr orb); + + ~RolyPoly_i (void); + + // Checkpointable + // + virtual CORBA::Any* + get_state (); + + virtual void + set_state (CORBA::Any const& state); + + + // RolyPoly + // + virtual CORBA::Short + number (char *&s ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, RolyPoly::E)); + + virtual void + shutdown (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + CORBA::Short number_; + + CORBA::ORB_var orb_; +}; + +#endif /* ROLY_POLY_I_H */ diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/StateUpdate.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/StateUpdate.h new file mode 100644 index 00000000000..2d9aec49fe8 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/StateUpdate.h @@ -0,0 +1,27 @@ +// file : RolyPoly/StateUpdate.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef STATE_UPDATE_H +#define STATE_UPDATE_H + +#include "tao/corba.h" + +class Checkpointable +{ +public: + virtual + ~Checkpointable (); + + virtual CORBA::Any* + get_state (); + + static void + associate_state (CORBA::ORB_ptr orb, CORBA::Any const& state); + + virtual void + set_state (CORBA::Any const& state) = 0; +}; + + +#endif // STATE_UPDATE_H diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/client.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/client.cpp new file mode 100644 index 00000000000..af43025ffa2 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/client.cpp @@ -0,0 +1,239 @@ +// file : RolyPoly/client.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "ace/Get_Opt.h" +#include "ace/OS_NS_unistd.h" +#include "ace/SString.h" +#include "ace/Unbounded_Queue.h" + +// IOR manipulation. +#include "tao/IORManipulation/IORManip_Loader.h" +#include "orbsvcs/FaultTolerance/FT_Service_Activate.h" +#include "orbsvcs/FaultTolerance/FT_IOGR_Property.h" + +#include "RolyPolyC.h" + +typedef ACE_Unbounded_Queue<ACE_SString> IOR_QUEUE; + +IOR_QUEUE ior_strs; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + { + ACE_SString ior(get_opts.opt_arg ()); + if (ior_strs.enqueue_tail (ior) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Unable to enqueue IOR: %s\n", + ior.c_str ()), + -1); + else + ACE_DEBUG ((LM_DEBUG, "Enqueued IOR: %s\n", ior.c_str ())); + } + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s " + "-k IOR ...\n", + argv[0]), + -1); + } + + return 0; +} + +int +main (int argc, char *argv[]) +{ + int status = 0; + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::ORB_var orb = CORBA::ORB_init (argc, + argv, + "Client ORB" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (::parse_args (argc, argv) != 0) return -1; + + if (ior_strs.is_empty ()) + ACE_ERROR_RETURN ((LM_ERROR, + "No IOR provided\n"), + -1); + + // Start out with the first IOR. Interaction with the second + // IOR occurs during the various interceptions executed during + // this test. + + CORBA::Object_var object; + + if (ior_strs.size() > 1) + { + // merge case + + ACE_DEBUG ((LM_DEBUG, "We got %d iors\n", ior_strs.size ())); + IOR_QUEUE::ITERATOR ior_go = ior_strs.begin (); + ACE_SString *pior = 0; + while (ior_go.next (pior) != 0) + { + ACE_DEBUG ((LM_DEBUG, "IOR: %s\n", pior->c_str ())); + ior_go.advance (); + } + + + IOR_QUEUE::ITERATOR ior_iter = ior_strs.begin (); + + ACE_SString *ior = 0; + ior_iter.next (ior); + + CORBA::Object_var object_primary; + + object_primary = + orb->string_to_object (ior->c_str() ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + // Get an object reference for the ORBs IORManipultion object! + CORBA::Object_ptr IORM = + orb->resolve_initial_references (TAO_OBJID_IORMANIPULATION, + 0 + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + TAO_IOP::TAO_IOR_Manipulation_ptr iorm = + TAO_IOP::TAO_IOR_Manipulation::_narrow (IORM ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + + // Create the list + TAO_IOP::TAO_IOR_Manipulation::IORList iors (ior_strs.size ()); + iors.length(ior_strs.size ()); + size_t cntr = 0; + iors [cntr] = CORBA::Object::_duplicate (object_primary.in ()); + + while (ior_iter.advance ()) + { + ++cntr; + ior_iter.next (ior); + ACE_DEBUG ((LM_DEBUG, "IOR%d: %s\n",cntr, ior->c_str ())); + iors [cntr] = + orb->string_to_object (ior->c_str() ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + } + + ACE_DEBUG ((LM_DEBUG, "Prepare to merge IORs.\n")); + // Create a merged set 1; + object = iorm->merge_iors (iors ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + + FT::TagFTGroupTaggedComponent ft_tag_component; + + // Property values + + // Major and Minor revision numbers + ft_tag_component.object_group_ref_version = 0; + + // Domain id + const char *id = "iogr_testing"; + ft_tag_component.group_domain_id = id; + + // Object group id + ft_tag_component.object_group_id = + (CORBA::ULongLong) 10; + + // Version + ft_tag_component.object_group_ref_version = + (CORBA::ULong) 5; + + // Construct the IOGR Property class + TAO_FT_IOGR_Property iogr_prop (ft_tag_component); + + // Set the property + CORBA::Boolean retval = iorm->set_property (&iogr_prop, + object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + retval = iorm->set_primary (&iogr_prop, + object_primary.in (), + object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + } + else + { + ACE_SString *ior = 0; + if (ior_strs.get (ior) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Unable to extract the only IOR string\n"), + -1); + object = orb->string_to_object (ior->c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + RolyPoly_var server = + RolyPoly::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (server.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Object reference is nil\n"), + 1); + } + + CORBA::Short number = 0; + + + for (int i = 1; i < 500; ++i) + { + CORBA::String_var str; + + try + { + number = server->number (str.inout () + ACE_ENV_ARG_PARAMETER); + } + catch (RolyPoly::E const& e) + { + ACE_DEBUG ((LM_INFO, + "client: received exception %s .\n", + e.s.in ())); + continue; + } + + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_INFO, + "client: received %d\n", + number)); + ACE_OS::sleep (1); + } + + server->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Caught exception:"); + return -1; + } + ACE_ENDTRY; + + return status; +} diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/server.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/server.cpp new file mode 100644 index 00000000000..65c0587a9b7 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/server.cpp @@ -0,0 +1,140 @@ +// file : RolyPoly/server.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" + +#include "RolyPoly_i.h" +#include "CrashPoint.h" +#include "ORB_Initializer.h" +#include "tao/ORBInitializer_Registry.h" + +const char *ior_file = 0; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:c:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_file = get_opts.opt_arg (); + break; + case 'c': + crash_point = ACE_OS::atoi (get_opts.opt_arg ()); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s " + "-o <IOR> " + "-c <CrashPoint>\n", + argv[0]), + -1); + } + + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + if (::parse_args (argc, argv) != 0) return -1; + + ORB_Initializer *temp_initializer = 0; + ACE_NEW_RETURN (temp_initializer, + ORB_Initializer, + -1); // No exceptions yet! + + PortableInterceptor::ORBInitializer_var orb_initializer = + temp_initializer; + + PortableInterceptor::register_orb_initializer (orb_initializer.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "Server ORB" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RolyPoly_i* roly_poly_impl; + + ACE_NEW_RETURN (roly_poly_impl, + RolyPoly_i (orb.in ()), + 1); + + PortableServer::ServantBase_var owner_transfer (roly_poly_impl); + + RolyPoly_var t = + roly_poly_impl->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::PolicyList policies; // Empty policy list. + + CORBA::String_var ior = + orb->object_to_string (t.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + FILE *output_file= ACE_OS::fopen (ior_file, "w"); + if (output_file == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file <%s> for writing " + "IOR: %s", + ior.in ()), + 1); + } + + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + + ACE_DEBUG ((LM_DEBUG, "Server is ready\n")); + + // Run the ORB event loop. + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + root_poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "Event loop finished.\n")); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Caught exception:"); + return -1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/ImR/Advanced/Advanced.mpc b/TAO/orbsvcs/examples/ImR/Advanced/Advanced.mpc new file mode 100644 index 00000000000..11a89093d9b --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/Advanced.mpc @@ -0,0 +1,54 @@ +//$Id$ +project(*IDL): taoidldefaults { + IDL_Files { + Manager.idl + Messenger.idl + } + custom_only = 1 +} + +project(*Manager): orbsvcsexe, portableserver, exceptions { + after += *IDL + Source_Files { + manager_main.cpp + Manager_i.cpp + ManagerS.cpp + ManagerC.cpp + } + Documentation_Files { + Advanced.mpc + run_test.pl + README + drivers/* + } + IDL_Files { + } +} + +project(*Server): orbsvcsexe, portableserver, iortable, exceptions { + after += *IDL + Source_Files { + server_main.cpp + TestServer.cpp + ManagerC.cpp + MessengerS.cpp + MessengerC.cpp + Messenger_i.cpp + } + IDL_Files { + } +} + +project(*Client): orbsvcsexe, exceptions { + after += *IDL + Source_Files { + client_main.cpp + TestClient.cpp + MessengerC.cpp + } + IDL_Files { + } + verbatim(gnuace, macros) { + VDIR := .obj/Client/ + } +} diff --git a/TAO/orbsvcs/examples/ImR/Advanced/Makefile.am b/TAO/orbsvcs/examples/ImR/Advanced/Makefile.am new file mode 100644 index 00000000000..967ebae0a58 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/Makefile.am @@ -0,0 +1,163 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_IDL = ACE_ROOT=$(ACE_ROOT) TAO_ROOT=$(TAO_ROOT) $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDL_DEP = $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDLFLAGS = -Ge 1 -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -I$(TAO_ROOT) -I$(srcdir) -g $(ACE_BUILDDIR)/apps/gperf/src/gperf +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Advanced_IDL.am + +BUILT_SOURCES = \ + ManagerC.cpp \ + ManagerC.h \ + ManagerC.inl \ + ManagerS.cpp \ + ManagerS.h \ + ManagerS.inl + +CLEANFILES = \ + Manager-stamp \ + ManagerC.cpp \ + ManagerC.h \ + ManagerC.inl \ + ManagerS.cpp \ + ManagerS.h \ + ManagerS.inl + +ManagerC.cpp ManagerC.h ManagerC.inl ManagerS.cpp ManagerS.h ManagerS.inl: Manager-stamp + +Manager-stamp: $(srcdir)/Manager.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -Sa -St $(srcdir)/Manager.idl + @touch $@ + +BUILT_SOURCES += \ + MessengerC.cpp \ + MessengerC.h \ + MessengerC.inl \ + MessengerS.cpp \ + MessengerS.h \ + MessengerS.inl + +CLEANFILES += \ + Messenger-stamp \ + MessengerC.cpp \ + MessengerC.h \ + MessengerC.inl \ + MessengerS.cpp \ + MessengerS.h \ + MessengerS.inl + +MessengerC.cpp MessengerC.h MessengerC.inl MessengerS.cpp MessengerS.h MessengerS.inl: Messenger-stamp + +Messenger-stamp: $(srcdir)/Messenger.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -Sa -St $(srcdir)/Messenger.idl + @touch $@ + + +noinst_HEADERS = \ + Manager.idl \ + Messenger.idl + +## Makefile.Advanced_Client.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += client_main + +client_main_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +client_main_SOURCES = \ + MessengerC.cpp \ + TestClient.cpp \ + client_main.cpp \ + TestClient.h + +client_main_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + +## Makefile.Advanced_Manager.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += manager_main + +manager_main_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +manager_main_SOURCES = \ + ManagerC.cpp \ + ManagerS.cpp \ + Manager_i.cpp \ + manager_main.cpp \ + Manager_i.h + +manager_main_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + +## Makefile.Advanced_Server.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += server_main + +server_main_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +server_main_SOURCES = \ + ManagerC.cpp \ + MessengerC.cpp \ + MessengerS.cpp \ + Messenger_i.cpp \ + TestServer.cpp \ + server_main.cpp \ + Messenger_i.h \ + TestServer.h + +server_main_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/ImR/Advanced/Manager.idl b/TAO/orbsvcs/examples/ImR/Advanced/Manager.idl new file mode 100644 index 00000000000..3b01e2ff7e3 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/Manager.idl @@ -0,0 +1,9 @@ +//$Id$ +interface Manager +{ + long registerServer(); + + void startRetry(in long count); + + long endRetry(); // returns unused attempts +}; diff --git a/TAO/orbsvcs/examples/ImR/Advanced/Manager_i.cpp b/TAO/orbsvcs/examples/ImR/Advanced/Manager_i.cpp new file mode 100644 index 00000000000..7a03c0c7de4 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/Manager_i.cpp @@ -0,0 +1,39 @@ +// -*- C++ -*- +// +// $Id$ +#include "Manager_i.h" + +Manager_i::Manager_i (long retryCount) +: server_instance_(0) +, retry_count_(retryCount) +, retry_attempt_(0) +{ +} + +Manager_i::~Manager_i (void) +{ +} + +CORBA::Long Manager_i::registerServer () +ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (retry_attempt_ < retry_count_) + { + ++retry_attempt_; + return -1; + } + return ++server_instance_; +} + +void Manager_i::startRetry (CORBA::Long count) +ACE_THROW_SPEC ((CORBA::SystemException)) +{ + retry_count_ = count; + retry_attempt_ = 0; +} + +CORBA::Long Manager_i::endRetry () +ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return retry_count_ - retry_attempt_; +} diff --git a/TAO/orbsvcs/examples/ImR/Advanced/Manager_i.h b/TAO/orbsvcs/examples/ImR/Advanced/Manager_i.h new file mode 100644 index 00000000000..5c45021ce6e --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/Manager_i.h @@ -0,0 +1,38 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef MANAGERI_H_ +#define MANAGERI_H_ + +#include "ManagerS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Manager_i + : public virtual POA_Manager +{ +public: + Manager_i (long retryCount); + + virtual ~Manager_i (void); + + virtual CORBA::Long registerServer () + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void startRetry (CORBA::Long count) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Long endRetry () + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + + long server_instance_; + long retry_count_; + long retry_attempt_; +}; + + +#endif /* MANAGERI_H_ */ diff --git a/TAO/orbsvcs/examples/ImR/Advanced/Messenger.idl b/TAO/orbsvcs/examples/ImR/Advanced/Messenger.idl new file mode 100644 index 00000000000..421512c8587 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/Messenger.idl @@ -0,0 +1,6 @@ +//$Id$ +interface Messenger +{ + long send_message(in long thread, in long iter, in long obj, in long req); + oneway void shutdownOrb(); +}; diff --git a/TAO/orbsvcs/examples/ImR/Advanced/Messenger_i.cpp b/TAO/orbsvcs/examples/ImR/Advanced/Messenger_i.cpp new file mode 100644 index 00000000000..235c97a6b6a --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/Messenger_i.cpp @@ -0,0 +1,41 @@ +// -*- C++ -*- +// +// $Id$ + +#include "Messenger_i.h" + +#include <ace/streams.h> + +Messenger_i::Messenger_i (CORBA::ORB_ptr orb, long instance) +: instance_(instance) +, orb_(CORBA::ORB::_duplicate(orb)) +, isHit_(false) +{ +} + +Messenger_i::~Messenger_i (void) +{ +} + +bool Messenger_i::acknowledgeHit() +{ + bool isHit = isHit_; + isHit_ = false; + return isHit; +} + +CORBA::Long Messenger_i::send_message (CORBA::Long thread, + CORBA::Long iter, + CORBA::Long obj, + CORBA::Long req) ACE_THROW_SPEC ((CORBA::SystemException)) +{ + cout << "* Invoked: (" << instance_ << "." << thread << "." << iter + << "." << obj << "." << req << ")" << endl; + isHit_ = true; + return instance_; +} + +void Messenger_i::shutdownOrb () ACE_THROW_SPEC ((CORBA::SystemException)) +{ + orb_->shutdown(0); +} diff --git a/TAO/orbsvcs/examples/ImR/Advanced/Messenger_i.h b/TAO/orbsvcs/examples/ImR/Advanced/Messenger_i.h new file mode 100644 index 00000000000..07730db0cbd --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/Messenger_i.h @@ -0,0 +1,41 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef MESSENGERI_H_ +#define MESSENGERI_H_ + +#include "MessengerS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Messenger_i + : public virtual POA_Messenger +{ +public: + Messenger_i (CORBA::ORB_ptr orb, long instance); + + virtual ~Messenger_i (void); + + virtual + CORBA::Long send_message ( + ::CORBA::Long thread, + ::CORBA::Long iter, + ::CORBA::Long obj, + ::CORBA::Long req + ) ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void shutdownOrb () + ACE_THROW_SPEC ((CORBA::SystemException)); + + bool acknowledgeHit(); + +private: + long instance_; + CORBA::ORB_var orb_; + bool isHit_; +}; + + +#endif /* MESSENGERI_H_ */ diff --git a/TAO/orbsvcs/examples/ImR/Advanced/README b/TAO/orbsvcs/examples/ImR/Advanced/README new file mode 100644 index 00000000000..08a1a004523 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/README @@ -0,0 +1,37 @@ +This example tests several uses of the Implementation Repository. + +How to Run +---------- + +Create driver files: +------------------------------------------------------ +Driver files are stored in the drivers directory. +Each file contains a set of parameters for each execution of the +test. + +Each line item in the file has one of the follow forms. +Empty lines are ignored. + + # <Comment> + begin + <param>=<value> + do <command> + - <Disabled Line> + -- (Begin/End Disabled Block) + +* Comment lines are printed to standard-out. +* 'begin' resets all parameters to default and clears temporary files. +* Parameter assignments override the default values. +* 'do' executes the specified command + - There are three predefined use-case commands + * use_invocation + * use_persistence + * use_environment + - All methods in run-test can be executed with the do command +* Disabled lines are ignored +* The -- designates the begin and end of a block of lines to ignore + +Execute the example script +---------------------------------------------------------------------- +The run_test.pl script reads the driver file and executes each line. +Simply execute run_test.pl to run all test in the drivers directory. diff --git a/TAO/orbsvcs/examples/ImR/Advanced/TestClient.cpp b/TAO/orbsvcs/examples/ImR/Advanced/TestClient.cpp new file mode 100644 index 00000000000..9b2da4d88c8 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/TestClient.cpp @@ -0,0 +1,258 @@ +//$Id$ +#include "TestClient.h" +#include "MessengerC.h" + +#include "tao/ORB_Constants.h" + +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/Get_Opt.h" + +TestClient::TestClient(CORBA::ORB_ptr orb, int argc, char* argv[]) +: orb_(CORBA::ORB::_duplicate(orb)) +, pauseType_('s') +, startupPause_(0) +, threadCount_(0) +, instance_(0) +, iterations_(0) +, requestCount_(0) +, randomRequests_(false) +, shutdownOrb_(false) +, expectHolding_(false) +, expectNoProfile_(false) +{ + parseCommands(argc, argv); +} + +TestClient::~TestClient() +{ +} + +int TestClient::parseCommands(int argc, char* argv[]) +{ + ACE_Get_Opt get_opts(argc, argv, "s:t:i:r:x:e:z:"); + int c; + while ((c = get_opts()) != -1) + { + switch (c) + { + case 's': + startupPause_ = ::atoi(get_opts.opt_arg()); + break; + + case 't': + threadCount_ = ::atoi(get_opts.opt_arg()); + break; + + case 'i': + iterations_ = ::atoi(get_opts.opt_arg()); + break; + + case 'r': + { + const char* opt = get_opts.opt_arg(); + if (opt[0] == 'r') { randomRequests_ = true; opt++; } + requestCount_ = ::atoi(opt); + break; + } + + case 'x': + { + const char* opt = get_opts.opt_arg(); + shutdownOrb_ = (opt && opt[0] != '0'); + break; + } + + case 'e': + { + const char* opt = get_opts.opt_arg(); + while (opt && *opt != '\0') + { + if (*opt == 'h') expectHolding_ = true; + else if (*opt == 'n') expectNoProfile_ = true; + opt++; + } + break; + } + + case 'z': + pauseType_ = get_opts.opt_arg()[0]; + break; + + case '?': + default: + ACE_ERROR_RETURN((LM_ERROR, + "usage: %s\n" + "\t-s <startup pause in milliseconds>\n" + "\t-t <number of threads>\n" + "\t-i <number of iterations per thread>\n" + "\t-r <r><number of requests per string_to_object>\n" + "\t-x 'shutdown server orb at end of a string_to_object'\n" + "\t-e <h><n> 'catch holding or no profile exceptions'\n" + "\n", + argv[0]), + -1); + } + } + return 0; +} + +void TestClient::pause(int milliseconds) +{ + if (milliseconds > 0) + { + if (pauseType_ == 's') + { + ACE_OS::sleep(ACE_Time_Value(0, milliseconds * 1000)); + } + else if (pauseType_ == 'r') + { + ACE_Time_Value tv(0, milliseconds * 1000); + orb_->run(tv); + } + } +} + +void TestClient::run() +{ + ACE_DEBUG((LM_DEBUG, "Starting Client.\n")); + pause(startupPause_); + ACE_DEBUG((LM_DEBUG, "* Client started.\n")); + + buildIORList(); + + if (this->activate(THR_NEW_LWP, threadCount_) == -1) + { + ACE_ERROR((LM_ERROR, "%p\n", "activate failed")); + } + wait(); + + ACE_DEBUG((LM_DEBUG, "* Client ended.\n")); + +} + +// Read in the stringified object references into an array +// Warning: The file may contain many separate IORs separated by linefeeds. +void TestClient::buildIORList() +{ + FILE* iorFile = ACE_OS::fopen ("imr_test.ior", "r"); + if ( iorFile == NULL ) + ACE_ERROR ((LM_ERROR, "Fail to open imr_test.ior\n")); + + ACE_TString ior; + while (getline(iorFile, ior) != EOF ) + { + if (ior.length() > 0) + iors_.push_back(ior); + else + break; + } +} + +int TestClient::svc() +{ + // Every invocation of svc increates the thread count + instance_++; + int threadNum = instance_; + size_t vec_size = iors_.size(); + + ACE_DEBUG((LM_DEBUG, "* Client Thread started (%d.%d.%d.%d)\n", + threadNum, iterations_, vec_size, requestCount_)); + + int i = 0; + size_t objIter = 0; + int requestIter = 0; + + ACE_TString currentIOR; + + ACE_OS::srand(ACE_OS::time()); + + try + { + int holdingCount = 0; + int noProfileCount = 0; + + // For each iteration + for (i = 1; i <= iterations_; i++) + { + // For each object reference read from file + for (objIter = 1; objIter <= vec_size; objIter++) + { + requestIter = -1; + // Get a imr_test_var + currentIOR = iors_[objIter - 1]; + CORBA::Object_var obj = orb_->string_to_object(currentIOR.c_str()); + if (CORBA::is_nil(obj.in()) == false) + { + requestIter = 0; + Messenger_var test = Messenger::_narrow(obj.in()); + + if (CORBA::is_nil(test.in()) == false) + { + // Calculate the number of requests + int newReqCount (randomRequests_ == false ? requestCount_ : + (int)((((double)ACE_OS::rand() / (double)RAND_MAX) * (double)(requestCount_ - 1)) + .5) + 1); + int serverInstance = 0; + // For each request + for (requestIter = 1; requestIter <= newReqCount; requestIter++) + { + try + { + serverInstance = test->send_message(threadNum, i, objIter, requestIter); + } + catch (CORBA::SystemException& ex) + { + // If these exceptions are expected record the number of instances, otherwise rethrow + if (expectHolding_ == true && ex.minor() == TAO_POA_HOLDING) + { + ACE_ERROR((LM_ERROR, "Caught expected holding exception with (%d.%d.%d)\n", + threadNum, objIter, requestIter)); + holdingCount++; + } + else + { + throw; + } + if (expectNoProfile_ == true + && ex.minor() == TAO_INVOCATION_SEND_REQUEST_MINOR_CODE) + { + ACE_ERROR((LM_ERROR, "Caught expected holding exception with (%d.%d.%d)\n", + threadNum, objIter, requestIter)); + noProfileCount++; + } + else + { + throw; + } + } // catch + } // for request + // We are done with our non-nil narrowed obj ref + if (shutdownOrb_ == true) test->shutdownOrb(); + } // if narrow + } // if obj + } // for obj + } // for iter + // Report expected exceptions + if (holdingCount > 0) + { + ACE_DEBUG((LM_DEBUG,"Client thread %d received %d holding error(s).\n", + threadNum, holdingCount)); + } + + if (noProfileCount > 0) + { + ACE_DEBUG((LM_DEBUG,"Client thread %d received %d no profile error(s).\n", + threadNum, noProfileCount)); + } + + return 0; + } // try + catch (CORBA::Exception& ex) + { + ACE_ERROR((LM_ERROR,"CORBA client error with (%d.%d.%d.%d):%s\n", + threadNum, i, objIter, requestIter, currentIOR.c_str())); + ACE_PRINT_EXCEPTION(ex, ""); + } + return 1; +} diff --git a/TAO/orbsvcs/examples/ImR/Advanced/TestClient.h b/TAO/orbsvcs/examples/ImR/Advanced/TestClient.h new file mode 100644 index 00000000000..237437daa5c --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/TestClient.h @@ -0,0 +1,38 @@ +//$Id$ +#include "tao/ORB.h" + +#include "ace/Task.h" + +#include <vector> +#include <string> +#include "ace/Capabilities.h" + +class TestClient : public ACE_Task_Base, public ACE_Capabilities +{ +public: + TestClient(CORBA::ORB_ptr orb, int argc, char* argv[]); + + virtual ~TestClient(); + + void run(); + +private: + int parseCommands(int argc, char* argv[]); + void buildIORList(); + void pause(int milliseconds); + virtual int svc(); + + CORBA::ORB_var orb_; + std::vector<ACE_TString> iors_; + + char pauseType_; + int startupPause_; + int threadCount_; + int instance_; + int iterations_; + int requestCount_; + bool randomRequests_; + bool shutdownOrb_; + bool expectHolding_; + bool expectNoProfile_; +}; diff --git a/TAO/orbsvcs/examples/ImR/Advanced/TestServer.cpp b/TAO/orbsvcs/examples/ImR/Advanced/TestServer.cpp new file mode 100644 index 00000000000..0b01378ccf8 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/TestServer.cpp @@ -0,0 +1,514 @@ +//$Id$ +#include "TestServer.h" + +#include "ManagerC.h" + +#include "tao/Profile.h" +#include "tao/Stub.h" +#include "tao/ORB_Core.h" +#include "tao/PortableServer/Root_POA.h" + +#include "ace/streams.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_ctype.h" +#include "ace/os_include/os_ctype.h" +#include "ace/Get_Opt.h" + +#include <sstream> +#include <utility> + +using std::string; + +// Does this function already exist? +// Is there a path class? + +string normalizePath(const string& dir, char delim = '/', bool toLower = false); +string getWorkingPath(char delim = '/', bool toLower = false); + +string deleteLeaf(const string& dir) +{ + string temp = dir; + temp.resize(dir.find_last_of("/\\")); + return temp; +} + +string getWorkingPath(char delim, bool toLower) +{ + char buffer[PATH_MAX + 2]; + ACE_OS::getcwd(buffer, PATH_MAX); + return normalizePath(buffer, delim, toLower); +} + +string normalizePath(const string& dir, char delim, bool toLower) +{ + if (dir.empty() == true) return string(); + char buffer[PATH_MAX + 2]; + + string::size_type i = 0; + + for (; ACE_OS::ace_isspace(dir[i]); i++); + + string::size_type begin = i; + + int j = 0; + for (; i < dir.size(); i++) + { + if (dir[i] == '\\' || dir[i] == '/') + { + // skip redundant + if (dir[i + 1] == '\\' || dir[i + 1] == '/') + { + } + // Convert to proper delim + else + { + buffer[j] = delim; j++; + } + } + else if (dir[i] == '.') + { + // If specifying current, skip + if (dir[i + 1] == '\\' || dir[i + 1] == '/' || dir[i + 1] == '\0') + { + if (i == begin) // relative start + { + string curDir = getWorkingPath(); + ACE_OS::strncpy(buffer, curDir.c_str(), sizeof(buffer)); + j = curDir.length(); + } + else + { + i += 2; + } + } + // If specifying parent, go back + else if (dir[i + 1] == '.') + { + if (i == begin) // relative start + { + string curDir = getWorkingPath(); + ACE_OS::strncpy(buffer, curDir.c_str(), sizeof(buffer)); + j = curDir.length(); + } + int k = j; + for (; buffer[k] != delim; k--); + k--; + for (; buffer[k] != delim; k--); + j = (k + 1); + i+=2; + } + else + { + if (toLower) + buffer[j] = ::tolower(dir[i]); + else + buffer[j] = dir[i]; + j++; + } + } + // normal character + else + { + if (toLower) + buffer[j] = ::tolower(dir[i]); + else + buffer[j] = dir[i]; + j++; + } + } + + if (buffer[j - 1] == delim) j--; + buffer[j] ='\0'; + return string(buffer); +} + +TestServer::TestServer(CORBA::ORB_ptr orb, int argc, char* argv[]) +: serverID_(1) +, serverInstanceID_(-1) +, useIORTable_(false) +, writeIORFile_(false) +, retryQuery_(false) +, pauseType_('s') +, startupPause_(0) +, objActivatePause_(0) +, activatePause_(0) +, runPause_(0) +, numPOAS_(0) +, numObjsPerPOA_(0) +, useItLoseItSecs_(0) +, orb_(CORBA::ORB::_duplicate(orb)) +, iorTable_(IORTable::Table::_nil()) +, root_(PortableServer::POA::_nil()) +, mgr_(PortableServer::POAManager::_nil()) +{ + parseCommands(argc, argv); + + verifyEnvironment(); + + // We really do not want the current directory set by the + // activator. baseDir_ is where all the operation files are. + if (baseDir_.empty() == false) + { + ACE_OS::chdir(baseDir_.c_str()); + } +} + +TestServer::~TestServer() +{ + root_->destroy(1, 1); +} + +// TestServer::parseCommands +// Reads params from command line +// +int TestServer::parseCommands(int argc, char* argv[]) +{ + ACE_Get_Opt get_opts(argc, argv, "w:e:d:t:o:s:c:a:r:p:n:x:z:q:b:"); + int c; + while ((c = get_opts()) != -1) + { + switch (c) + { + case 'w': + expectedDir_ = normalizePath(get_opts.opt_arg()); + break; + + case 'e': + { + string name = get_opts.opt_arg(); + string::size_type i = name.find_first_of("="); + string value = name.substr(i + 1, name.length() - 1); + name.resize(i); + expectedEnv_.push_back(std::make_pair(name, value)); + break; + } + + case 'd': + serverID_ = ACE_OS::atoi(get_opts.opt_arg()); + break; + + case 't': + { + const char* opt = get_opts.opt_arg(); + useIORTable_ = (opt && opt[0] != '0'); + break; + } + + case 'q': + { + const char* opt = get_opts.opt_arg(); + retryQuery_ = (opt && opt[0] != '0'); + break; + } + + case 'o': + { + const char* opt = get_opts.opt_arg(); + writeIORFile_ = (opt && opt[0] != '0'); + break; + } + + case 's': + startupPause_ = ACE_OS::atoi(get_opts.opt_arg()); + break; + + case 'c': + objActivatePause_ = ACE_OS::atoi(get_opts.opt_arg()); + break; + + case 'a': + activatePause_ = ACE_OS::atoi(get_opts.opt_arg()); + break; + + case 'r': + runPause_ = ACE_OS::atoi(get_opts.opt_arg()); + break; + + case 'p': + numPOAS_ = ACE_OS::atoi(get_opts.opt_arg()); + break; + + case 'n': + numObjsPerPOA_ = ACE_OS::atoi(get_opts.opt_arg()); + break; + + case 'x': + useItLoseItSecs_ = ACE_OS::atoi(get_opts.opt_arg()); + break; + + case 'z': + pauseType_ = get_opts.opt_arg()[0]; + break; + + case 'b': + baseDir_ = get_opts.opt_arg(); + break; + + case '?': + default: + ACE_ERROR_RETURN((LM_ERROR, + "usage: %s\n" + "\t-d <startup pause in milliseconds>\n" + "\t-t 'use IOR Table'\n" + "\t-o 'write the IOR file'\n" + "\t-s <startup pause in milliseconds>\n" + "\t-a <activation pause in milliseconds>\n" + "\t-r <run pause in milliseconds>\n" + "\t-p <number of POAS>\n" + "\t-n <number of objects per POA>\n" + "\t-x <number of seconds from last hit till exit>\n" + "\t-e <expected_env_var_name>=<value> 'can be repeated'\n" + "\t-w <expected_working_directory>\n" + "\n", + argv[0]), + -1); + } + } + return 0; +} + +// TestServer::verifyEnvironment +// Checks to see if the activator setup requested env vars and current directory +// +bool TestServer::verifyEnvironment() const +{ + bool err = false; + + // Check paths + string currentDir = getWorkingPath(); + if (expectedDir_.empty() == false && currentDir != expectedDir_) + { + ACE_DEBUG((LM_DEBUG, "Error: directory paths (%s,%s) do not match.\n", + currentDir.c_str(), expectedDir_.c_str())); + err |= true; + } + + // Check env vars + for (string::size_type i = 0; i < expectedEnv_.size(); i++) + { + const char* realValue = ACE_OS::getenv(expectedEnv_[i].first.c_str()) ; + if (realValue == NULL) + { + ACE_DEBUG((LM_DEBUG, "Error, env variable '%s' not found\n", + expectedEnv_[i].first.c_str())); + err |= true; + } + else if (expectedEnv_[i].second != realValue) + { + ACE_DEBUG((LM_DEBUG, "Error, env variable '%s' values (%s,%s) do not match.\n", + expectedEnv_[i].first.c_str(), realValue, expectedEnv_[i].second.c_str())); + err |= true; + } + } + + return (err ? 1 : 0); +} + +// TestServer::pause +// Pause processing by either sleep or timed run-loop +// +void TestServer::pause(int milliseconds) +{ + if (milliseconds > 0) + { + if (pauseType_ == 's') + { + ACE_OS::sleep(ACE_Time_Value(0, milliseconds * 1000)); + } + else if (pauseType_ == 'r') + { + ACE_Time_Value tv(0, milliseconds * 1000); + orb_->run(tv); + } + else + { + ACE_ASSERT(pauseType_ == 'r'); + } + } +} + +void TestServer::run() +{ + pause(startupPause_); + + // FUZZ: disable check_for_missing_rir_env + CORBA::Object_var obj = orb_->resolve_initial_references("RootPOA"); + root_ = PortableServer::POA::_narrow(obj.in()); + mgr_ = root_->the_POAManager(); + + if (registerWithManager() == false) + return; + + ACE_DEBUG((LM_DEBUG, "* Server (%d.%d) started.\n", + serverID_, serverInstanceID_)); + + if (useIORTable_ == true) + { + // FUZZ: disable check_for_missing_rir_env + CORBA::Object_var obj = orb_->resolve_initial_references("IORTable"); + iorTable_ = IORTable::Table::_narrow(obj.in()); + } + + servant_.reset(new Messenger_i(orb_.in(), serverInstanceID_)); + + buildObjects(); + + pause(activatePause_); + mgr_->activate(); + + if (useItLoseItSecs_ > 0) + { + pause(runPause_); + do + { + ACE_Time_Value tv(useItLoseItSecs_); + orb_->run(tv); + } while (orb_->orb_core()->has_shutdown() == 0 + && servant_->acknowledgeHit()); + } + + if (orb_->orb_core()->has_shutdown() != 0) + { + ACE_DEBUG((LM_DEBUG, "* Server (%d.%d) ended.\n", + serverID_, serverInstanceID_)); + } + else + { + ACE_DEBUG((LM_DEBUG, "* Server (%d.%d) self terminated.\n", + serverID_, serverInstanceID_)); + } +} + +// TestServer::registerServer +// This will register the server with the manager. +// +bool TestServer::registerWithManager() +{ + // So-far, the use cases dictate writting IOR + // responsibility is exclusive of registering + if (writeIORFile_ == false) + { + // Get the manager's ref + CORBA::Object_var obj = orb_->string_to_object("file://manager.ior"); + if (CORBA::is_nil(obj.in())) + { + cerr << "Server Error: Could not get Manager IOR." << endl; + return false; + } + Manager_var manager = Manager::_narrow(obj.in()); + if (CORBA::is_nil(manager.in())) { + cerr << "Server Error: IOR was not a Manager object reference." << endl; + return false; + } + + // If this is a query process + if (retryQuery_ == true) + { + int diff = manager->endRetry(); + if (diff != 0) + { + ACE_DEBUG((LM_DEBUG, "* Server Error: Not all retry attempts were made.\n")); + } + return false; + } + else // Get the server ID + { + serverInstanceID_ = manager->registerServer(); + if (serverInstanceID_ == -1) + { + ACE_DEBUG((LM_DEBUG, "* Server (%d,%d) could not register.\n", + serverID_, serverInstanceID_)); + return false; + } + } + } + return true; +} + +// TestServer::buildObjects +// Builds all the objects required by the client and server +// Writes IORs if requested +// +void TestServer::buildObjects() +{ + // Append to existing file + ofstream iorFile("imr_test.ior", ios::app); + + // Create number of requested POAS + for (int i = 0; i < numPOAS_; i++) + { + CORBA::PolicyList policies(3); + policies.length(3); + policies[0] = root_->create_id_assignment_policy(PortableServer::USER_ID); + policies[1] = root_->create_id_uniqueness_policy(PortableServer::MULTIPLE_ID); + policies[2] = root_->create_lifespan_policy(PortableServer::PERSISTENT); + + // Create a POA + string poaName; + { + std::stringstream poaStream; + poaStream << "POA_" << serverID_ << "_" << (i + 1); + poaName = poaStream.str(); + } + + ACE_DEBUG((LM_DEBUG, "* Creating POA: %s\n", poaName.c_str())); + + PortableServer::POA_var sub_poa = root_->create_POA(poaName.c_str(), mgr_.in(), policies); + + pause(objActivatePause_); + // Create number of requested object references + for (int j = 0; j < numObjsPerPOA_; j++) + { + // Create object reference and activate it + string objName; + { + std::stringstream objStream; + objStream << "OBJ_" << serverID_ << "_" << (i + 1) << "_" << (j + 1); + objName = objStream.str(); + } + ACE_DEBUG((LM_DEBUG, "* Activating Obj: %s\n", objName.c_str())); + + PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId(objName.c_str()); + sub_poa->activate_object_with_id(oid.in(), servant_.get()); + + // Output the stringified ID to the file for the client + if (! useIORTable_) + { + if (writeIORFile_) + { + // Write out IOR + CORBA::Object_var obj = sub_poa->id_to_reference(oid.in()); + CORBA::String_var ior = orb_->object_to_string(obj.in()); + iorFile << ior.in () << endl; + } + } + else // use IOR table + { + // Write out corbaloc + TAO_Root_POA* tmp_poa = dynamic_cast<TAO_Root_POA*>(sub_poa.in()); + // Make entry into ior table using the non IMRified object ref. + CORBA::Object_var obj = tmp_poa->id_to_reference_i(oid.in(), false); + CORBA::String_var ior = orb_->object_to_string(obj.in()); + string key = (poaName + "/" + objName); + iorTable_->bind(key.c_str(), ior.in()); + + if (writeIORFile_) + { + // Use the IMRified object ref to create the corbaloc. + CORBA::Object_var obj = sub_poa->id_to_reference(oid.in()); + + // Create a corbaloc + TAO_Profile* profile = obj->_stubobj()->profile_in_use(); + CORBA::String_var temp = profile->to_string(); + string corbaloc = temp.in(); + corbaloc.resize(corbaloc.find_first_of(profile->object_key_delimiter()) + 1); + corbaloc += key; + + // Write out corbaloc + iorFile << corbaloc.c_str() << endl; + } + } + } + } +} diff --git a/TAO/orbsvcs/examples/ImR/Advanced/TestServer.h b/TAO/orbsvcs/examples/ImR/Advanced/TestServer.h new file mode 100644 index 00000000000..d18bd441c6b --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/TestServer.h @@ -0,0 +1,50 @@ +//$Id$ +#include "Messenger_i.h" + +#include "ace/Auto_Ptr.h" + +#include "tao/IORTable/IORTable.h" + +#include <string> +#include <vector> + +class TestServer +{ +public: + TestServer(CORBA::ORB_ptr, int argc, char* argv[]); + + ~TestServer(); + + void run(); + +private: + int parseCommands(int argc, char* argv[]); + bool verifyEnvironment() const; + bool registerWithManager(); + void buildObjects(); + void pause(int milliseconds); + + int serverID_; + int serverInstanceID_; + bool useIORTable_; + bool writeIORFile_; + bool retryQuery_; + char pauseType_; + int startupPause_; + int objActivatePause_; + int activatePause_; + int runPause_; + int numPOAS_; + int numObjsPerPOA_; + int useItLoseItSecs_; + + std::string baseDir_; + std::string expectedDir_; + std::vector<std::pair<std::string, std::string> > expectedEnv_; + ACE_Auto_Ptr<Messenger_i> servant_; + + CORBA::ORB_var orb_; + IORTable::Table_var iorTable_; + PortableServer::POA_var root_; + PortableServer::POAManager_var mgr_; +}; diff --git a/TAO/orbsvcs/examples/ImR/Advanced/client_main.cpp b/TAO/orbsvcs/examples/ImR/Advanced/client_main.cpp new file mode 100644 index 00000000000..bcebff9a94f --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/client_main.cpp @@ -0,0 +1,25 @@ +//$Id$ +#include "TestClient.h" + +#include <ace/streams.h> + +int main(int argc, char* argv[]) +{ + try + { + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); + + { + TestClient client(orb.in(), argc, argv); + client.run(); + } + + orb->destroy(); + return 0; + } + catch (CORBA::Exception& ex) + { + cerr << "TestClient: " << ex << endl; + } + return 1; +} diff --git a/TAO/orbsvcs/examples/ImR/Advanced/drivers/all b/TAO/orbsvcs/examples/ImR/Advanced/drivers/all new file mode 100644 index 00000000000..d4a342bc676 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/drivers/all @@ -0,0 +1,6 @@ +# All Tests +run invocation +run environment +run persistence +run retry + diff --git a/TAO/orbsvcs/examples/ImR/Advanced/drivers/defaults b/TAO/orbsvcs/examples/ImR/Advanced/drivers/defaults new file mode 100644 index 00000000000..212a54c6bfb --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/drivers/defaults @@ -0,0 +1,76 @@ +- General + +- How should pauses be performed +pause_type=s +- Which file to parse next +file= + +- IMR + +- Is the ImR even turned on +imr_on=1 +- Shutdown the ImR using the tao_imr tool +imr_shutdown=0 +- Time between pings, in milliseconds +imr_ping_interval=10 +- Timeout for server activation, in seconds +imr_startup_timeout=5 +- The IMR's debug level [0-2] +imr_debug_level=1 +- How the IMR saves its information (registry, binary, XML) +imr_persistence= +- Clear the persistence on load +imr_persistence_clear=1 +- The enpoint for the IMR service +imr_endpoint=iiop://:33333 + +- Activator + +- Activator mode (empty), normal, manual, auto_start, per_client +activate_mode= +- Server retry count for the activator +activate_retry=0 +- How to register the servers, update or add +registration_type=update +- Number of test environment varaiables +env_varnum=0 +- Test working directory +env_dir= + +- Server + +- Server's reference style +server_ref_style= +- Use IORTable +server_ior_table=0 +- Pause before POA and servant creation, in milliseconds +server_start_pause=0 +- Pause before object activation, in milliseconds +server_obj_act_pause=0 +- Pause before POA MGR activate, in milliseconds +server_activate_pause=0 +- Pause before orb run, in milliseconds +server_run_pause=0 +- Inactivity shutdown time during run, in seconds +server_hit_time_min=15 +- Number of POAS to create +server_poas=2 +- Number of servant activations (IORS)per POA to create +server_poa_objs=2 + +- Client + +- Pause before thread creation, in milliseconds +client_start_pause=100 +- Number of threads to create +client_threads=2 +- Number of work iterations per thread +client_iterations=2 +- Number of requests per IOR +client_requests=2 +- Make the number of requests random per IOR +client_rand_req=0 +- Expect holding exceptions +client_holding=0 +- Expent no-profile exceptions +client_noprofile=0
\ No newline at end of file diff --git a/TAO/orbsvcs/examples/ImR/Advanced/drivers/environment b/TAO/orbsvcs/examples/ImR/Advanced/drivers/environment new file mode 100644 index 00000000000..5002846cc03 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/drivers/environment @@ -0,0 +1,14 @@ +# +# Environment Tests +# + +# Simple Environment +begin +imr_shutdown=2 +server_poas=1 +server_poa_objs=0 +activate_mode=manual +registration_type=add +env_varnum=4 +env_dir=./drivers +run use_environment diff --git a/TAO/orbsvcs/examples/ImR/Advanced/drivers/invocation b/TAO/orbsvcs/examples/ImR/Advanced/drivers/invocation new file mode 100644 index 00000000000..5a91bc532f3 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/drivers/invocation @@ -0,0 +1,48 @@ +# +# Invocation Tests +# + +# Default test +begin +run use_invocation + +# Default IOR Table +begin +server_ior_table=1 +run use_invocation + +# Default Activator +begin +activate_mode=normal +run use_invocation + +# Default Activator IOR Table +begin +server_ior_table=1 +activate_mode=normal +run use_invocation + +# Default Activator Per Client +begin +activate_mode=per_client +run use_invocation + +# Default Activator Per Client IOR Table +begin +server_ior_table=1 +activate_mode=per_client +run use_invocation + +# Default Activator Manual +begin +activate_mode=manual +run use_invocation + +# Default Activator Manual IOR Table +begin +server_ior_table=1 +activate_mode=manual +run use_invocation + +- activate_mode=auto_start is tested in persistence.txt + diff --git a/TAO/orbsvcs/examples/ImR/Advanced/drivers/persistence b/TAO/orbsvcs/examples/ImR/Advanced/drivers/persistence new file mode 100644 index 00000000000..4d522eddc11 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/drivers/persistence @@ -0,0 +1,57 @@ +# +# Persistence Tests +# + +# Default Persistence w/ auto_start - XML +begin +server_poas=1 +server_poa_objs=1 +client_threads=1 +client_iterations=1 +client_requests=1 +imr_persistence=XML +activate_mode=manual +env_varnum=4 +env_dir=./drivers +run use_persistence + +# Default Persistence w/ auto_start - Binary +begin +server_poas=1 +server_poa_objs=1 +client_threads=1 +client_iterations=1 +client_requests=1 +imr_persistence=binary +activate_mode=auto_start +env_varnum=4 +env_dir=./drivers +run use_persistence + +# Default Persistence w/ auto_start - Registry +begin +server_poas=1 +server_poa_objs=1 +client_threads=1 +client_iterations=1 +client_requests=1 +imr_persistence=registry +activate_mode=auto_start +env_varnum=4 +env_dir=./drivers +run use_persistence + +-- +# Clear the persistence +begin +imr_persistence_clear=1 +imr_persistence=registry +do start_imr(); +do kill_imr(); +imr_persistence=XML +do start_imr(); +do kill_imr(); +imr_persistence=binary +do start_imr(); +do kill_imr(); +--
\ No newline at end of file diff --git a/TAO/orbsvcs/examples/ImR/Advanced/drivers/retry b/TAO/orbsvcs/examples/ImR/Advanced/drivers/retry new file mode 100644 index 00000000000..7bcfdd99631 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/drivers/retry @@ -0,0 +1,28 @@ +# +# Retry Tests +# + +# Simple Retry Test +begin +server_poas=1 +server_poa_objs=1 +client_threads=1 +client_iterations=1 +client_requests=1 +activate_retry=4 +activate_mode=per_client +run use_invocation + +# Simple Ping Test +begin +debug_level=2 +activate_mode=manual +server_poas=1 +server_poa_objs=1 +client_threads=1 +client_iterations=1 +client_requests=1 +env_pause_type=r +ping_interval=500 +server_activate_pause=10000 +run use_invocation diff --git a/TAO/orbsvcs/examples/ImR/Advanced/drivers/use_environment b/TAO/orbsvcs/examples/ImR/Advanced/drivers/use_environment new file mode 100644 index 00000000000..35b5c3f0525 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/drivers/use_environment @@ -0,0 +1,19 @@ +- use_environment + +do start_imr +do start_activator + +# Regester Server (1/2) +do register_server +do activate_server +do kill_server +do unregister_server + +# Regester Server (2/2) +do register_server +do activate_server +do kill_server +do unregister_server + +do kill_activator +do kill_imr
\ No newline at end of file diff --git a/TAO/orbsvcs/examples/ImR/Advanced/drivers/use_invocation b/TAO/orbsvcs/examples/ImR/Advanced/drivers/use_invocation new file mode 100644 index 00000000000..927d1ab4100 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/drivers/use_invocation @@ -0,0 +1,12 @@ +- use_invocation + +do invoke_stats +do start_imr +do write_iors +do start_activator +do register_server +do start_server +do launch_client +do kill_server +do kill_activator +do kill_imr diff --git a/TAO/orbsvcs/examples/ImR/Advanced/drivers/use_persistence b/TAO/orbsvcs/examples/ImR/Advanced/drivers/use_persistence new file mode 100644 index 00000000000..9124a28ceaa --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/drivers/use_persistence @@ -0,0 +1,22 @@ +- use_persistence + +# Start the IMR +# +imr_persistence_clear=1 +do invoke_stats +do start_imr(); +do start_activator +do write_iors +do register_server +do kill_imr + +# Reload the IMR +# +imr_persistence_clear=0 +do start_imr +do activator_list +do start_server +do launch_client +do kill_server +do kill_activator +do kill_imr
\ No newline at end of file diff --git a/TAO/orbsvcs/examples/ImR/Advanced/manager_main.cpp b/TAO/orbsvcs/examples/ImR/Advanced/manager_main.cpp new file mode 100644 index 00000000000..6be76baf992 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/manager_main.cpp @@ -0,0 +1,59 @@ +//$Id$ +#include "Manager_i.h" + +#include <ace/Get_Opt.h> +#include <ace/streams.h> + +int main(int argc, char* argv[]) +{ + try + { + long retryCount = 0; + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); + + ACE_Get_Opt get_opts(argc, argv, "r:"); + int c; + while ((c = get_opts()) != -1) + { + switch (c) + { + case 'r': + retryCount = ::atoi(get_opts.opt_arg()); + break; + case '?': + default: + cout << "Usage: " << argv[0] << " [-r retryCount]" << endl; + break; + } + } + + CORBA::Object_var obj = orb->resolve_initial_references("RootPOA"); + PortableServer::POA_var poa = PortableServer::POA::_narrow(obj.in()); + + PortableServer::POAManager_var mgr = poa->the_POAManager(); + + Manager_i servant(retryCount); + PortableServer::ObjectId_var oid = poa->activate_object(&servant); + obj = poa->id_to_reference(oid.in()); + { + CORBA::String_var ior = orb->object_to_string(obj.in()); + ofstream iorFile("manager.ior"); + iorFile << ior.in() << endl; + } + + cout << "IMR Test Manager activated (servers retry = " << retryCount << ")." << endl; + + mgr->activate(); + + orb->run(); + + poa->destroy(1, 1); + orb->destroy(); + return 0; + } + catch (CORBA::Exception& ex) + { + cerr << "Manager: " << ex << endl; + } + return 1; +} diff --git a/TAO/orbsvcs/examples/ImR/Advanced/run_test.pl b/TAO/orbsvcs/examples/ImR/Advanced/run_test.pl new file mode 100755 index 00000000000..ff25de6d125 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/run_test.pl @@ -0,0 +1,519 @@ +##$Id$ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# This test currently does not perform +# ImplRepo_Service -m (multicast) +# ImplRepo_Service -l (loack database) +# ImplRepo_Service -c (install/remove Windows service) +# tao_imr shutdown -l hostname (shutdown servers on a specific host) +# tao_imr shutdown_repo (shutting down ImplRepo_Service via tao_imr) + +#use strict; +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; +use Sys::Hostname; +use File::Spec; +use Getopt::Long; + + +# Initialize variables +my %TestParams; +my $IMPL_IOR = "-ORBInitRef ImplRepoService=file://implrepo.ior"; +my $ENV_CMD; +my $IMR_CMD; +my $ACT_CMD; +my $IOR_CMD; +my $SERVER_CMD; +my $CLIENT_CMD; +my $MGR; +my $IMPL; +my $ACT; +my $SERVER; + +# Get command line params +$TestParams{file} = "./drivers/all"; +GetOptions("file|f=s" => \$TestParams{file}); +parse_file(); + +# Open the Param file and run the tests within +sub parse_file +{ + my $fh; + my $file = $TestParams{file}; + + my $disabled_block = 0; + if (open($fh, $file)) + { + while (<$fh>) + { + my $line = $_; + $line =~ s/\s+$//; + + # If the line is negated, ignore it + if ($line =~ /^--/) + { + $disabled_block = ! ($disabled_block); + } + + elsif ($disabled_block == 0) + { + # If the line is negated, ignore it + if ($line =~ /^-/) + { + } + + # If the line is a comment, print it + elsif ($line =~ /^#/) + { + print "$line\n"; + } + + # Start defining an execution + elsif ($line =~ /^begin/) + { + $TestParams{file} = "./drivers/defaults"; + parse_file(); + } + + # Parse a new file + elsif ($line =~ /^run (\w+)/) + { + $TestParams{file} = "./drivers/$1"; + parse_file(); + } + + # Acquire parameter + elsif ($line =~ /(\w+)=(.*)/) + { + &acquire_param($1, $2); + } + + # Execute a single line + elsif ($line =~ /^do (\w+)/) + { + my $methodRef = $1; + &$methodRef(); #how do I do this in the strict mode? + } + } + } + } +} + +sub invoke_stats() +{ + my $IORS = ($TestParams{server_poas} * $TestParams{server_poa_objs}); + my $THREAD_REQ = ($TestParams{client_iterations} * $IORS * $TestParams{client_requests}); + my $TOTAL_REQ = ($TestParams{client_threads} * $THREAD_REQ); + + my $RAND_MSG = ""; + if ($TestParams{client_rand_req} ne "0") + { + $RAND_MSG = "(max random)"; + } + print "* Invocation Stats\n"; + print "* POAs: $TestParams{server_poas}\n"; + print "* Obj/POA: $TestParams{server_poa_objs}\n"; + print "* IORs: $IORS\n"; + print "* Threads: $TestParams{client_threads}\n"; + print "* Iterations/Thread: $TestParams{client_iterations}\n"; + print "* Requests/Thread: $THREAD_REQ $RAND_MSG\n"; + print "* Total Requests: $TOTAL_REQ $RAND_MSG\n"; +} + +sub start_imr +{ + generateCommands(); + + # Start the manager + unlink "manager.ior"; + $MGR = new PerlACE::Process("manager_main", "-r $TestParams{activate_retry}"); + $MGR->Spawn(); + PerlACE::waitforfile_timed("manager.ior", 10); + + if ($TestParams{imr_on} eq "1") + { + # Start the IMR Service + unlink "implrepo.ior"; + $IMPL = new PerlACE::Process( + "$ENV{ACE_ROOT}/TAO/orbsvcs/ImplRepo_Service/ImplRepo_Service", + $IMR_CMD); + $IMPL->Spawn(); + PerlACE::waitforfile_timed("implrepo.ior", 10); + } +} + +sub kill_imr +{ + if ($TestParams{imr_on} eq "1") + { + if ($TestParams{imr_shutdown} ne "0") + { + my $tool_params = "$IMPL_IOR shutdown-repo"; + if ($TestParams{imr_shutdown} eq "2" && $TestParams{activate_mode} ne "") + { + $tool_params = "$tool_params -a"; + } + + my $TOOL = new PerlACE::Process("$ENV{ACE_ROOT}/bin/tao_imr", $tool_params); + $TOOL->IgnoreExeSubDir(1); + $TOOL->SpawnWaitKill(5); + + # test $IMPL + if ($TestParams{imr_shutdown} eq "2" && $TestParams{activate_mode} ne "") + { + $ACT->WaitKill(5); + print "* Activator Killed.\n"; + } + $IMPL->WaitKill(5); + } + else + { + $IMPL->TerminateWaitKill(1); + } + print "* IMR Killed.\n"; + } + + my $TEMP_SERV = new PerlACE::Process("server_main", "-q 1 -x 0"); + $TEMP_SERV->SpawnWaitKill(5); + $MGR->Kill(); +} + +# write_iors +# creates the IORS for all the objects the client will invoke +# The POAs will be temporarely registered with the IMR. +sub write_iors +{ + generateCommands(); + unlink "imr_test.ior"; + if ($TestParams{activate_mode} eq "per_client") + { + # Run a single fake server for every POA + for (my $i = 1; $i <= $TestParams{server_poas}; $i++) + { + my $TEMP_SERV = new PerlACE::Process("server_main", "$IOR_CMD -p 1 -d " . $i); + $TEMP_SERV->SpawnWaitKill(5); + } + print "* IORs Written\n"; + } + elsif ($TestParams{activate_mode} ne "") + { + # Run a single fake server for all POAs + my $TEMP_SERV = new PerlACE::Process("server_main", "$IOR_CMD -d 1 -p $TestParams{server_poas}"); + $TEMP_SERV->SpawnWaitKill(5); + PerlACE::waitforfile_timed("imr_test.ior", 10); + print "* IORs Written\n"; + } + else + { + # Without an activator, the server will write the IORs when manually launched + } +} + +sub start_activator +{ + if ($TestParams{activate_mode} ne "") + { + generateCommands(); + + # Start the Activator + unlink "activator.ior"; + $ACT = new PerlACE::Process( + "$ENV{ACE_ROOT}/TAO/orbsvcs/ImplRepo_Service/ImR_Activator", + $ACT_CMD); + $ACT->Spawn(); + PerlACE::waitforfile_timed("activator.ior", 5); + } +} + +sub kill_activator() +{ + if ($TestParams{activate_mode} ne "") + { + if ($TestParams{imr_shutdown} ne "2") + { + $ACT->TerminateWaitKill(1); + print "* Activator Killed.\n"; + } + } +} + +# activator_list +# Lists the known servers +sub activator_list() +{ + my $TOOL = new PerlACE::Process("$ENV{ACE_ROOT}/bin/tao_imr", "$IMPL_IOR list -v"); + $TOOL->IgnoreExeSubDir(1); + $TOOL->SpawnWaitKill(5); + + # TODO: parse output and check values +} + +# register_server +# Makes the activator know about the server +# Does nothing for the no-activator mode +sub register_server() +{ + if ($TestParams{activate_mode} eq "per_client") + { + # Register a single POA for each server + generateCommands(); + my $actname = hostname; + for (my $i = 1; $i <= $TestParams{server_poas}; $i++) + { + my $TOOL = new PerlACE::Process("$ENV{ACE_ROOT}/bin/tao_imr", "$IMPL_IOR $TestParams{registration_type} POA_".$i."_1 -c \"server_main $SERVER_CMD -d ".$i." -p 1\" -a $TestParams{activate_mode} -r $TestParams{activate_retry} -l $actname $ENV_CMD"); + $TOOL->IgnoreExeSubDir(1); + $TOOL->SpawnWaitKill(5); + } + } + elsif ($TestParams{activate_mode} ne "") + { + # Register only the first POA for our server + # The remaining POAs will auto-register when the server is started + generateCommands(); + my $actname = hostname; + my $TOOL = new PerlACE::Process("$ENV{ACE_ROOT}/bin/tao_imr", "$IMPL_IOR $TestParams{registration_type} POA_1_1 -c \"server_main $SERVER_CMD -d 1 -p $TestParams{server_poas}\" -a $TestParams{activate_mode} -r $TestParams{activate_retry} -l $actname $ENV_CMD"); + $TOOL->IgnoreExeSubDir(1); + $TOOL->SpawnWaitKill(5); + } + else + { + # nothing to register without an activator + } +} + +sub unregister_server() +{ + if ($TestParams{activate_mode} eq "per_client") + { + # Register a single POA for each server + generateCommands(); + my $actname = hostname; + for (my $i = 1; $i <= $TestParams{server_poas}; $i++) + { + my $TOOL = new PerlACE::Process("$ENV{ACE_ROOT}/bin/tao_imr", "$IMPL_IOR remove POA_".$i."_1"); + $TOOL->IgnoreExeSubDir(1); + $TOOL->SpawnWaitKill(5); + } + } + elsif ($TestParams{activate_mode} ne "") + { + # Register only the first POA for our server + # The remaining POAs will auto-register when the server is started + generateCommands(); + my $actname = hostname; + my $TOOL = new PerlACE::Process("$ENV{ACE_ROOT}/bin/tao_imr", "$IMPL_IOR remove POA_1_1"); + $TOOL->IgnoreExeSubDir(1); + $TOOL->SpawnWaitKill(5); + } + else + { + # nothing is registered without an activator + } +} + + +# start_server +# This method is called before the client is luanched. +# It only launches the server for the two manual modes (no-act and manual-act). +sub start_server() +{ + if ($TestParams{activate_mode} eq "") + { + generateCommands(); + $SERVER = new PerlACE::Process("server_main", "$SERVER_CMD -d 1 -o 1 -p $TestParams{server_poas}"); + $SERVER->Spawn(); + PerlACE::waitforfile_timed("imr_test.ior", 10); + } + elsif ($TestParams{activate_mode} eq "manual") + { + activate_server(); + } + else + { + # The server will be launched by the ImR or Client + } +} + +# Activate Server +# This method is an alternative way to start the server. +# It will activate the servers regardless of mode. +sub activate_server +{ + if ($TestParams{activate_mode} eq "per_client") + { + # Register a single POA for each server + generateCommands(); + my $actname = hostname; + for (my $i = 1; $i <= $TestParams{server_poas}; $i++) + { + my $TOOL = new PerlACE::Process("$ENV{ACE_ROOT}/bin/tao_imr", "$IMPL_IOR activate POA_".$i."_1"); + $TOOL->IgnoreExeSubDir(1); + $TOOL->SpawnWaitKill(5); + } + } + elsif ($TestParams{activate_mode} ne "") + { + # Register only the first POA for our server + # The remaining POAs will auto-register when the server is started + generateCommands(); + my $actname = hostname; + my $TOOL = new PerlACE::Process("$ENV{ACE_ROOT}/bin/tao_imr", "$IMPL_IOR activate POA_1_1"); + $TOOL->IgnoreExeSubDir(1); + $TOOL->SpawnWaitKill(5); + } + else # No activator + { + start_server(); + } +} + +# kill server +# This method is called when the services of the server are no longer required. +# per_client does nothing. +sub kill_server() +{ + if ($TestParams{activate_mode} eq "per_client") + { + # clients do this + } + elsif ($TestParams{activate_mode} ne "") + { + # Kill the single server + my $TOOL = new PerlACE::Process("$ENV{ACE_ROOT}/bin/tao_imr", "$IMPL_IOR shutdown POA_1_1"); + $TOOL->SpawnWaitKill(5); + } + else + { + $SERVER->Kill(); + print "* Server Killed.\n"; + } +} + +# launch_client +# This method spawns the client and blocks until the client is done +sub launch_client +{ + generateCommands(); + if ($TestParams{activate_mode} eq "per_client") + { + my $CLIENT = new PerlACE::Process("client_main", "$CLIENT_CMD -x 1"); + $CLIENT->SpawnWaitKill(500); + } + else + { + my $CLIENT = new PerlACE::Process("client_main", "$CLIENT_CMD"); + $CLIENT->SpawnWaitKill(500); + } +} + +# Private methods + +# acquire_param +# Transforms certain parameters into usable forms +sub acquire_param +{ + $TestParams{$_[0]} = $_[1]; + + if ($_[0] eq "imr_persistence") + { + if ($TestParams{imr_persistence} eq "registry") + { + $TestParams{imr_persistence} = "-r"; + } + elsif ($TestParams{imr_persistence} eq "binary") + { + $TestParams{imr_persistence} = "-p imr_persist"; + } + elsif ($TestParams{imr_persistence} eq "XML") + { + $TestParams{imr_persistence} = "-x imr_persist"; + } + } + + elsif ($_[0] eq "imr_persistence_clear") + { + if ($TestParams{imr_persistence_clear} eq "1") + { + $TestParams{imr_persistence_clear} = "-e"; + } + else + { + $TestParams{imr_persistence_clear} = ""; + } + } + + elsif ($_[0] eq "server_ref_style" && $TestParams{server_ref_style} ne "") + { + $TestParams{server_ref_style} = "-ORBObjRefStyle $TestParams{server_ref_style}"; + } + + elsif ($_[0] eq "client_rand_req" && $TestParams{client_rand_req} eq "1") + { + $TestParams{client_rand_req} = "r"; + } + + elsif ($_[0] eq "client_holding" && $TestParams{client_holding} eq "1") + { + $TestParams{client_holding} = "h"; + } + + elsif ($_[0] eq "client_noprofile" && $TestParams{client_noprofile} eq "1") + { + $TestParams{client_noprofile} = "n"; + } +} + +# generateCommands +# Create common cammand line sets +sub generateCommands +{ + $ENV_CMD = ""; + for (my $i = 0; $i < $TestParams{env_varnum}; $i++) + { + $ENV_CMD = "$ENV_CMD -e Name_" . $i . "=Value_" . $i . " "; + } + + if ($TestParams{env_dir} ne "") + { + $ENV_CMD = "$ENV_CMD -w " . File::Spec->rel2abs($TestParams{env_dir}) . " "; + } + + $IMR_CMD = "-o implrepo.ior " + . "$TestParams{imr_persistence} " + . "$TestParams{imr_persistence_clear} " + . "-ORBEndPoint $TestParams{imr_endpoint} " + . "-d $TestParams{imr_debug_level} " + . "-v $TestParams{imr_ping_interval} " + . "-t $TestParams{imr_startup_timeout} "; + + $ACT_CMD = "$IMPL_IOR -o activator.ior -d $TestParams{imr_debug_level}"; + + $SERVER_CMD = "-ORBUseIMR $TestParams{imr_on} $IMPL_IOR " + . "$ENV_CMD " + . "$TestParams{server_ref_style} " + . "-b " . File::Spec->rel2abs(".") . " " + . "-t $TestParams{server_ior_table} " + . "-z $TestParams{env_pause_type} " + . "-s $TestParams{server_start_pause} " + . "-c $TestParams{server_obj_act_pause} " + . "-a $TestParams{server_activate_pause} " + . "-r $TestParams{server_run_pause} " + . "-n $TestParams{server_poa_objs} " + . "-x $TestParams{server_hit_time_min} "; + + $CLIENT_CMD = "-z $TestParams{env_pause_type} " + . "-s $TestParams{client_start_pause} " + . "-t $TestParams{client_threads} " + . "-i $TestParams{client_iterations} " + . "-r $TestParams{client_rand_req}$TestParams{client_requests} " + . "-e $TestParams{client_holding}$TestParams{client_noprofile} "; + + $IOR_CMD = "-ORBUseIMR $TestParams{imr_on} $IMPL_IOR " + . "$TestParams{server_ref_style} " + . "-b " . File::Spec->rel2abs(".") . " " + . "-t $TestParams{server_ior_table} " + . "-n $TestParams{server_poa_objs} " + . "-z s -s 100 -o 1 -x 0 " # sleep 100, write iors, and exit +} diff --git a/TAO/orbsvcs/examples/ImR/Advanced/server_main.cpp b/TAO/orbsvcs/examples/ImR/Advanced/server_main.cpp new file mode 100644 index 00000000000..ccf813d0e9c --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Advanced/server_main.cpp @@ -0,0 +1,26 @@ +//$Id$ +#include "TestServer.h" + +#include <ace/streams.h> + +int main(int argc, char* argv[]) +{ + try + { + CORBA::ORB_var orb; + orb = CORBA::ORB_init(argc, argv); + + { + TestServer server(orb.in(), argc, argv); + server.run(); + } + + orb->destroy(); + return 0; + } + catch (CORBA::Exception& ex) + { + cerr << "CORBA error: " << ex << endl; + } + return 1; +} diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/ImR_Combined_Service.mpc b/TAO/orbsvcs/examples/ImR/Combined_Service/ImR_Combined_Service.mpc new file mode 100644 index 00000000000..fc8803905f7 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/ImR_Combined_Service.mpc @@ -0,0 +1,83 @@ +// $Id$ +project(*IDL): taoidldefaults { + idl_files { + service_config.idl + test.idl + } + custom_only = 1 +} + +project : orbsvcsexe, portableserver, exceptions { + exename = combined_service + after += *IDL + source_files { + combined.cpp + service_configC.cpp + service_configS.cpp + } + idl_files { + } +} + +project(*Controller) : orbsvcsexe, exceptions { + exename = controller + after += *IDL + source_files { + controller.cpp + service_configC.cpp + } + idl_files { + } +} + +// A client that uses corba to test out basic imr functionality +project(*Test) : orbsvcsexe, exceptions { + after += *IDL + source_files { + test.cpp + testC.cpp + } + idl_files { + } +} + +// A server to use with the imr +project(*TestServer) : orbsvcsexe, portableserver, iortable, exceptions { + after += *IDL + // The gnuace specific portion is to prevent invalid object files from + // IDL generated files being compiled simultaneously with parallel builds. + specific(gnuace) { + after += *Test + } + source_files { + test_server.cpp + testC.cpp + testS.cpp + } + idl_files { + } +} + +// Another simple server that can be loaded dynamically into the +// combined_service. +project(*DynamicServer) : taolib, portableserver, iortable, exceptions { + dynamicflags = DYNSERVER_BUILD_DLL + sharedname = DynServer + after += *IDL + // The gnuace specific portion is to prevent invalid object files from + // IDL-generated files being compiled simultaneously with parallel builds. + specific(gnuace) { + after += *TestServer + } + source_files { + testC.cpp + testS.cpp + dynserver.cpp + } + header_files { + dynserver.h + dynserver_export.h + } + idl_files { + } +} diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/Makefile.am b/TAO/orbsvcs/examples/ImR/Combined_Service/Makefile.am new file mode 100644 index 00000000000..88a88d3093b --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/Makefile.am @@ -0,0 +1,209 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_IDL = ACE_ROOT=$(ACE_ROOT) TAO_ROOT=$(TAO_ROOT) $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDL_DEP = $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDLFLAGS = -Ge 1 -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -I$(TAO_ROOT) -I$(srcdir) -g $(ACE_BUILDDIR)/apps/gperf/src/gperf +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.ImR_Combined_Service_IDL.am + +BUILT_SOURCES = \ + service_configC.cpp \ + service_configC.h \ + service_configC.inl \ + service_configS.cpp \ + service_configS.h \ + service_configS.inl + +CLEANFILES = \ + service_config-stamp \ + service_configC.cpp \ + service_configC.h \ + service_configC.inl \ + service_configS.cpp \ + service_configS.h \ + service_configS.inl + +service_configC.cpp service_configC.h service_configC.inl service_configS.cpp service_configS.h service_configS.inl: service_config-stamp + +service_config-stamp: $(srcdir)/service_config.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -Sa -St $(srcdir)/service_config.idl + @touch $@ + +BUILT_SOURCES += \ + testC.cpp \ + testC.h \ + testC.inl \ + testS.cpp \ + testS.h \ + testS.inl + +CLEANFILES += \ + test-stamp \ + testC.cpp \ + testC.h \ + testC.inl \ + testS.cpp \ + testS.h \ + testS.inl + +testC.cpp testC.h testC.inl testS.cpp testS.h testS.inl: test-stamp + +test-stamp: $(srcdir)/test.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -Sa -St $(srcdir)/test.idl + @touch $@ + + +noinst_HEADERS = \ + service_config.idl \ + test.idl + +## Makefile.ImR_Combined_Service.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += combined_service + +combined_service_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +combined_service_SOURCES = \ + combined.cpp \ + service_configC.cpp \ + service_configS.cpp \ + dynserver.h \ + dynserver_export.h + +combined_service_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + +## Makefile.ImR_Combined_Service_Controller.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += controller + +controller_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +controller_SOURCES = \ + controller.cpp \ + service_configC.cpp \ + dynserver.h \ + dynserver_export.h + +controller_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + +## Makefile.ImR_Combined_Service_DynamicServer.am + +if BUILD_EXCEPTIONS + +noinst_LTLIBRARIES = libDynServer.la + +libDynServer_la_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -DDYNSERVER_BUILD_DLL + +libDynServer_la_SOURCES = \ + dynserver.cpp \ + testC.cpp \ + testS.cpp + +noinst_HEADERS += \ + dynserver.h \ + dynserver_export.h + +endif BUILD_EXCEPTIONS + +## Makefile.ImR_Combined_Service_Test.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += test + +test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +test_SOURCES = \ + test.cpp \ + testC.cpp \ + dynserver.h \ + dynserver_export.h + +test_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + +## Makefile.ImR_Combined_Service_TestServer.am + +if BUILD_EXCEPTIONS + +noinst_PROGRAMS += test_server + +test_server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +test_server_SOURCES = \ + testC.cpp \ + testS.cpp \ + test_server.cpp \ + dynserver.h \ + dynserver_export.h + +test_server_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_IORTable.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_EXCEPTIONS + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/combined.cpp b/TAO/orbsvcs/examples/ImR/Combined_Service/combined.cpp new file mode 100644 index 00000000000..5864e974d00 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/combined.cpp @@ -0,0 +1,81 @@ +// $Id$ +// This is a simple example, showing how you can load an +// ImR Locator and/or Activator as ACE Service Objects +// using the ACE Service Configurator framework. + +#include "service_configS.h" + +#include "ace/Service_Config.h" +#include "ace/streams.h" +#include "ace/OS_NS_string.h" + + +using namespace CORBA; +using namespace PortableServer; + +class SvcConf + : public POA_ServiceConfigurator +{ + ACE_Service_Config& asc_; +public: + SvcConf(ACE_Service_Config& asc) + : asc_(asc) + { + } + virtual CORBA::Long process_directive(const char* s) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + ACE_ASSERT(s != 0); + ACE_ASSERT(ACE_OS::strlen(s) > 0); + return asc_.process_directive(s); + } + + virtual void reconfigure() ACE_THROW_SPEC ((CORBA::SystemException)) + { + asc_.reconfigure(); + } +}; + +int main (int argc, char* argv[]) +{ + try { + + ACE_Service_Config config; + config.open(argc, argv); + + ORB_var orb = ORB_init(argc, argv); + + Object_var obj = orb->resolve_initial_references("RootPOA"); + POA_var poa = POA::_narrow(obj.in()); + ACE_ASSERT(! is_nil(poa.in())); + POAManager_var poaman = poa->the_POAManager(); + + SvcConf svt(config); + + ObjectId_var id = poa->activate_object(&svt); + obj = poa->id_to_reference(id.in()); + ACE_ASSERT(! is_nil(obj.in())); + String_var ior = orb->object_to_string(obj.in()); + + poaman->activate(); + + { + ofstream out("combined.ior"); + out << ior; + } + + ACE_DEBUG((LM_DEBUG, "Combined service started.\n")); + + orb->run(); + + ACE_DEBUG((LM_DEBUG, "Combined service shutdown.\n")); + + poa->destroy(1, 1); + orb->destroy(); + + } catch (CORBA::Exception& e) { + ACE_PRINT_EXCEPTION(e, "Combined Service:"); + } + return 0; +} + diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/controller.cpp b/TAO/orbsvcs/examples/ImR/Combined_Service/controller.cpp new file mode 100644 index 00000000000..0bab1bfd6aa --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/controller.cpp @@ -0,0 +1,73 @@ +// $Id$ +// This is a simple test of an ImR using the corba interfaces + +#include "service_configC.h" + +#include <ace/streams.h> +#include <ace/SString.h> +#include <ace/Log_Msg.h> + +using namespace CORBA; + +namespace { + + ACE_CString directive; + + void showusage() { + ACE_DEBUG((LM_DEBUG, "Usage: controller [-r | -c \"service_configurator_directive\"]\n" + "(e.g. dynamic mysvc Service_Object * MySvc:_make_MySvc() \"-arg1 one\"\n\n")); + } + + bool parse_args(int argc, char* argv[]) { + if (argc != 2 && argc != 3) { + ACE_ERROR((LM_ERROR, "Controller: wrong number of arguments. %d\n", argc - 1)); + return false; + } + for (int i = 1; i < argc; ++i) { + ACE_CString s(argv[i]); + if (s == "-h" || s == "-help" || s == "--help" || s == "-?") + return false; + if (s == "-r") { + return true; + } + if (s == "-c" && ++i < argc) { + directive = argv[i]; + return true; + } + } + return false; + } +} + +int main(int argc, char* argv[]) { + + try { + + ORB_var orb = ORB_init(argc, argv); + + if (! parse_args(argc, argv)) { + showusage(); + return 1; + } + + ACE_DEBUG((LM_DEBUG, "Controller: Connecting to combined service...\n")); + + Object_var obj = orb->resolve_initial_references("ServiceConfig"); + ServiceConfigurator_var sc = ServiceConfigurator::_narrow(obj.in()); + ACE_ASSERT(! is_nil(sc.in())); + + if (directive.length() > 0) { + ACE_DEBUG((LM_DEBUG, "Controller: sending directive <%s>...\n", directive.c_str())); + sc->process_directive(directive.c_str()); + } else { + ACE_DEBUG((LM_DEBUG, "Controller: reloading config file...\n")); + sc->reconfigure(); + } + ACE_DEBUG((LM_DEBUG, "Controller: done.\n")); + + return 0; + } catch (CORBA::Exception& e) { + ACE_PRINT_EXCEPTION(e, "Controller:"); + } + return 1; +} diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver.conf b/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver.conf new file mode 100644 index 00000000000..4d63029f52e --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver.conf @@ -0,0 +1 @@ +dynamic DynServer_Loader Service_Object * DynServer:_make_DynServer_Loader() '-orbcollocation per-orb -orbuseimr 1 -orbinitref ImplRepoService=corbaloc::localhost:9999/ImplRepoService' diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver.cpp b/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver.cpp new file mode 100644 index 00000000000..8566023c945 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver.cpp @@ -0,0 +1,154 @@ +// $Id$ +#include "dynserver.h" + +#include "tao/IORTable/IORTable.h" +#include "tao/PortableServer/Root_POA.h" + +#include "ace/Dynamic_Service.h" +#include "ace/Task.h" + +using namespace CORBA; +using namespace PortableServer; + +DynServer::DynServer() +: n_(0) +{ +} + +DynServer::~DynServer() { +} + +Long DynServer::get() ACE_THROW_SPEC ((SystemException)) { + ACE_DEBUG((LM_DEBUG, "dynserver: get() %d\n", ++n_)); + return n_; +} + +namespace { + POA_ptr createPersistPOA(const char* name, POA_ptr root_poa, POAManager_ptr poaman) { + PolicyList policies (2); + policies.length (2); + policies[0] = root_poa->create_id_assignment_policy(USER_ID); + policies[1] = root_poa->create_lifespan_policy(PERSISTENT); + POA_var poa = root_poa->create_POA(name, poaman, policies); + policies[0]->destroy(); + policies[1]->destroy(); + return poa._retn(); + } +} + +class DynServer_ORB_Runner : public ACE_Task_Base +{ + ORB_var orb_; +public: + DynServer_ORB_Runner(ORB_ptr orb) + : orb_(ORB::_duplicate(orb)) + { + } + void end() { + if (! is_nil(orb_.in())) { + orb_->shutdown(1); + wait(); + } + } + virtual int svc() + { + orb_->run(); + orb_ = ORB::_nil(); + return 0; + } +}; + +DynServer_Loader::DynServer_Loader(void) +{ +} + +int +DynServer_Loader::init (int argc, ACE_TCHAR* argv[] ACE_ENV_ARG_DECL) +{ + try { + + orb_ = ORB_init(argc, argv, "DynServer"); + + Object_var obj = orb_->resolve_initial_references("RootPOA"); + root_poa_ = POA::_narrow(obj.in()); + POAManager_var poaman = root_poa_->the_POAManager(); + obj = this->orb_->resolve_initial_references ("IORTable"); + IORTable::Table_var ior_table = IORTable::Table::_narrow (obj.in()); + ACE_ASSERT(! is_nil(ior_table.in())); + + ACE_DEBUG((LM_DEBUG, "dynserver: creating poas. (Registers with ImR)\n")); + + POA_var poa1 = createPersistPOA("DynObject1", root_poa_.in(), poaman.in()); + POA_var poa2 = createPersistPOA("DynObject2", root_poa_.in(), poaman.in()); + + ACE_DEBUG((LM_DEBUG, "dynserver: activating objects.\n")); + + DynServer* svt1 = new DynServer; + ServantBase_var scoped_svt1(svt1); + DynServer* svt2 = new DynServer; + ServantBase_var scoped_svt2(svt2); + + ObjectId_var id = string_to_ObjectId("myobject"); + + poa1->activate_object_with_id(id.in(), svt1); + poa2->activate_object_with_id(id.in(), svt2); + + TAO_Root_POA* tmp_poa = dynamic_cast<TAO_Root_POA*>(poa1.in()); + obj = tmp_poa->id_to_reference_i (id.in(), false); + String_var ior = orb_->object_to_string(obj.in()); + ior_table->bind ("DynObject1", ior.in()); + + tmp_poa = dynamic_cast<TAO_Root_POA*>(poa2.in()); + obj = tmp_poa->id_to_reference_i (id.in(), false); + ior = orb_->object_to_string(obj.in()); + ior_table->bind ("DynObject2", ior.in()); + + poaman->activate(); + + runner_.reset(new DynServer_ORB_Runner(orb_.in())); + runner_->activate(); + + ACE_DEBUG((LM_DEBUG, "dynserver: running.\n")); + + } catch (Exception& e) { + ACE_PRINT_EXCEPTION(e, "DynServer::init()"); + } + return 0; +} + +int +DynServer_Loader::fini (void) +{ + ACE_ASSERT(runner_.get() != 0); + try { + + ACE_DEBUG((LM_DEBUG, "dynserver: shutting down.\n")); + + runner_->end(); + runner_.reset(0); + + root_poa_->destroy(1, 1); + orb_->destroy(); + + ACE_DEBUG((LM_DEBUG, "dynserver: shut down successfully.\n")); + + return 0; + + } catch (Exception& e) { + ACE_PRINT_EXCEPTION(e, "DynServer::fini()"); + } + return -1; +} + +Object_ptr +DynServer_Loader::create_object (ORB_ptr, + int, + ACE_TCHAR ** + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((SystemException)) +{ + ACE_THROW_RETURN(NO_IMPLEMENT(), Object::_nil()); +} + +ACE_FACTORY_DEFINE (DynServer, DynServer_Loader) + diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver.h b/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver.h new file mode 100644 index 00000000000..c222ebe531e --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver.h @@ -0,0 +1,58 @@ +// $Id$ +#ifndef DYNSERVER_H +#define DYNSERVER_H + +#include "dynserver_export.h" + +#include "testS.h" + +#include "tao/Object_Loader.h" + +#include "ace/Auto_Ptr.h" + +// Trivial test corba object +class DynServer_Export DynServer + : public POA_test +{ + int n_; +public: + DynServer(void); + virtual ~DynServer(); + virtual CORBA::Long get() ACE_THROW_SPEC ((CORBA::SystemException)); +}; + +class DynServer_ORB_Runner; + +// This dll supports the service configurator framework +class DynServer_Export DynServer_Loader : public TAO_Object_Loader +{ +public: + DynServer_Loader(void); + + // spawns a thread to run an internal orb which has activated + // a single DynServer servant. + virtual int init (int argc, ACE_TCHAR *argv[]); + + // Allows the service configurator to shutdown the orb + virtual int fini (void); + + // Not supported + virtual CORBA::Object_ptr create_object (CORBA::ORB_ptr orb, + int argc, + ACE_TCHAR *argv[]) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + CORBA::ORB_var orb_; + PortableServer::POA_var root_poa_; + DynServer service_; + ACE_Auto_Ptr<DynServer_ORB_Runner> runner_; + +private: + ACE_UNIMPLEMENTED_FUNC (DynServer_Loader (const DynServer_Loader &)) + ACE_UNIMPLEMENTED_FUNC (DynServer_Loader &operator = (const DynServer_Loader &)) +}; + +ACE_FACTORY_DECLARE (DynServer, DynServer_Loader) + +#endif diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver_export.h b/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver_export.h new file mode 100644 index 00000000000..459e4532891 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/dynserver_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl -s DynServer +// ------------------------------ +#ifndef DYNSERVER_EXPORT_H +#define DYNSERVER_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (DYNSERVER_HAS_DLL) +# define DYNSERVER_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && DYNSERVER_HAS_DLL */ + +#if !defined (DYNSERVER_HAS_DLL) +# define DYNSERVER_HAS_DLL 1 +#endif /* ! DYNSERVER_HAS_DLL */ + +#if defined (DYNSERVER_HAS_DLL) && (DYNSERVER_HAS_DLL == 1) +# if defined (DYNSERVER_BUILD_DLL) +# define DynServer_Export ACE_Proper_Export_Flag +# define DYNSERVER_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define DYNSERVER_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* DYNSERVER_BUILD_DLL */ +# define DynServer_Export ACE_Proper_Import_Flag +# define DYNSERVER_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define DYNSERVER_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* DYNSERVER_BUILD_DLL */ +#else /* DYNSERVER_HAS_DLL == 1 */ +# define DynServer_Export +# define DYNSERVER_SINGLETON_DECLARATION(T) +# define DYNSERVER_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* DYNSERVER_HAS_DLL == 1 */ + +// Set DYNSERVER_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (DYNSERVER_NTRACE) +# if (ACE_NTRACE == 1) +# define DYNSERVER_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define DYNSERVER_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !DYNSERVER_NTRACE */ + +#if (DYNSERVER_NTRACE == 1) +# define DYNSERVER_TRACE(X) +#else /* (DYNSERVER_NTRACE == 1) */ +# define DYNSERVER_TRACE(X) ACE_TRACE_IMPL(X) +#endif /* (DYNSERVER_NTRACE == 1) */ + +#endif /* DYNSERVER_EXPORT_H */ + +// End of auto generated file. diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/readme b/TAO/orbsvcs/examples/ImR/Combined_Service/readme new file mode 100644 index 00000000000..e10a95336ef --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/readme @@ -0,0 +1,28 @@ +Test Description: + +The test consists of several processes and the usual run_test.pl script. + +controller.exe -- This is a simple corba wrapper around the ServiceConfigurator + which takes -c <cmd> and -r options to run a command and + reload the conf file respectively. + +combined_service.exe -- It combines the tao imr locator, activator, and a dynamic + server in a single process. You can use any service + configurator command line options, and it also writes + out a combined.ior file that can be use d with the controller above. + +test_server.exe -- This is a simple tao server that exposes two imr-ified objects + called TestObject1 and TestObject2. You must start it with + -orbuseimr 1 as usual. + +dynserver.dll -- This is the same server as above, except for use with the ServiceConfigurator. + It exposes DynObject1 and DynObject2. This program is not currently used as + part of the run_test.pl + +test.exe -- This is a simple client that invokes the test() operation on the Test object. + Start it with -orbinitref Test=... It can be used against any of the + four objects above. + +There are also comments within the run_test.pl that describe the +test and expected results at various stages. + diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/run_test.pl b/TAO/orbsvcs/examples/ImR/Combined_Service/run_test.pl new file mode 100755 index 00000000000..f55689a5446 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/run_test.pl @@ -0,0 +1,184 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +############################################################################### +my $ACE_ROOT = $ENV{ACE_ROOT}; + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; +use Cwd; +use Sys::Hostname; +use File::Copy; + +use strict; + +my $cwd = getcwd(); + +if (!defined $ACE_ROOT) { + print "Error: ACE_ROOT not defined.\n"; + return 1; +} + +# this matches the orbendpoint used in start_all.conf +my $imr_corbaloc = "corbaloc::localhost:9999"; +my $imr_initref = "-orbinitref ImplRepoService=$imr_corbaloc/ImplRepoService"; + +my $imr_start_file = PerlACE::LocalFile ("imr_status"); +my $server_start_file = PerlACE::LocalFile ("server_status"); + +my $start_conf = PerlACE::LocalFile ("start_all.conf"); + +my $COMB = new PerlACE::Process (PerlACE::LocalFile ("combined_service")); +my $combined_ior = PerlACE::LocalFile ("combined.ior"); +my $cs_initref = "-orbinitref ServiceConfig=file://$combined_ior"; + +my $SERV = new PerlACE::Process (PerlACE::LocalFile ("test_server")); +my $test_server = $SERV->Executable (); + +my $IMRUTIL = new PerlACE::Process("$ACE_ROOT/bin/tao_imr"); + +my $CLI = new PerlACE::Process ('test'); +my $test_initref = "-orbinitref Test=$imr_corbaloc"; + +my $hostname = hostname(); +############################################################################### + +sub do_test +{ + unlink $combined_ior; + + my $start_time = time(); +print STDERR "Starting comb -f $start_conf\n"; + # First we start all the servers, including the test server + $COMB->Arguments("-f $start_conf"); + my $ret = $COMB->Spawn(); + if ($ret != 0) { + print "ERROR : spawning combined service.\n"; + return $ret; + } + + ## Wait a little bit for everything to get started + sleep(2); +print STDERR "Starting test_server -orbuseimr 1 $imr_initref\n"; + + $SERV->Arguments("-orbuseimr 1 $imr_initref"); + my $ret = $SERV->Spawn(); + if ($ret != 0) { + print "ERROR : spawning test server.\n"; + return $ret; + } + + ## Wait a little bit for everything to get started + sleep(2); +print STDERR "Starting client\n"; + + # The client should pass the simple test + $CLI->Arguments("$test_initref/TestObject1"); + $ret = $CLI->SpawnWaitKill(5); + if ($ret != 0) { + print "ERROR : spawning test client 1.\n"; + return $ret; + } + + # The client should pass the simple test again, this time with obj #2 + $CLI->Arguments("$test_initref/TestObject2"); + $ret = $CLI->SpawnWaitKill(5); + if ($ret != 0) { + print "ERROR : spawning test client 2.\n"; + return $ret; + } +print STDERR "Starting imr\n"; + + # The server was autoregistered without any start information. We + # need to update the registration with a command line so that the + # activator can be used to re-launch it. + $IMRUTIL->Arguments("$imr_initref update TestObject1 -l $hostname -c \"$test_server -orbuseimr 1 $imr_initref\""); + $ret = $IMRUTIL->SpawnWaitKill(5); + if ($ret != 0) { + print "ERROR : Updating TestObject1 cmdline.\n"; + return $ret; + } + + # The new command line should now be registered, but only for TestObject1 + $IMRUTIL->Arguments("$imr_initref list -v"); + $ret = $IMRUTIL->SpawnWaitKill(5); + if ($ret != 0) { + print "ERROR : Listing ImR Servers.\n"; + return $ret; + } + + # Now we can kill the server. + $IMRUTIL->Arguments("$imr_initref shutdown TestObject1"); + $ret = $IMRUTIL->SpawnWaitKill(5); + if ($ret != 0) { + print "ERROR : Shutting down test server.\n"; + return $ret; + } + + # Both TestObject1 and TestObject2 should now show up as "not running" + $IMRUTIL->Arguments("$imr_initref list -v"); + $ret = $IMRUTIL->SpawnWaitKill(5); + if ($ret != 0) { + print "ERROR : Listing ImR Servers.\n"; + return $ret; + } +print STDERR "Starting client\n"; + + # The client should pass the simple test again, because the Activator will + # restart test_server + $CLI->Arguments("$test_initref/TestObject1"); + $ret = $CLI->SpawnWaitKill(5); + if ($ret != 0) { + print "ERROR : spawning test client 3.\n"; + return $ret; + } + + # The client should pass the simple test again with obj #2, because both + # are started by the server + $CLI->Arguments("$test_initref/TestObject2"); + $ret = $CLI->SpawnWaitKill(5); + if ($ret != 0) { + print "ERROR : spawning test client 4.\n"; + return $ret; + } + + # We have to kill the server, since $SERV most likely does + # not refer to the actual process anymore since a new server + # was started by the ImR Activator. + $IMRUTIL->Arguments("$imr_initref shutdown TestObject1"); + $ret = $IMRUTIL->SpawnWaitKill(5); + if ($ret != 0) { + print "ERROR : Shutting down test server.\n"; + return $ret; + } + + $COMB->TerminateWaitKill(5); + if ($ret != 0) { + print "ERROR : Terminating combined service.\n"; + return $ret; + } + + $SERV->TerminateWaitKill(5); + if ($ret != 0) { + print "ERROR : Terminating test server.\n"; + return $ret; + } + + unlink $combined_ior; + + return $ret; +} + +my $ret = do_test(); + +# Regardless of the return value, ensure that the processes +# are terminated before exiting +$CLI->Kill(); +$COMB->Kill(); +$SERV->Kill(); + +exit $ret; diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/service_config.idl b/TAO/orbsvcs/examples/ImR/Combined_Service/service_config.idl new file mode 100644 index 00000000000..f4fb3363f8e --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/service_config.idl @@ -0,0 +1,6 @@ +// $Id$ +// Just provides a corba interface to the ACE Service Configurator +interface ServiceConfigurator { + long process_directive(in string s); + void reconfigure(); +}; diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/start_all.conf b/TAO/orbsvcs/examples/ImR/Combined_Service/start_all.conf new file mode 100644 index 00000000000..23e3db5379c --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/start_all.conf @@ -0,0 +1,2 @@ +dynamic ImR_Locator_Loader Service_Object * TAO_ImR_Locator:_make_ImR_Locator_Loader() '-orbcollocation no -orbobjrefstyle url -t 5 -d 2 -orbendpoint iiop://:9999' +dynamic ImR_Activator_Loader Service_Object * TAO_ImR_Activator:_make_ImR_Activator_Loader() '-orbcollocation per-orb -d 2 -orbinitref ImplRepoService=corbaloc::localhost:9999/ImplRepoService' diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/test.cpp b/TAO/orbsvcs/examples/ImR/Combined_Service/test.cpp new file mode 100644 index 00000000000..0976425f762 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/test.cpp @@ -0,0 +1,47 @@ +// $Id$ +// This is a simple test of an ImR using the corba interfaces + +#include "testC.h" + +#include "ace/SString.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include <stdexcept> +#include <string> + +#define assertTrue(CONDITION) \ + if (CONDITION == false) { \ + ACE_CString str ("Error : "#CONDITION" "__FILE__":"); \ + char line[32]; \ + ACE_OS::sprintf (line, "%d", __LINE__); \ + throw std::runtime_error (str.c_str ()); \ + } + +using namespace CORBA; + +int +main (int argc, char* argv[]) +{ + try + { + + ORB_var orb = ORB_init (argc, argv); + + Object_var obj = orb->resolve_initial_references ("Test"); + test_var test = test::_narrow (obj.in ()); + assertTrue (!is_nil (test.in ())); + + Long n = test->get (); + Long m = test->get (); + assertTrue (m == n + 1); + + ACE_DEBUG ((LM_DEBUG, "All tests ran successfully.\n")); + + return 0; + } + catch (CORBA::Exception& e) + { + ACE_PRINT_EXCEPTION (e, "test:"); + } + return 1; +} diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/test.idl b/TAO/orbsvcs/examples/ImR/Combined_Service/test.idl new file mode 100644 index 00000000000..9ff40e9c6a9 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/test.idl @@ -0,0 +1,4 @@ +// $Id$ +interface test { + long get(); +}; diff --git a/TAO/orbsvcs/examples/ImR/Combined_Service/test_server.cpp b/TAO/orbsvcs/examples/ImR/Combined_Service/test_server.cpp new file mode 100644 index 00000000000..a3d821fde70 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Combined_Service/test_server.cpp @@ -0,0 +1,93 @@ +// $Id$ +// This is a simple test of an ImR using the corba interfaces +// It uses multicast to find the ImplRepoService + +#include "testS.h" + +#include "tao/IORTable/IORTable.h" +#include "tao/PortableServer/Root_POA.h" + +#include "ace/streams.h" +#include "ace/ARGV.h" + +using namespace CORBA; +using namespace PortableServer; + +class test_i : public virtual POA_test { + int n_; +public: + test_i (void) : n_(0) + { + } + virtual ~test_i (void) { + } + virtual CORBA::Long get (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException)) { + ACE_DEBUG((LM_DEBUG, "dynserver: get() %d\n", ++n_)); + return n_; + } +}; + +POA_ptr createPersistPOA(const char* name, POA_ptr root_poa, POAManager_ptr poaman) { + CORBA::PolicyList policies (2); + policies.length (2); + policies[0] = root_poa->create_id_assignment_policy(USER_ID); + policies[1] = root_poa->create_lifespan_policy(PERSISTENT); + POA_var poa = root_poa->create_POA(name, poaman, policies); + policies[0]->destroy(); + policies[1]->destroy(); + return poa._retn(); +} + +int main(int argc, char* argv[]) { + + try { + + ORB_var orb = ORB_init(argc, argv); + + Object_var obj = orb->resolve_initial_references("RootPOA"); + POA_var root_poa = POA::_narrow(obj.in()); + POAManager_var poaman = root_poa->the_POAManager(); + obj = orb->resolve_initial_references ("IORTable"); + IORTable::Table_var ior_table = IORTable::Table::_narrow (obj.in()); + ACE_ASSERT(! is_nil(ior_table.in())); + + ACE_DEBUG((LM_DEBUG, "test_server: creating poas. (Registers with ImR)\n")); + + POA_var poa1 = createPersistPOA("TestObject1", root_poa.in(), poaman.in()); + POA_var poa2 = createPersistPOA("TestObject2", root_poa.in(), poaman.in()); + + ACE_DEBUG((LM_DEBUG, "test_server: activating objects.\n")); + + test_i svt1, svt2; + + ObjectId_var id = string_to_ObjectId("myobject"); + + poa1->activate_object_with_id(id.in(), &svt1); + poa2->activate_object_with_id(id.in(), &svt2); + + TAO_Root_POA* tmp_poa = dynamic_cast<TAO_Root_POA*>(poa1.in()); + obj = tmp_poa->id_to_reference_i (id.in(), false); + String_var ior = orb->object_to_string(obj.in()); + ior_table->bind ("TestObject1", ior.in()); + + tmp_poa = dynamic_cast<TAO_Root_POA*>(poa2.in()); + obj = tmp_poa->id_to_reference_i (id.in(), false); + ior = orb->object_to_string(obj.in()); + ior_table->bind ("TestObject2", ior.in()); + + poaman->activate(); + + ACE_DEBUG((LM_DEBUG, "test_server: Running...\n")); + + orb->run(); + + ACE_DEBUG((LM_DEBUG, "test_server: Shutting down...\n")); + + root_poa->destroy(1, 1); + orb->destroy(); + + } catch (CORBA::Exception& e) { + ACE_PRINT_EXCEPTION(e, "TestServer::init()"); + } + return 0; +} diff --git a/TAO/orbsvcs/examples/ImR/Makefile.am b/TAO/orbsvcs/examples/ImR/Makefile.am new file mode 100644 index 00000000000..0b48755fb65 --- /dev/null +++ b/TAO/orbsvcs/examples/ImR/Makefile.am @@ -0,0 +1,14 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + Advanced \ + Combined_Service + diff --git a/TAO/orbsvcs/examples/LoadBalancing/LoadBalancing.mpc b/TAO/orbsvcs/examples/LoadBalancing/LoadBalancing.mpc new file mode 100644 index 00000000000..3797e1cd0af --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/LoadBalancing.mpc @@ -0,0 +1,34 @@ +// $Id$ +project(*idl) : taoidldefaults, anytypecode { + IDL_Files { + Test.idl + } + custom_only = 1 +} + +project(*Server): taoexe, loadbalancing, pi_server, exceptions { + avoids += ace_for_tao + after += *idl + Source_Files { + ServerRequestInterceptor.cpp + ORBInitializer.cpp + StockFactory.cpp + RPS_Monitor.cpp + Stock.cpp + server.cpp + TestS.cpp + TestC.cpp + } + IDL_Files { + } +} + +project(*Client): taoclient, strategies { + after += *idl + Source_Files { + TestC.cpp + client.cpp + } + IDL_Files { + } +} diff --git a/TAO/orbsvcs/examples/LoadBalancing/Makefile.am b/TAO/orbsvcs/examples/LoadBalancing/Makefile.am new file mode 100644 index 00000000000..b4b3d851ccb --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/Makefile.am @@ -0,0 +1,141 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_IDL = ACE_ROOT=$(ACE_ROOT) TAO_ROOT=$(TAO_ROOT) $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDL_DEP = $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDLFLAGS = -Ge 1 -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -I$(TAO_ROOT) -I$(srcdir) -g $(ACE_BUILDDIR)/apps/gperf/src/gperf +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.LoadBalancing_Idl.am + +BUILT_SOURCES = \ + TestC.cpp \ + TestC.h \ + TestC.inl \ + TestS.cpp \ + TestS.h \ + TestS.inl + +CLEANFILES = \ + Test-stamp \ + TestC.cpp \ + TestC.h \ + TestC.inl \ + TestS.cpp \ + TestS.h \ + TestS.inl + +TestC.cpp TestC.h TestC.inl TestS.cpp TestS.h TestS.inl: Test-stamp + +Test-stamp: $(srcdir)/Test.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) $(srcdir)/Test.idl + @touch $@ + + +noinst_HEADERS = \ + Test.idl + +## Makefile.LoadBalancing_Client.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +client_SOURCES = \ + TestC.cpp \ + client.cpp \ + ORBInitializer.h \ + RPS_Monitor.h \ + ServerRequestInterceptor.h \ + Stock.h \ + StockFactory.h + +client_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_Strategies.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.LoadBalancing_Server.am + +if BUILD_AMI +if BUILD_CORBA_MESSAGING +if BUILD_EXCEPTIONS +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +server_SOURCES = \ + ORBInitializer.cpp \ + RPS_Monitor.cpp \ + ServerRequestInterceptor.cpp \ + Stock.cpp \ + StockFactory.cpp \ + TestC.cpp \ + TestS.cpp \ + server.cpp \ + ORBInitializer.h \ + RPS_Monitor.h \ + ServerRequestInterceptor.h \ + Stock.h \ + StockFactory.h + +server_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosLoadBalancing.la \ + $(TAO_BUILDDIR)/tao/libTAO_IORInterceptor.la \ + $(TAO_BUILDDIR)/tao/libTAO_ObjRefTemplate.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI_Server.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_PortableGroup.la \ + $(TAO_BUILDDIR)/tao/libTAO_IORManip.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_EXCEPTIONS +endif BUILD_CORBA_MESSAGING +endif BUILD_AMI + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/LoadBalancing/ORBInitializer.cpp b/TAO/orbsvcs/examples/LoadBalancing/ORBInitializer.cpp new file mode 100644 index 00000000000..f6239df905c --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/ORBInitializer.cpp @@ -0,0 +1,81 @@ +#include "ORBInitializer.h" +#include "ServerRequestInterceptor.h" + +#include "orbsvcs/LoadBalancing/LB_ServerRequestInterceptor.h" + +#include "orbsvcs/CosLoadBalancingC.h" +#include "tao/ORB_Constants.h" + + +ACE_RCSID (LoadBalancing, + ORBInitializer, + "$Id$") + + +ORBInitializer::ORBInitializer (void) + : load_alert_ (), + interceptor_ (0) +{ +} + +void +ORBInitializer::pre_init ( + PortableInterceptor::ORBInitInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +ORBInitializer::post_init ( + PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + + ACE_NEW_THROW_EX (this->interceptor_, + ServerRequestInterceptor, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK; + + PortableInterceptor::ServerRequestInterceptor_var sr_interceptor = + this->interceptor_; + + info->add_server_request_interceptor (sr_interceptor.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + PortableInterceptor::ServerRequestInterceptor_ptr reject_interceptor; + ACE_NEW_THROW_EX (reject_interceptor, + TAO_LB_ServerRequestInterceptor (this->load_alert_), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK; + + PortableInterceptor::ServerRequestInterceptor_var safe_reject_interceptor = + reject_interceptor; + + info->add_server_request_interceptor (safe_reject_interceptor.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + + +TAO_LB_LoadAlert & +ORBInitializer::load_alert (void) +{ + return this->load_alert_; +} + +ServerRequestInterceptor * +ORBInitializer::interceptor (void) const +{ + return this->interceptor_; +} diff --git a/TAO/orbsvcs/examples/LoadBalancing/ORBInitializer.h b/TAO/orbsvcs/examples/LoadBalancing/ORBInitializer.h new file mode 100644 index 00000000000..b366f733e93 --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/ORBInitializer.h @@ -0,0 +1,96 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file ORBInitializer.h + * + * $Id$ + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + + +#ifndef ORB_INITIALIZER_H +#define ORB_INITIALIZER_H + +#include /**/ "ace/pre.h" + +#include "orbsvcs/LoadBalancing/LB_LoadAlert.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/LocalObject.h" +#include "tao/PI/PI.h" + +// This is to remove "inherits via dominance" warnings from MSVC. +// MSVC is being a little too paranoid. +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + + +class ServerRequestInterceptor; + +/** + * @class ORBInitializer + * + * @brief ORBInitializer + * + * ORBInitializer + */ +class ORBInitializer + : public virtual PortableInterceptor::ORBInitializer, + public virtual TAO_Local_RefCounted_Object +{ +public: + + /// Constructor. + ORBInitializer (void); + + /** + * @name PortableInterceptor::ORBInitializer Methods + * + * Methods required by the PortableInterceptor::ORBInitializer + * interface. + */ + //@{ + virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + //@} + + /// Return a reference to the LoadAlert object. + TAO_LB_LoadAlert & load_alert (void); + + ServerRequestInterceptor * interceptor (void) const; + +private: + + /// The CosLoadBalancing::LoadAlert servant to be used at this + /// location. + /** + * This is the servant supplied by TAO's Load Balancer. It is + * used out of convencience. + */ + TAO_LB_LoadAlert load_alert_; + + ServerRequestInterceptor * interceptor_; + +}; + + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#include /**/ "ace/post.h" + +#endif /* ORB_INITIALIZER_H */ diff --git a/TAO/orbsvcs/examples/LoadBalancing/RPS_Monitor.cpp b/TAO/orbsvcs/examples/LoadBalancing/RPS_Monitor.cpp new file mode 100644 index 00000000000..431ebd7622f --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/RPS_Monitor.cpp @@ -0,0 +1,91 @@ +#include "RPS_Monitor.h" +#include "ServerRequestInterceptor.h" +#include "ace/UUID.h" +#include "tao/ORB_Constants.h" +#include "ace/OS_NS_sys_time.h" + +ACE_RCSID (LoadBalancing, + RPS_Monitor, + "$Id$") + + +RPS_Monitor::RPS_Monitor (ServerRequestInterceptor * interceptor) + : location_ (1), + interceptor_ (interceptor), + last_time_ (ACE_OS::gettimeofday ()), + lock_ () +{ + this->location_.length (1); + + ACE_Utils::UUID_GENERATOR::instance ()->init (); + + ACE_Utils::UUID uuid; + ACE_Utils::UUID_GENERATOR::instance ()->generateUUID (uuid); + + this->location_[0].id = CORBA::string_dup (uuid.to_string ()->c_str ()); + this->location_[0].kind = CORBA::string_dup ("UUID"); +} + +RPS_Monitor::~RPS_Monitor (void) +{ +} + +CosLoadBalancing::Location * +RPS_Monitor::the_location (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CosLoadBalancing::Location * location; + ACE_NEW_THROW_EX (location, + CosLoadBalancing::Location (this->location_), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (0); + + return location; +} + +CosLoadBalancing::LoadList * +RPS_Monitor::loads (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + const ACE_Time_Value current_time = ACE_OS::gettimeofday (); + + ACE_Time_Value elapsed_time; + + { + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, monitor, this->lock_, 0); + + elapsed_time = current_time - this->last_time_; + this->last_time_ = current_time; + } + + const CORBA::Long request_count = this->interceptor_->request_count (); + + CosLoadBalancing::LoadList * tmp; + ACE_NEW_THROW_EX (tmp, + CosLoadBalancing::LoadList (1), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (0); + + CosLoadBalancing::LoadList_var load_list = tmp; + + load_list->length (1); + + load_list[0].id = CosLoadBalancing::RequestsPerSecond; + + // VC 7.1 gives a warning without an explicit cast. + load_list[0].value = + static_cast<CORBA::Float> (request_count / elapsed_time.msec () * 1000); + + // Strictly for debugging or + ACE_DEBUG ((LM_DEBUG, "%f\n", load_list[0].value)); + + return load_list._retn (); +} diff --git a/TAO/orbsvcs/examples/LoadBalancing/RPS_Monitor.h b/TAO/orbsvcs/examples/LoadBalancing/RPS_Monitor.h new file mode 100644 index 00000000000..fb623e0852e --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/RPS_Monitor.h @@ -0,0 +1,93 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file RPS_Monitor.h + * + * $Id$ + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + + +#ifndef TAO_RPS_MONITOR_H +#define TAO_RPS_MONITOR_H + +#include /**/ "ace/pre.h" + +#include "orbsvcs/CosLoadBalancingS.h" + +# if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +# endif /* ACE_LACKS_PRAGMA_ONCE */ + + +class ServerRequestInterceptor; + +/** + * @class RPS_Monitor + * + * @brief LoadMonitor implementation that calculates the number of + * request arriving per second. + */ +class RPS_Monitor + : public virtual POA_CosLoadBalancing::LoadMonitor +{ +public: + + /// Constructor + RPS_Monitor (ServerRequestInterceptor * interceptor); + + /** + * @name CosLoadBalancing::LoadMonitor Methods + * + * Methods required by the CosLoadBalancing::LoadMonitor interface. + */ + //@{ + + /// Return the location at which the LoadMonitor resides. + /** + * The returned "Location" is a sequence of length 1. + */ + virtual CosLoadBalancing::Location * the_location ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Return the average CPU load at the location which this + /// LoadMonitor resides. + /** + * @return A "Load" sequence of length 1 that contains a LoadId + * equal to CosLoadBalancing::LoadAverage, and the average CPU + * load. + */ + virtual CosLoadBalancing::LoadList * loads ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + //@} + +protected: + + /// Destructor + /** + * Protected destructor to enforce proper memory management through + * reference counting. + */ + ~RPS_Monitor (void); + +private: + + /// The name of the location at which this LoadMonitor resides. + CosLoadBalancing::Location location_; + + ServerRequestInterceptor * interceptor_; + + ACE_Time_Value last_time_; + + ACE_SYNCH_MUTEX lock_; +}; + +#include /**/ "ace/post.h" + +#endif /* TAO_RPS_MONITOR_H */ diff --git a/TAO/orbsvcs/examples/LoadBalancing/ServerRequestInterceptor.cpp b/TAO/orbsvcs/examples/LoadBalancing/ServerRequestInterceptor.cpp new file mode 100644 index 00000000000..8deb50cae85 --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/ServerRequestInterceptor.cpp @@ -0,0 +1,82 @@ +#include "ServerRequestInterceptor.h" + +ACE_RCSID (LoadBalancing, + ServerRequestInterceptor, + "$Id$") + + +ServerRequestInterceptor::ServerRequestInterceptor (void) + : request_count_ (0) +{ +} + +ServerRequestInterceptor::~ServerRequestInterceptor (void) +{ +} + +char * +ServerRequestInterceptor::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::string_dup ("ServerRequestInterceptor"); +} + +void +ServerRequestInterceptor::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +ServerRequestInterceptor::receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr /* ri */ + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ + ++this->request_count_; +} + +void +ServerRequestInterceptor::receive_request ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +ServerRequestInterceptor::send_reply ( + PortableInterceptor::ServerRequestInfo_ptr /* ri */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +ServerRequestInterceptor::send_exception ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +ServerRequestInterceptor::send_other ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +CORBA::Long +ServerRequestInterceptor::request_count (void) +{ + const CORBA::Long r = this->request_count_.value (); + this->request_count_ = 0; + + return r; +} diff --git a/TAO/orbsvcs/examples/LoadBalancing/ServerRequestInterceptor.h b/TAO/orbsvcs/examples/LoadBalancing/ServerRequestInterceptor.h new file mode 100644 index 00000000000..7768134b610 --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/ServerRequestInterceptor.h @@ -0,0 +1,123 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file ServerRequestInterceptor.h + * + * $Id$ + * + * @author Ossama Othman <ossama@dre.vanderbilt.edu> + */ +//============================================================================= + + +#ifndef TAO_SERVER_REQUEST_INTERCEPTOR_H +#define TAO_SERVER_REQUEST_INTERCEPTOR_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PI_Server/PI_Server.h" +#include "tao/PortableInterceptorC.h" +#include "tao/LocalObject.h" + +#include "ace/Atomic_Op.h" + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL +class TAO_LB_LoadAlert; +TAO_END_VERSIONED_NAMESPACE_DECL + +/** + * @class ServerRequestInterceptor + * + * @brief ServerRequestInterceptor that calculates the number of + * requests arriving per second. + * + * This ServerRequestInterceptor is responsible for redirecting + * requests back to the LoadManager. + */ +class ServerRequestInterceptor + : public virtual PortableInterceptor::ServerRequestInterceptor, + public virtual TAO_Local_RefCounted_Object +{ +public: + + /// Constructor. + ServerRequestInterceptor (void); + + /** + * @name Methods Required by the ServerRequestInterceptor + * Interface + * + * These are the canonical methods required for all + * ServerRequestInterceptors. + */ + //@{ + virtual char * name (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void destroy (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void receive_request ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void send_reply ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void send_exception ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void send_other ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + //@} + + CORBA::Long request_count (void); + +protected: + + /// Destructor. + /** + * Protected destructor to enforce correct memory management via + * reference counting. + */ + ~ServerRequestInterceptor (void); + +private: + + /// The number of requests that have arrived on the server. + ACE_Atomic_Op<ACE_SYNCH_MUTEX, long> request_count_; + +}; + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + + +#endif /* TAO_SERVER_REQUEST_INTERCEPTOR_H */ diff --git a/TAO/orbsvcs/examples/LoadBalancing/Stock.cpp b/TAO/orbsvcs/examples/LoadBalancing/Stock.cpp new file mode 100644 index 00000000000..fd6a8f70e77 --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/Stock.cpp @@ -0,0 +1,32 @@ +// +// $Id$ +// + +#include "Stock.h" + +Stock::Stock (const char *symbol, + const char *full_name, + CORBA::Double price) + : symbol_ (symbol), + full_name_ (full_name), + price_ (price) +{ +} + +char * +Stock::symbol () throw (CORBA::SystemException) +{ + return CORBA::string_dup (this->symbol_.c_str ()); +} + +char * +Stock::full_name () throw (CORBA::SystemException) +{ + return CORBA::string_dup (this->full_name_.c_str ()); +} + +CORBA::Double +Stock::price () throw (CORBA::SystemException) +{ + return this->price_; +} diff --git a/TAO/orbsvcs/examples/LoadBalancing/Stock.h b/TAO/orbsvcs/examples/LoadBalancing/Stock.h new file mode 100644 index 00000000000..3a902ed5261 --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/Stock.h @@ -0,0 +1,34 @@ +// +// $Id$ +// + +#ifndef STOCK_H +#define STOCK_H + +#include "TestS.h" +#include <string> + +class Stock + : public POA_Test::Stock +{ +public: + Stock (const char *symbol, + const char *full_name, + CORBA::Double price); + + char *symbol () throw (CORBA::SystemException); + char *full_name () throw (CORBA::SystemException); + CORBA::Double price () throw (CORBA::SystemException); + +private: +#if defined (HPUX) && (ACE_HAS_STANDARD_CPP_LIBRARY == 0) + string symbol_; + string full_name_; +#else + std::string symbol_; + std::string full_name_; +#endif /* HPUX */ + CORBA::Double price_; +}; + +#endif /* STOCK_H */ diff --git a/TAO/orbsvcs/examples/LoadBalancing/StockFactory.cpp b/TAO/orbsvcs/examples/LoadBalancing/StockFactory.cpp new file mode 100644 index 00000000000..59c96439de0 --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/StockFactory.cpp @@ -0,0 +1,34 @@ +// +// $Id$ +// + +#include "StockFactory.h" +#include "ace/streams.h" + +StockFactory::StockFactory (CORBA::ORB_ptr orb, int number) + : orb_ (CORBA::ORB::_duplicate (orb)), + rhat_ ("RHAT", "RedHat, Inc.", 210), + msft_ ("MSFT", "Microsoft, Inc.", 91), + number_ (number) +{ +} + +Test::Stock_ptr +StockFactory::get_stock (const char *symbol) + throw (Test::Invalid_Stock_Symbol) +{ + cout << "Server Number is " << number_ << endl; + if (strcmp (symbol, "RHAT") == 0) { + return this->rhat_._this (); + } else if (strcmp (symbol, "MSFT") == 0) { + return this->msft_._this (); + } + throw Test::Invalid_Stock_Symbol (); +} + +void +StockFactory::shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} diff --git a/TAO/orbsvcs/examples/LoadBalancing/StockFactory.h b/TAO/orbsvcs/examples/LoadBalancing/StockFactory.h new file mode 100644 index 00000000000..47bf026ce81 --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/StockFactory.h @@ -0,0 +1,30 @@ +// +// $Id$ +// + +#ifndef STOCKFACTORY_H +#define STOCKFACTORY_H + +#include "TestS.h" +#include "Stock.h" + +class StockFactory + : public POA_Test::StockFactory +{ +public: + StockFactory (CORBA::ORB_ptr orb, int number); + + Test::Stock_ptr get_stock (const char *symbol) + throw (Test::Invalid_Stock_Symbol); + + virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + CORBA::ORB_var orb_; + Stock rhat_; + Stock msft_; + int number_; +}; + +#endif /* STOCKFACTORY_H */ diff --git a/TAO/orbsvcs/examples/LoadBalancing/Test.idl b/TAO/orbsvcs/examples/LoadBalancing/Test.idl new file mode 100644 index 00000000000..c9f270a36a3 --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/Test.idl @@ -0,0 +1,47 @@ +// +// $Id$ +// + +module Test +{ + exception Invalid_Stock_Symbol {}; + // Used to report an invalid stock name + + // Forward declare the Stock interface + interface Stock; + + interface StockFactory + { + // = TITLE + // A factory class for the stock interfaces + // + // = DESCRIPTION + // Return the Stock interfaces based on their names + // + Stock get_stock (in string stock_symbol) + raises (Invalid_Stock_Symbol); + + oneway void shutdown (); + + }; + + interface Stock + { + // = TITLE + // A simple interface to query the name and price of stock + // + // = DESCRIPTION + // Return the price and name of a single stock + // + + readonly attribute string symbol; + // Get the stock symbol. + + readonly attribute string full_name; + // Get the name. + + double price (); + // Get the price + + }; +}; diff --git a/TAO/orbsvcs/examples/LoadBalancing/client.cpp b/TAO/orbsvcs/examples/LoadBalancing/client.cpp new file mode 100644 index 00000000000..47508dba78e --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/client.cpp @@ -0,0 +1,110 @@ +#include "TestC.h" +#include "ace/Get_Opt.h" +#include "ace/streams.h" + + +ACE_RCSID (LoadBalancing, + client, + "$Id$") + + +const char *ior = "file://obj.ior"; + +int niterations = 100; +int number; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:n:i:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + + case 'n': + number = ACE_OS::atoi (get_opts.opt_arg ()); + break; + + case 'i': + niterations = ACE_OS::atoi (get_opts.opt_arg ()); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-k <ior> " + "-i <niterations> " + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_TRY_NEW_ENV + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) != 0) + return 1; + + CORBA::Object_var tmp = + orb->string_to_object (ior ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + Test::StockFactory_var stockfactory = + Test::StockFactory::_narrow (tmp.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (stockfactory.in ())) + { + ACE_ERROR_RETURN ((LM_DEBUG, + "Nil Test::StockFactory reference <%s>\n", + ior), + 1); + } + + ACE_DEBUG ((LM_DEBUG, "Starting Client %d\n", number)); + + for (int i = 0; i < niterations; ++i) + { + Test::Stock_var stock = + stockfactory->get_stock ("RHAT"); + + CORBA::String_var full_name = stock->full_name (); + + CORBA::Double price = stock->price (); + + ACE_DEBUG ((LM_DEBUG, "The price of a stock in \"%s\" is $%f\n", + full_name.in (), + price)); + } + + //stockfactory->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + //ACE_TRY_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Exception caught in client.cpp:"); + return 1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/LoadBalancing/run_test.pl b/TAO/orbsvcs/examples/LoadBalancing/run_test.pl new file mode 100755 index 00000000000..06107b7b97d --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/run_test.pl @@ -0,0 +1,105 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "../../../../bin"; +use PerlACE::Run_Test; + +$iorfile = PerlACE::LocalFile ("obj.ior"); +unlink $iorfile; + +$lm_ior = "lm.ior"; +unlink $lm_ior; +$ns_ior = "ns.ior"; +unlink $ns_ior; + +$status = 0; + +$init_ref = "-ORBInitRef LoadManager=file://lm.ior -n 1 -ORBInitRef NameService=file://ns.ior -s LeastLoaded -r 9000 -c 10300 -d 0.1 "; +$init_ref_backup = "-ORBInitRef LoadManager=file://lm.ior -n 2 -ORBInitRef NameService=file://ns.ior -s LeastLoaded -r 9000 -c 10300 -d 0.1 "; + +$init_client_ref = "-k file://$iorfile -i 5 -n 1 -ORBInitRef NameService=file://ns.ior "; +$init_client_ref_backup = "-k file://$iorfile -i 5 -n 2 -ORBInitRef NameService=file://ns.ior "; + +$LM = new PerlACE::Process ("../../LoadBalancer/LoadManager", "-o lm.ior"); +$NS = new PerlACE::Process ("../../Naming_Service/Naming_Service", "-o ns.ior"); +$SV = new PerlACE::Process ("server", $init_ref); +$SR = new PerlACE::Process ("server", $init_ref_backup); +$CL = new PerlACE::Process ("client", $init_client_ref); +$CR = new PerlACE::Process ("client", $init_client_ref_backup); + +$LM->Spawn (); + +if (PerlACE::waitforfile_timed ("lm.ior", 5) == -1) { + print STDERR "ERROR: cannot find file LoadManager IOR: lm.ior\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; +} + +$NS->Spawn (); + +if (PerlACE::waitforfile_timed ("ns.ior", 5) == -1) { + print STDERR "ERROR: cannot find file NameService IOR: ns.ior\n"; + $NS->Kill (); $NS->TimedWait (1); + exit 1; +} + +$SV->Spawn (); + +if (PerlACE::waitforfile_timed ($iorfile, 10) == -1) { + print STDERR "ERROR: cannot find server file <$iorfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; +} + +$SR->Spawn (); + +if (PerlACE::waitforfile_timed ($iorfile, 10) == -1) { + print STDERR "ERROR: cannot find server file <$iorfile>\n"; + $SR->Kill (); $SR->TimedWait (1); + exit 1; +} + +$client = $CL->SpawnWaitKill (100); + +if ($client != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +$clientbackup = $CR->SpawnWaitKill (100); + +if ($clientbackup != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +$server = $SV->WaitKill (10); + +if ($server != 0) { + print STDERR "ERROR: server returned $server\n"; + $status = 1; +} + +$load_manager = $LM->TerminateWaitKill (10); + +if ($load_manager != 0) { + print STDERR "ERROR: LoadManager returned $load_manager\n"; + $status = 1; +} + +$name_service = $NS->TerminateWaitKill (10); + +if ($name_service != 0) { + print STDERR "ERROR: NameService returned $name_service\n"; + $status = 1; +} + +unlink $iorfile; +unlink $lm_ior; +unlink $ns_ior; + +exit $status; diff --git a/TAO/orbsvcs/examples/LoadBalancing/server.cpp b/TAO/orbsvcs/examples/LoadBalancing/server.cpp new file mode 100644 index 00000000000..66d41596ce8 --- /dev/null +++ b/TAO/orbsvcs/examples/LoadBalancing/server.cpp @@ -0,0 +1,370 @@ +#include "tao/ORBInitializer_Registry.h" +#include "StockFactory.h" +#include "ORBInitializer.h" +#include "RPS_Monitor.h" +#include "ace/OS.h" + +#include "ace/Get_Opt.h" + +ACE_RCSID (LoadBalancing, + server, + "$Id$") + +const char *ior_output_file = "obj.ior"; + +CORBA::Float reject_threshold = 0; +CORBA::Float critical_threshold = 0; +CORBA::Float dampening = 0; +const char * strategy = "LeastLoaded"; +int number; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:n:s:r:c:d:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.opt_arg (); + break; + + case 's': + strategy = get_opts.opt_arg (); + break; + + case 'n': + number = ACE_OS::atoi (get_opts.opt_arg ()); + break; + + case 'r': + reject_threshold = + static_cast<CORBA::Float> (::atof (get_opts.opt_arg ())); + break; + + case 'c': + critical_threshold = + static_cast<CORBA::Float> (::atof (get_opts.opt_arg ())); + break; + + case 'd': + dampening = + static_cast<CORBA::Float> (::atof (get_opts.opt_arg ())); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s\n" + " -o <iorfile>\n" + " -s <RoundRobin | Random | LeastLoaded>\n" + " -r <reject threshold> (LeastLoaded only)\n" + " -c <critical threshold> (LeastLoaded only)\n" + " -d <damping value> (LeastLoaded only)\n" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +CORBA::Object_ptr +join_object_group (CORBA::ORB_ptr orb, + CosLoadBalancing::LoadManager_ptr lm, + const PortableGroup::Location & location + ACE_ENV_ARG_PARAMETER) +{ + CORBA::Object_var ns_object = + orb->resolve_initial_references ("NameService" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + CosNaming::NamingContext_var nc = + CosNaming::NamingContext::_narrow (ns_object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + CosNaming::Name name (1); + name.length (1); + + name[0].id = "StockFactoryObjectGroup"; + name[0].kind = "Object Group"; + + CORBA::Object_var group; + + ACE_TRY + { + group = nc->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCH (CosNaming::NamingContext::NotFound, ex) + { + // Object group not created. Create one. + const char repository_id[] = "IDL:Test/StockFactory:1.0"; + + PortableGroup::Criteria criteria (1); + criteria.length (1); + + PortableGroup::Property & property = criteria[0]; + property.nam.length (1); + + property.nam[0].id = + CORBA::string_dup ("omg.org.PortableGroup.MembershipStyle"); + + PortableGroup::MembershipStyleValue msv = + PortableGroup::MEMB_APP_CTRL; + property.val <<= msv; + + PortableGroup::GenericFactory::FactoryCreationId_var fcid; + + group = lm->create_object (repository_id, + criteria, + fcid.out () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_TRY_EX (foo) + { + nc->bind (name, + group.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK_EX (foo); + + PortableGroup::Properties props (1); + props.length (1); + props[0].nam.length (1); + props[0].nam[0].id = + CORBA::string_dup ("org.omg.CosLoadBalancing.StrategyInfo"); + + CosLoadBalancing::StrategyInfo strategy_info; + + strategy_info.name = CORBA::string_dup (strategy); + + if (ACE_OS::strcasecmp (strategy, "LeastLoaded") == 0 + && (reject_threshold != 0 + || critical_threshold != 0 + || dampening != 0)) + { + CORBA::ULong len = 1; + + PortableGroup::Properties & props = + strategy_info.props; + + if (reject_threshold != 0) + { + const CORBA::ULong i = len - 1; + + props.length (len++); + + props[i].nam.length (1); + props[i].nam[0].id = + CORBA::string_dup ("org.omg.CosLoadBalancing.Strategy.LeastLoaded.RejectThreshold"); + props[i].val <<= reject_threshold; + } + + if (critical_threshold != 0) + { + const CORBA::ULong i = len - 1; + + props.length (len++); + + props[i].nam.length (1); + props[i].nam[0].id = + CORBA::string_dup ("org.omg.CosLoadBalancing.Strategy.LeastLoaded.CriticalThreshold"); + props[i].val <<= critical_threshold; + } + + if (dampening != 0) + { + const CORBA::ULong i = len - 1; + + props.length (len++); + + props[i].nam.length (1); + props[i].nam[0].id = + CORBA::string_dup ("org.omg.CosLoadBalancing.Strategy.LeastLoaded.Dampening"); + props[i].val <<= dampening; + } + + } + + props[0].val <<= strategy_info; + + lm->set_default_properties (props + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCH (CosNaming::NamingContext::AlreadyBound, ex) + { + // Somebody beat us to creating the object group. Clean up + // the one we created. + lm->delete_object (fcid.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK_EX (foo); + + group = nc->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK_EX (foo); + } + ACE_ENDTRY; + ACE_TRY_CHECK; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + StockFactory * stockfactory_impl; + ACE_NEW_THROW_EX (stockfactory_impl, + StockFactory (orb, number), + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + PortableServer::ServantBase_var owner_transfer (stockfactory_impl); + + Test::StockFactory_var stockfactory = + stockfactory_impl->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + group = lm->add_member (group.in (), + location, + stockfactory.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + return group._retn (); +} + +int +main (int argc, char *argv[]) +{ + ACE_TRY_NEW_ENV + { + ORBInitializer *initializer = 0; + ACE_NEW_RETURN (initializer, + ORBInitializer, + -1); // No exceptions yet! + PortableInterceptor::ORBInitializer_var orb_initializer = + initializer; + + PortableInterceptor::register_orb_initializer (orb_initializer.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) != 0) + return 1; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var lm_object = + orb->resolve_initial_references ("LoadManager" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosLoadBalancing::LoadManager_var load_manager = + CosLoadBalancing::LoadManager::_narrow (lm_object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RPS_Monitor * monitor_servant; + ACE_NEW_THROW_EX (monitor_servant, + RPS_Monitor (initializer->interceptor ()), + CORBA::NO_MEMORY ()); + ACE_TRY_CHECK; + + PortableServer::ServantBase_var safe_monitor_servant (monitor_servant); + + CosLoadBalancing::LoadMonitor_var load_monitor = + monitor_servant->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableGroup::Location_var location = + load_monitor->the_location (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var stockfactory = + ::join_object_group (orb.in (), + load_manager.in (), + location.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + TAO_LB_LoadAlert & alert_servant = initializer->load_alert (); + + CosLoadBalancing::LoadAlert_var load_alert = + alert_servant._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + + CORBA::String_var ior = + orb->object_to_string (stockfactory.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // If the ior_output_file exists, output the ior to it + FILE *output_file= ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing IOR: %s", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + + load_manager->register_load_monitor (location.in (), + load_monitor.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + load_manager->register_load_alert (location.in (), + load_alert.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) server - event loop finished\n")); + + root_poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "lb_server exception"); + return 1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Log/Basic/Log_Basic.mpc b/TAO/orbsvcs/examples/Log/Basic/Log_Basic.mpc new file mode 100644 index 00000000000..73476b098d4 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Basic/Log_Basic.mpc @@ -0,0 +1,6 @@ +// -*- MPC -*- +// $Id$ + +project(*Client) : orbsvcsexe, dslogadmin, naming { + exename = client +} diff --git a/TAO/orbsvcs/examples/Log/Basic/Makefile.am b/TAO/orbsvcs/examples/Log/Basic/Makefile.am new file mode 100644 index 00000000000..9d3b10cddcc --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Basic/Makefile.am @@ -0,0 +1,46 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +## Makefile.Log_Basic_Client.am + +noinst_PROGRAMS = client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +client_SOURCES = \ + TLS_Client.cpp \ + main.cpp \ + TLS_Client.h + +client_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsLogAdmin.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Log/Basic/README b/TAO/orbsvcs/examples/Log/Basic/README new file mode 100644 index 00000000000..573d86b75cb --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Basic/README @@ -0,0 +1,17 @@ +// $Id$ + +Telecom Log Service (TLS) Client example +---------------------------------------- +This is a simple example example to show how to create a basic log and write events +to the Log. + +To run this example: +1) You need a running Naming Service, $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service +2) You need a running Log Service, $TAO_ROOT/orbsvcs/Logging_Service/Logging_Service +3) ./tls_client + +The client locates the log service factory from the naming service. +Then it creates a DsLogAdmin::BasicLog does the following operations: +- writes records, query records, delete records. + +report bugs to D A Hanvey <d.hanvey@qub.ac.uk> diff --git a/TAO/orbsvcs/examples/Log/Basic/TLS_Client.cpp b/TAO/orbsvcs/examples/Log/Basic/TLS_Client.cpp new file mode 100644 index 00000000000..6c4fd3a47b3 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Basic/TLS_Client.cpp @@ -0,0 +1,198 @@ +#include "TLS_Client.h" +#include "ace/Log_Msg.h" + +ACE_RCSID (Basic, + TLS_Client, + "$Id$") + +#define NAMING_SERVICE_NAME "NameService" +#define BASIC_TLS_LOG_FACTORY_NAME "BasicLogFactory" +#define LOG_EVENT_COUNT 9 +#define QUERY_1 "id < 5" +#define QUERY_2 "id >= 0" +#define QUERY_LANG "TCL" + + + +TLS_Client::TLS_Client (void) +{ + // No-Op. +} + +TLS_Client::~TLS_Client () +{ + // No-Op. +} + +void +TLS_Client::init (int argc, char *argv [] ACE_ENV_ARG_DECL) +{ + init_ORB (argc, argv ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + resolve_naming_service (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + resolve_TLS_Basic_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +TLS_Client::init_ORB (int argc, + char *argv [] + ACE_ENV_ARG_DECL) +{ + this->orb_ = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TLS_Client::resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL) +{ + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW (CORBA::UNKNOWN ()); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TLS_Client::resolve_TLS_Basic_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (BASIC_TLS_LOG_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->basic_log_factory_ = + DsLogAdmin::BasicLogFactory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TLS_Client::run_tests (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->basic_log_factory_.in ())); + + // create a log.. + + ACE_DEBUG ((LM_DEBUG, + "\nCalling BasicLogFactory::create...\n")); + + DsLogAdmin::LogFullActionType logfullaction = DsLogAdmin::halt; + CORBA::ULongLong max_size = 0; // 0 means "infinite" + + DsLogAdmin::LogId logid = 0; + + DsLogAdmin::BasicLog_var basic_log = + this->basic_log_factory_->create (logfullaction, + max_size, + logid + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Create returned logid = %d\n",logid)); + + // Create some fake log events. + DsLogAdmin::Anys any_seq (LOG_EVENT_COUNT); + any_seq.length (LOG_EVENT_COUNT); + + for (int i = 0; i < LOG_EVENT_COUNT; i++) + { + any_seq [i] <<= "Foo"; + } + + ACE_DEBUG ((LM_DEBUG, + "Writing %d records...\n", LOG_EVENT_COUNT)); + basic_log->write_records (any_seq ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Calling BasicLog::get_n_records...\n")); +#ifndef ACE_LACKS_LONGLONG_T + CORBA::ULongLong retval = basic_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +#else + CORBA::Long retval = basic_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Number of records in Log = %d \n", retval)); + + ACE_DEBUG ((LM_DEBUG, + "Calling BasicLog::get_current_size...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = basic_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +#else + retval = basic_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Size of data in Log = %d \n", retval)); + + ACE_DEBUG ((LM_DEBUG, "Querying the Log: %s\n", QUERY_1)); + DsLogAdmin::Iterator_var iter_out; + DsLogAdmin::RecordList_var rec_list = + basic_log->query (QUERY_LANG, QUERY_1, iter_out); + + CORBA::ULong j = 0; + for (; j < rec_list->length();++j) //dhanvey added info +#ifndef ACE_LACKS_LONGLONG_T + ACE_DEBUG ((LM_DEBUG, + "id = %Q, time= %Q\n", + rec_list[j].id, rec_list[j].time)); + +#else + ACE_DEBUG ((LM_DEBUG, + "id = %u, time= %u\n", + rec_list[j].id.lo(), rec_list[j].time.lo())); +#endif + + ACE_DEBUG ((LM_DEBUG, + "Deleting records... \n")); + + retval = basic_log->delete_records (QUERY_LANG, QUERY_2 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Calling BasicLog::get_n_records...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = basic_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +#else + retval = basic_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Number of records in Log after delete = %d \n", + retval)); + + ACE_DEBUG ((LM_DEBUG, "Geting the current_size again...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = basic_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +#else + retval = basic_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Size of data in Log = %d \n", retval)); + + basic_log->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} diff --git a/TAO/orbsvcs/examples/Log/Basic/TLS_Client.h b/TAO/orbsvcs/examples/Log/Basic/TLS_Client.h new file mode 100644 index 00000000000..b06ffc65f92 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Basic/TLS_Client.h @@ -0,0 +1,63 @@ +/* -*- C++ -*- */ + +// ============================================================================ +/** + * @file TLS_Client.h + * + * $Id$ + * + * An example of using the Basic_Logging_Service + * + * + * + * @author D A Hanvey (d.hanvey@qub.ac.uk) + */ +// ============================================================================ + +#ifndef TLS_CLIENT_H +#define TLS_CLIENT_H + +#include "orbsvcs/DsLogAdminC.h" +#include "orbsvcs/CosNamingC.h" + +class TLS_Client +{ + // = TITLE + // Telecom Log Service Client + // = DESCRIPTION + // This client demonstates how to use the log service. + public: + // = Initialization and Termination + TLS_Client (void); + ~TLS_Client (); + + void init (int argc, char *argv [] ACE_ENV_ARG_DECL); + // Init the Client. + + void run_tests (ACE_ENV_SINGLE_ARG_DECL); + // Run the tests.. + + protected: + void init_ORB (int argc, char *argv [] ACE_ENV_ARG_DECL); + // Initializes the ORB. + + void resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL); + // Try to get hold of a running naming service. + + void resolve_TLS_Basic_factory (ACE_ENV_SINGLE_ARG_DECL); + // Try to resolve the TLS factory from the Naming service. + + // = Data Members + CORBA::ORB_var orb_; + // The ORB that we use. + + CosNaming::NamingContext_var naming_context_; + // Handle to the name service. + + DsLogAdmin::BasicLogFactory_var basic_log_factory_; + // The basic log factory from the Log Service. + + + +}; +#endif /* TLS_CLIENT_H */ diff --git a/TAO/orbsvcs/examples/Log/Basic/main.cpp b/TAO/orbsvcs/examples/Log/Basic/main.cpp new file mode 100644 index 00000000000..3b5098b43ad --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Basic/main.cpp @@ -0,0 +1,39 @@ +#include "TLS_Client.h" +#include "ace/OS_main.h" + +ACE_RCSID (Basic, + main, + "$Id$") + + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TLS_Client client; // Telecom Log Service Client + + ACE_TRY_NEW_ENV + { + client.init (argc, argv + ACE_ENV_ARG_PARAMETER); //Init the Client + ACE_TRY_CHECK; + + client.run_tests (ACE_ENV_SINGLE_ARG_PARAMETER); //Init the Client + + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::UserException, ue) + { + ACE_PRINT_EXCEPTION (ue, + "TLS_Client user error: "); + return 1; + } + ACE_CATCH (CORBA::SystemException, se) + { + ACE_PRINT_EXCEPTION (se, + "TLS_Client system error: "); + return 1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Log/Basic/run_test.pl b/TAO/orbsvcs/examples/Log/Basic/run_test.pl new file mode 100755 index 00000000000..8cd52e4559d --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Basic/run_test.pl @@ -0,0 +1,57 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../../bin'; +use PerlACE::Run_Test; + +$status = 0; + +$nsior = PerlACE::LocalFile ("ns.ior"); + +unlink $nsior; + +$NS = new PerlACE::Process ("../../../Naming_Service/Naming_Service", "-o $nsior"); +$LS = new PerlACE::Process ("../../../Logging_Service/Basic_Logging_Service/Basic_Logging_Service", "-ORBInitRef NameService=file://$nsior"); +$CLIENT = new PerlACE::Process ("client", "-ORBInitRef NameService=file://$nsior"); + + +print STDERR "Starting Naming Service\n"; + +$NS->Spawn (); + +if (PerlACE::waitforfile_timed ($nsior, 20) == -1) { + print STDERR "ERROR: cannot find naming service IOR file\n"; + $NS->Kill (); + exit 1; +} + +print STDERR "Starting Logging Service\n"; + +$LS->Spawn (); + +# Give time for logging service to initialize and install its object +# reference in the nameing service. +sleep (5); + +print STDERR "Starting client\n"; + +$CLIENT->Spawn (); + +$client = $CLIENT->WaitKill (10); + +$NS->Kill (); + +$LS->Kill (); + +if ($client != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +unlink $nsior; + +exit $status; diff --git a/TAO/orbsvcs/examples/Log/Event/Event_Consumer.cpp b/TAO/orbsvcs/examples/Log/Event/Event_Consumer.cpp new file mode 100644 index 00000000000..1b102beac2f --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Event/Event_Consumer.cpp @@ -0,0 +1,131 @@ +#include "Event_Consumer.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "ace/OS_main.h" + +ACE_RCSID (Event, + Event_Consumer, + "$Id$") + +#define NAMING_SERVICE_NAME "NameService" +#define EVENT_TLS_LOG_FACTORY_NAME "EventLogFactory" + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Consumer consumer; + + return consumer.run (argc, argv); +} + +// **************************************************************** + +Consumer::Consumer (void) + : event_count_ (0) +{ +} + +int +Consumer::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Do *NOT* make a copy because we don't want the ORB to outlive + // the Consumer object. + this->orb_ = orb.in (); + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW_RETURN (CORBA::UNKNOWN (),0); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (EVENT_TLS_LOG_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->event_log_factory_ = + DsEventLogAdmin::EventLogFactory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->supplier_ = + this->event_log_factory_->obtain_push_supplier (); + + CosEventComm::PushConsumer_var consumer = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + + this->supplier_->connect_push_consumer (consumer.in () ACE_ENV_ARG_PARAMETER); + + orb_->run (); + + // We don't do any cleanup, it is hard to do it after shutdown, + // and would complicate the example; plus it is almost + // impossible to do cleanup after ORB->run() because the POA is + // in the holding state. Applications should use + // work_pending()/perform_work() to do more interesting stuff. + // Check the supplier for the proper way to do cleanup. + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Consumer::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Consumer::push (const CORBA::Any & + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + + this->event_count_ ++; + + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t): %d log generated events received\n", + this->event_count_)); + +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // In this example we shutdown the ORB when we disconnect from the + // EC (or rather the EC disconnects from us), but this doesn't have + // to be the case.... + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} + diff --git a/TAO/orbsvcs/examples/Log/Event/Event_Consumer.h b/TAO/orbsvcs/examples/Log/Event/Event_Consumer.h new file mode 100644 index 00000000000..946299dc55d --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Event/Event_Consumer.h @@ -0,0 +1,74 @@ +/* -*- C++ -*- */ + +// ============================================================================ +/** + * @file Event_Consumer.h + * + * $Id$ + * + * An example of using the Event_Logging_Service. + * The Event_Consumer consumes log-generated events. + * + * + * @author D A Hanvey (d.hanvey@qub.ac.uk) + */ +// ============================================================================ + +#ifndef EVENT_CONSUMER_H +#define EVENT_CONSUMER_H + +#include "orbsvcs/DsEventLogAdminC.h" +#include "orbsvcs/CosEventCommS.h" +#include "orbsvcs/CosNamingC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Consumer : public POA_CosEventComm::PushConsumer +{ + // = TITLE + // Simple consumer object + // + // = DESCRIPTION + // This class is a consumer of log generated events. + // +public: + Consumer (void); + // Constructor + + int run (int argc, char* argv[]); + // Run the test + + // = The CosEventComm::PushConsumer methods + + virtual void push (const CORBA::Any &event + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: + + // = Data Members + CORBA::ULong event_count_; + // Keep track of the number of events received. + + CORBA::ORB_var orb_; + // The orb, just a pointer because the ORB does not outlive the + // run() method... + + CosNaming::NamingContext_var naming_context_; + // Handle to the name service. + + DsEventLogAdmin::EventLogFactory_var event_log_factory_; + // The Event Log Factory that generates the events to be consumed. + + CosEventChannelAdmin::ProxyPushSupplier_var supplier_; + // The proxy that we are connected to. + +}; + +#endif /* EVENT_CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/Log/Event/Event_Supplier.cpp b/TAO/orbsvcs/examples/Log/Event/Event_Supplier.cpp new file mode 100644 index 00000000000..f65f4a420e9 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Event/Event_Supplier.cpp @@ -0,0 +1,240 @@ +#include "Event_Supplier.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "ace/OS_main.h" + +ACE_RCSID (Event, + Event_Supplier, + "$Id$") + +#define NAMING_SERVICE_NAME "NameService" +#define EVENT_TLS_LOG_FACTORY_NAME "EventLogFactory" +#define LOG_EVENT_COUNT 9 +#define QUERY_1 "id > 0" +#define QUERY_2 "id >= 0" +#define QUERY_LANG "TCL" + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Supplier supplier; + + return supplier.run (argc, argv); +} + +// **************************************************************** + +Supplier::Supplier (void) +{ +} + +int +Supplier::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + this->orb_ = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var object = + this->orb_->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW_RETURN (CORBA::UNKNOWN (), 0); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (EVENT_TLS_LOG_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->event_log_factory_ = + DsEventLogAdmin::EventLogFactory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ASSERT (!CORBA::is_nil (this->event_log_factory_.in ())); + + + // create a log.. + + ACE_DEBUG ((LM_DEBUG, + "\nCalling EventLogFactory::create...\n")); + + DsLogAdmin::LogFullActionType logfullaction = DsLogAdmin::halt; + DsLogAdmin::CapacityAlarmThresholdList threshold = 0; + CORBA::ULongLong max_size = 0; // 0 means "infinite" + + DsLogAdmin::LogId logid = 0; + + DsEventLogAdmin::EventLog_var event_log = + // DsLogAdmin::Log_var event_log = + this->event_log_factory_->create (logfullaction, + max_size, + threshold, + logid + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + ACE_DEBUG ((LM_DEBUG, + "Create returned logid = %d\n",logid)); + + CosEventChannelAdmin::SupplierAdmin_var supplier_admin = + event_log->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + + this->consumer_ = + supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + + CosEventComm::PushSupplier_var supplier = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + + this->consumer_->connect_push_supplier (supplier.in () ACE_ENV_ARG_PARAMETER); + + // Create some fake log events. + CORBA::Any event; + event <<= CORBA::ULong (10); + + for (int d = 0; d < LOG_EVENT_COUNT; d++) + { + this->consumer_->push (event ACE_ENV_ARG_PARAMETER); + } + + ACE_DEBUG ((LM_DEBUG, + "Writing %d records...\n", LOG_EVENT_COUNT)); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Calling EventLog::get_n_records...\n")); +#ifndef ACE_LACKS_LONGLONG_T + CORBA::ULongLong retval = event_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + CORBA::Long retval = event_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Number of records in Log = %d \n", retval)); + + ACE_DEBUG ((LM_DEBUG, + "Calling EventLog::get_current_size...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = event_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + retval = event_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Size of data in Log = %d \n", retval)); + + ACE_DEBUG ((LM_DEBUG, "Querying the Log: %s\n", QUERY_1)); + DsLogAdmin::Iterator_var iter_out; + DsLogAdmin::RecordList_var rec_list = + event_log->query (QUERY_LANG, QUERY_1, iter_out); + + CORBA::ULong j = 0; + for (; j < rec_list->length();++j) +#ifndef ACE_LACKS_LONGLONG_T + ACE_DEBUG ((LM_DEBUG, + "id = %Q, time= %Q\n", + rec_list[j].id, rec_list[j].time)); +#else + ACE_DEBUG ((LM_DEBUG, + "id = %u, time= %u\n", + rec_list[j].id.lo(), rec_list[j].time.lo())); +#endif + + ACE_DEBUG ((LM_DEBUG, + "Deleting records... \n")); + + retval = event_log->delete_records (QUERY_LANG, QUERY_2 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Calling EventLog::get_n_records...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = event_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + retval = event_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Number of records in Log after delete = %d \n", + retval)); + + ACE_DEBUG ((LM_DEBUG, "Geting the current_size again...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = event_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + retval = event_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Size of data in Log = %d \n", retval)); + + // Disconnect from the EC + this->consumer_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the EC.... + //event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + event_log->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Deactivate this object... + PortableServer::ObjectId_var id = + poa->servant_to_id (this ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the POA + poa->destroy (1, 0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Supplier::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/examples/Log/Event/Event_Supplier.h b/TAO/orbsvcs/examples/Log/Event/Event_Supplier.h new file mode 100644 index 00000000000..c37b9a5c9df --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Event/Event_Supplier.h @@ -0,0 +1,66 @@ +/* -*- C++ -*- */ + +// ============================================================================ +/** + * @file Event_Supplier.h + * + * $Id$ + * + * An example of using the Event_Logging_Service. + * + * + * + * @author D A Hanvey (d.hanvey@qub.ac.uk) + */ +// ============================================================================ + +#ifndef EVENT_SUPPLIER_H +#define EVENT_SUPPLIER_H + +#include "orbsvcs/DsEventLogAdminC.h" +#include "orbsvcs/CosEventCommS.h" +#include "orbsvcs/CosNamingC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Supplier : public POA_CosEventComm::PushSupplier +{ + // = TITLE + // Simple supplier object + // + // = DESCRIPTION + // This class is a supplier of events. + // +public: + Supplier (void); + // Constructor + + int run (int argc, char* argv[]); + // Run the test + + // = The CosEventComm::PushSupplier methods + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: + + // = Data Members + CORBA::ORB_var orb_; + // The ORB that we use. + + CosNaming::NamingContext_var naming_context_; + // Handle to the name service. + + DsEventLogAdmin::EventLogFactory_var event_log_factory_; + // The Event Log Factory that generates the events to be consumed. + + CosEventChannelAdmin::ProxyPushConsumer_var consumer_; + // The proxy that we are connected to. + +}; + +#endif /* EVENT_SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/Log/Event/Log_Event.mpc b/TAO/orbsvcs/examples/Log/Event/Log_Event.mpc new file mode 100644 index 00000000000..c96507ed65c --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Event/Log_Event.mpc @@ -0,0 +1,16 @@ +// -*- MPC -*- +// $Id$ + +project(*Consumer) : orbsvcsexe, dseventlogadmin, event_skel, naming { + exename = Event_Consumer + source_files { + Event_Consumer.cpp + } +} + +project(*Supplier) : orbsvcsexe, dseventlogadmin, event_skel, naming { + exename = Event_Supplier + source_files { + Event_Supplier.cpp + } +} diff --git a/TAO/orbsvcs/examples/Log/Event/Makefile.am b/TAO/orbsvcs/examples/Log/Event/Makefile.am new file mode 100644 index 00000000000..5fad8b3b991 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Event/Makefile.am @@ -0,0 +1,88 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Log_Event_Consumer.am + +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Event_Consumer + +Event_Consumer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Event_Consumer_SOURCES = \ + Event_Consumer.cpp \ + Event_Consumer.h + +Event_Consumer_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsEventLogAdmin.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsLogAdmin.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA + +## Makefile.Log_Event_Supplier.am + +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Event_Supplier + +Event_Supplier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Event_Supplier_SOURCES = \ + Event_Supplier.cpp \ + Event_Supplier.h + +Event_Supplier_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsEventLogAdmin.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsLogAdmin.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Log/Event/README b/TAO/orbsvcs/examples/Log/Event/README new file mode 100644 index 00000000000..ab49cd6d438 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Event/README @@ -0,0 +1,18 @@ +// $Id$ + +Telecom Log Service (TLS) Client example +---------------------------------------- +This is a simple example example to show how to create an event log and write events +to the Log. + +To run this example: +1) You need a running Naming Service, $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service +2) You need a running Event Logging Service, $TAO_ROOT/orbsvcs/Logging_Service/Event_Logging_Service +3) To collect log-generated events you will need to run, ./Event_Consumer +4) To run the sample log events run, ./Event_Supplier + +The client locates the log service factory from the naming service. +Then it creates a DsEventLogAdmin::EventLog does the following operations: +- writes records, query records, delete records. + +report bugs to D A Hanvey <d.hanvey@qub.ac.uk> diff --git a/TAO/orbsvcs/examples/Log/Event/run_test.pl b/TAO/orbsvcs/examples/Log/Event/run_test.pl new file mode 100755 index 00000000000..5d7a369ed5d --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Event/run_test.pl @@ -0,0 +1,67 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../../bin'; +use PerlACE::Run_Test; + +$status = 0; + +$nsior = PerlACE::LocalFile ("ns.ior"); + +unlink $nsior; + +$NS = new PerlACE::Process ("../../../Naming_Service/Naming_Service", "-o $nsior"); +$LS = new PerlACE::Process ("../../../Logging_Service/Event_Logging_Service/Event_Logging_Service", "-ORBInitRef NameService=file://$nsior"); +$consumer = new PerlACE::Process ("Event_Consumer", "-ORBInitRef NameService=file://$nsior"); +$supplier = new PerlACE::Process ("Event_Supplier", "-ORBInitRef NameService=file://$nsior"); + + +print STDERR "Starting Naming Service\n"; + +$NS->Spawn (); + +if (PerlACE::waitforfile_timed ($nsior, 20) == -1) { + print STDERR "ERROR: cannot find naming service IOR file\n"; + $NS->Kill (); + exit 1; +} + +print STDERR "Starting Logging Service\n"; + +$LS->Spawn (); + +# Give time for logging service to initialize and install its object +# reference in the naming service. +sleep (5); + +print STDERR "Starting Consumer\n"; + +$consumer->Spawn (); + +sleep (1); + +print STDERR "Starting Supplier\n"; + +$supplier->Spawn (); + + +$supplier->WaitKill (5); + +$consumer->Kill (); + +$NS->Kill (); + +$LS->Kill (); + +#if ($client != 0) { +# print STDERR "ERROR: client returned $client\n"; +# $status = 1; +#} + +unlink $nsior; + +exit $status; diff --git a/TAO/orbsvcs/examples/Log/Makefile.am b/TAO/orbsvcs/examples/Log/Makefile.am new file mode 100644 index 00000000000..2ce0dbc980d --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + Basic \ + Event \ + Notify \ + RTEvent + diff --git a/TAO/orbsvcs/examples/Log/Notify/Log_Notify.mpc b/TAO/orbsvcs/examples/Log/Notify/Log_Notify.mpc new file mode 100644 index 00000000000..9082517a64c --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Notify/Log_Notify.mpc @@ -0,0 +1,16 @@ +// -*- MPC -*- +// $Id$ + +project(*Consumer) : orbsvcsexe, dsnotifylogadmin, notification_skel, naming { + exename = Notify_Consumer + source_files { + Notify_Consumer.cpp + } +} + +project(*Supplier) : orbsvcsexe, dsnotifylogadmin, notification_skel, naming { + exename = Notify_Supplier + source_files { + Notify_Supplier.cpp + } +} diff --git a/TAO/orbsvcs/examples/Log/Notify/Makefile.am b/TAO/orbsvcs/examples/Log/Notify/Makefile.am new file mode 100644 index 00000000000..46d235ac030 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Notify/Makefile.am @@ -0,0 +1,94 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Log_Notify_Consumer.am + +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Notify_Consumer + +Notify_Consumer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Notify_Consumer_SOURCES = \ + Notify_Consumer.cpp \ + Notify_Consumer.h + +Notify_Consumer_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsNotifyLogAdmin.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsEventLogAdmin.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsLogAdmin.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA + +## Makefile.Log_Notify_Supplier.am + +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Notify_Supplier + +Notify_Supplier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Notify_Supplier_SOURCES = \ + Notify_Supplier.cpp \ + Notify_Supplier.h + +Notify_Supplier_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsNotifyLogAdmin.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsEventLogAdmin.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsLogAdmin.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Log/Notify/Notify_Consumer.cpp b/TAO/orbsvcs/examples/Log/Notify/Notify_Consumer.cpp new file mode 100644 index 00000000000..0d27c8860d3 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Notify/Notify_Consumer.cpp @@ -0,0 +1,174 @@ +#include "Notify_Consumer.h" +#include "orbsvcs/CosEventChannelAdminS.h" +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include "ace/OS_main.h" + +ACE_RCSID (Notify, + Notify_Consumer, + "$Id$") + +#define NAMING_SERVICE_NAME "NameService" +#define NOTIFY_TLS_LOG_FACTORY_NAME "NotifyLogFactory" +#define LOG_EVENT_COUNT 29 +#define QUERY_1 "id > 0" +#define QUERY_2 "id >= 0" +#define QUERY_LANG "TCL" +#define SA_FILTER "threshold > 10" +#define TCL_GRAMMAR "TCL" +#define EVENTS_TO_SEND 30 + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Consumer consumer; + + return consumer.run (argc, argv); +} + +// **************************************************************** + +Consumer::Consumer (void) + : event_count_ (0) +{ +} + +int +Consumer::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Do *NOT* make a copy because we don't want the ORB to outlive + // the Consumer object. + this->orb_ = orb.in (); + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW_RETURN (CORBA::UNKNOWN (), 0); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (NOTIFY_TLS_LOG_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->notify_log_factory_ = + DsNotifyLogAdmin::NotifyLogFactory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNotifyComm::PushConsumer_var objref = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ASSERT (!CORBA::is_nil (objref.in ())); + + CosNotifyChannelAdmin::ProxySupplier_var proxysupplier = + this->notify_log_factory_->obtain_notification_push_supplier (CosNotifyChannelAdmin::ANY_EVENT, proxy_supplier_id_ ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxysupplier.in ())); + + + this->proxy_supplier_ = + CosNotifyChannelAdmin::ProxyPushSupplier:: + _narrow (proxysupplier.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxy_supplier_.in ())); + + proxy_supplier_->connect_any_push_consumer (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb_->run (); + + // We don't do any cleanup, it is hard to do it after shutdown, + // and would complicate the example; plus it is almost + // impossible to do cleanup after ORB->run() because the POA is + // in the holding state. Applications should use + // work_pending()/perform_work() to do more interesting stuff. + // Check the supplier for the proper way to do cleanup. + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Consumer::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Consumer::push (const CORBA::Any &event + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )) +{ + ACE_UNUSED_ARG (event); + + this->event_count_ ++; + + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t): %d log generated events received\n", + this->event_count_)); +} + +void +Consumer::disconnect_push_consumer + (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + this->proxy_supplier_-> + disconnect_push_supplier(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Consumer::offer_change + (const CosNotification::EventTypeSeq & /*added*/, + const CosNotification::EventTypeSeq & /*removed*/ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )) +{ + // No-Op. +} + diff --git a/TAO/orbsvcs/examples/Log/Notify/Notify_Consumer.h b/TAO/orbsvcs/examples/Log/Notify/Notify_Consumer.h new file mode 100644 index 00000000000..0a125e95824 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Notify/Notify_Consumer.h @@ -0,0 +1,100 @@ +/* -*- C++ -*- */ + +// ============================================================================ +/** + * @file Notify_Consumer.h + * + * $Id$ + * + * An example of using the Notify_Logging_Service. + * The Notify_Consumer consumes log-generated events. + * + * + * @author D A Hanvey (d.hanvey@qub.ac.uk) + */ +// ============================================================================ + +#ifndef NOTIFY_CONSUMER_H +#define NOTIFY_CONSUMER_H + +#include "orbsvcs/DsNotifyLogAdminS.h" +#include "orbsvcs/DsEventLogAdminC.h" +#include "orbsvcs/CosEventCommS.h" +#include "orbsvcs/CosNotifyCommS.h" +#include "orbsvcs/CosNamingC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Consumer + : public POA_CosNotifyComm::PushConsumer +{ + // = TITLE + // Simple consumer object + // + // = DESCRIPTION + // This class is a consumer of log generated events. + // +public: + Consumer (void); + // Constructor + + int run (int argc, char* argv[]); + // Run the test + +protected: + + CosNotifyChannelAdmin::ProxyID proxy_supplier_id_; + // The proxy_supplier id. + + // = Methods + + // Destructor + + // = NotifyPublish method + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )); + + // = StructuredPushSupplier methods +virtual void push (const CORBA::Any &event + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )); + + + virtual void disconnect_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + +private: + CORBA::ULong event_count_; + // Keep track of the number of events received. + + // = Data Members + CORBA::ORB_var orb_; + // The ORB that we use. + + CosNaming::NamingContext_var naming_context_; + // Handle to the name service. + + DsNotifyLogAdmin::NotifyLogFactory_var notify_log_factory_; + + CosNotifyChannelAdmin::ProxyPushSupplier_var proxy_supplier_; + + +}; + +#endif /* NOTIFY_CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/Log/Notify/Notify_Supplier.cpp b/TAO/orbsvcs/examples/Log/Notify/Notify_Supplier.cpp new file mode 100644 index 00000000000..86fbfd2be3c --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Notify/Notify_Supplier.cpp @@ -0,0 +1,362 @@ +#include "Notify_Supplier.h" +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include "ace/OS_main.h" + +ACE_RCSID (Notify, + Notify_Supplier, + "$Id$") + + +#define NAMING_SERVICE_NAME "NameService" +#define NOTIFY_TLS_LOG_FACTORY_NAME "NotifyLogFactory" +#define LOG_EVENT_COUNT 10 +#define QUERY_1 "id > 0" +#define QUERY_2 "id >= 0" +#define QUERY_LANG "TCL" +#define SA_FILTER "threshold > 10" +#define TCL_GRAMMAR "TCL" +#define EVENTS_TO_SEND 10 + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Supplier supplier; + + return supplier.run (argc, argv); +} + +// **************************************************************** + +Supplier::Supplier (void) +{ +} + +Supplier::~Supplier () +{ + +} + +int +Supplier::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + this->orb_ = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW_RETURN (CORBA::UNKNOWN (), 0); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (NOTIFY_TLS_LOG_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->notify_log_factory_ = + DsNotifyLogAdmin::NotifyLogFactory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ASSERT (!CORBA::is_nil (this->notify_log_factory_.in ())); + + // create a log.. + + ACE_DEBUG ((LM_DEBUG, + "\nCalling NotifyLogFactory::create...\n")); + + DsLogAdmin::LogFullActionType logfullaction = DsLogAdmin::halt; + DsLogAdmin::CapacityAlarmThresholdList threshold = 0; + CORBA::ULongLong max_size = 0; // 0 means "infinite" + + DsLogAdmin::LogId logid = 0; + CosNotification::QoSProperties initial_qos; + CosNotification::AdminProperties initial_admin; + + this->notify_log_ = + this->notify_log_factory_->create (logfullaction, + max_size, + threshold, + initial_qos, + initial_admin, + logid + ACE_ENV_ARG_PARAMETER); + + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Create returned logid = %d\n",logid)); + + // Create some fake log events. + DsLogAdmin::Anys any_seq (LOG_EVENT_COUNT); + any_seq.length (LOG_EVENT_COUNT); + + //DsLogAdmin::RecordIdList id_seq (LOG_EVENT_COUNT); + //id_seq.length (LOG_EVENT_COUNT); + + for (int i = 0; i < LOG_EVENT_COUNT; i++) + { + any_seq [i] <<= i; + } + + CosNotifyChannelAdmin::AdminID adminID = 0; + this->supplier_admin_ = + notify_log_->new_for_suppliers (CosNotifyChannelAdmin::OR_OP, adminID); + ACE_ASSERT (!CORBA::is_nil (supplier_admin_.in ())); + + CosNotifyFilter::FilterFactory_var ffact = + notify_log_->default_filter_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // setup a filter at the consumer admin + CosNotifyFilter::Filter_var sa_filter = + ffact->create_filter (TCL_GRAMMAR ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ASSERT (!CORBA::is_nil (sa_filter.in ())); + + CosNotifyFilter::ConstraintExpSeq constraint_list (1); + constraint_list.length (1); + + constraint_list[0].event_types.length (0); + constraint_list[0].constraint_expr = CORBA::string_dup (SA_FILTER); + + sa_filter->add_constraints (constraint_list ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + supplier_admin_->add_filter (sa_filter.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // startup the first supplier + ACE_NEW_THROW_EX (supplier_1, + Filter_StructuredPushSupplier (ACE_ENV_SINGLE_ARG_PARAMETER), + CORBA::NO_MEMORY ()); + + supplier_1->connect (supplier_admin_.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // operations: + CosNotification::StructuredEvent event; + + // EventHeader + + // FixedEventHeader + // EventType + // string + event.header.fixed_header.event_type.domain_name = CORBA::string_dup("*"); + // string + event.header.fixed_header.event_type.type_name = CORBA::string_dup("*"); + // string + event.header.fixed_header.event_name = CORBA::string_dup("myevent"); + + // OptionalHeaderFields + // PropertySeq + // sequence<Property>: string name, any value + event.header.variable_header.length (1); // put nothing here + + // FilterableEventBody + // PropertySeq + // sequence<Property>: string name, any value + event.filterable_data.length (3); + event.filterable_data[0].name = CORBA::string_dup("threshold"); + + event.filterable_data[1].name = CORBA::string_dup("temperature"); + event.filterable_data[1].value <<= (CORBA::Long)70; + + event.filterable_data[2].name = CORBA::string_dup("pressure"); + event.filterable_data[2].value <<= (CORBA::Long)80; + + event.filterable_data[0].value <<= (CORBA::Long)4; + + // any + event.remainder_of_body <<= (CORBA::Long)4; + + for (int k = 0; k < EVENTS_TO_SEND; k++) + { + event.filterable_data[0].value <<= (CORBA::Long)k; + + // any + event.remainder_of_body <<= (CORBA::Long)k; + + supplier_1->send_event (event ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + ACE_DEBUG ((LM_DEBUG, + "Calling NotifyLog get_n_records...\n")); + +#ifndef ACE_LACKS_LONGLONG_T + CORBA::ULongLong retval = notify_log_->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + CORBA::Long retval = notify_log_->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Number of records in Log = %d \n", retval)); + + ACE_DEBUG ((LM_DEBUG, + "Calling NotifyLog::get_current_size...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = notify_log_->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + retval = notify_log_->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Size of data in Log = %d \n", retval)); + + ACE_DEBUG ((LM_DEBUG, "Querying the Log: %s\n", QUERY_1)); + DsLogAdmin::Iterator_var iter_out; + DsLogAdmin::RecordList_var rec_list = + notify_log_->query (QUERY_LANG, QUERY_1, iter_out); + + CORBA::ULong j = 0; + for (; j < rec_list->length();++j) +#ifndef ACE_LACKS_LONGLONG_T + ACE_DEBUG ((LM_DEBUG, + "id = %Q, time= %Q\n", + rec_list[j].id, rec_list[j].time)); +#else + ACE_DEBUG ((LM_DEBUG, + "id = %u, time= %u\n", + rec_list[j].id.lo(), rec_list[j].time.lo())); +#endif + + ACE_DEBUG ((LM_DEBUG, + "Deleting records... \n")); + + retval = notify_log_->delete_records (QUERY_LANG, QUERY_2 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Calling NotifyLog::get_n_records...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = notify_log_->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + retval = notify_log_->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Number of records in Log after delete = %d \n", + retval)); + + ACE_DEBUG ((LM_DEBUG, "Geting the current_size again...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = notify_log_->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + retval = notify_log_->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Size of data in Log = %d \n", retval)); + + this->notify_log_->destroy(); + + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Supplier::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + + +Filter_StructuredPushSupplier::Filter_StructuredPushSupplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ +} + +Filter_StructuredPushSupplier::~Filter_StructuredPushSupplier () +{ +} + +void +Filter_StructuredPushSupplier::connect (CosNotifyChannelAdmin::SupplierAdmin_ptr supplier_admin ACE_ENV_ARG_DECL) +{ + CosNotifyComm::StructuredPushSupplier_var objref = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::ProxyConsumer_var proxyconsumer = + supplier_admin->obtain_notification_push_consumer (CosNotifyChannelAdmin::STRUCTURED_EVENT, proxy_consumer_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxyconsumer.in ())); + + // narrow + this->proxy_consumer_ = + CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow (proxyconsumer.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxy_consumer_.in ())); + + proxy_consumer_->connect_structured_push_supplier (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Filter_StructuredPushSupplier::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->proxy_consumer_.in ())); + + this->proxy_consumer_->disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +Filter_StructuredPushSupplier::subscription_change + (const CosNotification::EventTypeSeq & /*added*/, + const CosNotification::EventTypeSeq & /*removed */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )) +{ + //No-Op. +} + +void +Filter_StructuredPushSupplier::send_event + (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->proxy_consumer_.in ())); + + proxy_consumer_->push_structured_event (event ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Filter_StructuredPushSupplier::disconnect_structured_push_supplier + (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + // No-Op. +} + diff --git a/TAO/orbsvcs/examples/Log/Notify/Notify_Supplier.h b/TAO/orbsvcs/examples/Log/Notify/Notify_Supplier.h new file mode 100644 index 00000000000..bd4e26f2fda --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Notify/Notify_Supplier.h @@ -0,0 +1,128 @@ +/* -*- C++ -*- */ + +// ============================================================================ +/** + * @file Notify_Supplier.h + * + * $Id$ + * + * An example of using the Notify_Logging_Service. + * + * + * + * @author D A Hanvey (d.hanvey@qub.ac.uk) + */ +// ============================================================================ + +#ifndef NOTIFY_SUPPLIER_H +#define NOTIFY_SUPPLIER_H + +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include "orbsvcs/DsNotifyLogAdminC.h" +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/CosNotifyCommS.h" + + +class Filter_StructuredPushSupplier; + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Supplier +{ + // = TITLE + // Simple supplier object + // + // = DESCRIPTION + // This class is a supplier of events. + // +public: + Supplier (void); + // Constructor + + ~Supplier (); + // Destructor. + + int run (int argc, char* argv[]); + // Run the test + +private: + + // = Data Members + CORBA::ORB_var orb_; + // The ORB that we use. + + CosNaming::NamingContext_var naming_context_; + // Handle to the name service. + + DsNotifyLogAdmin::NotifyLogFactory_var notify_log_factory_; + // The notify log factory from the Log Service. + + DsNotifyLogAdmin::NotifyLog_var notify_log_; + + Filter_StructuredPushSupplier* supplier_1; + + CosNotifyChannelAdmin::SupplierAdmin_var supplier_admin_; +}; + +class Filter_StructuredPushSupplier + : public POA_CosNotifyComm::StructuredPushSupplier +{ + // = TITLE + // Filter_StructuredPushSupplier + // + // = DESCRIPTION + // Supplier for the filter example. + // + public: + // = Initialization and Termination code + Filter_StructuredPushSupplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED); + // Constructor. + + void connect (CosNotifyChannelAdmin::SupplierAdmin_ptr supplier_admin + ACE_ENV_ARG_DECL); + // Connect the Supplier to the EventChannel. + // Creates a new proxy supplier and connects to it. + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the supplier. + + virtual void send_event (const CosNotification::StructuredEvent& event + ACE_ENV_ARG_DECL); + // Send one event. + +protected: + // = Data members + CosNotifyChannelAdmin::StructuredProxyPushConsumer_var proxy_consumer_; + // The proxy that we are connected to. + + CosNotifyChannelAdmin::ProxyID proxy_consumer_id_; + // This supplier's id. + + // = Protected Methods + virtual ~Filter_StructuredPushSupplier (); + // Destructor + + // = NotifySubscribe + virtual void subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )); + + // = StructuredPushSupplier method + virtual void disconnect_structured_push_supplier ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); +}; + + +#endif /* NOTIFY_SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/Log/Notify/README b/TAO/orbsvcs/examples/Log/Notify/README new file mode 100644 index 00000000000..9de15b27dae --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Notify/README @@ -0,0 +1,18 @@ +// $Id$ + +Telecom Log Service (TLS) Client example +---------------------------------------- +This is a simple example example to show how to create a notify log and write events +to the Log. + +To run this example: +1) You need a running Naming Service, $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service +2) You need a running Notify Logging Service, $TAO_ROOT/orbsvcs/Logging_Service/Notify_Logging_Service +3) To collect log-generated events you will need to run, ./Notify_Consumer +4) To run the sample log events run, ./Notify_Supplier + +The client locates the log service factory from the naming service. +Then it creates a DsNotifyLogAdmin::NotifyLog does the following operations: +- writes records, query records, delete records. + +report bugs to D A Hanvey <d.hanvey@qub.ac.uk> diff --git a/TAO/orbsvcs/examples/Log/Notify/run_test.pl b/TAO/orbsvcs/examples/Log/Notify/run_test.pl new file mode 100755 index 00000000000..781e0e05543 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/Notify/run_test.pl @@ -0,0 +1,67 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../../bin'; +use PerlACE::Run_Test; + +$status = 0; + +$nsior = PerlACE::LocalFile ("ns.ior"); + +unlink $nsior; + +$NS = new PerlACE::Process ("../../../Naming_Service/Naming_Service", "-o $nsior"); +$LS = new PerlACE::Process ("../../../Logging_Service/Notify_Logging_Service/Notify_Logging_Service", "-ORBInitRef NameService=file://$nsior"); +$consumer = new PerlACE::Process ("Notify_Consumer", "-ORBInitRef NameService=file://$nsior"); +$supplier = new PerlACE::Process ("Notify_Supplier", "-ORBInitRef NameService=file://$nsior"); + + +print STDERR "Starting Naming Service\n"; + +$NS->Spawn (); + +if (PerlACE::waitforfile_timed ($nsior, 20) == -1) { + print STDERR "ERROR: cannot find naming service IOR file\n"; + $NS->Kill (); + exit 1; +} + +print STDERR "Starting Logging Service\n"; + +$LS->Spawn (); + +# Give time for logging service to initialize and install its object +# reference in the naming service. +sleep (5); + +print STDERR "Starting Consumer\n"; + +$consumer->Spawn (); + +sleep (1); + +print STDERR "Starting Supplier\n"; + +$supplier->Spawn (); + + +$supplier->WaitKill (5); + +$consumer->Kill (); + +$NS->Kill (); + +$LS->Kill (); + +#if ($client != 0) { +# print STDERR "ERROR: client returned $client\n"; +# $status = 1; +#} + +unlink $nsior; + +exit $status; diff --git a/TAO/orbsvcs/examples/Log/README b/TAO/orbsvcs/examples/Log/README new file mode 100644 index 00000000000..aa5579fff01 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/README @@ -0,0 +1,18 @@ +Logging Service +=============== + +PLEASE NOTE - the Logging_Service test that was previously in this directory +has been moved to $TAO_ROOT/orbsvcs/tests/Log. + +ALSO - the example that was contained in Client has been deleted. +---------------------------------------------------------------------- + +These examples show basic operations of the 4 logging services. + +Please see the README documents in each of the above folders for details +on how to execute the respective services. + +Author: +------- +David Hanvey +send suggestions, bugs, to David Hanvey <d.hanvey@qub.ac.uk> diff --git a/TAO/orbsvcs/examples/Log/RTEvent/Log_RTEvent.mpc b/TAO/orbsvcs/examples/Log/RTEvent/Log_RTEvent.mpc new file mode 100644 index 00000000000..83fed7aa672 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/RTEvent/Log_RTEvent.mpc @@ -0,0 +1,16 @@ +// -*- MPC -*- +// $Id$ + +project(*Consumer) : orbsvcsexe, rtevent_skel, naming, rteventlogadmin { + exename = RTEvent_Consumer + source_files { + RTEvent_Consumer.cpp + } +} + +project(*Supplier) : orbsvcsexe, rtevent_skel, naming, rteventlogadmin { + exename = RTEvent_Supplier + source_files { + RTEvent_Supplier.cpp + } +} diff --git a/TAO/orbsvcs/examples/Log/RTEvent/Makefile.am b/TAO/orbsvcs/examples/Log/RTEvent/Makefile.am new file mode 100644 index 00000000000..0c83282a06d --- /dev/null +++ b/TAO/orbsvcs/examples/Log/RTEvent/Makefile.am @@ -0,0 +1,96 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Log_RTEvent_Consumer.am + +if BUILD_CORBA_MESSAGING + +noinst_PROGRAMS += RTEvent_Consumer + +RTEvent_Consumer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +RTEvent_Consumer_SOURCES = \ + RTEvent_Consumer.cpp \ + RTEvent_Consumer.h + +RTEvent_Consumer_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEventLogAdmin.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsLogAdmin.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_CORBA_MESSAGING + +## Makefile.Log_RTEvent_Supplier.am + +if BUILD_CORBA_MESSAGING + +noinst_PROGRAMS += RTEvent_Supplier + +RTEvent_Supplier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +RTEvent_Supplier_SOURCES = \ + RTEvent_Supplier.cpp \ + RTEvent_Supplier.h + +RTEvent_Supplier_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEventLogAdmin.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_DsLogAdmin.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Log/RTEvent/README b/TAO/orbsvcs/examples/Log/RTEvent/README new file mode 100644 index 00000000000..103bab83664 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/RTEvent/README @@ -0,0 +1,18 @@ +// $Id$ + +Telecom Log Service (TLS) Client example +---------------------------------------- +This is a simple example example to show how to create an real-time event log and write events +to the Log. + +To run this example: +1) You need a running Naming Service, $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service +2) You need a running Event Logging Service, $TAO_ROOT/orbsvcs/Logging_Service/RTEvent_Logging_Service +3) To collect log-generated events you will need to run, ./RTEvent_Consumer +4) To run the sample log events run, ./RTEvent_Supplier + +The client locates the log service factory from the naming service. +Then it creates a RTEventLogAdmin::RTEventLog does the following operations: +- writes records, query records, delete records. + +report bugs to D A Hanvey <d.hanvey@qub.ac.uk> diff --git a/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Consumer.cpp b/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Consumer.cpp new file mode 100644 index 00000000000..a9ce5387a62 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Consumer.cpp @@ -0,0 +1,175 @@ +#include "RTEvent_Consumer.h" +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "ace/OS_main.h" + +ACE_RCSID (RTEvent, + RTEvent_Consumer, + "$Id$") + +#define NAMING_SERVICE_NAME "NameService" +#define EVENT_TLS_LOG_FACTORY_NAME "RTEventLogFactory" + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Consumer consumer; + + return consumer.run (argc, argv); +} + +// **************************************************************** + +Consumer::Consumer (void) + : event_count_ (0) +{ +} + +int +Consumer::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Do *NOT* make a copy because we don't want the ORB to outlive + // the run() method. + this->orb_ = orb.in (); +/* + if (argc <= 1) + { + ACE_ERROR ((LM_ERROR, + "Usage: Consumer <event_channel_ior>\n")); + return 1; + } +*/ + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel, we could use a naming service, a + // command line argument or resolve_initial_references(), but + // this is simpler... +/* object = + orb->string_to_object (argv[1] ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::EventChannel_var event_channel = + RtecEventChannelAdmin::EventChannel::_narrow (object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; +*/ + + // Obtain the event channel + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW_RETURN (CORBA::UNKNOWN (), 0); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (EVENT_TLS_LOG_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->event_log_factory_ = + RTEventLogAdmin::EventLogFactory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + // The canonical protocol to connect to the EC + + this->supplier_ = + this->event_log_factory_->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushConsumer_var consumer = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Simple subscription, but usually the helper classes in + // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this. + RtecEventChannelAdmin::ConsumerQOS qos; + qos.dependencies.length (2); + RtecEventComm::EventHeader& h0 = + qos.dependencies[0].event.header; + h0.type = ACE_ES_DISJUNCTION_DESIGNATOR; + h0.source = ACE_ES_EVENT_SOURCE_ANY; + + RtecEventComm::EventHeader& h1 = + qos.dependencies[1].event.header; + h1.type = ACE_ES_EVENT_UNDEFINED; // first free event type + h1.source = ACE_ES_EVENT_SOURCE_ANY; + + this->supplier_->connect_push_consumer (consumer.in (), qos + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Wait for events, using work_pending()/perform_work() may help + // or using another thread, this example is too simple for that. + orb->run (); + + // We don't do any cleanup, it is hard to do it after shutdown, + // and would complicate the example; plus it is almost + // impossible to do cleanup after ORB->run() because the POA is + // in the holding state. Applications should use + // work_pending()/perform_work() to do more interesting stuff. + // Check the supplier for the proper way to do cleanup. + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Consumer::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Consumer::push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_UNUSED_ARG (events); + + this->event_count_ ++; + + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t): %d log generated events received\n", + this->event_count_)); +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // In this example we shutdown the ORB when we disconnect from the + // EC (or rather the EC disconnects from us), but this doesn't have + // to be the case.... + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} + diff --git a/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Consumer.h b/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Consumer.h new file mode 100644 index 00000000000..5c908495901 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Consumer.h @@ -0,0 +1,72 @@ +/* -*- C++ -*- */ + +// ============================================================================ +/** + * @file RTEvent_Consumer.h + * + * $Id$ + * + * An example of using the RTEvent_Logging_Service. + * The RTEvent_Consumer consumes log-generated events. + * + * + * @author D A Hanvey (d.hanvey@qub.ac.uk) + */ +// ============================================================================ + +#ifndef RTEVENT_CONSUMER_H +#define RTEVENT_CONSUMER_H + +#include "orbsvcs/RtecEventCommS.h" +#include "orbsvcs/RTEventLogAdminC.h" +#include "orbsvcs/CosNamingC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Consumer : public POA_RtecEventComm::PushConsumer +{ + // = TITLE + // Simple consumer object + // + // = DESCRIPTION + // This class is a consumer of events. + // It simply registers for one event type. + // +public: + Consumer (void); + // Constructor + + int run (int argc, char* argv[]); + // Run the test + + // = The RtecEventComm::PushConsumer methods + + virtual void push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: + CORBA::ULong event_count_; + // Keep track of the number of events received. + + CORBA::ORB_ptr orb_; + // The orb, just a pointer because the ORB does not outlive the + // run() method... + + CosNaming::NamingContext_var naming_context_; + // Handle to the name service. + + RTEventLogAdmin::EventLogFactory_var event_log_factory_; + // The Event Log Factory that generates the events to be consumed. + + RtecEventChannelAdmin::ProxyPushSupplier_var supplier_; + // The proxy that we are connected to. + +}; + +#endif /* RTEVENT_CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Supplier.cpp b/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Supplier.cpp new file mode 100644 index 00000000000..1a2de3ca9b9 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Supplier.cpp @@ -0,0 +1,297 @@ +#include "RTEvent_Supplier.h" +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "ace/OS_main.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID (RTEvent, + RTEvent_Supplier, + "$Id$") + +#define NAMING_SERVICE_NAME "NameService" +#define EVENT_TLS_LOG_FACTORY_NAME "RTEventLogFactory" +#define LOG_EVENT_COUNT 29 +#define QUERY_1 "id > 0" +#define QUERY_2 "id >= 0" +#define QUERY_LANG "TCL" + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + Supplier supplier; + + return supplier.run (argc, argv); + +} + +// **************************************************************** + +Supplier::Supplier (void) +{ +} + +int +Supplier::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + +/* + if (argc <= 1) + { + ACE_ERROR ((LM_ERROR, + "Usage: Supplier <event_channel_ior>\n")); + return 1; + } +*/ + + // Do *NOT* make a copy because we don't want the ORB to outlive + // the run() method. + // this->orb_ = orb.in (); + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel, we could use a naming service, a + // command line argument or resolve_initial_references(), but + // this is simpler... +/* object = + orb->string_to_object (argv[1] ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::EventChannel_var event_channel = + RtecEventChannelAdmin::EventChannel::_narrow (object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; +*/ + + CORBA::Object_var naming_obj = + orb->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW_RETURN (CORBA::UNKNOWN (), 0); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (EVENT_TLS_LOG_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->event_log_factory_ = + RTEventLogAdmin::EventLogFactory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ASSERT (!CORBA::is_nil (this->event_log_factory_.in ())); + + + + + + // create a log.. + + ACE_DEBUG ((LM_DEBUG, + "\nCalling EventLogFactory::create...\n")); + + DsLogAdmin::LogFullActionType logfullaction = DsLogAdmin::halt; + DsLogAdmin::CapacityAlarmThresholdList threshold = 0; + CORBA::ULongLong max_size = 0; // 0 means "infinite" + + DsLogAdmin::LogId logid = 0; + + RTEventLogAdmin::EventLog_var event_log = + // DsLogAdmin::Log_var event_log = + this->event_log_factory_->create (logfullaction, + max_size, + threshold, + logid + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + ACE_DEBUG ((LM_DEBUG, + "Create returned logid = %d\n",logid)); + + // The canonical protocol to connect to the EC + RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = + event_log->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->consumer_ = + supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushSupplier_var supplier = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + + // Simple publication, but usually the helper classes in + // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this. + RtecEventChannelAdmin::SupplierQOS qos; + qos.publications.length (1); + RtecEventComm::EventHeader& h0 = + qos.publications[0].event.header; + h0.type = ACE_ES_EVENT_UNDEFINED; // first free event type + h0.source = 1; // first free event source + + this->consumer_->connect_push_supplier (supplier.in (), qos + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + // Create some fake log events. + // Push the events... + ACE_Time_Value sleep_time (0, 10000); // 10 milliseconds + + RtecEventComm::EventSet event (1); + event.length (1); + event[0].header.type = ACE_ES_EVENT_UNDEFINED; + event[0].header.source = 1; + event[0].header.ttl = 1; + + for (int i = 0; i != LOG_EVENT_COUNT; ++i) + { + this->consumer_->push (event ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_OS::sleep (sleep_time); + } + + ACE_DEBUG ((LM_DEBUG, + "Writing %d records...\n", LOG_EVENT_COUNT)); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Calling EventLog::get_n_records...\n")); +#ifndef ACE_LACKS_LONGLONG_T + CORBA::ULongLong retval = event_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + CORBA::Long retval = event_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Number of records in Log = %d \n", retval)); + + ACE_DEBUG ((LM_DEBUG, + "Calling EventLog::get_current_size...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = event_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + retval = event_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Size of data in Log = %d \n", retval)); + + ACE_DEBUG ((LM_DEBUG, "Querying the Log: %s\n", QUERY_1)); + DsLogAdmin::Iterator_var iter_out; + DsLogAdmin::RecordList_var rec_list = + event_log->query (QUERY_LANG, QUERY_1, iter_out); + + CORBA::ULong j = 0; + for (; j < rec_list->length();++j) +#ifndef ACE_LACKS_LONGLONG_T + ACE_DEBUG ((LM_DEBUG, + "id = %Q, time= %Q\n", + rec_list[j].id, rec_list[j].time)); +#else + ACE_DEBUG ((LM_DEBUG, + "id = %u, time= %u\n", + rec_list[j].id.lo(), rec_list[j].time.lo())); +#endif + + ACE_DEBUG ((LM_DEBUG, + "Deleting records... \n")); + + retval = event_log->delete_records (QUERY_LANG, QUERY_2 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "Calling EventLog::get_n_records...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = event_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + retval = event_log->get_n_records (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Number of records in Log after delete = %d \n", + retval)); + + ACE_DEBUG ((LM_DEBUG, "Geting the current_size again...\n")); +#ifndef ACE_LACKS_LONGLONG_T + retval = event_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; +#else + retval = event_log->get_current_size (ACE_ENV_SINGLE_ARG_PARAMETER).lo(); + ACE_TRY_CHECK; +#endif + + ACE_DEBUG ((LM_DEBUG, "Size of data in Log = %d \n", retval)); + + // Disconnect from the EC + this->consumer_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the EC.... + //event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + event_log->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Deactivate this object... + PortableServer::ObjectId_var id = + poa->servant_to_id (this ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the POA + poa->destroy (1, 0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Supplier::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Supplier.h b/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Supplier.h new file mode 100644 index 00000000000..170a98db896 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/RTEvent/RTEvent_Supplier.h @@ -0,0 +1,63 @@ +/* -*- C++ -*- */ + +// ============================================================================ +/** + * @file RTEvent_Supplier.h + * + * $Id$ + * + * An example of using the RTEvent_Logging_Service. + * + * + * + * @author D A Hanvey (d.hanvey@qub.ac.uk) + */ +// ============================================================================ + +#ifndef RTEVENT_SUPPLIER_H +#define RTEVENT_SUPPLIER_H + +#include "orbsvcs/RtecEventCommS.h" +#include "orbsvcs/RTEventLogAdminC.h" +#include "orbsvcs/CosNamingC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Supplier : public POA_RtecEventComm::PushSupplier +{ + // = TITLE + // Simple supplier object + // + // = DESCRIPTION + // This class is a supplier of events. + // It simply publishes one event type. + // +public: + Supplier (void); + // Constructor + + int run (int argc, char* argv[]); + // Run the test + + // = The RtecEventComm::PushSupplier methods + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: + + // = Data Members + CosNaming::NamingContext_var naming_context_; + // Handle to the name service. + + RTEventLogAdmin::EventLogFactory_var event_log_factory_; + // The Event Log Factory that generates the events to be consumed. + + RtecEventChannelAdmin::ProxyPushConsumer_var consumer_; + // The proxy that we are connected to. +}; + +#endif /* RTEVENT_SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/Log/RTEvent/run_test.pl b/TAO/orbsvcs/examples/Log/RTEvent/run_test.pl new file mode 100755 index 00000000000..bb8d0417f41 --- /dev/null +++ b/TAO/orbsvcs/examples/Log/RTEvent/run_test.pl @@ -0,0 +1,67 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../../bin'; +use PerlACE::Run_Test; + +$status = 0; + +$nsior = PerlACE::LocalFile ("ns.ior"); + +unlink $nsior; + +$NS = new PerlACE::Process ("../../../Naming_Service/Naming_Service", "-o $nsior"); +$LS = new PerlACE::Process ("../../../Logging_Service/RTEvent_Logging_Service/RTEvent_Logging_Service", "-ORBInitRef NameService=file://$nsior"); +$consumer = new PerlACE::Process ("RTEvent_Consumer", "-ORBInitRef NameService=file://$nsior"); +$supplier = new PerlACE::Process ("RTEvent_Supplier", "-ORBInitRef NameService=file://$nsior"); + + +print STDERR "Starting Naming Service\n"; + +$NS->Spawn (); + +if (PerlACE::waitforfile_timed ($nsior, 20) == -1) { + print STDERR "ERROR: cannot find naming service IOR file\n"; + $NS->Kill (); + exit 1; +} + +print STDERR "Starting Logging Service\n"; + +$LS->Spawn (); + +# Give time for logging service to initialize and install its object +# reference in the naming service. +sleep (5); + +print STDERR "Starting Consumer\n"; + +$consumer->Spawn (); + +sleep (1); + +print STDERR "Starting Supplier\n"; + +$supplier->Spawn (); + + +$supplier->WaitKill (5); + +$consumer->Kill (); + +$NS->Kill (); + +$LS->Kill (); + +#if ($client != 0) { +# print STDERR "ERROR: client returned $client\n"; +# $status = 1; +#} + +unlink $nsior; + +exit $status; diff --git a/TAO/orbsvcs/examples/Makefile.am b/TAO/orbsvcs/examples/Makefile.am new file mode 100644 index 00000000000..b93a6688dc9 --- /dev/null +++ b/TAO/orbsvcs/examples/Makefile.am @@ -0,0 +1,21 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + CosEC \ + FaultTolerance \ + ImR \ + LoadBalancing \ + Log \ + Notify \ + ORT \ + RtEC \ + Security + diff --git a/TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.cpp b/TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.cpp new file mode 100644 index 00000000000..3e6109e1ee1 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.cpp @@ -0,0 +1,346 @@ +// file : Agent.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include <ace/streams.h> +#if defined(ACE_USES_OLD_IOSTREAMS) +# if defined(_MSC_VER) +# include <strstrea.h> +# else +# include <strstream.h> +# endif +#else +# include <sstream> +#endif + +#include "ace/OS.h" + +#include "tao/corba.h" + +#include "orbsvcs/CosNotificationC.h" +#include "orbsvcs/CosNotifyChannelAdminC.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "orbsvcs/CosNotifyCommS.h" + +// For in-process Notification Service. +// +#include "ace/Dynamic_Service.h" +#include "orbsvcs/Notify/Service.h" +#include "orbsvcs/Notify/CosNotify_Initializer.h" // NS static link helper. + + +#include "Gate/Gate.h" + +using namespace CORBA; +using namespace CosNotifyComm; +using namespace CosNotification; +using namespace CosNotifyChannelAdmin; + +class Agent : public POA_CosNotifyComm::StructuredPushConsumer, + public PortableServer::RefCountServantBase +{ +public: + Agent (char const* space_craft_name, + char const* agent_name, + EventChannel_ptr ch) + : space_craft_name_ (space_craft_name), + agent_name_ (agent_name), + counter_ (0) + { + // Obtain a proxy consumer. + // + ProxyConsumer_var pc ( + ch->default_supplier_admin ()->obtain_notification_push_consumer ( + STRUCTURED_EVENT, consumer_id_)); + + consumer_ = StructuredProxyPushConsumer::_narrow (pc.in ()); + + consumer_->connect_structured_push_supplier ( + StructuredPushSupplier::_nil ()); + + // Register as a consumer. + // + StructuredPushConsumer_var ref (_this ()); // Activate on the default POA. + + ProxySupplier_var ps ( + ch->default_consumer_admin ()->obtain_notification_push_supplier ( + STRUCTURED_EVENT, supplier_id_)); + + supplier_ = StructuredProxyPushSupplier::_narrow (ps.in ()); + + supplier_->connect_structured_push_consumer (ref.in ()); + + // Start tracker thread. + // + if (ACE_OS::thr_create (&tracker_thunk, + this, + THR_JOINABLE, + &thread_) != 0) ::abort (); + } + +private: + static ACE_THR_FUNC_RETURN + tracker_thunk (void* arg) + { + Agent* a = reinterpret_cast<Agent*> (arg); + a->tracker (); + return 0; + } + + void + tracker () + { + while (true) + { + StructuredEvent e; + + // Header. + // + e.header.fixed_header.event_type.domain_name = string_dup ("Aerospace"); + e.header.fixed_header.event_type.type_name = string_dup ("AgentDiscovery"); + + // Make a unique "event id" by combining space_craft_name, agent_name, + // and counter. This can be handy for debugging. + // +#if defined(ACE_USES_OLD_IOSTREAMS) + ostrstream ostr; +#else + std::ostringstream ostr; +#endif + ostr << space_craft_name_ << ":" << agent_name_ << ":" << counter_++; + +#if defined(ACE_USES_OLD_IOSTREAMS) + e.header.fixed_header.event_name = ostr.str (); +#else + e.header.fixed_header.event_name = ostr.str ().c_str (); +#endif + + // Also add space_craft_name and agent_name fields separately + // into variable_header. This will make filtering easier. + // + e.header.variable_header.length (2); + + e.header.variable_header[0].name = string_dup ("space_craft_name"); + e.header.variable_header[0].value <<= string_dup (space_craft_name_.in ()); + + e.header.variable_header[1].name = string_dup ("agent_name"); + e.header.variable_header[1].value <<= string_dup (agent_name_.in ()); + + // Add the counter value into filterable_data section of the event. + // + e.filterable_data.length (1); + + e.filterable_data[0].name = string_dup ("counter"); + e.filterable_data[0].value <<= counter_; + + + consumer_->push_structured_event (e); + + ACE_OS::sleep (ACE_Time_Value (3, 0)); + } + } + +private: + // NotifyPublish interface. + // + virtual void + offer_change (EventTypeSeq const&, + EventTypeSeq const& + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + CosNotifyComm::InvalidEventType)) + { + // We don't care. + } + + // StructuredPushSupplier interface. + // + virtual void + push_structured_event (StructuredEvent const& e ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)) + { + // Extract space_craft_name and agent_name. + // + Char const* space_craft_name = 0; + Char const* agent_name = 0; + + e.header.variable_header[0].value >>= space_craft_name; + e.header.variable_header[1].value >>= agent_name; + + // Extract the counter value. + // + CORBA::ULong counter; + e.filterable_data[0].value >>= counter; + + cerr << e.header.fixed_header.event_type.domain_name << "::" + << e.header.fixed_header.event_type.type_name << " " + << "id=" << e.header.fixed_header.event_name << " from " + << "(" << space_craft_name << ", " << agent_name << ")" + << ": " << counter << endl; + } + + + virtual void + disconnect_structured_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + // We don't care. + } + +private: + String_var space_craft_name_; + String_var agent_name_; + ULong counter_; + + ACE_thread_t thread_; + + ProxyID consumer_id_; + StructuredProxyPushConsumer_var consumer_; + + ProxyID supplier_id_; + StructuredProxyPushSupplier_var supplier_; + +}; + +int +main (int argc, char* argv[]) +{ + ACE_TRY_NEW_ENV + { + ORB_var orb (ORB_init (argc, argv)); + + if (argc < 2) + { + ACE_ERROR ((LM_ERROR, + "Usage: %s <agent-name> [<space-craft-name>={a, b, c}]\n", + argv[0])); + return 1; + } + + + // Activate the root POA. + // + CORBA::Object_var obj ( + orb->resolve_initial_references ("RootPOA" + ACE_ENV_ARG_PARAMETER)); + ACE_TRY_CHECK; + + PortableServer::POA_var root_poa (PortableServer::POA::_narrow (obj.in ())); + + PortableServer::POAManager_var poa_manager (root_poa->the_POAManager ()); + + poa_manager->activate (); + + + // Initialize Notification Service. + // + TAO_Notify_Service* ns = + ACE_Dynamic_Service<TAO_Notify_Service>::instance ( + TAO_NOTIFICATION_SERVICE_NAME); + + if (ns == 0) + { + ns = + ACE_Dynamic_Service<TAO_Notify_Service>::instance ( + TAO_NOTIFY_DEF_EMO_FACTORY_NAME); + } + + if (ns == 0) + { + ACE_ERROR ((LM_ERROR, + "Notification Service not found! check svc.conf\n")); + return -1; + } + + + ns->init_service (orb.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Create the channel factory. + // + EventChannelFactory_var factory (ns->create (root_poa.in () + ACE_ENV_ARG_PARAMETER)); + ACE_TRY_CHECK; + + if (is_nil (factory.in ())) + { + ACE_ERROR ((LM_ERROR, + "Unable to create channel factory\n")); + return 1; + } + + + // Create the channel. + // + QoSProperties qosp; + AdminProperties ap; + ChannelID id; + + EventChannel_var channel (factory->create_channel (qosp, ap, id)); + + // Find which space craft we are on. + // + ACE_INET_Addr addr; + char const* space_craft_name = 0; + + if (argc < 3) + space_craft_name = "a"; // Default to spacecraft "a". + else + space_craft_name = argv[2]; + + // Do a quick mapping to mcast addresses. + // + switch (space_craft_name[0]) + { + case 'a': + { + addr = ACE_INET_Addr ("224.1.0.1:10000"); + break; + } + case 'b': + { + addr = ACE_INET_Addr ("224.1.0.2:10000"); + break; + } + case 'c': + { + addr = ACE_INET_Addr ("224.1.0.3:10000"); + break; + } + default: + { + ACE_ERROR ((LM_ERROR, + "Space craft name should be either 'a', 'b', or 'c'.\n")); + return 1; + } + } + + // Create the gate. + // + Gate gate (addr, channel.in ()); + + // Start the agent. + // + Agent agent (space_craft_name, argv[1], channel.in ()); + + orb->run (); + + return 0; + } + ACE_CATCH (CORBA::UserException, ue) + { + ACE_PRINT_EXCEPTION (ue, + "User exception: "); + return 1; + } + ACE_CATCH (CORBA::SystemException, se) + { + ACE_PRINT_EXCEPTION (se, + "System exception: "); + return 1; + } + ACE_ENDTRY; + + return 1; +} diff --git a/TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.mpc b/TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.mpc new file mode 100644 index 00000000000..1083905d845 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Agent/Agent.mpc @@ -0,0 +1,14 @@ +// -*- MPC -*- +// $Id$ + +project : rmcast, orbsvcsexe, notification, notification_skel, notification_serv, typecodefactory { + exename = agent + after += Gate + libs += Gate + + specific (automake) { + includes += $(srcdir)/.. + } else { + includes += .. + } +} diff --git a/TAO/orbsvcs/examples/Notify/Federation/Agent/Makefile.am b/TAO/orbsvcs/examples/Notify/Federation/Agent/Makefile.am new file mode 100644 index 00000000000..ae1c7216075 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Agent/Makefile.am @@ -0,0 +1,67 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.Agent.am + +if BUILD_THREADS +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS = agent + +agent_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(srcdir)/.. \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +agent_SOURCES = \ + Agent.cpp + +agent_LDADD = \ + $(top_builddir)/orbsvcs/examples/Notify/Federation/Gate/libGate.la \ + $(TAO_BUILDDIR)/tao/libTAO_TypeCodeFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_IFR_Client.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Serv.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicAny.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_ETCL.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/protocols/ace/RMCast/libACE_RMCast.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_THREADS + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Notify/Federation/Agent/README b/TAO/orbsvcs/examples/Notify/Federation/Agent/README new file mode 100644 index 00000000000..53f999666f6 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Agent/README @@ -0,0 +1,12 @@ +Agent is a simple application which sends and receives discovery messages +via multicast-based federation of Notification Service. To run the example +you don't need to start Notification Service; each agent process will create +its own. Just start a few agents (in different terminal windows): + + +$ ./agent smith +$ ./agent johnson + + +-- +Boris Kolpackov <boris@kolpackov.net> diff --git a/TAO/orbsvcs/examples/Notify/Federation/Agent/agent.dia b/TAO/orbsvcs/examples/Notify/Federation/Agent/agent.dia Binary files differnew file mode 100644 index 00000000000..9840e3fe8a6 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Agent/agent.dia diff --git a/TAO/orbsvcs/examples/Notify/Federation/Gate/Export.h b/TAO/orbsvcs/examples/Notify/Federation/Gate/Export.h new file mode 100644 index 00000000000..c813c802bc0 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Gate/Export.h @@ -0,0 +1,44 @@ +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by +// generate_export_file.pl +// ------------------------------ +#if !defined (GATE_EXPORT_H) +#define GATE_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (GATE_HAS_DLL) +# define GATE_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && GATE_HAS_DLL */ + +#if !defined (GATE_HAS_DLL) +#define GATE_HAS_DLL 1 +#endif /* ! GATE_HAS_DLL */ + +#if defined (GATE_HAS_DLL) +# if (GATE_HAS_DLL == 1) +# if defined (GATE_BUILD_DLL) +# define Gate_Export ACE_Proper_Export_Flag +# define GATE_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define GATE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else +# define Gate_Export ACE_Proper_Import_Flag +# define GATE_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define GATE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* GATE_BUILD_DLL */ +# else +# define Gate_Export +# define GATE_SINGLETON_DECLARATION(T) +# define GATE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* ! GATE_HAS_DLL == 1 */ +#else +# define Gate_Export +# define GATE_SINGLETON_DECLARATION(T) +# define GATE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* GATE_HAS_DLL */ + +#endif /* GATE_EXPORT_H */ + +// End of auto generated file. diff --git a/TAO/orbsvcs/examples/Notify/Federation/Gate/Gate.cpp b/TAO/orbsvcs/examples/Notify/Federation/Gate/Gate.cpp new file mode 100644 index 00000000000..f34fd4bd09c --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Gate/Gate.cpp @@ -0,0 +1,266 @@ +// file : Gate.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "Gate.h" + +/* +#include <iostream> + +using std::cerr; +using std::endl; +*/ + +using namespace CORBA; +using namespace CosNotifyComm; +using namespace CosNotification; +using namespace CosNotifyChannelAdmin; + +Gate:: +~Gate () +{ + // Stop tracker thread. + // + { + Lock l (mutex_); + stop_ = true; + } + + thread_mgr_.wait (); +} + + +Gate:: +Gate (ACE_INET_Addr const& group, EventChannel_ptr ch) + : socket_ (group, false), + stop_ (false) +{ + init (ch->default_consumer_admin (), + ch->default_supplier_admin ()); +} + +Gate:: +Gate (ACE_INET_Addr const& group, + ConsumerAdmin_ptr consumer_admin, + SupplierAdmin_ptr supplier_admin) + : socket_ (group, false), + stop_ (false) +{ + init (consumer_admin, supplier_admin); +} + +void Gate:: +init (ConsumerAdmin_ptr consumer_admin, + SupplierAdmin_ptr supplier_admin) +{ + // Generate unique id. It is used to prevent event looping. + // + ACE_Utils::UUID uuid; + ACE_Utils::UUID_GENERATOR::instance ()->init (); + ACE_Utils::UUID_GENERATOR::instance ()->generateUUID (uuid); + + id_ = string_alloc (uuid.to_string ()->length () + 2); + strcpy (id_.inout (), "_"); + strcpy (id_.inout () + 1, uuid.to_string ()->rep ()); + + // ACE_DEBUG ((LM_DEBUG, "ID: %s\n", id_.in ())); + + + // Obtain proxy consumer. + // + ProxyConsumer_var pc ( + supplier_admin->obtain_notification_push_consumer ( + STRUCTURED_EVENT, consumer_id_)); + + consumer_ = StructuredProxyPushConsumer::_narrow (pc.in ()); + + consumer_->connect_structured_push_supplier ( + StructuredPushSupplier::_nil ()); + + + // Register as consumer. + // + StructuredPushConsumer_var ref (_this ()); // Activate on default POA. + + ProxySupplier_var ps ( + consumer_admin->obtain_notification_push_supplier ( + STRUCTURED_EVENT, supplier_id_)); + + supplier_ = StructuredProxyPushSupplier::_narrow (ps.in ()); + + supplier_->connect_structured_push_consumer (ref.in ()); + + + // Create tracker thread. + // + thread_mgr_.spawn (tracker_thunk, this); +} + +ACE_THR_FUNC_RETURN Gate:: +tracker_thunk (void* arg) +{ + Gate* a = reinterpret_cast<Gate*> (arg); + a->tracker (); + return 0; +} + +void Gate:: +tracker () +{ + // Time period after which a manual cancellation request is + // checked for. + // + ACE_Time_Value const timeout (0, 500); + + while (true) + { + ssize_t n; + + while (true) + { + n = socket_.size (timeout); + + // Check for cancellation request. + // + { + Lock l (mutex_); + + if (stop_) + return; + } + + if (n == -1) + { + if (errno != ETIME) + abort (); + } + else + break; + } + + OctetSeq seq (n); + seq.length (n); + + char* buffer = reinterpret_cast<char*> (seq.get_buffer ()); + + if (socket_.recv (buffer, n) != n) + { + ACE_ERROR ((LM_ERROR, + "recv() reported different size than size()\n")); + continue; + } + + TAO_InputCDR cdr (buffer, n); + + StructuredEvent e; + + cdr >> e; + + // Add TTL header to prevent infinite message looping. + // + ULong i (0); + + for (; i < e.header.variable_header.length (); ++i) + { + if (strcmp (e.header.variable_header[i].name.in (), id_.in ()) == 0) + break; + } + + if (i == e.header.variable_header.length ()) + { + e.header.variable_header.length (i + 1); + + e.header.variable_header[i].name = string_dup (id_.in ()); + } + + //ACE_DEBUG ((LM_DEBUG, + // "adding %s as header #%d\n", + // e.header.variable_header[i].name.in (), i)); + + e.header.variable_header[i].value <<= ULong (1); + + /* + cerr << "IN: " + << e.header.fixed_header.event_type.domain_name << "::" + << e.header.fixed_header.event_type.type_name << " " + << e.header.fixed_header.event_name << endl; + */ + + consumer_->push_structured_event (e); + } +} + +void Gate:: +push_structured_event (StructuredEvent const& e ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)) +{ + for (ULong i (0); i < e.header.variable_header.length (); ++i) + { + if (strcmp (e.header.variable_header[i].name.in (), id_.in ()) == 0) + { + ULong ttl; + + e.header.variable_header[i].value >>= ttl; + + if (ttl <= 1) + { + //ACE_DEBUG ((LM_DEBUG, + // "DROPPED\n")); + return; + } + + break; + } + } + + /* + cerr << "OUT: " + << e.header.fixed_header.event_type.domain_name << "::" + << e.header.fixed_header.event_type.type_name << " " + << e.header.fixed_header.event_name << endl; + */ + + TAO_OutputCDR cdr; + + cdr << e; + + size_t size (cdr.total_length ()); + + OctetSeq seq (size); + seq.length (size); + + char* buffer = reinterpret_cast<char*> (seq.get_buffer ()); + + { + char* buf = buffer; + + for (ACE_Message_Block const* mb = cdr.begin (); + mb != 0; + mb = mb->cont ()) + { + ACE_OS::memcpy (buf, mb->rd_ptr (), mb->length ()); + buf += mb->length (); + } + } + + socket_.send (buffer, size); +} + + +void Gate:: +disconnect_structured_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // We don't care. +} + +void Gate:: +offer_change (EventTypeSeq const&, + EventTypeSeq const& + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + CosNotifyComm::InvalidEventType)) +{ + // We don't care. +} diff --git a/TAO/orbsvcs/examples/Notify/Federation/Gate/Gate.h b/TAO/orbsvcs/examples/Notify/Federation/Gate/Gate.h new file mode 100644 index 00000000000..312bb6b5a20 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Gate/Gate.h @@ -0,0 +1,93 @@ +// file : Gate.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef GATE_H +#define GATE_H + +#include "ace/OS.h" +#include "ace/INET_Addr.h" +#include "ace/UUID.h" + +#include "ace/Thread_Mutex.h" +#include "ace/Thread_Manager.h" + +#include "tao/corba.h" + +#include "orbsvcs/CosNotificationC.h" +#include "orbsvcs/CosNotifyChannelAdminC.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "orbsvcs/CosNotifyCommS.h" + +#include "ace/RMCast/Socket.h" + +#include "Export.h" + +class Gate_Export Gate : public POA_CosNotifyComm::StructuredPushConsumer +{ +public: + virtual + ~Gate (); + + Gate (ACE_INET_Addr const& group, + CosNotifyChannelAdmin::EventChannel_ptr ch); + + Gate (ACE_INET_Addr const& group, + CosNotifyChannelAdmin::ConsumerAdmin_ptr consumer_admin, + CosNotifyChannelAdmin::SupplierAdmin_ptr supplier_admin); + +private: + void + init (CosNotifyChannelAdmin::ConsumerAdmin_ptr consumer_admin, + CosNotifyChannelAdmin::SupplierAdmin_ptr supplier_admin); + + static ACE_THR_FUNC_RETURN + tracker_thunk (void* arg); + + void + tracker (); + +private: + // NotifyPublish interface. + // + virtual void + offer_change (CosNotification::EventTypeSeq const&, + CosNotification::EventTypeSeq const& + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosNotifyComm::InvalidEventType)); + + // StructuredPushSupplier interface. + // + virtual void + push_structured_event (CosNotification::StructuredEvent const& e + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CosEventComm::Disconnected)); + + + virtual void + disconnect_structured_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + ACE_thread_t thread_; + + CosNotifyChannelAdmin::ProxyID consumer_id_; + CosNotifyChannelAdmin::StructuredProxyPushConsumer_var consumer_; + + CosNotifyChannelAdmin::ProxyID supplier_id_; + CosNotifyChannelAdmin::StructuredProxyPushSupplier_var supplier_; + + ACE_RMCast::Socket socket_; + CORBA::String_var id_; + + typedef ACE_SYNCH_MUTEX Mutex; + typedef ACE_Guard<Mutex> Lock; + + bool stop_; + Mutex mutex_; + ACE_Thread_Manager thread_mgr_; +}; + +#endif // GATE_H diff --git a/TAO/orbsvcs/examples/Notify/Federation/Gate/Gate.mpc b/TAO/orbsvcs/examples/Notify/Federation/Gate/Gate.mpc new file mode 100644 index 00000000000..c533b204bba --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Gate/Gate.mpc @@ -0,0 +1,7 @@ +// -*- MPC -*- +// $Id$ + +project(Gate) : rmcast, orbsvcsexe, notification, notification_skel { + sharedname = Gate + dynamicflags = GATE_BUILD_DLL +} diff --git a/TAO/orbsvcs/examples/Notify/Federation/Gate/Makefile.am b/TAO/orbsvcs/examples/Notify/Federation/Gate/Makefile.am new file mode 100644 index 00000000000..30fdd5a97a3 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Gate/Makefile.am @@ -0,0 +1,53 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.Gate.am + +if BUILD_THREADS +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_LTLIBRARIES = libGate.la + +libGate_la_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL \ + -DGATE_BUILD_DLL + +libGate_la_SOURCES = \ + Gate.cpp + +noinst_HEADERS = \ + Export.h \ + Gate.h + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_THREADS + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Notify/Federation/Makefile.am b/TAO/orbsvcs/examples/Notify/Federation/Makefile.am new file mode 100644 index 00000000000..3e06864939a --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/Makefile.am @@ -0,0 +1,15 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + Gate \ + Agent \ + SpaceCraft + diff --git a/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/Makefile.am b/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/Makefile.am new file mode 100644 index 00000000000..dc08a9bae17 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/Makefile.am @@ -0,0 +1,67 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.SpaceCraft.am + +if BUILD_THREADS +if !BUILD_ACE_FOR_TAO +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS = craft + +craft_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(ACE_ROOT)/protocols \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(srcdir)/.. \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +craft_SOURCES = \ + SpaceCraft.cpp + +craft_LDADD = \ + $(top_builddir)/orbsvcs/examples/Notify/Federation/Gate/libGate.la \ + $(TAO_BUILDDIR)/tao/libTAO_TypeCodeFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_IFR_Client.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Serv.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicAny.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_ETCL.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/protocols/ace/RMCast/libACE_RMCast.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif !BUILD_ACE_FOR_TAO +endif BUILD_THREADS + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/README b/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/README new file mode 100644 index 00000000000..3be18eaa394 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/README @@ -0,0 +1,27 @@ +This example simulates spacecraft constellation. Each spacecraft +connects to a constellation-wide multicast group to which it +forwards pre-filtered messages on behalf of its agents. To run +the example start a few spacecrafts (in separate terminal windows): + +$ ./craft a +$ ./craft b +$ ./craft c + +Then start a few agents (from ../Agent) for each spacecraft: + +$ ./agent 1 a +$ ./agent 2 a + +$ ./agent 1 b +$ ./agent 2 b + +$ ./agent 1 c +$ ./agent 2 c + +You should be able to observer that each agent receives only +every third message from the agents on other spacecrafts. + + +-- +Boris Kolpackov <boris@kolpackov.net> + diff --git a/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.cpp b/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.cpp new file mode 100644 index 00000000000..2751694dcd7 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.cpp @@ -0,0 +1,197 @@ +// file : SpaceCraft.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include <iostream> +#include <sstream> + +#include "ace/OS.h" + +#include "tao/corba.h" + +#include "orbsvcs/CosNotificationC.h" +#include "orbsvcs/CosNotifyChannelAdminC.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "orbsvcs/CosNotifyCommS.h" + +// For in-process Notification Service. +// +#include "ace/Dynamic_Service.h" +#include "orbsvcs/Notify/Service.h" +#include "orbsvcs/Notify/CosNotify_Initializer.h" // NS static link helper. + + +#include "Gate/Gate.h" + +using std::cerr; +using std::endl; + +using namespace CORBA; +using namespace CosNotifyComm; +using namespace CosNotifyFilter; +using namespace CosNotification; +using namespace CosNotifyChannelAdmin; + +int +main (int argc, char* argv[]) +{ + ACE_TRY_NEW_ENV + { + ORB_var orb (ORB_init (argc, argv)); + + if (argc < 2) + { + ACE_ERROR ((LM_ERROR, + "Usage: %s <space-craft-name>={a, b, c}\n", + argv[0])); + return 1; + } + + // Activate the root POA. + // + CORBA::Object_var obj ( + orb->resolve_initial_references ("RootPOA" + ACE_ENV_ARG_PARAMETER)); + ACE_TRY_CHECK; + + PortableServer::POA_var root_poa (PortableServer::POA::_narrow (obj.in ())); + + PortableServer::POAManager_var poa_manager (root_poa->the_POAManager ()); + + poa_manager->activate (); + + + // Initialize Notification Service. + // + TAO_Notify_Service* ns = + ACE_Dynamic_Service<TAO_Notify_Service>::instance ( + TAO_NOTIFICATION_SERVICE_NAME); + + if (ns == 0) + { + ns = + ACE_Dynamic_Service<TAO_Notify_Service>::instance ( + TAO_NOTIFY_DEF_EMO_FACTORY_NAME); + } + + if (ns == 0) + { + ACE_ERROR ((LM_ERROR, + "Notification Service not found! check svc.conf\n")); + return -1; + } + + + ns->init_service (orb.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Create the channel factory. + // + EventChannelFactory_var factory (ns->create (root_poa.in () + ACE_ENV_ARG_PARAMETER)); + ACE_TRY_CHECK; + + if (is_nil (factory.in ())) + { + ACE_ERROR ((LM_ERROR, + "Unable to create channel factory\n")); + return 1; + } + + // Create the channel. + // + QoSProperties qosp; + AdminProperties ap; + ChannelID id; + + EventChannel_var channel (factory->create_channel (qosp, ap, id)); + + // Create and install the filter. We want to reduce the amount + // of dicovery messages that are propagated between space crafts. + // + FilterFactory_var filter_factory (channel->default_filter_factory ()); + Filter_var filter (filter_factory->create_filter ("EXTENDED_TCL")); + + ConstraintExpSeq constraints (1); + constraints.length (1); + + constraints[0].event_types.length (0); + constraints[0].constraint_expr = string_dup ( + "$domain_name == 'Aerospace' and " + "$type_name == 'AgentDiscovery' and " + "($.counter - 3 * ($.counter / 3)) == 0");// ETCL (or TAO) doesn't have %? + + filter->add_constraints (constraints); + + AdminID admin_id = 0; + ConsumerAdmin_var consumer_admin ( + channel->new_for_consumers (AND_OP, admin_id)); + + consumer_admin->add_filter (filter.in ()); + + // Find which space craft we are. + // + ACE_INET_Addr space_craft_addr; + char const* space_craft_name = 0; + + space_craft_name = argv[1]; + + // Do a quick mapping to mcast addresses. + // + switch (space_craft_name[0]) + { + case 'a': + { + space_craft_addr = ACE_INET_Addr ("224.1.0.1:10000"); + break; + } + case 'b': + { + space_craft_addr = ACE_INET_Addr ("224.1.0.2:10000"); + break; + } + case 'c': + { + space_craft_addr = ACE_INET_Addr ("224.1.0.3:10000"); + break; + } + default: + { + ACE_ERROR ((LM_ERROR, + "Space craft name should be either 'a', 'b', or 'c'.\n")); + return 1; + } + } + + // Create the SpaceCraft <=> Channel gate. + // + Gate space_craft_gate (space_craft_addr, + consumer_admin.in (), + channel->default_supplier_admin ()); + + + // Create the Channel <=> Constellation gate. + // + ACE_INET_Addr constellation_addr ("224.1.1.1:10000"); + Gate constellation_gate (constellation_addr, channel.in ()); + + orb->run (); + + return 0; + } + ACE_CATCH (CORBA::UserException, ue) + { + ACE_PRINT_EXCEPTION (ue, + "User exception: "); + return 1; + } + ACE_CATCH (CORBA::SystemException, se) + { + ACE_PRINT_EXCEPTION (se, + "System exception: "); + return 1; + } + ACE_ENDTRY; + + return 1; +} diff --git a/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.mpc b/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.mpc new file mode 100644 index 00000000000..8c44304de30 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Federation/SpaceCraft/SpaceCraft.mpc @@ -0,0 +1,14 @@ +// -*- MPC -*- +// $Id$ + +project : rmcast, orbsvcsexe, notification, notification_skel, notification_serv, typecodefactory { + exename = craft + after += Gate + libs += Gate + + specific (automake) { + includes += $(srcdir)/.. + } else { + includes += .. + } +} diff --git a/TAO/orbsvcs/examples/Notify/Filter/Filter.cpp b/TAO/orbsvcs/examples/Notify/Filter/Filter.cpp new file mode 100644 index 00000000000..a2aa9dbf434 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Filter/Filter.cpp @@ -0,0 +1,507 @@ +/* -*- C++ -*- $Id$ */ + +#include "Filter.h" + +ACE_RCSID(Filter, Filter, "$Id$") + +#define NOTIFY_FACTORY_NAME "NotifyEventChannelFactory" +#define NAMING_SERVICE_NAME "NameService" +#define CA_FILTER "threshold < 20" +#define SA_FILTER "threshold > 10" +#define TCL_GRAMMAR "TCL" +#define EVENTS_TO_SEND 30 +#define EVENTS_EXPECTED_TO_RECEIVE 9*4 // 2 consumers get the same events from 2 suppliers + + ACE_Atomic_Op <TAO_SYNCH_MUTEX, int> g_result_count = 0; + +FilterClient::FilterClient (void) + :done_ (0) +{ + g_result_count = 0; + // No-Op. + ifgop_ = CosNotifyChannelAdmin::AND_OP; +} + +FilterClient::~FilterClient () +{ + this->ec_->destroy (); +} + +void +FilterClient::init (int argc, char *argv [] ACE_ENV_ARG_DECL) +{ + init_ORB (argc, argv ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + resolve_naming_service (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + resolve_Notify_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + create_EC (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + create_supplieradmin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + create_consumeradmin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + create_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + create_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +FilterClient::run (ACE_ENV_SINGLE_ARG_DECL) +{ + send_events (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + if (g_result_count != EVENTS_EXPECTED_TO_RECEIVE) + { // if we still need to wait for events, run the orb. + while (!this->done_) + if (this->orb_->work_pending ()) + this->orb_->perform_work (); + } +} + +void +FilterClient::done (void) +{ + this->done_ = 1; +} + +void +FilterClient::init_ORB (int argc, + char *argv [] + ACE_ENV_ARG_DECL) +{ + this->orb_ = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_ptr poa_object = + this->orb_->resolve_initial_references("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (poa_object)) + { + ACE_ERROR ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n")); + return; + } + this->root_poa_ = + PortableServer::POA::_narrow (poa_object + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::POAManager_var poa_manager = + root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +FilterClient::resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL) +{ + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW (CORBA::UNKNOWN ()); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +FilterClient::resolve_Notify_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (NOTIFY_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->notify_factory_ = + CosNotifyChannelAdmin::EventChannelFactory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +FilterClient::create_EC (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyChannelAdmin::ChannelID id; + + ec_ = notify_factory_->create_channel (initial_qos_, + initial_admin_, + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (ec_.in ())); +} + +void +FilterClient::create_supplieradmin (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyChannelAdmin::AdminID adminid = 0; + + supplier_admin_ = + ec_->new_for_suppliers (this->ifgop_, adminid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (supplier_admin_.in ())); + + CosNotifyFilter::FilterFactory_var ffact = + ec_->default_filter_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // setup a filter at the consumer admin + CosNotifyFilter::Filter_var sa_filter = + ffact->create_filter (TCL_GRAMMAR ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (sa_filter.in ())); + + CosNotifyFilter::ConstraintExpSeq constraint_list (1); + constraint_list.length (1); + + constraint_list[0].event_types.length (0); + constraint_list[0].constraint_expr = CORBA::string_dup (SA_FILTER); + + sa_filter->add_constraints (constraint_list ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + supplier_admin_->add_filter (sa_filter.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +FilterClient:: create_consumeradmin (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyChannelAdmin::AdminID adminid = 0; + + consumer_admin_ = + ec_->new_for_consumers (this->ifgop_, adminid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (consumer_admin_.in ())); + + CosNotifyFilter::FilterFactory_var ffact = + ec_->default_filter_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // setup a filter at the consumer admin + CosNotifyFilter::Filter_var ca_filter = + ffact->create_filter (TCL_GRAMMAR ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (ca_filter.in ())); + + /* struct ConstraintExp { + CosNotification::EventTypeSeq event_types; + string constraint_expr; + }; + */ + CosNotifyFilter::ConstraintExpSeq constraint_list (1); + constraint_list.length (1); + + constraint_list[0].event_types.length (0); + constraint_list[0].constraint_expr = CORBA::string_dup (CA_FILTER); + + ca_filter->add_constraints (constraint_list ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + consumer_admin_->add_filter (ca_filter.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +FilterClient::create_consumers (ACE_ENV_SINGLE_ARG_DECL) +{ + // startup the first consumer. + ACE_NEW_THROW_EX (consumer_1, + Filter_StructuredPushConsumer (this, "consumer1"), + CORBA::NO_MEMORY ()); + + consumer_1->connect (consumer_admin_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // startup the second consumer. + ACE_NEW_THROW_EX (consumer_2, + Filter_StructuredPushConsumer (this, "consumer2"), + CORBA::NO_MEMORY ()); + + consumer_2->connect (consumer_admin_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +FilterClient::create_suppliers (ACE_ENV_SINGLE_ARG_DECL) +{ + // startup the first supplier + ACE_NEW_THROW_EX (supplier_1, + Filter_StructuredPushSupplier ("supplier1"), + CORBA::NO_MEMORY ()); + + supplier_1->connect (supplier_admin_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // startup the second supplier + ACE_NEW_THROW_EX (supplier_2, + Filter_StructuredPushSupplier ("supplier2"), + CORBA::NO_MEMORY ()); + + supplier_2->connect (supplier_admin_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +FilterClient::send_events (ACE_ENV_SINGLE_ARG_DECL) +{ + // operations: + CosNotification::StructuredEvent event; + + // EventHeader + + // FixedEventHeader + // EventType + // string + event.header.fixed_header.event_type.domain_name = CORBA::string_dup("*"); + // string + event.header.fixed_header.event_type.type_name = CORBA::string_dup("*"); + // string + event.header.fixed_header.event_name = CORBA::string_dup("myevent"); + + // OptionalHeaderFields + // PropertySeq + // sequence<Property>: string name, any value + event.header.variable_header.length (1); // put nothing here + + // FilterableEventBody + // PropertySeq + // sequence<Property>: string name, any value + event.filterable_data.length (3); + event.filterable_data[0].name = CORBA::string_dup("threshold"); + + event.filterable_data[1].name = CORBA::string_dup("temperature"); + event.filterable_data[1].value <<= (CORBA::Long)70; + + event.filterable_data[2].name = CORBA::string_dup("pressure"); + event.filterable_data[2].value <<= (CORBA::Long)80; + + event.filterable_data[0].value <<= (CORBA::Long)4; + + // any + event.remainder_of_body <<= (CORBA::Long)4; + + for (int i = 0; i < EVENTS_TO_SEND; i++) + { + event.filterable_data[0].value <<= (CORBA::Long)i; + + // any + event.remainder_of_body <<= (CORBA::Long)i; + + supplier_1->send_event (event ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + supplier_2->send_event (event ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +} + + +Filter_StructuredPushConsumer::Filter_StructuredPushConsumer (FilterClient* filter, const char* my_name) + :filter_ (filter), + my_name_ (my_name) +{ +} + +Filter_StructuredPushConsumer::~Filter_StructuredPushConsumer (void) +{ +} + +void +Filter_StructuredPushConsumer::connect (CosNotifyChannelAdmin::ConsumerAdmin_ptr consumer_admin ACE_ENV_ARG_DECL) +{ + // Activate the consumer with the default_POA_ + CosNotifyComm::StructuredPushConsumer_var objref = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::ProxySupplier_var proxysupplier = + consumer_admin->obtain_notification_push_supplier (CosNotifyChannelAdmin::STRUCTURED_EVENT, proxy_supplier_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxysupplier.in ())); + + // narrow + this->proxy_supplier_ = + CosNotifyChannelAdmin::StructuredProxyPushSupplier:: + _narrow (proxysupplier.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxy_supplier_.in ())); + + proxy_supplier_->connect_structured_push_consumer (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Filter_StructuredPushConsumer::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + this->proxy_supplier_-> + disconnect_structured_push_supplier(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Filter_StructuredPushConsumer::offer_change + (const CosNotification::EventTypeSeq & /*added*/, + const CosNotification::EventTypeSeq & /*removed*/ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )) +{ + // No-Op. +} + +void +Filter_StructuredPushConsumer::push_structured_event + (const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )) +{ + CORBA::Long val; + + notification.remainder_of_body >>= val; + + // @@ Pradeep: for your tests try to make sure that you count the + // number of expected and sent events to verify that things work + // correctly in an automatic way... + + + ACE_DEBUG ((LM_DEBUG, + "%s received event, %d\n", my_name_.fast_rep (), val)); + + ACE_DEBUG ((LM_DEBUG,"event count %d\n", g_result_count.value ())); + + if (++g_result_count == EVENTS_EXPECTED_TO_RECEIVE) + this->filter_->done (); // all events received, we're done. +} + +void +Filter_StructuredPushConsumer::disconnect_structured_push_consumer + (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + // No-Op. +} + + +/*****************************************************************/ + +Filter_StructuredPushSupplier::Filter_StructuredPushSupplier (const char* my_name) + :my_name_ (my_name) +{ +} + +Filter_StructuredPushSupplier::~Filter_StructuredPushSupplier () +{ +} + +void +Filter_StructuredPushSupplier::connect (CosNotifyChannelAdmin::SupplierAdmin_ptr supplier_admin ACE_ENV_ARG_DECL) +{ + CosNotifyComm::StructuredPushSupplier_var objref = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::ProxyConsumer_var proxyconsumer = + supplier_admin->obtain_notification_push_consumer (CosNotifyChannelAdmin::STRUCTURED_EVENT, proxy_consumer_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxyconsumer.in ())); + + // narrow + this->proxy_consumer_ = + CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow (proxyconsumer.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxy_consumer_.in ())); + + proxy_consumer_->connect_structured_push_supplier (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Filter_StructuredPushSupplier::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->proxy_consumer_.in ())); + + this->proxy_consumer_->disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +Filter_StructuredPushSupplier::subscription_change + (const CosNotification::EventTypeSeq & /*added*/, + const CosNotification::EventTypeSeq & /*removed */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )) +{ + //No-Op. +} + +void +Filter_StructuredPushSupplier::send_event + (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->proxy_consumer_.in ())); + + ACE_DEBUG ((LM_DEBUG, + "%s is sending an event \n", my_name_.fast_rep ())); + + proxy_consumer_->push_structured_event (event ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Filter_StructuredPushSupplier::disconnect_structured_push_supplier + (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + // No-Op. +} + diff --git a/TAO/orbsvcs/examples/Notify/Filter/Filter.h b/TAO/orbsvcs/examples/Notify/Filter/Filter.h new file mode 100644 index 00000000000..e7f9cd236a4 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Filter/Filter.h @@ -0,0 +1,261 @@ +/* -*- C++ -*- */ +// $Id$ +// ========================================================================== +// +// = FILENAME +// Filter.h +// +// = DESCRIPTION +// Class to demo structured event filtering. +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// ========================================================================== + +#ifndef NOTIFY_FILTER_CLIENT_H +#define NOTIFY_FILTER_CLIENT_H + +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "orbsvcs/CosNamingC.h" +#include "ace/SString.h" + +class Filter_StructuredPushConsumer; +class Filter_StructuredPushSupplier; + +class FilterClient +{ + // = TITLE + // Filter Client + // = DESCRIPTION + // Client example that shows how to do Structured Event filtering + // in the Notification Service. + + public: + // = Initialization and Termination + FilterClient (void); + // Constructor + + ~FilterClient (); + // Destructor + + void init (int argc, char *argv [] ACE_ENV_ARG_DECL); + // Init the Client. + + void run (ACE_ENV_SINGLE_ARG_DECL); + // Run the demo. + + void done (void); + // Consumer calls done, We're done. + + protected: + void init_ORB (int argc, char *argv [] ACE_ENV_ARG_DECL); + // Initializes the ORB. + + void resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL); + // Try to get hold of a running naming service. + + void resolve_Notify_factory (ACE_ENV_SINGLE_ARG_DECL); + // Try to resolve the Notify factory from the Naming service. + + void create_EC (ACE_ENV_SINGLE_ARG_DECL); + // Create an EC. + + void create_supplieradmin(ACE_ENV_SINGLE_ARG_DECL); + // Create the Supplier Admin. + + void create_consumeradmin (ACE_ENV_SINGLE_ARG_DECL); + // Create the Consumer Admin. + + void create_consumers (ACE_ENV_SINGLE_ARG_DECL); + // Create and initialize the consumers. + + void create_suppliers (ACE_ENV_SINGLE_ARG_DECL); + // create and initialize the suppliers. + + void send_events (ACE_ENV_SINGLE_ARG_DECL); + // send the events. + + // = Data Members + PortableServer::POA_var root_poa_; + // Reference to the root poa. + + CORBA::ORB_var orb_; + // The ORB that we use. + + CosNaming::NamingContext_var naming_context_; + // Handle to the name service. + + CosNotifyChannelAdmin::EventChannelFactory_var notify_factory_; + // Channel factory. + + CosNotifyChannelAdmin::EventChannel_var ec_; + // The one channel that we create using the factory. + + CosNotifyChannelAdmin::InterFilterGroupOperator ifgop_; + // The group operator between admin-proxy's. + + CosNotification::QoSProperties initial_qos_; + // Initial qos specified to the factory when creating the EC. + + CosNotification::AdminProperties initial_admin_; + // Initial admin props specified to the factory when creating the EC. + + CosNotifyChannelAdmin::ConsumerAdmin_var consumer_admin_; + // The consumer admin used by consumers. + + CosNotifyChannelAdmin::SupplierAdmin_var supplier_admin_; + // The supplier admin used by suppliers. + + Filter_StructuredPushConsumer* consumer_1; + // Consumer #1 + + Filter_StructuredPushConsumer* consumer_2; + // Consumer #2 + + Filter_StructuredPushSupplier* supplier_1; + // Supplier #1 + + Filter_StructuredPushSupplier* supplier_2; + // Supplier #2 + + CORBA::Boolean done_; + // Set this flag to exit the run loop. +}; + +/*****************************************************************/ +class Filter_StructuredPushConsumer + : public POA_CosNotifyComm::StructuredPushConsumer +{ + // = TITLE + // Filter_StructuredPushConsumer + // + // = DESCRIPTION + // Consumer for the Filter example. + // + + public: + // = Initialization and Termination code + Filter_StructuredPushConsumer (FilterClient* filter, const char *my_name); + // Constructor. + + void connect (CosNotifyChannelAdmin::ConsumerAdmin_ptr consumer_admin ACE_ENV_ARG_DECL); + // Connect the Consumer to the EventChannel. + // Creates a new proxy supplier and connects to it. + + virtual void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the supplier. + +protected: + // = Data members + + FilterClient* filter_; + // The callback for <done> + + ACE_CString my_name_; + // The name of this consumer. + + CosNotifyChannelAdmin::StructuredProxyPushSupplier_var proxy_supplier_; + // The proxy that we are connected to. + + CosNotifyChannelAdmin::ProxyID proxy_supplier_id_; + // The proxy_supplier id. + + // = Methods + virtual ~Filter_StructuredPushConsumer (void); + // Destructor + + // = NotifyPublish method + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )); + + // = StructuredPushSupplier methods + virtual void push_structured_event ( + const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )); + + virtual void disconnect_structured_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); +}; + +/*****************************************************************/ + +class Filter_StructuredPushSupplier + : public POA_CosNotifyComm::StructuredPushSupplier +{ + // = TITLE + // Filter_StructuredPushSupplier + // + // = DESCRIPTION + // Supplier for the filter example. + // + public: + // = Initialization and Termination code + Filter_StructuredPushSupplier (const char* my_name); + // Constructor. + + void connect (CosNotifyChannelAdmin::SupplierAdmin_ptr supplier_admin + ACE_ENV_ARG_DECL); + // Connect the Supplier to the EventChannel. + // Creates a new proxy supplier and connects to it. + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the supplier. + + virtual void send_event (const CosNotification::StructuredEvent& event + ACE_ENV_ARG_DECL); + // Send one event. + +protected: + // = Data members + ACE_CString my_name_; + // The name of this consumer. + + CosNotifyChannelAdmin::StructuredProxyPushConsumer_var proxy_consumer_; + // The proxy that we are connected to. + + CosNotifyChannelAdmin::ProxyID proxy_consumer_id_; + // This supplier's id. + + // = Protected Methods + virtual ~Filter_StructuredPushSupplier (); + // Destructor + + // = NotifySubscribe + virtual void subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )); + + // = StructuredPushSupplier method + virtual void disconnect_structured_push_supplier ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); +}; + +#endif /* NOTIFY_FILTER_CLIENT_H */ diff --git a/TAO/orbsvcs/examples/Notify/Filter/Makefile.am b/TAO/orbsvcs/examples/Notify/Filter/Makefile.am new file mode 100644 index 00000000000..f7fb9130144 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Filter/Makefile.am @@ -0,0 +1,56 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.Notify_Filter.am + +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS = main + +main_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +main_SOURCES = \ + Filter.cpp \ + main.cpp \ + Filter.h + +main_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Notify/Filter/Notify_Filter.mpc b/TAO/orbsvcs/examples/Notify/Filter/Notify_Filter.mpc new file mode 100644 index 00000000000..0c0e54324fc --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Filter/Notify_Filter.mpc @@ -0,0 +1,5 @@ +// -*- MPC -*- +// $Id$ + +project : orbsvcsexe, notification, notification_skel, naming { +} diff --git a/TAO/orbsvcs/examples/Notify/Filter/README b/TAO/orbsvcs/examples/Notify/Filter/README new file mode 100644 index 00000000000..ddc5af0fca2 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Filter/README @@ -0,0 +1,23 @@ +Filter example: + +This example shows how to filter structured events in the Notification Service. + +The Notification service must be up and running before launching this example. +(See the README under $TAO_ROOT/orbsvcs/Notify_Service for more details.) + +The example connects to the Notification Service's factory object and creates +an event channel. It then hooks up 2 suppliers and consumers with the EC. +The consumers and suppliers use the <TAO_Notify_StructuredPushConsumer> and +<TAO_Notify_StructuredPushSupplier> classes which are utility classes included +with the Notification Service to help developers write consumers and suppliers. + +Both the suppliers send 30 events to the EC and contain the event property +"threshold". +Only events in the "threshold" range 10 to 20 are delivered to the consumers +because of the filters setup at the ConsumerAdmin and SupplierAdmin. + +Similar filters can be setup in the ConsumerProxy and SupplierProxy classes. + +thanks, +Pradeep +<pradeep@cs.wustl.edu> diff --git a/TAO/orbsvcs/examples/Notify/Filter/main.cpp b/TAO/orbsvcs/examples/Notify/Filter/main.cpp new file mode 100644 index 00000000000..845f7ab68f7 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Filter/main.cpp @@ -0,0 +1,35 @@ +// -*- C++ -*- +// $Id$ + +#include "Filter.h" + +int +main (int argc, char *argv []) +{ + FilterClient client; + + ACE_TRY_NEW_ENV + { + client.init (argc, argv + ACE_ENV_ARG_PARAMETER); //Init the Client + ACE_TRY_CHECK; + + client.run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::UserException, ue) + { + ACE_PRINT_EXCEPTION (ue, + "TLS_Client user error: "); + return 1; + } + ACE_CATCH (CORBA::SystemException, se) + { + ACE_PRINT_EXCEPTION (se, + "Filter system error: "); + return 1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Notify/Filter/run_test.pl b/TAO/orbsvcs/examples/Notify/Filter/run_test.pl new file mode 100755 index 00000000000..0a8753dc3e5 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Filter/run_test.pl @@ -0,0 +1,73 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "../../../../../bin"; +use PerlACE::Run_Test; + +$experiment_timeout = 60; +$startup_timeout = 60; + +$notify_ior = PerlACE::LocalFile ("notify.ior"); + +$naming_ior = PerlACE::LocalFile ("naming.ior"); + +$status = 0; + +$Naming = new PerlACE::Process ("../../../Naming_Service/Naming_Service", + "-o $naming_ior"); + +$Notification = new PerlACE::Process ("../../../Notify_Service/Notify_Service"); + +$Notify_Args = "-ORBInitRef NameService=file://$naming_ior -IORoutput $notify_ior "; + +$Filter = new PerlACE::Process ("Filter"); + +$Filter_Args = "-ORBInitRef NameService=file://$naming_ior"; + +unlink $naming_ior; +$Naming->Spawn (); + +if (PerlACE::waitforfile_timed ($naming_ior, $startup_timeout) == -1) { + print STDERR "ERROR: waiting for the naming service to start\n"; + $Naming->Kill (); + exit 1; +} + +unlink $notify_ior; +$Notification->Arguments ($Notify_Args); +$args = $Notification->Arguments (); +print STDERR "Running Notification with arguments: $args\n"; +$Notification->Spawn (); + +if (PerlACE::waitforfile_timed ($notify_ior, $startup_timeout) == -1) { + print STDERR "ERROR: waiting for the notify service to start\n"; + $Notification->Kill (); + $Naming->Kill (); + exit 1; +} + +$Filter->Arguments ($Filter_Args); +$args = $Filter->Arguments (); +print STDERR "Running Filter with arguments: $args\n"; +$status = $Filter->SpawnWaitKill ($experiment_timeout); + +if ($status != 0) + { + print STDERR "ERROR: Filter returned $status\n"; + $Filter->Kill (); + $Notification->Kill (); + $Naming->Kill (); + exit 1; + } + +$Notification->Kill (); +unlink $notify_ior; + +$Naming->Kill (); +unlink $naming_ior; + +exit $status; diff --git a/TAO/orbsvcs/examples/Notify/Lanes/Consumer.cpp b/TAO/orbsvcs/examples/Notify/Lanes/Consumer.cpp new file mode 100644 index 00000000000..17d2109cfb0 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/Consumer.cpp @@ -0,0 +1,171 @@ +// $Id$ + +#include "Consumer.h" + +ACE_RCSID (Notify, + TAO_Notify_Lanes_Consumer, + "$Id$") + + +TAO_Notify_Lanes_Consumer::TAO_Notify_Lanes_Consumer (TAO_Notify_ORB_Objects& orb_objects) + : orb_objects_ (orb_objects) +{ +} + +TAO_Notify_Lanes_Consumer::~TAO_Notify_Lanes_Consumer (void) +{ +} + +void +TAO_Notify_Lanes_Consumer::init (PortableServer::POA_var& poa, CosNotifyChannelAdmin::ConsumerAdmin_var& admin, ACE_CString& event_type ACE_ENV_ARG_DECL) +{ + this->default_POA_ = poa; + this->admin_ = admin; + this->event_type_ = event_type; + + this->connect (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +PortableServer::POA_ptr +TAO_Notify_Lanes_Consumer::_default_POA (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + return PortableServer::POA::_duplicate (this->default_POA_.in ()); +} + +void +TAO_Notify_Lanes_Consumer::run (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + // Nothing to do. +} + +void +TAO_Notify_Lanes_Consumer::connect (ACE_ENV_SINGLE_ARG_DECL) +{ + // Activate the consumer with the default_POA_ + CosNotifyComm::StructuredPushConsumer_var objref = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::ProxySupplier_var proxysupplier = + this->admin_->obtain_notification_push_supplier (CosNotifyChannelAdmin::STRUCTURED_EVENT + , proxy_supplier_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxysupplier.in ())); + + // narrow + this->proxy_supplier_ = + CosNotifyChannelAdmin::StructuredProxyPushSupplier::_narrow (proxysupplier.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxy_supplier_.in ())); + + this->proxy_supplier_->connect_structured_push_consumer (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Call subscription_change to inform the supplier that this consumer is available. + CosNotification::EventTypeSeq added (1); + CosNotification::EventTypeSeq removed; + + added.length (1); + added[0].domain_name = CORBA::string_dup ("TEST_DOMAIN"); + added[0].type_name = CORBA::string_dup (this->event_type_.c_str ()); + + this->proxy_supplier_->subscription_change (added, removed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_Notify_Lanes_Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + this->proxy_supplier_->disconnect_structured_push_supplier(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_Notify_Lanes_Consumer::offer_change (const CosNotification::EventTypeSeq & /*added*/, + const CosNotification::EventTypeSeq & /*removed*/ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )) +{ + // No-Op. +} + +void +TAO_Notify_Lanes_Consumer::push_structured_event (const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )) +{ + ACE_TRY_NEW_ENV + { + // Check the current threads priority. + RTCORBA::Priority thread_priority = + this->orb_objects_.current_->the_priority (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + const CosNotification::PropertySeq& prop_seq = notification.header.variable_header; + + // Extract the priority at which the supplier send it. + RTCORBA::Priority event_priority = 0; + + for (CORBA::ULong i = 0; i < prop_seq.length (); ++i) + { + if (ACE_OS::strcmp (prop_seq[i].name.in (), CosNotification::Priority) == 0) + prop_seq[i].value >>= event_priority; + } + + ACE_DEBUG ((LM_DEBUG, "(%P, %t) Consumer received event with priority = %d and thread priority = %d\n", + event_priority, thread_priority)); + + // The current thread priority and the event priority must match. + if (event_priority != thread_priority) + ACE_DEBUG ((LM_DEBUG, "(%P, %t) Error: Event priority and thread priority are different. \n")); + + // Disconnect from the EC + this->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + + // Deactivate this object. + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); + + // We received the event, shutdown the ORB. + this->orb_objects_.orb_->shutdown (1); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, + ACE_TEXT ("Consumer error ")); + + return; + } + ACE_ENDTRY; +} + +void +TAO_Notify_Lanes_Consumer::deactivate (ACE_ENV_SINGLE_ARG_DECL) +{ + PortableServer::POA_var poa (this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER)); + ACE_CHECK; + + PortableServer::ObjectId_var id (poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER)); + ACE_CHECK; + + poa->deactivate_object (id.in() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_Notify_Lanes_Consumer::disconnect_structured_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); +} diff --git a/TAO/orbsvcs/examples/Notify/Lanes/Consumer.h b/TAO/orbsvcs/examples/Notify/Lanes/Consumer.h new file mode 100644 index 00000000000..0f3c3d76dd9 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/Consumer.h @@ -0,0 +1,111 @@ +/* -*- C++ -*- */ +/** + * @file Consumer.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_CONSUMER_H +#define TAO_Notify_CONSUMER_H + +#include /**/ "ace/pre.h" + +#include "ORB_Objects.h" +#include "tao/RTCORBA/RTCORBA.h" +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "ace/SString.h" + +/** + * @class TAO_Notify_Lanes_Consumer + * + * @brief Consumer + * + */ + +class TAO_Notify_Lanes_Consumer + : public POA_CosNotifyComm::StructuredPushConsumer +{ +public: + /// Constuctor + TAO_Notify_Lanes_Consumer (TAO_Notify_ORB_Objects& orb_objects); + + /// Init + void init (PortableServer::POA_var& poa, CosNotifyChannelAdmin::ConsumerAdmin_var& admin, ACE_CString& event_type ACE_ENV_ARG_DECL); + + /// Run + void run (ACE_ENV_SINGLE_ARG_DECL_NOT_USED); + +protected: + // = Data members + + /// ORB Objects. + TAO_Notify_ORB_Objects orb_objects_; + + /// The proxy that we are connected to. + CosNotifyChannelAdmin::StructuredProxyPushSupplier_var proxy_supplier_; + + /// The proxy_supplier id. + CosNotifyChannelAdmin::ProxyID proxy_supplier_id_; + + // POA. + PortableServer::POA_var default_POA_; + + // The Consumer Admin + CosNotifyChannelAdmin::ConsumerAdmin_var admin_; + + /// The Type the Consumer should subscribe to. + ACE_CString event_type_; + + // = Methods + /// Destructor + virtual ~TAO_Notify_Lanes_Consumer (void); + + // = ServantBase operations + virtual PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS); + + /// Connect the Consumer to the EventChannel. + /// Creates a new proxy supplier and connects to it. + void connect (ACE_ENV_SINGLE_ARG_DECL); + + /// Disconnect the supplier. + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + + /// Deactivate. + void deactivate (ACE_ENV_SINGLE_ARG_DECL); + + // = NotifyPublish method + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )); + + // = StructuredPushSupplier methods + virtual void push_structured_event ( + const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )); + + virtual void disconnect_structured_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/Notify/Lanes/Consumer_Client.cpp b/TAO/orbsvcs/examples/Notify/Lanes/Consumer_Client.cpp new file mode 100644 index 00000000000..942d444d0cf --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/Consumer_Client.cpp @@ -0,0 +1,269 @@ +// $Id$ + +#include "Consumer_Client.h" +#include "Consumer.h" +#include "ORB_Run_Task.h" +#include "ace/Arg_Shifter.h" +#include "orbsvcs/NotifyExtC.h" +#include "orbsvcs/CosNamingC.h" +#include "tao/ORB_Core.h" +#include "ace/Sched_Params.h" +#include "ace/OS_NS_errno.h" + +ACE_RCSID (Notify, TAO_Notify_Lanes_Consumer_Client, "$Id$") + +TAO_Notify_Lanes_Consumer_Client::TAO_Notify_Lanes_Consumer_Client (TAO_Notify_ORB_Objects& orb_objects) + : orb_objects_ (orb_objects) + , lane_priority_ (0) + , consumer_ (0) +{ +} + +TAO_Notify_Lanes_Consumer_Client::~TAO_Notify_Lanes_Consumer_Client () +{ +} + +int +TAO_Notify_Lanes_Consumer_Client::parse_args (int argc, char *argv[]) +{ + ACE_Arg_Shifter arg_shifter (argc, argv); + + const ACE_TCHAR *current_arg = 0; + + while (arg_shifter.is_anything_left ()) + { + if ((current_arg = arg_shifter.get_the_parameter (ACE_TEXT("-LanePriority")))) // LanePriority + { + if (current_arg != 0) + { + this->lane_priority_ = ACE_OS::atoi (current_arg); + + char type[BUFSIZ]; + ACE_OS::sprintf (type, "TEST_TYPE_%d", this->lane_priority_); + this->event_type_ = type; + } + + arg_shifter.consume_arg (); + } + else + { + arg_shifter.ignore_arg (); + } + } + + return 0; +} + +void +TAO_Notify_Lanes_Consumer_Client::initialize (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_DEBUG ((LM_DEBUG, "(%P, %t)Initializing Consumer Client with lane priority = %d, event type = (%s)\n" + , this->lane_priority_, this->event_type_.c_str ())); + + PortableServer::POAManager_var poa_manager = + this->orb_objects_.root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Resolve the Notification Factory. + CosNotifyChannelAdmin::EventChannelFactory_var ecf = this->orb_objects_.notify_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Find the EventChannel created by the supplier. + CosNotifyChannelAdmin::ChannelIDSeq_var channel_seq = ecf->get_all_channels (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::EventChannel_var ec; + + if (channel_seq->length() > 0) + { + ec = ecf->get_event_channel (channel_seq[0] ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + ACE_DEBUG ((LM_DEBUG, "No Event Channel active!\n")); + return; + } + + // Create a Consumer Admin + CosNotifyChannelAdmin::AdminID adminid = 0; + + CosNotifyChannelAdmin::ConsumerAdmin_var consumer_admin = + ec->new_for_consumers (CosNotifyChannelAdmin::AND_OP, adminid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (consumer_admin.in ())); + + PortableServer::POA_var rt_poa = this->create_rt_poa (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Create a Consumer + this->consumer_ = new TAO_Notify_Lanes_Consumer (this->orb_objects_); + + // Initialize it. + this->consumer_->init (rt_poa, consumer_admin, this->event_type_ ACE_ENV_ARG_PARAMETER); +} + +PortableServer::POA_ptr +TAO_Notify_Lanes_Consumer_Client::create_rt_poa (ACE_ENV_SINGLE_ARG_DECL) +{ + PortableServer::POA_var rt_poa; + + // Create an RT POA with a lane at the given priority. + CORBA::Policy_var priority_model_policy; + CORBA::Policy_var lanes_policy; + + CORBA::Policy_var activation_policy = + this->orb_objects_.root_poa_->create_implicit_activation_policy (PortableServer::IMPLICIT_ACTIVATION ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + // Create a priority model policy. + priority_model_policy = + this->orb_objects_.rt_orb_->create_priority_model_policy (RTCORBA::CLIENT_PROPAGATED + , 0 + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + RTCORBA::ThreadpoolLanes lanes (1); + lanes.length (1); + + lanes[0].lane_priority = this->lane_priority_; + lanes[0].static_threads = 1; + lanes[0].dynamic_threads = 0; + + + // Create a thread-pool. + CORBA::ULong stacksize = 0; + CORBA::Boolean allow_request_buffering = 0; + CORBA::ULong max_buffered_requests = 0; + CORBA::ULong max_request_buffer_size = 0; + CORBA::Boolean allow_borrowing = 0; + + // Create the thread-pool. + RTCORBA::ThreadpoolId threadpool_id = + this->orb_objects_.rt_orb_->create_threadpool_with_lanes (stacksize, + lanes, + allow_borrowing, + allow_request_buffering, + max_buffered_requests, + max_request_buffer_size + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + // Create a thread-pool policy. + lanes_policy = + this->orb_objects_.rt_orb_->create_threadpool_policy (threadpool_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + CORBA::PolicyList poa_policy_list; + + poa_policy_list.length (3); + poa_policy_list[0] = priority_model_policy; + poa_policy_list[1] = activation_policy; + poa_policy_list[2] = lanes_policy; + + PortableServer::POAManager_var poa_manager = + this->orb_objects_.root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + rt_poa = this->orb_objects_.root_poa_->create_POA ("RT POA!", + poa_manager.in (), + poa_policy_list + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + return rt_poa._retn (); +} + +void +TAO_Notify_Lanes_Consumer_Client::run (ACE_ENV_SINGLE_ARG_DECL) +{ + this->consumer_->run (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +int +TAO_Notify_Lanes_Consumer_Client::svc (void) +{ + ACE_TRY_NEW_ENV + { + // Initialize this threads priority. + this->orb_objects_.current_->the_priority (0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->initialize (ACE_ENV_SINGLE_ARG_PARAMETER); //Init the Client + ACE_TRY_CHECK; + + this->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, + ACE_TEXT ("Supplier error ")); + + } + ACE_ENDTRY; + + return 0; +} + +int +main (int argc, char *argv []) +{ + ACE_TRY_NEW_ENV + { + // Initialize an ORB + CORBA::ORB_var orb = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + TAO_Notify_ORB_Objects orb_objects; + + orb_objects.init (orb ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + TAO_Notify_ORB_Run_Task orb_run_task (orb_objects); + + TAO_Notify_Lanes_Consumer_Client client (orb_objects); + + if (client.parse_args (argc, argv) != 0) + { + ACE_DEBUG ((LM_DEBUG, "Consumer_Client::Error parsing options\n")); + return -1; + } + + long flags = THR_NEW_LWP | THR_JOINABLE; + + flags |= + orb->orb_core ()->orb_params ()->thread_creation_flags (); + + + if (orb_run_task.activate (flags) == -1 || client.activate (flags) == -1) + { + if (ACE_OS::last_error () == EPERM) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Insufficient privilege to activate ACE_Task.\n")), + -1); + else + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%t) Task activation at priority %d failed. \n"))); + } + + orb_run_task.thr_mgr ()->wait (); + client.thr_mgr ()->wait (); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, + ACE_TEXT ("Consumer Client error ")); + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Notify/Lanes/Consumer_Client.h b/TAO/orbsvcs/examples/Notify/Lanes/Consumer_Client.h new file mode 100644 index 00000000000..31193b994f2 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/Consumer_Client.h @@ -0,0 +1,77 @@ +/* -*- C++ -*- */ +/** + * @file Consumer_Client.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_CONSUMER_CLIENT_H +#define TAO_Notify_CONSUMER_CLIENT_H + +#include /**/ "ace/pre.h" + +#include "ORB_Objects.h" + +#include "tao/RTCORBA/RTCORBA.h" + +#include "ace/SString.h" +#include "ace/Task.h" + +class TAO_Notify_Lanes_Consumer; + +/** + * @class TAO_Notify_Lanes_Consumer_Client + * + * @brief + * + */ +class TAO_Notify_Lanes_Consumer_Client : public ACE_Task_Base +{ +public: + /// Constuctor + TAO_Notify_Lanes_Consumer_Client (TAO_Notify_ORB_Objects& orb_objects); + + /// Destructor + ~TAO_Notify_Lanes_Consumer_Client (); + + /// Init + void initialize (ACE_ENV_SINGLE_ARG_DECL); + + /// Run + void run (ACE_ENV_SINGLE_ARG_DECL); + + /// Parse Args + int parse_args (int argc, char *argv[]); + + /// The thread entry point. + virtual int svc (void); + +protected: + /// Create an RT POA with a single lane at the specified RT Priority. + PortableServer::POA_ptr create_rt_poa (ACE_ENV_SINGLE_ARG_DECL); + + /// ORB Objects. + TAO_Notify_ORB_Objects orb_objects_; + + /// Lock to serialize internal state. + TAO_SYNCH_MUTEX lock_; + + /// Count how many consumers are done + int consumer_done_count_; + + /// The Priority that we want the consumer lane to be at. + RTCORBA::Priority lane_priority_; + + /// The Consumer. + TAO_Notify_Lanes_Consumer* consumer_; + + /// The Type the Consumer should subscribe to. + ACE_CString event_type_; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_CONSUMER_CLIENT_H */ diff --git a/TAO/orbsvcs/examples/Notify/Lanes/Makefile.am b/TAO/orbsvcs/examples/Notify/Lanes/Makefile.am new file mode 100644 index 00000000000..3115e27c5f6 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/Makefile.am @@ -0,0 +1,129 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Notify_Lanes_Consumer.am + +if BUILD_CORBA_MESSAGING +if BUILD_RT_CORBA +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Consumer + +Consumer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(TAO_ROOT)/orbsvcs/tests/Notify/lib \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Consumer_SOURCES = \ + Consumer.cpp \ + Consumer_Client.cpp \ + ORB_Objects.cpp \ + ORB_Run_Task.cpp \ + Consumer.h \ + Consumer_Client.h \ + ORB_Objects.h \ + ORB_Run_Task.h + +Consumer_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RT_Notification.la \ + $(TAO_BUILDDIR)/tao/libTAO_RTCORBA.la \ + $(TAO_BUILDDIR)/orbsvcs/tests/Notify/lib/libTAO_NotifyTests.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Serv.la \ + $(TAO_BUILDDIR)/tao/libTAO_IFR_Client.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicInterface.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Serv.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicAny.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_ETCL.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif BUILD_RT_CORBA +endif BUILD_CORBA_MESSAGING + +## Makefile.Notify_Lanes_Supplier.am + +if BUILD_RT_CORBA +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Supplier + +Supplier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Supplier_SOURCES = \ + ORB_Objects.cpp \ + ORB_Run_Task.cpp \ + Supplier.cpp \ + Supplier_Client.cpp \ + ORB_Objects.h \ + ORB_Run_Task.h \ + Supplier.h \ + Supplier_Client.h + +Supplier_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RT_Notification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Serv.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicAny.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_ETCL.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_RTCORBA.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif BUILD_RT_CORBA + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Notify/Lanes/Notify_Lanes.mpc b/TAO/orbsvcs/examples/Notify/Lanes/Notify_Lanes.mpc new file mode 100644 index 00000000000..147604e0274 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/Notify_Lanes.mpc @@ -0,0 +1,22 @@ +// -*- MPC -*- +// $Id$ + +project(*Supplier): rtcorba, rtnotify, minimum_corba, naming { + exename = Supplier + Source_Files { + Supplier.cpp + Supplier_Client.cpp + ORB_Objects.cpp + ORB_Run_Task.cpp + } +} + +project(*Consumer): notifytest, rtcorba, rtnotify, minimum_corba { + exename = Consumer + Source_Files { + Consumer.cpp + Consumer_Client.cpp + ORB_Objects.cpp + ORB_Run_Task.cpp + } +} diff --git a/TAO/orbsvcs/examples/Notify/Lanes/ORB_Objects.cpp b/TAO/orbsvcs/examples/Notify/Lanes/ORB_Objects.cpp new file mode 100644 index 00000000000..b26b9dbb0ec --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/ORB_Objects.cpp @@ -0,0 +1,71 @@ +// $Id$ + +#include "ORB_Objects.h" + +ACE_RCSID (Notify, TAO_Notify_ORB_Objects, "$Id$") + +TAO_Notify_ORB_Objects::TAO_Notify_ORB_Objects (void) +{ +} + +void +TAO_Notify_ORB_Objects::init (CORBA::ORB_var& orb ACE_ENV_ARG_DECL) +{ + this->orb_ = orb; + + CORBA::Object_var object = this->orb_->resolve_initial_references("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->root_poa_ = PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Resolve the RTORB. + object = this->orb_->resolve_initial_references ("RTORB" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->rt_orb_ = RTCORBA::RTORB::_narrow (object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Resolve the Current + object = this->orb_->resolve_initial_references ("RTCurrent" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->current_ = RTCORBA::Current::_narrow (object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Resolve the Naming service + object = this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->naming_ = CosNaming::NamingContextExt::_narrow (object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +TAO_Notify_ORB_Objects::~TAO_Notify_ORB_Objects () +{ +} + +CosNotifyChannelAdmin::EventChannelFactory_ptr +TAO_Notify_ORB_Objects::notify_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyChannelAdmin::EventChannelFactory_var ecf; + + // Look for the Notification Service + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup ("NotifyEventChannelFactory"); + + CORBA::Object_var object = this->naming_->resolve (name ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ecf._retn ()); + + ecf = CosNotifyChannelAdmin::EventChannelFactory::_narrow (object.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ecf._retn ()); + + return ecf._retn (); +} diff --git a/TAO/orbsvcs/examples/Notify/Lanes/ORB_Objects.h b/TAO/orbsvcs/examples/Notify/Lanes/ORB_Objects.h new file mode 100644 index 00000000000..e846e43303b --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/ORB_Objects.h @@ -0,0 +1,56 @@ +/* -*- C++ -*- */ +/** + * @file ORB_Objects.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_ORB_OBJECTS_H +#define TAO_Notify_ORB_OBJECTS_H + +#include /**/ "ace/pre.h" + +#include "tao/RTCORBA/RTCORBA.h" +#include "tao/PortableServer/PortableServer.h" +#include "orbsvcs/NotifyExtC.h" +#include "orbsvcs/CosNamingC.h" + +/** + * @class TAO_Notify_ORB_Objects + * + * @brief Handy Objects that we keep asking the ORB for. + * + */ +class TAO_Notify_ORB_Objects +{ +public: + /// Constuctor + TAO_Notify_ORB_Objects (void); + + /// Destructor + ~TAO_Notify_ORB_Objects (); + + /// Resolves all the references. + void init (CORBA::ORB_var& orb ACE_ENV_ARG_DECL); + + /// Resolve Notification + CosNotifyChannelAdmin::EventChannelFactory_ptr notify_factory (ACE_ENV_SINGLE_ARG_DECL); + + ///= Public Data + CORBA::ORB_var orb_; + + PortableServer::POA_var root_poa_; + + RTCORBA::RTORB_var rt_orb_; + + RTCORBA::Current_var current_; + + CosNaming::NamingContextExt_var naming_; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_ORB_OBJECTS_H */ diff --git a/TAO/orbsvcs/examples/Notify/Lanes/ORB_Run_Task.cpp b/TAO/orbsvcs/examples/Notify/Lanes/ORB_Run_Task.cpp new file mode 100644 index 00000000000..953328f78c5 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/ORB_Run_Task.cpp @@ -0,0 +1,33 @@ +// $Id$ + +#include "ORB_Run_Task.h" + +ACE_RCSID (Notify, TAO_Notify_ORB_Run_Task, "$Id$") + +TAO_Notify_ORB_Run_Task::TAO_Notify_ORB_Run_Task (TAO_Notify_ORB_Objects& orb_objects) + : orb_objects_ (orb_objects) +{ +} + +TAO_Notify_ORB_Run_Task::~TAO_Notify_ORB_Run_Task () +{ +} + +int +TAO_Notify_ORB_Run_Task::svc (void) +{ + ACE_TRY_NEW_ENV + { + this->orb_objects_.current_->the_priority (0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->orb_objects_.orb_->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Notify/Lanes/ORB_Run_Task.h b/TAO/orbsvcs/examples/Notify/Lanes/ORB_Run_Task.h new file mode 100644 index 00000000000..83fd657406b --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/ORB_Run_Task.h @@ -0,0 +1,44 @@ +/* -*- C++ -*- */ +/** + * @file ORB_Run_Task.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_ORB_RUN_TASK_H +#define TAO_Notify_ORB_RUN_TASK_H + +#include /**/ "ace/pre.h" +#include "ace/Task.h" + +#include "ORB_Objects.h" + +/** + * @class TAO_Notify_ORB_Run_Task + * + * @brief Run the ORB::run method in a seperate thread. + * + */ +class TAO_Notify_ORB_Run_Task : public ACE_Task_Base +{ +public: + /// Constuctor + TAO_Notify_ORB_Run_Task (TAO_Notify_ORB_Objects& orb_objects); + + /// Destructor + ~TAO_Notify_ORB_Run_Task (); + + /// The thread entry point. + virtual int svc (void); + +private: + /// ORB Objects. + TAO_Notify_ORB_Objects orb_objects_; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_ORB_RUN_TASK_H */ diff --git a/TAO/orbsvcs/examples/Notify/Lanes/README b/TAO/orbsvcs/examples/Notify/Lanes/README new file mode 100644 index 00000000000..f08b653ab39 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/README @@ -0,0 +1,62 @@ + +Lanes example +============= + +This example shows how to use RTCORBA lanes with Notification to +create a priority path between suppliers and consumers. + +The example consists of 2 executables: +./Supplier and ./Consumer + +Each of these encapsulate a Supplier and Consumer process consisting +of exactly 1 Notification PushSupplier and a Notification PushConsumer +respectively. + +First we start the Naming and RT Notification Service. + +Then we start the Supplier. The Supplier starts up and creates an event channel. It uses the +<set_qos> to set the ThreadpoolLanesParams QoS on the event +channel. This QoS specifies a lane for each priority that a consumer +will run at. There is also an extra lane created at priority 0 (Note: +the example uses the continuous priority mapping policy) to facilitate +invocations by the supplier's worker thread for administrative methods +(such as <subscription_change>). + +Then we start each consumer at prorities 1,2.3.. sequentially. The +run_test.pl script shows 2 consumers at priority 1 and 2. + +Each consumer is specified a priority at which it is hosted in an RT +POA. The consumer client process creates an RT POA with 1 lane and +activates the consumer in it. + +Each consumer send a subscription change message to the event channel +for its type. The message reaches the supplier and it updates its +count of the consumers that have connected. + +When the expected number of consumers have connected, the suppliers +starts a loop in which it send an event each to the event channel with +the correct priority and evvent type for each consumer. + +The RT_Notification matches the lane for the proxy consumer and sends +the event to the consumer using the CLIENT_PROPAGATED priority model. + +Running the example +=================== + +Simply execute the run_test.pl script in this directoty. +Remember, you must have root privileges to set RT priorities. + +Expected result: +================ + +You should see the following messages: + +(4784, 328)Initializing Consumer Client with lane priority = 2, event type = (TEST_TYPE_2) +(6020, 6032)Initializing Consumer Client with lane priority = 1, event type = (TEST_TYPE_1) +(6060, 4532) Supplier is sending an event of type TEST_TYPE_1 at priority 1 +(6020, 6068) Consumer received event with priority = 1 and thread priority = 1 +(6060, 4532) Supplier is sending an event of type TEST_TYPE_2 at priority 2 +(4784, 4760) Consumer received event with priority = 2 and thread priority = 2 + +if there is a mismatch in the expected results. The consumer will +print a warning message. diff --git a/TAO/orbsvcs/examples/Notify/Lanes/Supplier.cpp b/TAO/orbsvcs/examples/Notify/Lanes/Supplier.cpp new file mode 100644 index 00000000000..8b3a2a50862 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/Supplier.cpp @@ -0,0 +1,185 @@ +// $Id$ + +#include "Supplier.h" + +ACE_RCSID (Notify, TAO_Notify_Lanes_Supplier, "$Id$") + +#include "tao/ORB_Core.h" + +TAO_Notify_Lanes_Supplier::TAO_Notify_Lanes_Supplier (TAO_Notify_ORB_Objects& orb_objects) + : orb_objects_ (orb_objects) + , proxy_consumer_id_ (0) + , expected_consumer_count_ (2) + , consumers_connected_ (lock_) + , consumer_count_ (0) +{ +} + +TAO_Notify_Lanes_Supplier::~TAO_Notify_Lanes_Supplier () +{ +} + +void +TAO_Notify_Lanes_Supplier::init (CosNotifyChannelAdmin::SupplierAdmin_var& admin, int expected_consumer_count ACE_ENV_ARG_DECL) +{ + // First initialize the class members. + this->admin_ = admin; + this->expected_consumer_count_ = expected_consumer_count; + + this->connect (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +TAO_Notify_Lanes_Supplier::run (ACE_ENV_SINGLE_ARG_DECL) +{ + // The Priority at which we send the first event to the first consumer. + RTCORBA::Priority priority = 1; + + { + ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_); + + ACE_DEBUG ((LM_DEBUG, "(%P, %t) Waiting for %d consumers to connect...\n", this->expected_consumer_count_)); + + // Wait till the consumers are ready to go. + while (this->consumer_count_ != this->expected_consumer_count_) + this->consumers_connected_.wait (); + } + + // Send an event each to each consumer. + // Each Consumer expects a different priority. + for (int i = 0; i < this->expected_consumer_count_; ++i, ++priority) + { + // Set this threads priority. + this->orb_objects_.current_->the_priority (priority ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Make sure the priority was set, get the priority of the current thread. + RTCORBA::Priority thread_priority = + this->orb_objects_.current_->the_priority (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // We will send this event. + CosNotification::StructuredEvent event; + + // Populate the Priority field so that the consumer can deduce the suppliers priority + // to do a sanity check when it receives the event. + CosNotification::PropertySeq& opt = event.header.variable_header; + opt.length (1); + + CORBA::Any buffer; + buffer <<= (CORBA::Short) thread_priority; + + opt[0].name = CORBA::string_dup (CosNotification::Priority); + opt[0].value = buffer; + + // Set the domain and type nams in the event's fixed header. + char type[BUFSIZ]; + ACE_OS::sprintf (type, "TEST_TYPE_%d", thread_priority); + + event.header.fixed_header.event_type.domain_name = CORBA::string_dup("TEST_DOMAIN"); + event.header.fixed_header.event_type.type_name = CORBA::string_dup(type); + + ACE_DEBUG ((LM_DEBUG, + "(%P, %t) Supplier is sending an event of type %s at priority %d\n", type, thread_priority)); + + // send the event + this->send_event (event ACE_ENV_ARG_PARAMETER); + } // repeat for the next consumer at the next priority. + + // Disconnect from the EC + this->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + + // Deactivate this object. + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); + + // we're done. shutdown the ORB to exit the process. + this->orb_objects_.orb_->shutdown (1); +} + +void +TAO_Notify_Lanes_Supplier::connect (ACE_ENV_SINGLE_ARG_DECL) +{ + // Activate the supplier object. + CosNotifyComm::StructuredPushSupplier_var objref = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Obtain the proxy. + CosNotifyChannelAdmin::ProxyConsumer_var proxyconsumer = + this->admin_->obtain_notification_push_consumer (CosNotifyChannelAdmin::STRUCTURED_EVENT + , proxy_consumer_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxyconsumer.in ())); + + // narrow + this->proxy_consumer_ = + CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow (proxyconsumer.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxy_consumer_.in ())); + + // connect to the proxyconsumer. + proxy_consumer_->connect_structured_push_supplier (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_Notify_Lanes_Supplier::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->proxy_consumer_.in ())); + + this->proxy_consumer_->disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +TAO_Notify_Lanes_Supplier::deactivate (ACE_ENV_SINGLE_ARG_DECL) +{ + PortableServer::POA_var poa (this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER)); + ACE_CHECK; + + PortableServer::ObjectId_var id (poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER)); + ACE_CHECK; + + poa->deactivate_object (id.in() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_Notify_Lanes_Supplier::subscription_change (const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & /*removed */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_); + + // Count the number of consumers connect and signal the supplier thread when the expected count have connected. + if (added.length () > 0) + { + if (++this->consumer_count_ == this->expected_consumer_count_) + this->consumers_connected_.signal (); + } +} + +void +TAO_Notify_Lanes_Supplier::send_event (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->proxy_consumer_.in ())); + + proxy_consumer_->push_structured_event (event ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_Notify_Lanes_Supplier::disconnect_structured_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); +} diff --git a/TAO/orbsvcs/examples/Notify/Lanes/Supplier.h b/TAO/orbsvcs/examples/Notify/Lanes/Supplier.h new file mode 100644 index 00000000000..db4a8f816cd --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/Supplier.h @@ -0,0 +1,110 @@ +/* -*- C++ -*- */ +/** + * @file Supplier.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_SUPPLIER_H +#define TAO_Notify_SUPPLIER_H +#include /**/ "ace/pre.h" + +#include "ORB_Objects.h" +#include "tao/RTCORBA/RTCORBA.h" +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "ace/SString.h" +#include "ace/Condition_Thread_Mutex.h" + +/** + * @class TAO_Notify_Lanes_Supplier + * + * @brief Implement a Structured Supplier. + * + */ +class TAO_Notify_Lanes_Supplier + : public POA_CosNotifyComm::StructuredPushSupplier +{ + public: + // = Initialization and Termination code + + /// Constructor. + TAO_Notify_Lanes_Supplier (TAO_Notify_ORB_Objects& orb_objects); + + /// Init + void init (CosNotifyChannelAdmin::SupplierAdmin_var& admin, int count ACE_ENV_ARG_DECL); + + /// Run + void run (ACE_ENV_SINGLE_ARG_DECL); + +protected: + // = Protected Methods + + /// Connect the Supplier to the EventChannel. + /// Creates a new proxy consumer and connects to it. + void connect (ACE_ENV_SINGLE_ARG_DECL); + + /// Disconnect the supplier. + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + + /// Deactivate. + void deactivate (ACE_ENV_SINGLE_ARG_DECL); + + /// Send one event. + virtual void send_event (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL); + + /// Destructor + virtual ~TAO_Notify_Lanes_Supplier (); + + // = NotifySubscribe + virtual void subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )); + + // = StructuredPushSupplier method + virtual void disconnect_structured_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + /// = Data members + + /// ORB Objects. + TAO_Notify_ORB_Objects orb_objects_; + + /// The proxy that we are connected to. + CosNotifyChannelAdmin::StructuredProxyPushConsumer_var proxy_consumer_; + + /// This supplier's id. + CosNotifyChannelAdmin::ProxyID proxy_consumer_id_; + + /// Number of Consumers expected to connect. + int expected_consumer_count_; + + // The ORB that we use. + CORBA::ORB_var orb_; + + // The Supplier Admin + CosNotifyChannelAdmin::SupplierAdmin_var admin_; + + /// Lock to serialize internal state. + TAO_SYNCH_MUTEX lock_; + + /// Condition that consumers are connected. + TAO_SYNCH_CONDITION consumers_connected_; + + /// Number of consumers connected. + int consumer_count_; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/Notify/Lanes/Supplier_Client.cpp b/TAO/orbsvcs/examples/Notify/Lanes/Supplier_Client.cpp new file mode 100644 index 00000000000..2acb6bcc18b --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/Supplier_Client.cpp @@ -0,0 +1,272 @@ +// $Id$ + +#include "Supplier_Client.h" + +#include "ORB_Run_Task.h" +#include "ace/Arg_Shifter.h" +#include "tao/ORB_Core.h" +#include "ace/Sched_Params.h" +#include "Supplier.h" +#include "orbsvcs/NotifyExtC.h" +#include "orbsvcs/CosNamingC.h" +#include "ace/OS_NS_errno.h" + +ACE_RCSID (Notify, TAO_Notify_Lanes_Supplier_Client, "$Id$") + +TAO_Notify_Lanes_Supplier_Client::TAO_Notify_Lanes_Supplier_Client (TAO_Notify_ORB_Objects& orb_objects) + : orb_objects_ (orb_objects) + ,supplier_ (0) + , consumer_count_ (2) +{ +} + +TAO_Notify_Lanes_Supplier_Client::~TAO_Notify_Lanes_Supplier_Client () +{ +} + +int +TAO_Notify_Lanes_Supplier_Client::parse_args (int argc, char *argv[]) +{ + ACE_Arg_Shifter arg_shifter (argc, argv); + + const ACE_TCHAR *current_arg = 0; + + while (arg_shifter.is_anything_left ()) + { + if ((current_arg = arg_shifter.get_the_parameter (ACE_TEXT("-Consumers")))) // Number of consumers that we need to send an event to. + { + if (current_arg != 0) + { + this->consumer_count_ = ACE_OS::atoi (current_arg); + } + + arg_shifter.consume_arg (); + } + else if ((current_arg = arg_shifter.get_the_parameter (ACE_TEXT("-IORoutput")))) // The file to output the supplier ior to. + { + if (current_arg != 0) + { + this->ior_file_name_ = current_arg; + } + + arg_shifter.consume_arg (); + } + else + { + arg_shifter.ignore_arg (); + } + } + + return 0; +} + +void +TAO_Notify_Lanes_Supplier_Client::initialize (ACE_ENV_SINGLE_ARG_DECL) +{ + PortableServer::POAManager_var poa_manager = + this->orb_objects_.root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::EventChannel_var ec = this->create_ec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Create a Supplier Admin + CosNotifyChannelAdmin::AdminID adminid = 0; + + CosNotifyChannelAdmin::SupplierAdmin_var supplier_admin = + ec->new_for_suppliers (CosNotifyChannelAdmin::AND_OP, adminid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (supplier_admin.in ())); + + // Create a Supplier + this->supplier_ = new TAO_Notify_Lanes_Supplier (this->orb_objects_); + + // Initialize it. + this->supplier_->init (supplier_admin, this->consumer_count_ ACE_ENV_ARG_PARAMETER); +} + +CosNotifyChannelAdmin::EventChannel_ptr +TAO_Notify_Lanes_Supplier_Client::create_ec (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyChannelAdmin::EventChannel_var ec; + + CosNotifyChannelAdmin::EventChannelFactory_var ecf = this->orb_objects_.notify_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (ec._retn ()); + + // Create an EventChannel + CosNotification::QoSProperties qos; + CosNotification::AdminProperties admin; + + // Create an event channel + CosNotifyChannelAdmin::ChannelID id; + + ec = ecf->create_channel (qos, + admin, + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ec._retn ()); + + // Set the Qos : 2 Lanes + NotifyExt::ThreadPoolLanesParams tpl_params; + + tpl_params.priority_model = NotifyExt::CLIENT_PROPAGATED; + tpl_params.server_priority = 0; + tpl_params.stacksize = 0; + tpl_params.lanes.length (this->consumer_count_ + 1); + tpl_params.allow_borrowing = 0; + tpl_params.allow_request_buffering = 0; + tpl_params.max_buffered_requests = 0; + tpl_params.max_request_buffer_size = 0; + + /* + * Note that we actually create 1 extra Lane. + * The extra Lane at priority 0 is created to match the priority 0 of the supplier thread. + * As the ProxyConsumer is activated in an RT POA with lanes, each invocation must mach some lane. + * Now, we typically reserve higer priorities to make requests and the lowest priority 0 for administrative calls + * e.g. <subscription_change>. If we do not have a lane at the lowest 0 priority, then the invocation made from + * the supplier at priority 0 will fail. + */ + tpl_params.lanes[0].lane_priority = 0; // Priority 0 + tpl_params.lanes[0].static_threads = 1; + tpl_params.lanes[0].dynamic_threads = 0; + + RTCORBA::Priority priority = 1; // The priority at which we send an event each. + + for (int i = 1; i <= this->consumer_count_; ++i, ++priority) + { + tpl_params.lanes[i].lane_priority = priority; + tpl_params.lanes[i].static_threads = 1; + tpl_params.lanes[i].dynamic_threads = 0; + } + + qos.length (1); + qos[0].name = CORBA::string_dup (NotifyExt::ThreadPoolLanes); + qos[0].value <<= tpl_params; + + // Note that instead of <set_qos>, the <qos> can also be passed while creating the channel. + ec->set_qos (qos ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ec._retn ()); + + return ec._retn (); +} + +void +TAO_Notify_Lanes_Supplier_Client::run (ACE_ENV_SINGLE_ARG_DECL) +{ + /// First, signal that the supplier is ready. + this->write_ior (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_->run (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +TAO_Notify_Lanes_Supplier_Client::write_ior (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyComm::StructuredPushSupplier_var objref = this->supplier_->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Write the ior to a file to signal waiting consumers. + FILE *ior_output_file = ACE_OS::fopen (this->ior_file_name_.c_str (), ACE_TEXT("w")); + + if (ior_output_file != 0) + { + CORBA::String_var str = + this->orb_objects_.orb_->object_to_string (objref.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_OS::fprintf (ior_output_file, + "%s", + str.in ()); + ACE_OS::fclose (ior_output_file); + } +} + +int +TAO_Notify_Lanes_Supplier_Client::svc (void) +{ + ACE_TRY_NEW_ENV + { + this->orb_objects_.current_->the_priority (0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->initialize (ACE_ENV_SINGLE_ARG_PARAMETER); //Init the Client + ACE_TRY_CHECK; + + this->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, + ACE_TEXT ("Supplier error ")); + + } + ACE_ENDTRY; + + return 0; +} + +int +main (int argc, char *argv []) +{ + ACE_TRY_NEW_ENV + { + // Initialize an ORB + CORBA::ORB_var orb = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Create a holder for the common ORB Objects. + TAO_Notify_ORB_Objects orb_objects; + + orb_objects.init (orb ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + /* Run the ORB in a seperate thread */ + TAO_Notify_ORB_Run_Task orb_run_task (orb_objects); + + /* Create a Client */ + TAO_Notify_Lanes_Supplier_Client client (orb_objects); + + if (client.parse_args (argc, argv) != 0) + { + ACE_DEBUG ((LM_DEBUG, "Supplier_Client::Error parsing options\n")); + return -1; + } + + long flags = THR_NEW_LWP | THR_JOINABLE; + + flags |= + orb->orb_core ()->orb_params ()->thread_creation_flags (); + + /* Both the tasks initialize themselves at Priority 0*/ + if (orb_run_task.activate (flags) == -1 || client.activate (flags) == -1) + { + if (ACE_OS::last_error () == EPERM) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Insufficient privilege to activate ACE_Task.\n")), + -1); + else + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%t) Task activation at priority %d failed. \n"))); + } + + orb_run_task.thr_mgr ()->wait (); + client.thr_mgr ()->wait (); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, + ACE_TEXT ("Supplier Client error ")); + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Notify/Lanes/Supplier_Client.h b/TAO/orbsvcs/examples/Notify/Lanes/Supplier_Client.h new file mode 100644 index 00000000000..7dd4eb19259 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/Supplier_Client.h @@ -0,0 +1,71 @@ +/* -*- C++ -*- */ +/** + * @file Supplier_Client.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_SUPPLIER_CLIENT_H +#define TAO_Notify_SUPPLIER_CLIENT_H + +#include /**/ "ace/pre.h" +#include "ace/Task.h" +#include "ace/SString.h" + +#include "ORB_Objects.h" + +class TAO_Notify_Lanes_Supplier; + +/** + * @class TAO_Notify_Lanes_Supplier_Client + * + * @brief Supplier Client + * + */ +class TAO_Notify_Lanes_Supplier_Client : public ACE_Task_Base +{ +public: + /// Constuctor + TAO_Notify_Lanes_Supplier_Client (TAO_Notify_ORB_Objects& orb_objects); + + /// Destructor + ~TAO_Notify_Lanes_Supplier_Client (); + + /// Init + void initialize (ACE_ENV_SINGLE_ARG_DECL); + + /// Run + void run (ACE_ENV_SINGLE_ARG_DECL); + + /// Parse Args + int parse_args (int argc, char *argv[]); + + /// The thread entry point. + virtual int svc (void); + +protected: + /// Create an EC + CosNotifyChannelAdmin::EventChannel_ptr create_ec (ACE_ENV_SINGLE_ARG_DECL); + + /// Write ior to file. + void write_ior (ACE_ENV_SINGLE_ARG_DECL); + + /// ORB Objects. + TAO_Notify_ORB_Objects orb_objects_; + + /// Supplier that sends events. + TAO_Notify_Lanes_Supplier* supplier_; + + /// The Number of consumers that we expect to send an event to. + int consumer_count_; + + /// Name of the file to write the supplier ior to. + ACE_CString ior_file_name_; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_SUPPLIER_CLIENT_H */ diff --git a/TAO/orbsvcs/examples/Notify/Lanes/client.conf b/TAO/orbsvcs/examples/Notify/Lanes/client.conf new file mode 100644 index 00000000000..52878238bc7 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/client.conf @@ -0,0 +1 @@ +static RT_ORB_Loader "-ORBSchedPolicy SCHED_FIFO -ORBScopePolicy SYSTEM -ORBPriorityMapping continuous"
\ No newline at end of file diff --git a/TAO/orbsvcs/examples/Notify/Lanes/notify.conf b/TAO/orbsvcs/examples/Notify/Lanes/notify.conf new file mode 100644 index 00000000000..9aa94294430 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/notify.conf @@ -0,0 +1,3 @@ +dynamic TAO_RT_ORB_Loader Service_Object *TAO_RTCORBA:_make_TAO_RT_ORB_Loader () "-ORBSchedPolicy SCHED_FIFO -ORBScopePolicy PROCESS -ORBPriorityMapping continuous" + +dynamic TAO_Notify_Service Service_Object * TAO_RT_Notification:_make_TAO_RT_Notify_Service () "" diff --git a/TAO/orbsvcs/examples/Notify/Lanes/run_test.pl b/TAO/orbsvcs/examples/Notify/Lanes/run_test.pl new file mode 100755 index 00000000000..5b808cbd5f6 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Lanes/run_test.pl @@ -0,0 +1,128 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "../../../../../bin"; +use PerlACE::Run_Test; + +# Lanes Example +# + +$experiment_timeout = 60; +$startup_timeout = 60; +$notify_conf = PerlACE::LocalFile ("notify.conf"); +$notify_ior = PerlACE::LocalFile ("notify.ior"); + +$naming_ior = PerlACE::LocalFile ("naming.ior"); + +$supplier_ior = PerlACE::LocalFile ("supplier.ior"); + +$supplier_conf = PerlACE::LocalFile ("client.conf"); + +$consumer_conf = PerlACE::LocalFile ("client.conf"); + +$consumer2_conf = PerlACE::LocalFile ("client.conf"); + +$status = 0; + +$Naming = new PerlACE::Process ("../../../Naming_Service/Naming_Service", + "-o $naming_ior"); + +$Notification = new PerlACE::Process ("../../../Notify_Service/Notify_Service"); + +$Notify_Args = "-ORBInitRef NameService=file://$naming_ior -IORoutput $notify_ior -ORBSvcConf $notify_conf"; +#$Notify_Args = "-ORBInitRef NameService=file://$naming_ior -IORoutput $notify_ior -ORBSvcConf $notify_conf -ORBDebugLevel 1"; + +$Supplier = new PerlACE::Process ("Supplier"); + +$Supplier_Args = "-ORBInitRef NameService=file://$naming_ior -ORBSvcConf $supplier_conf -IORoutput $supplier_ior"; +#$Supplier_Args = "-ORBInitRef NameService=file://$naming_ior -ORBSvcConf $supplier_conf -ORBDebugLevel 1"; + +$Consumer = new PerlACE::Process ("Consumer"); + +$Consumer_Args = "-ORBInitRef NameService=file://$naming_ior -ORBSvcConf $consumer_conf -LanePriority 1"; +#$Consumer_Args = "-ORBInitRef NameService=file://$naming_ior -ORBSvcConf $consumer_conf -ORBDebugLevel 1"; + +$Consumer2 = new PerlACE::Process ("Consumer"); + +$Consumer2_Args = "-ORBInitRef NameService=file://$naming_ior -ORBSvcConf $consumer2_conf -LanePriority 2"; +#$Consumer2_Args = "-ORBInitRef NameService=file://$naming_ior -ORBSvcConf $consumer_conf -ORBDebugLevel 1"; + +unlink $naming_ior; +$Naming->Spawn (); + +if (PerlACE::waitforfile_timed ($naming_ior, $startup_timeout) == -1) { + print STDERR "ERROR: waiting for the naming service to start\n"; + $Naming->Kill (); + exit 1; +} + +unlink $notify_ior; +$Notification->Arguments ($Notify_Args); +$args = $Notification->Arguments (); +print STDERR "Running Notification with arguments: $args\n"; +$Notification->Spawn (); + +if (PerlACE::waitforfile_timed ($notify_ior, $startup_timeout) == -1) { + print STDERR "ERROR: waiting for the notify service to start\n"; + $Notification->Kill (); + $Naming->Kill (); + exit 1; +} + +unlink $supplier_ior; +$Supplier->Arguments ($Supplier_Args); +$args = $Supplier->Arguments (); +print STDERR "Running Supplier with arguments: $args\n"; +$Supplier->Spawn (); + +if (PerlACE::waitforfile_timed ($supplier_ior, $startup_timeout) == -1) { + print STDERR "ERROR: waiting for the supplier to start\n"; + $Notification->Kill (); + $Naming->Kill (); + exit 1; +} + +$Consumer->Arguments ($Consumer_Args); +$args = $Consumer->Arguments (); +print STDERR "Running Consumer with arguments: $args\n"; +$status = $Consumer->Spawn (); + +if ($status != 0) + { + print STDERR "ERROR: Consumer returned $status\n"; + $Supplier->Kill (); + $Notification->Kill (); + $Naming->Kill (); + exit 1; + } + +$Consumer2->Arguments ($Consumer2_Args); +$args = $Consumer2->Arguments (); +print STDERR "Running Consumer2 with arguments: $args\n"; +$status = $Consumer2->SpawnWaitKill ($experiment_timeout); + +if ($status != 0) + { + print STDERR "ERROR: Consumer2 returned $status\n"; + $Supplier->Kill (); + $Notification->Kill (); + $Naming->Kill (); + exit 1; + } + +$Consumer->Wait (); +$Supplier->Wait (); + +unlink $supplier_ior; + +$Notification->Kill (); +unlink $notify_ior; + +$Naming->Kill (); +unlink $naming_ior; + +exit $status; diff --git a/TAO/orbsvcs/examples/Notify/Makefile.am b/TAO/orbsvcs/examples/Notify/Makefile.am new file mode 100644 index 00000000000..2ddbd449fb9 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Makefile.am @@ -0,0 +1,17 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + Federation \ + Filter \ + Lanes \ + Subscribe \ + ThreadPool + diff --git a/TAO/orbsvcs/examples/Notify/README b/TAO/orbsvcs/examples/Notify/README new file mode 100644 index 00000000000..7028c60fe5d --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/README @@ -0,0 +1,18 @@ + +Notification Service examples: + +This directory has examples to illustrate how to use the Notification Service + +Examples: + +Filter: A simple example to how how to do filtering of events. +------ +An event passing through the channel encounters filters at the proxy, +admin and channel level.This example shows how to setup filters and use them. + +Subscribe: A simple example to show how to specify subscription constraints. +--------- +This example does not add any filters to keep the example simple. +If filters are added, then they would be evaluated *after* the event type +constraints have been met. +Thus subscriptions are a way of provide coarse grain filtering. diff --git a/TAO/orbsvcs/examples/Notify/Subscribe/Makefile.am b/TAO/orbsvcs/examples/Notify/Subscribe/Makefile.am new file mode 100644 index 00000000000..fcbd47a2d9c --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Subscribe/Makefile.am @@ -0,0 +1,56 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.Notify_Subscribe.am + +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS = Subscribe + +Subscribe_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Subscribe_SOURCES = \ + Subscribe.cpp \ + main.cpp \ + Subscribe.h + +Subscribe_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Notify/Subscribe/Notify_Subscribe.mpc b/TAO/orbsvcs/examples/Notify/Subscribe/Notify_Subscribe.mpc new file mode 100644 index 00000000000..39521d11a30 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Subscribe/Notify_Subscribe.mpc @@ -0,0 +1,6 @@ +// -*- MPC -*- +// $Id$ + +project : orbsvcsexe, notification, notification_skel, naming, minimum_corba { + exename = Subscribe +} diff --git a/TAO/orbsvcs/examples/Notify/Subscribe/README b/TAO/orbsvcs/examples/Notify/Subscribe/README new file mode 100644 index 00000000000..8dc7fac8cb6 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Subscribe/README @@ -0,0 +1,28 @@ +Subscribe example: +---------------- +Note: This example is under construction. + +The Notification service must be up and running before launching this example. +(See the README under $TAO_ROOT/orbsvcs/Notify_Service for more details.) + +Description: +------------ +This example sets subscription event type constraints (domain_name,type_name): + +At the consumer admin. C1 = ("domain_A", "Type_1"). +This means that all consumers connected to this admin object are interested +in receiving events of "domain_A" and "Type_1". + +At consumer 1, C2 = ("domain_B", Type_2") +At consumer 2, C3 = ("domain_C", Type_3") + +A supplier then send events of all 3 types to the event channel. +i,e. event E1 with event type C1, + event E2 with event type C2 and + event E3 with event type C3. + +From the subscriptions, consumer1 receives E1 and E2, (not E3) and +consumer2 receives E1 and E3 (not E2). + +running the ./Subscribe example will output the events received by each +consumer.
\ No newline at end of file diff --git a/TAO/orbsvcs/examples/Notify/Subscribe/Subscribe.cpp b/TAO/orbsvcs/examples/Notify/Subscribe/Subscribe.cpp new file mode 100644 index 00000000000..a7a0e96183f --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Subscribe/Subscribe.cpp @@ -0,0 +1,471 @@ +/* -*- C++ -*- $Id$ */ +#include "Subscribe.h" + +ACE_RCSID(Notify, Subscribe, "$Id$") + +#define NOTIFY_FACTORY_NAME "NotifyEventChannelFactory" +#define NAMING_SERVICE_NAME "NameService" + +#define DOMAIN_A "domain_a" +#define DOMAIN_B "domain_b" +#define DOMAIN_C "domain_c" + +#define TYPE_A "type_a" +#define TYPE_B "type_b" +#define TYPE_C "type_c" + +#define EVENT_COUNT 4 // number of events we expect the consumer to get from the EC + + ACE_Atomic_Op <TAO_SYNCH_MUTEX, int> g_result_count = 0; // we wait for 4 events. + +Subscribe::Subscribe (void) + : done_ (0) +{ + // No-Op. + ifgop_ = CosNotifyChannelAdmin::OR_OP; +} + +Subscribe::~Subscribe () +{ + this->ec_->destroy (); +} + +void +Subscribe::init (int argc, char *argv [] ACE_ENV_ARG_DECL) +{ + init_ORB (argc, argv ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + resolve_naming_service (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + resolve_Notify_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + create_EC (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + create_supplieradmin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + create_consumeradmin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + create_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + create_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Subscribe::run (ACE_ENV_SINGLE_ARG_DECL) +{ + this->send_events (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + if (g_result_count != EVENT_COUNT) // if we still need to wait for events, run the orb. + { // if we still need to wait for events, run the orb. + while (!this->done_) + if (this->orb_->work_pending ()) + this->orb_->perform_work (); + } +} + +void +Subscribe::done (void) +{ + this->done_ = 1; +} + +void +Subscribe::init_ORB (int argc, + char *argv [] + ACE_ENV_ARG_DECL) +{ + this->orb_ = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Object_ptr poa_object = + this->orb_->resolve_initial_references("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (poa_object)) + { + ACE_ERROR ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n")); + return; + } + this->root_poa_ = + PortableServer::POA::_narrow (poa_object ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + PortableServer::POAManager_var poa_manager = + root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Subscribe::resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL) +{ + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references (NAMING_SERVICE_NAME + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Need to check return value for errors. + if (CORBA::is_nil (naming_obj.in ())) + ACE_THROW (CORBA::UNKNOWN ()); + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Subscribe::resolve_Notify_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (NOTIFY_FACTORY_NAME); + + CORBA::Object_var obj = + this->naming_context_->resolve (name + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->notify_factory_ = + CosNotifyChannelAdmin::EventChannelFactory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Subscribe::create_EC (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyChannelAdmin::ChannelID id; + + ec_ = notify_factory_->create_channel (initial_qos_, + initial_admin_, + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (ec_.in ())); +} + +void +Subscribe::create_supplieradmin (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyChannelAdmin::AdminID adminid; + + supplier_admin_ = + ec_->new_for_suppliers (this->ifgop_, adminid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (supplier_admin_.in ())); +} + +void +Subscribe:: create_consumeradmin (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyChannelAdmin::AdminID adminid; + + consumer_admin_ = + ec_->new_for_consumers (this->ifgop_, adminid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (consumer_admin_.in ())); +} + +void +Subscribe::create_consumers (ACE_ENV_SINGLE_ARG_DECL) +{ + consumer_1_ = new Subscribe_StructuredPushConsumer (this); + consumer_1_->connect (this->consumer_admin_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + consumer_2_ = new Subscribe_StructuredPushConsumer (this); + consumer_2_->connect (this->consumer_admin_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Subscribe::create_suppliers (ACE_ENV_SINGLE_ARG_DECL) +{ + supplier_1_ = new Subscribe_StructuredPushSupplier (); + supplier_1_->connect (this->supplier_admin_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + supplier_2_ = new Subscribe_StructuredPushSupplier (); + supplier_2_->connect (this->supplier_admin_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Subscribe::send_events (ACE_ENV_SINGLE_ARG_DECL) +{ + // Setup the CA to receive event_type : "domain_A", "Type_a" + CosNotification::EventTypeSeq added(1); + CosNotification::EventTypeSeq removed (0); + added.length (1); + + added[0].domain_name = CORBA::string_dup (DOMAIN_A); + added[0].type_name = CORBA::string_dup (TYPE_A); + + this->consumer_admin_->subscription_change (added, removed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Setup the Consumer 1 to receive event_type : "domain_B", "Type_b" + CosNotification::EventTypeSeq added_1(1); + CosNotification::EventTypeSeq removed_1 (0); + + added_1[0].domain_name = CORBA::string_dup (DOMAIN_B); + added_1[0].type_name = CORBA::string_dup (TYPE_B); + added_1.length (1); + removed_1.length (0); + + this->consumer_1_->get_proxy_supplier ()->subscription_change (added_1, removed_1 + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Setup the Consumer 2 to receive event_type : "domain_C", "Type_c" + CosNotification::EventTypeSeq added_2(1); + CosNotification::EventTypeSeq removed_2 (0); + + added_2[0].domain_name = CORBA::string_dup (DOMAIN_C); + added_2[0].type_name = CORBA::string_dup (TYPE_C); + added_2.length (1); + removed_2.length (0); + + this->consumer_2_->get_proxy_supplier ()->subscription_change (added_2, removed_2 + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Create the events - one of each type + // Event 1 + CosNotification::StructuredEvent event1; + event1.header.fixed_header.event_type.domain_name = + CORBA::string_dup(DOMAIN_A); + event1.header.fixed_header.event_type.type_name = + CORBA::string_dup(TYPE_A); + event1.header.fixed_header.event_name = CORBA::string_dup(""); + event1.header.variable_header.length (0); // put nothing here + event1.filterable_data.length (0); + event1.remainder_of_body <<= (CORBA::Long)10; + + // Event 2 + CosNotification::StructuredEvent event2; + event2.header.fixed_header.event_type.domain_name = + CORBA::string_dup(DOMAIN_B); + event2.header.fixed_header.event_type.type_name = + CORBA::string_dup(TYPE_B); + event2.header.fixed_header.event_name = CORBA::string_dup(""); + event2.header.variable_header.length (0); // put nothing here + event2.filterable_data.length (0); + event2.remainder_of_body <<= (CORBA::Long)10; + + // event 3 + CosNotification::StructuredEvent event3; + event3.header.fixed_header.event_type.domain_name = + CORBA::string_dup(DOMAIN_C); + event3.header.fixed_header.event_type.type_name = + CORBA::string_dup(TYPE_C); + event3.header.fixed_header.event_name = CORBA::string_dup(""); + event3.header.variable_header.length (0); // put nothing here + event3.filterable_data.length (0); + event3.remainder_of_body <<= (CORBA::Long)10; + + // let supplier 1 send all these events + for (int i = 0; i < 1; ++i) + { + supplier_1_->send_event (event1 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + supplier_1_->send_event (event2 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + supplier_1_->send_event (event3 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +} + +/*****************************************************************/ +Subscribe_StructuredPushConsumer::Subscribe_StructuredPushConsumer (Subscribe* subscribe) + : subscribe_ (subscribe) +{ +} + +Subscribe_StructuredPushConsumer::~Subscribe_StructuredPushConsumer () +{ +} + +void +Subscribe_StructuredPushConsumer::connect + (CosNotifyChannelAdmin::ConsumerAdmin_ptr consumer_admin + ACE_ENV_ARG_DECL) +{ + // Activate the consumer with the default_POA_ + CosNotifyComm::StructuredPushConsumer_var objref = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::ProxySupplier_var proxysupplier = + consumer_admin->obtain_notification_push_supplier (CosNotifyChannelAdmin::STRUCTURED_EVENT, proxy_supplier_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxysupplier.in ())); + + // narrow + this->proxy_supplier_ = + CosNotifyChannelAdmin::StructuredProxyPushSupplier:: + _narrow (proxysupplier.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxy_supplier_.in ())); + + proxy_supplier_->connect_structured_push_consumer (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Subscribe_StructuredPushConsumer::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + this->proxy_supplier_-> + disconnect_structured_push_supplier(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +Subscribe_StructuredPushConsumer::offer_change + (const CosNotification::EventTypeSeq & /*added*/, + const CosNotification::EventTypeSeq & /*removed*/ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )) +{ + // No-Op. +} + +void +Subscribe_StructuredPushConsumer::push_structured_event + (const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )) +{ + const char* domain_name = + notification.header.fixed_header.event_type.domain_name; + + const char* type_name = + notification.header.fixed_header.event_type.type_name; + + ACE_DEBUG ((LM_DEBUG, "Structured Subscribe Consumer %d received event, domain = %s, type = %s\n", this->proxy_supplier_id_, domain_name, type_name)); + + if (++g_result_count == EVENT_COUNT) + subscribe_->done (); + +} + +void +Subscribe_StructuredPushConsumer::disconnect_structured_push_consumer + (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + // No-Op. +} + +CosNotifyChannelAdmin::StructuredProxyPushSupplier_ptr +Subscribe_StructuredPushConsumer::get_proxy_supplier (void) +{ + return proxy_supplier_.in (); +} + +/*****************************************************************/ + +Subscribe_StructuredPushSupplier::Subscribe_StructuredPushSupplier (void) +{ +} + +Subscribe_StructuredPushSupplier::~Subscribe_StructuredPushSupplier () +{ +} + +void +Subscribe_StructuredPushSupplier::connect + (CosNotifyChannelAdmin::SupplierAdmin_ptr supplier_admin + ACE_ENV_ARG_DECL) +{ + CosNotifyComm::StructuredPushSupplier_var objref = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::ProxyConsumer_var proxyconsumer = + supplier_admin->obtain_notification_push_consumer (CosNotifyChannelAdmin::STRUCTURED_EVENT, proxy_consumer_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxyconsumer.in ())); + + // narrow + this->proxy_consumer_ = + CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow (proxyconsumer.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxy_consumer_.in ())); + + proxy_consumer_->connect_structured_push_supplier (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Subscribe_StructuredPushSupplier::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->proxy_consumer_.in ())); + + this->proxy_consumer_->disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +Subscribe_StructuredPushSupplier::subscription_change + (const CosNotification::EventTypeSeq & /*added*/, + const CosNotification::EventTypeSeq & /*removed */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )) +{ + //No-Op. +} + +void +Subscribe_StructuredPushSupplier::send_event + (const CosNotification::StructuredEvent& event + ACE_ENV_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->proxy_consumer_.in ())); + + proxy_consumer_->push_structured_event (event ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Subscribe_StructuredPushSupplier::disconnect_structured_push_supplier + (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + // No-Op. +} + diff --git a/TAO/orbsvcs/examples/Notify/Subscribe/Subscribe.h b/TAO/orbsvcs/examples/Notify/Subscribe/Subscribe.h new file mode 100644 index 00000000000..126b842a4ca --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Subscribe/Subscribe.h @@ -0,0 +1,246 @@ +/* -*- C++ -*- */ +// $Id$ +// ========================================================================== +// +// = FILENAME +// Subscribe.h +// +// = DESCRIPTION +// Class to demo structured event subscription. +// +// = AUTHOR +// Pradeep Gore <pradeep@cs.wustl.edu> +// +// ========================================================================== + +#ifndef NOTIFY_SUBSCRIBE_CLIENT_H +#define NOTIFY_SUBSCRIBE_CLIENT_H + +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "orbsvcs/CosNamingC.h" + +class Subscribe_StructuredPushConsumer; +class Subscribe_StructuredPushSupplier; + +class Subscribe +{ + // = TITLE + // Subscribe + // = DESCRIPTION + // Shows how consumers subscribe for events. + + public: + // = Initialization and Termination + Subscribe (void); + ~Subscribe (); + + void init (int argc, char *argv [] ACE_ENV_ARG_DECL); + // Init the Client. + + void run (ACE_ENV_SINGLE_ARG_DECL); + // Run the demo. + + void done (void); + // Called when all events we are waiting for have occured. + + protected: + void init_ORB (int argc, char *argv [] ACE_ENV_ARG_DECL); + // Initializes the ORB. + + void resolve_naming_service (ACE_ENV_SINGLE_ARG_DECL); + // Try to get hold of a running naming service. + + void resolve_Notify_factory (ACE_ENV_SINGLE_ARG_DECL); + // Try to resolve the Notify factory from the Naming service. + + void create_EC (ACE_ENV_SINGLE_ARG_DECL); + // Create an EC. + + void create_supplieradmin(ACE_ENV_SINGLE_ARG_DECL); + // Create the Supplier Admin. + + void create_consumeradmin (ACE_ENV_SINGLE_ARG_DECL); + // Create the Consumer Admin. + + void create_consumers (ACE_ENV_SINGLE_ARG_DECL); + // Create and initialize the consumers. + + void create_suppliers (ACE_ENV_SINGLE_ARG_DECL); + // create and initialize the suppliers. + + void send_events (ACE_ENV_SINGLE_ARG_DECL); + // send the events. + + // = Data Members + PortableServer::POA_var root_poa_; + // Reference to the root poa. + + CORBA::ORB_var orb_; + // The ORB that we use. + + CosNaming::NamingContext_var naming_context_; + // Handle to the name service. + + CosNotifyChannelAdmin::EventChannelFactory_var notify_factory_; + // Channel factory. + + CosNotifyChannelAdmin::EventChannel_var ec_; + // The one channel that we create using the factory. + + CosNotifyChannelAdmin::InterFilterGroupOperator ifgop_; + // The group operator between admin-proxy's. + + CosNotification::QoSProperties initial_qos_; + // Initial qos specified to the factory when creating the EC. + + CosNotification::AdminProperties initial_admin_; + // Initial admin props specified to the factory when creating the EC. + + CosNotifyChannelAdmin::ConsumerAdmin_var consumer_admin_; + // The consumer admin used by consumers. + + CosNotifyChannelAdmin::SupplierAdmin_var supplier_admin_; + // The supplier admin used by suppliers. + + Subscribe_StructuredPushConsumer* consumer_1_; + Subscribe_StructuredPushConsumer* consumer_2_; + + Subscribe_StructuredPushSupplier* supplier_1_; + Subscribe_StructuredPushSupplier* supplier_2_; + + CORBA::Boolean done_; + // Set this flag to exit the run loop. +}; + +/*****************************************************************/ +class Subscribe_StructuredPushConsumer + : public POA_CosNotifyComm::StructuredPushConsumer +{ + // = TITLE + // Subscribe_StructuredPushConsumer + // + // = DESCRIPTION + // Consumer for the Subscribe example. + // + + public: + // = Initialization and Termination code + Subscribe_StructuredPushConsumer (Subscribe* subscribe); + // Constructor. + + void connect (CosNotifyChannelAdmin::ConsumerAdmin_ptr consumer_admin ACE_ENV_ARG_DECL); + // Connect the Consumer to the EventChannel. + // Creates a new proxy supplier and connects to it. + + virtual void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the supplier. + + CosNotifyChannelAdmin::StructuredProxyPushSupplier_ptr get_proxy_supplier (void); + // Accessor for the Proxy that we're connected to. + +protected: + // = Data members + CosNotifyChannelAdmin::StructuredProxyPushSupplier_var proxy_supplier_; + // The proxy that we are connected to. + + CosNotifyChannelAdmin::ProxyID proxy_supplier_id_; + // The proxy_supplier id. + + Subscribe* subscribe_; + // callback <done> + + // = Methods + virtual ~Subscribe_StructuredPushConsumer (void); + // Destructor + + // = NotifyPublish method + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )); + + // = StructuredPushSupplier methods + virtual void push_structured_event ( + const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )); + + virtual void disconnect_structured_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); +}; + +/*****************************************************************/ + +class Subscribe_StructuredPushSupplier + : public POA_CosNotifyComm::StructuredPushSupplier +{ + // = TITLE + // Subscribe_StructuredPushSupplier + // + // = DESCRIPTION + // Supplier for the SUBSCRIBE example. + // + public: + // = Initialization and Termination code + Subscribe_StructuredPushSupplier (void); + // Constructor. + + void connect (CosNotifyChannelAdmin::SupplierAdmin_ptr supplier_admin + ACE_ENV_ARG_DECL); + // Connect the Supplier to the EventChannel. + // Creates a new proxy consumer and connects to it. + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the supplier. + + virtual void send_event (const CosNotification::StructuredEvent& event + ACE_ENV_ARG_DECL); + // Send one event. + +protected: + // = Data members + CosNotifyChannelAdmin::StructuredProxyPushConsumer_var proxy_consumer_; + // The proxy that we are connected to. + + CosNotifyChannelAdmin::ProxyID proxy_consumer_id_; + // This supplier's id. + + // = Protected Methods + virtual ~Subscribe_StructuredPushSupplier (); + // Destructor + + // = NotifySubscribe + virtual void subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )); + + // = StructuredPushSupplier method + virtual void disconnect_structured_push_supplier ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); +}; + +#endif /* NOTIFY_SUBSCRIBE_CLIENT_H */ diff --git a/TAO/orbsvcs/examples/Notify/Subscribe/main.cpp b/TAO/orbsvcs/examples/Notify/Subscribe/main.cpp new file mode 100644 index 00000000000..b817728c231 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Subscribe/main.cpp @@ -0,0 +1,35 @@ +// -*- C++ -*- +// $Id$ + +#include "Subscribe.h" + +int +main (int argc, char *argv []) +{ + Subscribe client; + + ACE_TRY_NEW_ENV + { + client.init (argc, argv + ACE_ENV_ARG_PARAMETER); //Init the Client + ACE_TRY_CHECK; + + client.run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::UserException, ue) + { + ACE_PRINT_EXCEPTION (ue, + "TLS_Client user error: "); + return 1; + } + ACE_CATCH (CORBA::SystemException, se) + { + ACE_PRINT_EXCEPTION (se, + "Filter system error: "); + return 1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Notify/Subscribe/run_test.pl b/TAO/orbsvcs/examples/Notify/Subscribe/run_test.pl new file mode 100755 index 00000000000..7b14c5cee62 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/Subscribe/run_test.pl @@ -0,0 +1,73 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "../../../../../bin"; +use PerlACE::Run_Test; + +$experiment_timeout = 60; +$startup_timeout = 60; + +$notify_ior = PerlACE::LocalFile ("notify.ior"); + +$naming_ior = PerlACE::LocalFile ("naming.ior"); + +$status = 0; + +$Naming = new PerlACE::Process ("../../../Naming_Service/Naming_Service", + "-o $naming_ior"); + +$Notification = new PerlACE::Process ("../../../Notify_Service/Notify_Service"); + +$Notify_Args = "-ORBInitRef NameService=file://$naming_ior -IORoutput $notify_ior "; + +$Subscribe = new PerlACE::Process ("Subscribe"); + +$Subscribe_Args = "-ORBInitRef NameService=file://$naming_ior"; + +unlink $naming_ior; +$Naming->Spawn (); + +if (PerlACE::waitforfile_timed ($naming_ior, $startup_timeout) == -1) { + print STDERR "ERROR: waiting for the naming service to start\n"; + $Naming->Kill (); + exit 1; +} + +unlink $notify_ior; +$Notification->Arguments ($Notify_Args); +$args = $Notification->Arguments (); +print STDERR "Running Notification with arguments: $args\n"; +$Notification->Spawn (); + +if (PerlACE::waitforfile_timed ($notify_ior, $startup_timeout) == -1) { + print STDERR "ERROR: waiting for the notify service to start\n"; + $Notification->Kill (); + $Naming->Kill (); + exit 1; +} + +$Subscribe->Arguments ($Subscribe_Args); +$args = $Subscribe->Arguments (); +print STDERR "Running Subscribe with arguments: $args\n"; +$status = $Subscribe->SpawnWaitKill ($experiment_timeout); + +if ($status != 0) + { + print STDERR "ERROR: Subscribe returned $status\n"; + $Subscribe->Kill (); + $Notification->Kill (); + $Naming->Kill (); + exit 1; + } + +$Notification->Kill (); +unlink $notify_ior; + +$Naming->Kill (); +unlink $naming_ior; + +exit $status; diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer.cpp b/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer.cpp new file mode 100644 index 00000000000..3f8b943dba2 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer.cpp @@ -0,0 +1,219 @@ +// $Id$ + +#include "Consumer.h" + +ACE_RCSID (Notify, + TAO_Notify_ThreadPool_Consumer, + "$Id$") + +#include "tao/debug.h" + +#include "ace/High_Res_Timer.h" +#include "ace/Stats.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" + +TAO_Notify_ThreadPool_Consumer::TAO_Notify_ThreadPool_Consumer (TAO_Notify_ORB_Objects& orb_objects) + : orb_objects_ (orb_objects) + , proxy_supplier_thread_count_ (0) + , max_events_ (10) + , events_received_count_ (0) + , t_first_ (0) + , t_last_ (0) +{ +} + +TAO_Notify_ThreadPool_Consumer::~TAO_Notify_ThreadPool_Consumer (void) +{ +} + +void +TAO_Notify_ThreadPool_Consumer::init (PortableServer::POA_var& poa, CosNotifyChannelAdmin::ConsumerAdmin_var& admin, + int proxy_supplier_thread_count, int max_events, long delay ACE_ENV_ARG_DECL) +{ + this->default_POA_ = poa; + this->admin_ = admin; + this->proxy_supplier_thread_count_ = proxy_supplier_thread_count; + this->max_events_ = max_events; + this->delay_ = ACE_Time_Value (delay, 0); + + ACE_DEBUG ((LM_DEBUG, "(%P, %t)Consumer Delay = %d, param = %d\n", delay_.sec (), delay)); + + this->connect (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +PortableServer::POA_ptr +TAO_Notify_ThreadPool_Consumer::_default_POA (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + return PortableServer::POA::_duplicate (this->default_POA_.in ()); +} + +void +TAO_Notify_ThreadPool_Consumer::run (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + // Nothing to do. +} + +void +TAO_Notify_ThreadPool_Consumer::connect (ACE_ENV_SINGLE_ARG_DECL) +{ + // Activate the consumer with the default_POA_ + CosNotifyComm::StructuredPushConsumer_var objref = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::ProxySupplier_var proxysupplier; + + if (this->proxy_supplier_thread_count_ != 0) + { + // Narrow to the extended interface. + NotifyExt::ConsumerAdmin_var admin_ext = NotifyExt::ConsumerAdmin::_narrow (this->admin_.in ()ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + NotifyExt::ThreadPoolParams tp_params = { NotifyExt::CLIENT_PROPAGATED, 0, + 0, this->proxy_supplier_thread_count_, 0, 0, 0, 0, 0 }; + + CosNotification::QoSProperties qos (1); + qos.length (1); + qos[0].name = CORBA::string_dup (NotifyExt::ThreadPool); + qos[0].value <<= tp_params; + + // Obtain the proxy. The QoS is applied to the POA in which the Proxy is hosted. + proxysupplier = admin_ext->obtain_notification_push_supplier_with_qos (CosNotifyChannelAdmin::STRUCTURED_EVENT + , proxy_supplier_id_, qos ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + proxysupplier = this->admin_->obtain_notification_push_supplier (CosNotifyChannelAdmin::STRUCTURED_EVENT + , proxy_supplier_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + + ACE_ASSERT (!CORBA::is_nil (proxysupplier.in ())); + + // narrow + this->proxy_supplier_ = + CosNotifyChannelAdmin::StructuredProxyPushSupplier::_narrow (proxysupplier.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxy_supplier_.in ())); + + this->proxy_supplier_->connect_structured_push_consumer (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Call subscription_change to inform the supplier that this consumer is available. + CosNotification::EventTypeSeq added (1); + CosNotification::EventTypeSeq removed; + + added.length (1); + added[0].domain_name = CORBA::string_dup ("TEST_DOMAIN"); + + /* We generate a unique Id for the consumer type so that the supplier can distinguish between the consumers.*/ + char type[BUFSIZ]; + ACE_OS::sprintf (type, "TEST_TYPE_%d", this->proxy_supplier_id_); + + added[0].type_name = CORBA::string_dup (type); + + this->proxy_supplier_->subscription_change (added, removed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_DEBUG ((LM_DEBUG, "(%P,%t) Created Consumer %d with %d threads at the ProxySupplier\n", proxy_supplier_id_, + this->proxy_supplier_thread_count_)); +} + +void +TAO_Notify_ThreadPool_Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + this->proxy_supplier_->disconnect_structured_push_supplier(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_Notify_ThreadPool_Consumer::offer_change (const CosNotification::EventTypeSeq & /*added*/, + const CosNotification::EventTypeSeq & /*removed*/ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )) +{ + // No-Op. +} + +void +TAO_Notify_ThreadPool_Consumer::push_structured_event (const CosNotification::StructuredEvent & /*notification*/ + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock_); + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, "(%P, %t) Consumer received event %d\n", + this->events_received_count_)); + + // Increment the received count. + ++this->events_received_count_; + + if (this->events_received_count_ == 1) + { + this->t_first_ = ACE_OS::gethrtime (); + } + else if (this->events_received_count_ == this->max_events_) + { + this->t_last_ = ACE_OS::gethrtime (); + + // Disconnect from the EC + this->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Deactivate this object. + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // We received the event, shutdown the ORB. + this->orb_objects_.orb_->shutdown (1); + } + + // Eat CPU: + ACE_OS::sleep (this->delay_); +} + +void +TAO_Notify_ThreadPool_Consumer::dump_throughput (void) +{ + ACE_UINT32 gsf = ACE_High_Res_Timer::global_scale_factor (); + + ACE_DEBUG ((LM_DEBUG, "(%P,%t) Consumer %d \n", proxy_supplier_id_)); + + ACE_Throughput_Stats::dump_throughput ("Total", gsf, + t_last_ - t_first_, + this->max_events_); +} + +void +TAO_Notify_ThreadPool_Consumer::deactivate (ACE_ENV_SINGLE_ARG_DECL) +{ + PortableServer::POA_var poa (this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER)); + ACE_CHECK; + + PortableServer::ObjectId_var id (poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER)); + ACE_CHECK; + + poa->deactivate_object (id.in() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_Notify_ThreadPool_Consumer::disconnect_structured_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); +} diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer.h b/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer.h new file mode 100644 index 00000000000..0af5b74d5fa --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer.h @@ -0,0 +1,138 @@ +/* -*- C++ -*- */ +/** + * @file Consumer.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_CONSUMER_H +#define TAO_Notify_CONSUMER_H + +#include /**/ "ace/pre.h" + +#include "ORB_Objects.h" +#include "tao/RTCORBA/RTCORBA.h" +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "ace/SString.h" +#include "ace/OS_NS_time.h" + +/** + * @class TAO_Notify_ThreadPool_Consumer + * + * @brief Consumer + * + */ + +class TAO_Notify_ThreadPool_Consumer + : public POA_CosNotifyComm::StructuredPushConsumer +{ +public: + /// Constuctor + TAO_Notify_ThreadPool_Consumer (TAO_Notify_ORB_Objects& orb_objects); + + /// Init + void init (PortableServer::POA_var& poa, CosNotifyChannelAdmin::ConsumerAdmin_var& admin, int proxy_supplier_thread_count, int max_events, long delay ACE_ENV_ARG_DECL); + + /// Run + void run (ACE_ENV_SINGLE_ARG_DECL_NOT_USED); + + /// Print the consumer throughput + void dump_throughput (void); + +protected: + // = Methods + /// Destructor + virtual ~TAO_Notify_ThreadPool_Consumer (void); + + /// Connect the Consumer to the EventChannel. + /// Creates a new proxy supplier and connects to it. + void connect (ACE_ENV_SINGLE_ARG_DECL); + + /// Disconnect the supplier. + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + + /// Deactivate. + void deactivate (ACE_ENV_SINGLE_ARG_DECL); + + // = ServantBase operations + virtual PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS); + + // = NotifyPublish method + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )); + + // = StructuredPushSupplier methods + virtual void push_structured_event ( + const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )); + + virtual void disconnect_structured_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + // = Data members + + /// Lock + TAO_SYNCH_MUTEX lock_; + + /// ORB Objects. + TAO_Notify_ORB_Objects orb_objects_; + + // POA. + PortableServer::POA_var default_POA_; + + /// The proxy that we are connected to. + CosNotifyChannelAdmin::StructuredProxyPushSupplier_var proxy_supplier_; + + /// The proxy_supplier id. + CosNotifyChannelAdmin::ProxyID proxy_supplier_id_; + + // The Consumer Admin + CosNotifyChannelAdmin::ConsumerAdmin_var admin_; + + /// The Type the Consumer should subscribe to. + ACE_CString event_type_; + + /// ProxySupplier thread count. + int proxy_supplier_thread_count_; + + /// Max events to receive + int max_events_; + + /// Count the number of events received. + int events_received_count_; + + /// Time when the first sample was received. + //ACE_UINT64 t_first_; + ACE_hrtime_t t_first_; + + /// Time when the last sample was received. + //ACE_UINT64 t_last_; + ACE_hrtime_t t_last_; + + /// Delay: Sec of wait in each push. + ACE_Time_Value delay_; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer_Client.cpp b/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer_Client.cpp new file mode 100644 index 00000000000..480dbb5005c --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer_Client.cpp @@ -0,0 +1,274 @@ +// $Id$ + +#include "Consumer_Client.h" +#include "Consumer.h" +#include "ORB_Run_Task.h" +#include "ace/Arg_Shifter.h" +#include "orbsvcs/NotifyExtC.h" +#include "orbsvcs/CosNamingC.h" +#include "tao/ORB_Core.h" +#include "ace/Sched_Params.h" +#include "ace/OS_NS_errno.h" + +ACE_RCSID (Notify, TAO_Notify_ThreadPool_Consumer_Client, "$Id$") + +TAO_Notify_ThreadPool_Consumer_Client::TAO_Notify_ThreadPool_Consumer_Client (TAO_Notify_ORB_Objects& orb_objects) + : orb_objects_ (orb_objects) + , consumer_ (0) + , proxy_supplier_thread_count_ (0) + , max_events_ (10) + , delay_ (0) +{ +} + +TAO_Notify_ThreadPool_Consumer_Client::~TAO_Notify_ThreadPool_Consumer_Client () +{ +} + +int +TAO_Notify_ThreadPool_Consumer_Client::parse_args (int argc, char *argv[]) +{ + ACE_Arg_Shifter arg_shifter (argc, argv); + + const ACE_TCHAR *current_arg = 0; + + while (arg_shifter.is_anything_left ()) + { + if ((current_arg = arg_shifter.get_the_parameter(ACE_TEXT("-ProxySupplier_ThreadPool")))) // Specify a threadpool. + { + this->proxy_supplier_thread_count_ = ACE_OS::atoi (arg_shifter.get_current ()); + + arg_shifter.consume_arg (); + } + else if ((current_arg = arg_shifter.get_the_parameter(ACE_TEXT("-MaxEvents")))) // Max Events + { + this->max_events_ = ACE_OS::atoi (arg_shifter.get_current ()); + + arg_shifter.consume_arg (); + } + else if ((current_arg = arg_shifter.get_the_parameter(ACE_TEXT("-Delay")))) // seconds wait in consumer per push. + { + this->delay_ = ACE_OS::atoi (current_arg); + + arg_shifter.consume_arg (); + } + else + { + arg_shifter.ignore_arg (); + } + } + + return 0; +} + +void +TAO_Notify_ThreadPool_Consumer_Client::_init (ACE_ENV_SINGLE_ARG_DECL) +{ + PortableServer::POAManager_var poa_manager = + this->orb_objects_.root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Resolve the Notification Factory. + CosNotifyChannelAdmin::EventChannelFactory_var ecf = this->orb_objects_.notify_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Find the EventChannel created by the supplier. + CosNotifyChannelAdmin::ChannelIDSeq_var channel_seq = ecf->get_all_channels (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::EventChannel_var ec; + + if (channel_seq->length() > 0) + { + ec = ecf->get_event_channel (channel_seq[0] ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + ACE_DEBUG ((LM_DEBUG, "No Event Channel active!\n")); + return; + } + + // Create a Consumer Admin + CosNotifyChannelAdmin::AdminID adminid = 0; + + CosNotifyChannelAdmin::ConsumerAdmin_var consumer_admin = + ec->new_for_consumers (CosNotifyChannelAdmin::AND_OP, adminid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (consumer_admin.in ())); + + PortableServer::POA_var rt_poa = this->create_rt_poa (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Create a Consumer + this->consumer_ = new TAO_Notify_ThreadPool_Consumer (this->orb_objects_); + + // Initialize it. + this->consumer_->init (rt_poa, consumer_admin, this->proxy_supplier_thread_count_, this->max_events_, this->delay_ ACE_ENV_ARG_PARAMETER); +} + +PortableServer::POA_ptr +TAO_Notify_ThreadPool_Consumer_Client::create_rt_poa (ACE_ENV_SINGLE_ARG_DECL) +{ + PortableServer::POA_var rt_poa; + + // Create an RT POA with a lane at the given priority. + CORBA::Policy_var priority_model_policy; + CORBA::Policy_var thread_pool_policy; + + CORBA::Policy_var activation_policy = + this->orb_objects_.root_poa_->create_implicit_activation_policy (PortableServer::IMPLICIT_ACTIVATION ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + // Create a priority model policy. + priority_model_policy = + this->orb_objects_.rt_orb_->create_priority_model_policy (RTCORBA::CLIENT_PROPAGATED + , 0 + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + CORBA::ULong stacksize = 0; + CORBA::ULong static_threads = 1; + CORBA::ULong dynamic_threads = 0; + RTCORBA::Priority default_priority = 0; + CORBA::Boolean allow_request_buffering = 0; + CORBA::ULong max_buffered_requests = 0; + CORBA::ULong max_request_buffer_size = 0; + + // Create the thread-pool. + RTCORBA::ThreadpoolId threadpool_id = + this->orb_objects_.rt_orb_->create_threadpool (stacksize, + static_threads, + dynamic_threads, + default_priority, + allow_request_buffering, + max_buffered_requests, + max_request_buffer_size + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + thread_pool_policy = + this->orb_objects_.rt_orb_->create_threadpool_policy (threadpool_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + CORBA::PolicyList poa_policy_list; + + poa_policy_list.length (3); + poa_policy_list[0] = priority_model_policy; + poa_policy_list[1] = activation_policy; + poa_policy_list[2] = thread_pool_policy; + + PortableServer::POAManager_var poa_manager = + this->orb_objects_.root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + rt_poa = this->orb_objects_.root_poa_->create_POA ("RT POA!", + poa_manager.in (), + poa_policy_list + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (rt_poa._retn ()); + + return rt_poa._retn (); +} + +void +TAO_Notify_ThreadPool_Consumer_Client::run (ACE_ENV_SINGLE_ARG_DECL) +{ + this->consumer_->run (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +TAO_Notify_ThreadPool_Consumer_Client::dump_stats (void) +{ + this->consumer_->dump_throughput (); +} + +int +TAO_Notify_ThreadPool_Consumer_Client::svc (void) +{ + ACE_TRY_NEW_ENV + { + // Initialize this threads priority. + this->orb_objects_.current_->the_priority (0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->_init (ACE_ENV_SINGLE_ARG_PARAMETER); //Init the Client + ACE_TRY_CHECK; + + this->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, + ACE_TEXT ("Supplier error ")); + + } + ACE_ENDTRY; + + return 0; +} + +int +main (int argc, char *argv []) +{ + ACE_TRY_NEW_ENV + { + // Initialize an ORB + CORBA::ORB_var orb = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + TAO_Notify_ORB_Objects orb_objects; + + orb_objects.init (orb ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + TAO_Notify_ORB_Run_Task orb_run_task (orb_objects); + + TAO_Notify_ThreadPool_Consumer_Client client (orb_objects); + + if (client.parse_args (argc, argv) != 0) + { + ACE_DEBUG ((LM_DEBUG, "Consumer_Client::Error parsing options\n")); + return -1; + } + + long flags = THR_NEW_LWP | THR_JOINABLE; + + flags |= + orb->orb_core ()->orb_params ()->thread_creation_flags (); + + + if (orb_run_task.activate (flags) == -1 || client.activate (flags) == -1) + { + if (ACE_OS::last_error () == EPERM) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Insufficient privilege to activate ACE_Task.\n")), + -1); + else + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%t) Task activation at priority %d failed. \n"))); + } + + orb_run_task.thr_mgr ()->wait (); + client.thr_mgr ()->wait (); + + client.dump_stats (); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, + ACE_TEXT ("Consumer Client error ")); + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer_Client.h b/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer_Client.h new file mode 100644 index 00000000000..158c1005daa --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/Consumer_Client.h @@ -0,0 +1,83 @@ +/* -*- C++ -*- */ +/** + * @file Consumer_Client.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_CONSUMER_CLIENT_H +#define TAO_Notify_CONSUMER_CLIENT_H + +#include /**/ "ace/pre.h" +#include "ace/Task.h" +#include "ace/SString.h" + +/// @@Pradeep, pragma please... + +#include "ORB_Objects.h" +#include "tao/RTCORBA/RTCORBA.h" + +class TAO_Notify_ThreadPool_Consumer; + +/** + * @class TAO_Notify_ThreadPool_Consumer_Client + * + * @brief + * + */ +class TAO_Notify_ThreadPool_Consumer_Client : public ACE_Task_Base +{ +public: + /// Constuctor + TAO_Notify_ThreadPool_Consumer_Client (TAO_Notify_ORB_Objects& orb_objects); + + /// Destructor + ~TAO_Notify_ThreadPool_Consumer_Client (); + + /// Init + void _init (ACE_ENV_SINGLE_ARG_DECL); + + /// Run + void run (ACE_ENV_SINGLE_ARG_DECL); + + /// Parse Args + int parse_args (int argc, char *argv[]); + + /// The thread entry point. + virtual int svc (void); + + /// Dump stats. + void dump_stats (void); + +protected: + /// Create an RT POA with a single threadpool. + PortableServer::POA_ptr create_rt_poa (ACE_ENV_SINGLE_ARG_DECL); + + /// ORB Objects. + TAO_Notify_ORB_Objects orb_objects_; + + /// Lock to serialize internal state. + TAO_SYNCH_MUTEX lock_; + + /// Count how many consumers are done + int consumer_done_count_; + + /// The Consumer. + TAO_Notify_ThreadPool_Consumer* consumer_; + + /// ProxySuppler Thread count. + int proxy_supplier_thread_count_; + + /// Max events that we expect to receive. + int max_events_; + + /// Delay in ms + long delay_; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_CONSUMER_CLIENT_H */ diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/Makefile.am b/TAO/orbsvcs/examples/Notify/ThreadPool/Makefile.am new file mode 100644 index 00000000000..130c85fa5b5 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/Makefile.am @@ -0,0 +1,140 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Notify_ThreadPool_Consumer.am + +if BUILD_CORBA_MESSAGING +if BUILD_RT_CORBA +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Consumer + +Consumer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(TAO_ROOT)/orbsvcs/tests/Notify/lib \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Consumer_SOURCES = \ + Consumer.cpp \ + Consumer_Client.cpp \ + ORB_Objects.cpp \ + ORB_Run_Task.cpp \ + Consumer.h \ + Consumer_Client.h \ + ORB_Objects.h \ + ORB_Run_Task.h + +Consumer_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_RTPortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/tests/Notify/lib/libTAO_NotifyTests.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Serv.la \ + $(TAO_BUILDDIR)/tao/libTAO_IFR_Client.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicInterface.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RT_Notification.la \ + $(TAO_BUILDDIR)/tao/libTAO_RTCORBA.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Serv.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicAny.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_ETCL.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif BUILD_RT_CORBA +endif BUILD_CORBA_MESSAGING + +## Makefile.Notify_ThreadPool_Supplier.am + +if BUILD_CORBA_MESSAGING +if BUILD_RT_CORBA +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += Supplier + +Supplier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(TAO_ROOT)/orbsvcs/tests/Notify/lib \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +Supplier_SOURCES = \ + ORB_Objects.cpp \ + ORB_Run_Task.cpp \ + Supplier.cpp \ + Supplier_Client.cpp \ + ORB_Objects.h \ + ORB_Run_Task.h \ + Supplier.h \ + Supplier_Client.h + +Supplier_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_RTPortableServer.la \ + $(TAO_BUILDDIR)/orbsvcs/tests/Notify/lib/libTAO_NotifyTests.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Serv.la \ + $(TAO_BUILDDIR)/tao/libTAO_IFR_Client.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicInterface.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RT_Notification.la \ + $(TAO_BUILDDIR)/tao/libTAO_RTCORBA.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Serv.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicAny.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_ETCL.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNotification.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif BUILD_RT_CORBA +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/Notify_ThreadPool.mpc b/TAO/orbsvcs/examples/Notify/ThreadPool/Notify_ThreadPool.mpc new file mode 100644 index 00000000000..ed469821a28 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/Notify_ThreadPool.mpc @@ -0,0 +1,20 @@ +// $Id$ +project(*Supplier): rtnotify, notifytest, rtportableserver, minimum_corba { + exename = Supplier + Source_Files { + Supplier.cpp + Supplier_Client.cpp + ORB_Objects.cpp + ORB_Run_Task.cpp + } +} + +project(*Consumer): rtnotify, notifytest, rtportableserver, minimum_corba { + exename = Consumer + Source_Files { + Consumer.cpp + Consumer_Client.cpp + ORB_Objects.cpp + ORB_Run_Task.cpp + } +} diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Objects.cpp b/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Objects.cpp new file mode 100644 index 00000000000..b26b9dbb0ec --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Objects.cpp @@ -0,0 +1,71 @@ +// $Id$ + +#include "ORB_Objects.h" + +ACE_RCSID (Notify, TAO_Notify_ORB_Objects, "$Id$") + +TAO_Notify_ORB_Objects::TAO_Notify_ORB_Objects (void) +{ +} + +void +TAO_Notify_ORB_Objects::init (CORBA::ORB_var& orb ACE_ENV_ARG_DECL) +{ + this->orb_ = orb; + + CORBA::Object_var object = this->orb_->resolve_initial_references("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->root_poa_ = PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Resolve the RTORB. + object = this->orb_->resolve_initial_references ("RTORB" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->rt_orb_ = RTCORBA::RTORB::_narrow (object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Resolve the Current + object = this->orb_->resolve_initial_references ("RTCurrent" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->current_ = RTCORBA::Current::_narrow (object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Resolve the Naming service + object = this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->naming_ = CosNaming::NamingContextExt::_narrow (object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +TAO_Notify_ORB_Objects::~TAO_Notify_ORB_Objects () +{ +} + +CosNotifyChannelAdmin::EventChannelFactory_ptr +TAO_Notify_ORB_Objects::notify_factory (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyChannelAdmin::EventChannelFactory_var ecf; + + // Look for the Notification Service + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup ("NotifyEventChannelFactory"); + + CORBA::Object_var object = this->naming_->resolve (name ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ecf._retn ()); + + ecf = CosNotifyChannelAdmin::EventChannelFactory::_narrow (object.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ecf._retn ()); + + return ecf._retn (); +} diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Objects.h b/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Objects.h new file mode 100644 index 00000000000..7ca6ab99442 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Objects.h @@ -0,0 +1,55 @@ +/* -*- C++ -*- */ +/** + * @file ORB_Objects.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_ORB_OBJECTS_H +#define TAO_Notify_ORB_OBJECTS_H +#include /**/ "ace/pre.h" + +#include "tao/RTCORBA/RTCORBA.h" +#include "tao/PortableServer/PortableServer.h" +#include "orbsvcs/NotifyExtC.h" +#include "orbsvcs/CosNamingC.h" + +/** + * @class TAO_Notify_ORB_Objects + * + * @brief Handy Objects that we keep asking the ORB for. + * + */ +class TAO_Notify_ORB_Objects +{ +public: + /// Constuctor + TAO_Notify_ORB_Objects (void); + + /// Destructor + ~TAO_Notify_ORB_Objects (); + + /// Resolves all the references. + void init (CORBA::ORB_var& orb ACE_ENV_ARG_DECL); + + /// Resolve Notification + CosNotifyChannelAdmin::EventChannelFactory_ptr notify_factory (ACE_ENV_SINGLE_ARG_DECL); + + ///= Public Data + CORBA::ORB_var orb_; + + PortableServer::POA_var root_poa_; + + RTCORBA::RTORB_var rt_orb_; + + RTCORBA::Current_var current_; + + CosNaming::NamingContextExt_var naming_; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_ORB_OBJECTS_H */ diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Run_Task.cpp b/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Run_Task.cpp new file mode 100644 index 00000000000..953328f78c5 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Run_Task.cpp @@ -0,0 +1,33 @@ +// $Id$ + +#include "ORB_Run_Task.h" + +ACE_RCSID (Notify, TAO_Notify_ORB_Run_Task, "$Id$") + +TAO_Notify_ORB_Run_Task::TAO_Notify_ORB_Run_Task (TAO_Notify_ORB_Objects& orb_objects) + : orb_objects_ (orb_objects) +{ +} + +TAO_Notify_ORB_Run_Task::~TAO_Notify_ORB_Run_Task () +{ +} + +int +TAO_Notify_ORB_Run_Task::svc (void) +{ + ACE_TRY_NEW_ENV + { + this->orb_objects_.current_->the_priority (0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->orb_objects_.orb_->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Run_Task.h b/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Run_Task.h new file mode 100644 index 00000000000..83fd657406b --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/ORB_Run_Task.h @@ -0,0 +1,44 @@ +/* -*- C++ -*- */ +/** + * @file ORB_Run_Task.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_ORB_RUN_TASK_H +#define TAO_Notify_ORB_RUN_TASK_H + +#include /**/ "ace/pre.h" +#include "ace/Task.h" + +#include "ORB_Objects.h" + +/** + * @class TAO_Notify_ORB_Run_Task + * + * @brief Run the ORB::run method in a seperate thread. + * + */ +class TAO_Notify_ORB_Run_Task : public ACE_Task_Base +{ +public: + /// Constuctor + TAO_Notify_ORB_Run_Task (TAO_Notify_ORB_Objects& orb_objects); + + /// Destructor + ~TAO_Notify_ORB_Run_Task (); + + /// The thread entry point. + virtual int svc (void); + +private: + /// ORB Objects. + TAO_Notify_ORB_Objects orb_objects_; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_ORB_RUN_TASK_H */ diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/README b/TAO/orbsvcs/examples/Notify/ThreadPool/README new file mode 100644 index 00000000000..f02bd65b73c --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/README @@ -0,0 +1,57 @@ + +ThreadPool example for RT-Notification +====================================== + +This example has 1 Supplier and 2 Consumers. + +The supplier sends an different event to each of the consumers in a +supplier thread continuously. + +One of the consumers has 1 second delay in its push method. +let us call it the "slow" consumer and the other consumer - the "fast" consumer. + +If no threadpools are used then the throughput of both consumers is ~1 +event per second. + +We deploy a threadpool at each proxysupplier. +This causes each consumer to have a seperate data path. + +Hence the fast consumer finishes first without any interference from +the slow consumer. + +Command Line Options +==================== + +Supplier: +-------- + +-Consumers count + +-Event_Channel_ThreradPool static_threads + +-ProxyConsumer_ThreadPool static_threads + +-IORoutput ior_file + +-MaxEvents count + + +Consumer: +-------- + +-ProxySupplier_ThreadPool static_threads + +-MaxEvents count + +-Delay seconds + +Running the example +=================== + +Simply run the run_test.pl file. + +The run_test.pl file has options that can be modified to run the +example with threadpools deployed at different points. + + + diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier.cpp b/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier.cpp new file mode 100644 index 00000000000..bb29cbd1af7 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier.cpp @@ -0,0 +1,194 @@ +// $Id$ + +#include "Supplier.h" + +ACE_RCSID (Notify, TAO_Notify_ThreadPool_Supplier, "$Id$") + +#include "tao/ORB_Core.h" + +TAO_Notify_ThreadPool_Supplier::TAO_Notify_ThreadPool_Supplier (TAO_Notify_ORB_Objects& orb_objects) + : orb_objects_ (orb_objects) + , proxy_consumer_id_ (0) + , expected_consumer_count_ (2) + , consumers_connected_ (lock_) + , consumer_count_ (0) + , max_events_ (10) + , proxy_consumer_thread_count_ (0) +{ +} + +TAO_Notify_ThreadPool_Supplier::~TAO_Notify_ThreadPool_Supplier () +{ +} + +void +TAO_Notify_ThreadPool_Supplier::init (CosNotifyChannelAdmin::SupplierAdmin_var& admin, int expected_consumer_count ,int max_events, + int proxy_consumer_thread_count ACE_ENV_ARG_DECL) +{ + // First initialize the class members. + this->admin_ = admin; + this->expected_consumer_count_ = expected_consumer_count; + this->max_events_ = max_events; + this->proxy_consumer_thread_count_ = proxy_consumer_thread_count; + + this->connect (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +TAO_Notify_ThreadPool_Supplier::run (ACE_ENV_SINGLE_ARG_DECL) +{ + { + ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_); + + ACE_DEBUG ((LM_DEBUG, "(%P, %t) Waiting for %d consumers to connect...\n", this->expected_consumer_count_-1)); + + // Wait till the consumers are ready to go. + while (this->consumer_count_ != this->expected_consumer_count_) + this->consumers_connected_.wait (); + } + + ACE_DEBUG ((LM_DEBUG, + "(%P, %t) Supplier is sending an events...\n")); + + // Send events to each consumer. + for (int i = 0; i < this->max_events_; ++i) + { + for (int j = 0; j < this->expected_consumer_count_; ++j) + { + // send the event + this->send_event (this->event_[j] ACE_ENV_ARG_PARAMETER); + } + } + + // Disconnect from the EC + this->disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + + // Deactivate this object. + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); + + // we're done. shutdown the ORB to exit the process. + this->orb_objects_.orb_->shutdown (1); +} + +void +TAO_Notify_ThreadPool_Supplier::connect (ACE_ENV_SINGLE_ARG_DECL) +{ + // Activate the supplier object. + CosNotifyComm::StructuredPushSupplier_var objref = this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::ProxyConsumer_var proxyconsumer; + + if (this->proxy_consumer_thread_count_ != 0) + { + // Narrow to the extended interface. + NotifyExt::SupplierAdmin_var admin_ext = NotifyExt::SupplierAdmin::_narrow (this->admin_.in ()ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + NotifyExt::ThreadPoolParams tp_params = { NotifyExt::CLIENT_PROPAGATED, 0, + 0, this->proxy_consumer_thread_count_, 0, 0, 0, 0, 0 }; + + CosNotification::QoSProperties qos (1); + qos.length (1); + qos[0].name = CORBA::string_dup (NotifyExt::ThreadPool); + qos[0].value <<= tp_params; + + // Obtain the proxy. The QoS is applied to the POA in which the Proxy is hosted. + proxyconsumer = admin_ext->obtain_notification_push_consumer_with_qos (CosNotifyChannelAdmin::STRUCTURED_EVENT + , proxy_consumer_id_, qos ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + // Obtain the proxy. + proxyconsumer = this->admin_->obtain_notification_push_consumer (CosNotifyChannelAdmin::STRUCTURED_EVENT + , proxy_consumer_id_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + + ACE_ASSERT (!CORBA::is_nil (proxyconsumer.in ())); + + // narrow + this->proxy_consumer_ = + CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow (proxyconsumer.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (proxy_consumer_.in ())); + + // connect to the proxyconsumer. + proxy_consumer_->connect_structured_push_supplier (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_DEBUG ((LM_DEBUG, "(%P,%t) Created Supplier %d with %d threads at the ProxyConsumer\n", proxy_consumer_id_, + this->proxy_consumer_thread_count_)); +} + +void +TAO_Notify_ThreadPool_Supplier::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->proxy_consumer_.in ())); + + this->proxy_consumer_->disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +TAO_Notify_ThreadPool_Supplier::deactivate (ACE_ENV_SINGLE_ARG_DECL) +{ + PortableServer::POA_var poa (this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER)); + ACE_CHECK; + + PortableServer::ObjectId_var id (poa->servant_to_id (this + ACE_ENV_ARG_PARAMETER)); + ACE_CHECK; + + poa->deactivate_object (id.in() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_Notify_ThreadPool_Supplier::subscription_change (const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & /*removed */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_); + + // Count the number of consumers connect and signal the supplier thread when the expected count have connected. + // Only 1 consumer connects at a time. + if (added.length () > 0) + { + // Set the domain and type nams in the event's fixed header. + this->event_[consumer_count_].header.fixed_header.event_type.domain_name = CORBA::string_dup(added[0].domain_name); + this->event_[consumer_count_].header.fixed_header.event_type.type_name = CORBA::string_dup(added[0].type_name); + + ++this->consumer_count_; + + ACE_DEBUG ((LM_DEBUG, "(%P,%t) Received Type %d: (%s)\n", this->consumer_count_, added[0].type_name.in ())); + + if (this->consumer_count_ == this->expected_consumer_count_) + this->consumers_connected_.signal (); + } +} + +void +TAO_Notify_ThreadPool_Supplier::send_event (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL) +{ + ACE_ASSERT (!CORBA::is_nil (this->proxy_consumer_.in ())); + + proxy_consumer_->push_structured_event (event ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +TAO_Notify_ThreadPool_Supplier::disconnect_structured_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); +} diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier.h b/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier.h new file mode 100644 index 00000000000..e5238d0af7e --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier.h @@ -0,0 +1,121 @@ +/* -*- C++ -*- */ +/** + * @file Supplier.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_SUPPLIER_H +#define TAO_Notify_SUPPLIER_H +#include /**/ "ace/pre.h" + +#include "ORB_Objects.h" +#include "tao/RTCORBA/RTCORBA.h" +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "ace/Condition_Thread_Mutex.h" + +#define TEST_MAX_CONSUMERS 10 + +/** + * @class TAO_Notify_ThreadPool_Supplier + * + * @brief Implement a Structured Supplier. + * + */ +class TAO_Notify_ThreadPool_Supplier + : public POA_CosNotifyComm::StructuredPushSupplier +{ +public: + // = Initialization and Termination code + + /// Constructor. + TAO_Notify_ThreadPool_Supplier (TAO_Notify_ORB_Objects& orb_objects); + + /// Init + void init (CosNotifyChannelAdmin::SupplierAdmin_var& admin, int expected_consumer_count, int max_events, + int proxy_consumer_thread_count ACE_ENV_ARG_DECL); + + /// Run + void run (ACE_ENV_SINGLE_ARG_DECL); + +protected: + // = Protected Methods + + /// Connect the Supplier to the EventChannel. + /// Creates a new proxy consumer and connects to it. + void connect (ACE_ENV_SINGLE_ARG_DECL); + + /// Disconnect the supplier. + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + + /// Deactivate. + void deactivate (ACE_ENV_SINGLE_ARG_DECL); + + /// Send one event. + virtual void send_event (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL); + + /// Destructor + virtual ~TAO_Notify_ThreadPool_Supplier (); + + // = NotifySubscribe + virtual void subscription_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosNotifyComm::InvalidEventType + )); + + // = StructuredPushSupplier method + virtual void disconnect_structured_push_supplier (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + /// = Data members + + /// ORB Objects. + TAO_Notify_ORB_Objects orb_objects_; + + /// The proxy that we are connected to. + CosNotifyChannelAdmin::StructuredProxyPushConsumer_var proxy_consumer_; + + /// This supplier's id. + CosNotifyChannelAdmin::ProxyID proxy_consumer_id_; + + /// Number of Consumers expected to connect. + int expected_consumer_count_; + + // The ORB that we use. + CORBA::ORB_var orb_; + + // The Supplier Admin + CosNotifyChannelAdmin::SupplierAdmin_var admin_; + + /// Lock to serialize internal state. + TAO_SYNCH_MUTEX lock_; + + /// Condition that consumers are connected. + TAO_SYNCH_CONDITION consumers_connected_; + + /// Number of consumers connected. + int consumer_count_; + + /// Number of events to send. + int max_events_; + + /// Number of Threads at the ProxyConsumer. + int proxy_consumer_thread_count_; + + /// Array of events to send. + CosNotification::StructuredEvent event_[TEST_MAX_CONSUMERS]; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier_Client.cpp b/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier_Client.cpp new file mode 100644 index 00000000000..fb8dcf0c8ad --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier_Client.cpp @@ -0,0 +1,270 @@ +// $Id$ + +#include "Supplier_Client.h" + +#include "ORB_Run_Task.h" +#include "ace/Arg_Shifter.h" +#include "tao/ORB_Core.h" +#include "ace/Sched_Params.h" +#include "Supplier.h" +#include "orbsvcs/NotifyExtC.h" +#include "orbsvcs/CosNamingC.h" +#include "ace/OS_NS_errno.h" + +ACE_RCSID (Notify, TAO_Notify_ThreadPool_Supplier_Client, "$Id$") + +TAO_Notify_ThreadPool_Supplier_Client::TAO_Notify_ThreadPool_Supplier_Client (TAO_Notify_ORB_Objects& orb_objects) + : orb_objects_ (orb_objects) + , supplier_ (0) + , consumer_count_ (2) + , ec_thread_count_ (0) + , proxy_consumer_thread_count_ (0) + , max_events_ (10) +{ +} + +TAO_Notify_ThreadPool_Supplier_Client::~TAO_Notify_ThreadPool_Supplier_Client () +{ +} + +int +TAO_Notify_ThreadPool_Supplier_Client::parse_args (int argc, char *argv[]) +{ + ACE_Arg_Shifter arg_shifter (argc, argv); + + const ACE_TCHAR *current_arg = 0; + + while (arg_shifter.is_anything_left ()) + { + if ((current_arg = arg_shifter.get_the_parameter (ACE_TEXT("-Consumers")))) // Number of consumers that we need to send an event to. + { + if (current_arg != 0) + { + this->consumer_count_ = ACE_OS::atoi (current_arg); + } + + arg_shifter.consume_arg (); + } + else if ((current_arg = arg_shifter.get_the_parameter(ACE_TEXT("-EventChannel_ThreadPool")))) // Specify a threadpool. + { + this->ec_thread_count_ = ACE_OS::atoi (current_arg); + arg_shifter.consume_arg (); + } + else if ((current_arg = arg_shifter.get_the_parameter(ACE_TEXT("-ProxyConsumer_ThreadPool")))) // Specify a threadpool. + { + this->proxy_consumer_thread_count_= ACE_OS::atoi (current_arg); + arg_shifter.consume_arg (); + } + else if ((current_arg = arg_shifter.get_the_parameter (ACE_TEXT("-IORoutput")))) // The file to output the supplier ior to. + { + if (current_arg != 0) + { + this->ior_file_name_ = current_arg; + } + + arg_shifter.consume_arg (); + } + else if ((current_arg = arg_shifter.get_the_parameter(ACE_TEXT("-MaxEvents")))) // Max Events + { + this->max_events_ = ACE_OS::atoi (arg_shifter.get_current ()); + + arg_shifter.consume_arg (); + } + else + { + arg_shifter.ignore_arg (); + } + } + + return 0; +} + +void +TAO_Notify_ThreadPool_Supplier_Client::_init (ACE_ENV_SINGLE_ARG_DECL) +{ + PortableServer::POAManager_var poa_manager = + this->orb_objects_.root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CosNotifyChannelAdmin::EventChannel_var ec = this->create_ec (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Create a Supplier Admin + CosNotifyChannelAdmin::AdminID adminid = 0; + + CosNotifyChannelAdmin::SupplierAdmin_var supplier_admin = + ec->new_for_suppliers (CosNotifyChannelAdmin::AND_OP, adminid ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_ASSERT (!CORBA::is_nil (supplier_admin.in ())); + + // Create a Supplier + this->supplier_ = new TAO_Notify_ThreadPool_Supplier (this->orb_objects_); + + // Initialize it. + this->supplier_->init (supplier_admin, this->consumer_count_, this->max_events_, this->proxy_consumer_thread_count_ + ACE_ENV_ARG_PARAMETER); +} + +CosNotifyChannelAdmin::EventChannel_ptr +TAO_Notify_ThreadPool_Supplier_Client::create_ec (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyChannelAdmin::EventChannel_var ec; + + CosNotifyChannelAdmin::EventChannelFactory_var ecf = this->orb_objects_.notify_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (ec._retn ()); + + // Create an EventChannel + CosNotification::QoSProperties qos; + CosNotification::AdminProperties admin; + + // Create an event channel + CosNotifyChannelAdmin::ChannelID id; + + ec = ecf->create_channel (qos, + admin, + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ec._retn ()); + + // Set the Qos + // See $TAO_ROOT/orbsvcs/orbsvcs/NotifyExt.idl + if (this->ec_thread_count_) + { + NotifyExt::ThreadPoolParams tp_params = { NotifyExt::CLIENT_PROPAGATED, 0, + 0, this->ec_thread_count_, 0, 0, 0, 0, 0 }; + + CosNotification::QoSProperties qos (1); + qos.length (1); + qos[0].name = CORBA::string_dup (NotifyExt::ThreadPool); + qos[0].value <<= tp_params; + + // Note that instead of <set_qos>, the <qos> can also be passed while creating the channel. + ec->set_qos (qos ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ec._retn ()); + } + + ACE_DEBUG ((LM_DEBUG, "(%P,%t) Created Event Channel with %d threads\n", this->ec_thread_count_)); + + return ec._retn (); +} + +void +TAO_Notify_ThreadPool_Supplier_Client::run (ACE_ENV_SINGLE_ARG_DECL) +{ + /// First, signal that the supplier is ready. + this->write_ior (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->supplier_->run (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +TAO_Notify_ThreadPool_Supplier_Client::write_ior (ACE_ENV_SINGLE_ARG_DECL) +{ + CosNotifyComm::StructuredPushSupplier_var objref = this->supplier_->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Write the ior to a file to signal waiting consumers. + FILE *ior_output_file = ACE_OS::fopen (this->ior_file_name_.c_str (), ACE_TEXT("w")); + + if (ior_output_file != 0) + { + CORBA::String_var str = + this->orb_objects_.orb_->object_to_string (objref.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + ACE_OS::fprintf (ior_output_file, + "%s", + str.in ()); + ACE_OS::fclose (ior_output_file); + } +} + +int +TAO_Notify_ThreadPool_Supplier_Client::svc (void) +{ + ACE_TRY_NEW_ENV + { + this->orb_objects_.current_->the_priority (0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->_init (ACE_ENV_SINGLE_ARG_PARAMETER); //Init the Client + ACE_TRY_CHECK; + + this->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, + ACE_TEXT ("Supplier error ")); + + } + ACE_ENDTRY; + + return 0; +} + +int +main (int argc, char *argv []) +{ + ACE_TRY_NEW_ENV + { + // Initialize an ORB + CORBA::ORB_var orb = CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Create a holder for the common ORB Objects. + TAO_Notify_ORB_Objects orb_objects; + + orb_objects.init (orb ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + /* Run the ORB in a seperate thread */ + TAO_Notify_ORB_Run_Task orb_run_task (orb_objects); + + /* Create a Client */ + TAO_Notify_ThreadPool_Supplier_Client client (orb_objects); + + if (client.parse_args (argc, argv) != 0) + { + ACE_DEBUG ((LM_DEBUG, "Supplier_Client::Error parsing options\n")); + return -1; + } + + long flags = THR_NEW_LWP | THR_JOINABLE; + + flags |= + orb->orb_core ()->orb_params ()->thread_creation_flags (); + + /* Both the tasks initialize themselves at Priority 0*/ + if (orb_run_task.activate (flags) == -1 || client.activate (flags) == -1) + { + if (ACE_OS::last_error () == EPERM) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Insufficient privilege to activate ACE_Task.\n")), + -1); + else + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("(%t) Task activation at priority %d failed. \n"))); + } + + orb_run_task.thr_mgr ()->wait (); + client.thr_mgr ()->wait (); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, + ACE_TEXT ("Supplier Client error ")); + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier_Client.h b/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier_Client.h new file mode 100644 index 00000000000..b54786ea808 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/Supplier_Client.h @@ -0,0 +1,79 @@ +/* -*- C++ -*- */ +/** + * @file Supplier_Client.h + * + * $Id$ + * + * @author Pradeep Gore <pradeep@oomworks.com> + * + * + */ + +#ifndef TAO_Notify_SUPPLIER_CLIENT_H +#define TAO_Notify_SUPPLIER_CLIENT_H +#include /**/ "ace/pre.h" + +#include "ORB_Objects.h" +#include "ace/Task.h" +#include "ace/SString.h" + +class TAO_Notify_ThreadPool_Supplier; + +/** + * @class TAO_Notify_ThreadPool_Supplier_Client + * + * @brief Supplier Client + * + */ +class TAO_Notify_ThreadPool_Supplier_Client : public ACE_Task_Base +{ +public: + /// Constuctor + TAO_Notify_ThreadPool_Supplier_Client (TAO_Notify_ORB_Objects& orb_objects); + + /// Destructor + ~TAO_Notify_ThreadPool_Supplier_Client (); + + /// Init + void _init (ACE_ENV_SINGLE_ARG_DECL); + + /// Run + void run (ACE_ENV_SINGLE_ARG_DECL); + + /// Parse Args + int parse_args (int argc, char *argv[]); + + /// The thread entry point. + virtual int svc (void); + +protected: + /// Create an EC + CosNotifyChannelAdmin::EventChannel_ptr create_ec (ACE_ENV_SINGLE_ARG_DECL); + + /// Write ior to file. + void write_ior (ACE_ENV_SINGLE_ARG_DECL); + + /// ORB Objects. + TAO_Notify_ORB_Objects orb_objects_; + + /// Supplier that sends events. + TAO_Notify_ThreadPool_Supplier* supplier_; + + /// The Number of consumers that we expect to send an event to. + int consumer_count_; + + /// Name of the file to write the supplier ior to. + ACE_CString ior_file_name_; + + /// Number of threads at the EC + int ec_thread_count_; + + /// Number of Therads at the ProxyConsumer. + int proxy_consumer_thread_count_; + + // Max events to send. + int max_events_; +}; + +#include /**/ "ace/post.h" +#endif /* TAO_Notify_SUPPLIER_CLIENT_H */ diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/client.conf b/TAO/orbsvcs/examples/Notify/ThreadPool/client.conf new file mode 100644 index 00000000000..52878238bc7 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/client.conf @@ -0,0 +1 @@ +static RT_ORB_Loader "-ORBSchedPolicy SCHED_FIFO -ORBScopePolicy SYSTEM -ORBPriorityMapping continuous"
\ No newline at end of file diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/notify.conf b/TAO/orbsvcs/examples/Notify/ThreadPool/notify.conf new file mode 100644 index 00000000000..80a46e01105 --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/notify.conf @@ -0,0 +1,3 @@ +dynamic TAO_RT_ORB_Loader Service_Object *TAO_RTCORBA:_make_TAO_RT_ORB_Loader () "-ORBSchedPolicy SCHED_FIFO -ORBScopePolicy SYSTEM -ORBPriorityMapping continuous" +##dynamic TAO_Notify_Factory Service_Object * TAO_CosNotification_Serv:_make_TAO_Notify_Default_Factory () "" +dynamic TAO_Notify_Service Service_Object * TAO_RT_Notification:_make_TAO_RT_Notify_Service () "" diff --git a/TAO/orbsvcs/examples/Notify/ThreadPool/run_test.pl b/TAO/orbsvcs/examples/Notify/ThreadPool/run_test.pl new file mode 100755 index 00000000000..26f20dccf8d --- /dev/null +++ b/TAO/orbsvcs/examples/Notify/ThreadPool/run_test.pl @@ -0,0 +1,131 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "../../../../../bin"; +use PerlACE::Run_Test; + +# ThreadPool Example +# + +$experiment_timeout = 60; +$startup_timeout = 60; +$max_events = 10; +$ec_tp = 0; +$pc_tp = 0; +$ps1_tp = 1; +$ps2_tp = 1; +$debug = 0; + +$notify_conf = PerlACE::LocalFile ("notify.conf"); +$notify_ior = PerlACE::LocalFile ("notify.ior"); + +$naming_ior = PerlACE::LocalFile ("naming.ior"); + +$supplier_ior = PerlACE::LocalFile ("supplier.ior"); + +$supplier_conf = PerlACE::LocalFile ("client.conf"); + +$consumer_conf = PerlACE::LocalFile ("client.conf"); + +$consumer2_conf = PerlACE::LocalFile ("client.conf"); + +$status = 0; + +$Naming = new PerlACE::Process ("../../../Naming_Service/Naming_Service", + "-o $naming_ior"); + +$Notification = new PerlACE::Process ("../../../Notify_Service/Notify_Service"); + +$Notify_Args = "-ORBInitRef NameService=file://$naming_ior -IORoutput $notify_ior -ORBSvcConf $notify_conf -ORBDebugLevel $debug"; + +$Supplier = new PerlACE::Process ("Supplier"); + +$Supplier_Args = "-ORBInitRef NameService=file://$naming_ior -ORBSvcConf $supplier_conf -IORoutput $supplier_ior -Consumers 2 -EventChannel_ThreadPool $ec_tp -MaxEvents $max_events -ProxyConsumer_ThreadPool $pc_tp -ORBDebugLevel $debug"; + +$Consumer = new PerlACE::Process ("Consumer"); + +$Consumer_Args = "-ORBInitRef NameService=file://$naming_ior -ORBSvcConf $consumer_conf -MaxEvents $max_events -Delay 1 -ProxySupplier_ThreadPool $ps1_tp -ORBDebugLevel $debug"; + +$Consumer2 = new PerlACE::Process ("Consumer"); + +$Consumer2_Args = "-ORBInitRef NameService=file://$naming_ior -ORBSvcConf $consumer2_conf -MaxEvents $max_events -ProxySupplier_ThreadPool $ps2_tp -ORBDebugLevel $debug"; + +unlink $naming_ior; +$Naming->Spawn (); + +if (PerlACE::waitforfile_timed ($naming_ior, $startup_timeout) == -1) { + print STDERR "ERROR: waiting for the naming service to start\n"; + $Naming->Kill (); + exit 1; +} + +unlink $notify_ior; +$Notification->Arguments ($Notify_Args); +$args = $Notification->Arguments (); +print STDERR "Running Notification with arguments: $args\n"; +$Notification->Spawn (); + +if (PerlACE::waitforfile_timed ($notify_ior, $startup_timeout) == -1) { + print STDERR "ERROR: waiting for the notify service to start\n"; + $Notification->Kill (); + $Naming->Kill (); + exit 1; +} + +unlink $supplier_ior; +$Supplier->Arguments ($Supplier_Args); +$args = $Supplier->Arguments (); +print STDERR "Running Supplier with arguments: $args\n"; +$Supplier->Spawn (); + +if (PerlACE::waitforfile_timed ($supplier_ior, $startup_timeout) == -1) { + print STDERR "ERROR: waiting for the supplier to start\n"; + $Notification->Kill (); + $Naming->Kill (); + exit 1; +} + +$Consumer->Arguments ($Consumer_Args); +$args = $Consumer->Arguments (); +print STDERR "Running Consumer with arguments: $args\n"; +$status = $Consumer->Spawn (); + +if ($status != 0) + { + print STDERR "ERROR: Consumer returned $status\n"; + $Supplier->Kill (); + $Notification->Kill (); + $Naming->Kill (); + exit 1; + } + +$Consumer2->Arguments ($Consumer2_Args); +$args = $Consumer2->Arguments (); +print STDERR "Running Consumer2 with arguments: $args\n"; +$status = $Consumer2->SpawnWaitKill ($experiment_timeout); + +if ($status != 0) + { + print STDERR "ERROR: Consumer2 returned $status\n"; + $Supplier->Kill (); + $Notification->Kill (); + $Naming->Kill (); + exit 1; + } + +$Consumer->Wait (); +$Supplier->Wait (); + +unlink $supplier_ior; + +$Notification->Kill (); +unlink $notify_ior; + +$Naming->Kill (); +unlink $naming_ior; + +exit $status; diff --git a/TAO/orbsvcs/examples/ORT/Gateway.idl b/TAO/orbsvcs/examples/ORT/Gateway.idl new file mode 100644 index 00000000000..7f97783707c --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Gateway.idl @@ -0,0 +1,16 @@ +// $Id$ + +#ifndef GATEWAY_IDL +#define GATEWAY_IDL + +module Gateway +{ + interface Object_Factory + { + Object create_object (in string interface_repository_id, + in Object gatewayed_object); + }; + +}; + +#endif /* GATEWAY_IDL */ diff --git a/TAO/orbsvcs/examples/ORT/Gateway_ObjRef_Factory.cpp b/TAO/orbsvcs/examples/ORT/Gateway_ObjRef_Factory.cpp new file mode 100644 index 00000000000..ecc1d6e1055 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Gateway_ObjRef_Factory.cpp @@ -0,0 +1,35 @@ +// $Id$ + +#include "Gateway_ObjRef_Factory.h" + +Gateway_ObjRef_Factory:: +Gateway_ObjRef_Factory ( + Gateway::Object_Factory_ptr gateway_object_factory, + PortableInterceptor::ObjectReferenceFactory *old_factory) + : gateway_object_factory_ (gateway_object_factory), + old_factory_ (old_factory) +{ + CORBA::add_ref (old_factory); +} + +CORBA::Object_ptr +Gateway_ObjRef_Factory:: +make_object (const char *interface_repository_id, + const PortableInterceptor::ObjectId & id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CORBA::Object_var object = + this->old_factory_->make_object (interface_repository_id, + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + CORBA::Object_ptr object_ptr = + this->gateway_object_factory_->create_object (interface_repository_id, + object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + return object_ptr; +} diff --git a/TAO/orbsvcs/examples/ORT/Gateway_ObjRef_Factory.h b/TAO/orbsvcs/examples/ORT/Gateway_ObjRef_Factory.h new file mode 100644 index 00000000000..3af0da985b3 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Gateway_ObjRef_Factory.h @@ -0,0 +1,40 @@ +// -*- C++ -*- +// +// $Id$ + +#ifndef GATEWAY_OBJREF_FACTORY_H +#define GATEWAY_OBJREF_FACTORY_H + +#include "ObjectReferenceFactoryC.h" +#include "GatewayC.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +class Gateway_ObjRef_Factory + : public CORBA::DefaultValueRefCountBase, + public virtual OBV_ORT::ObjectReferenceFactory +{ +public: + + Gateway_ObjRef_Factory ( + Gateway::Object_Factory_ptr gateway_object_factory, + PortableInterceptor::ObjectReferenceFactory *old_factory); + + virtual CORBA::Object_ptr make_object ( + const char *repository_id, + const PortableInterceptor::ObjectId &id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + + Gateway::Object_Factory_var gateway_object_factory_; + + PortableInterceptor::ObjectReferenceFactory_var old_factory_; +}; + +#endif /* GATEWAY_OBJREF_FACTORY_H */ diff --git a/TAO/orbsvcs/examples/ORT/Gateway_i.cpp b/TAO/orbsvcs/examples/ORT/Gateway_i.cpp new file mode 100644 index 00000000000..f4ce9754556 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Gateway_i.cpp @@ -0,0 +1,181 @@ +//$Id$ + +#include "Gateway_i.h" + +#include "tao/AnyTypeCode/Any.h" +#include "tao/AnyTypeCode/NVList.h" +#include "tao/AnyTypeCode/ExceptionA.h" + +#include "tao/IFR_Client/IFR_BasicC.h" + +#include "tao/DynamicInterface/Server_Request.h" +#include "tao/DynamicInterface/Request.h" +#include "tao/DynamicInterface/Unknown_User_Exception.h" + +#include "tao/ORB.h" +#include "tao/LocalObject.h" + +ACE_RCSID (ORT, + Gateway_i, + "$Id$") + +Gateway_i:: +Gateway_i (CORBA::ORB_ptr orb, + PortableServer::Current_ptr poa_current) + : orb_ (orb), + poa_current_ (poa_current) +{ + /// Constructor +} + +void +Gateway_i::invoke (CORBA::ServerRequest_ptr request + ACE_ENV_ARG_DECL) +{ + PortableServer::ObjectId_var target_id = + this->poa_current_->get_object_id (); + + CORBA::String_var stringified_object_id = + PortableServer::ObjectId_to_string (target_id.in ()); + + CORBA::Object_var target_object = + this->orb_->string_to_object (stringified_object_id.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Use the IfR interfaces to query the NVList for this object... + CORBA::InterfaceDef_var target_interface = + target_object->_get_interface (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (target_interface.in ())) + { + /// + } + + // This is the target operation... + CORBA::String_var operation_name = + request->operation (); + + CORBA::Contained_var contained_operation = + target_interface->lookup (operation_name.in ()); + + CORBA::OperationDef_var operation = + CORBA::OperationDef::_narrow (contained_operation.in ()); + + // Save the result typecode... + CORBA::TypeCode_var result_typecode = + operation.in ()->result (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CORBA::ParDescriptionSeq_var parameters = + operation.in ()->params (); + + // Build the NVList based on the info from the IfR + CORBA::NVList_ptr arguments; + this->orb_->create_list (parameters->length (), + arguments + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::Flags flags = 0; + + CORBA::ULong length = parameters->length (); + + CORBA::ULong i = 0; + + for (i = 0; i < length; ++i) + { + switch (parameters[i].mode) + { + case CORBA::PARAM_IN: + flags = CORBA::ARG_IN; + break; + case CORBA::PARAM_OUT: + flags = CORBA::ARG_OUT; + break; + case CORBA::PARAM_INOUT: + flags = CORBA::ARG_INOUT; + break; + } + } + + for (i = 0; i != length; ++i) + { + CORBA::Any any; + any._tao_set_typecode (parameters[i].type.in ()); + + arguments->add_value (parameters[i].name, + any, + flags + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + + // Extract the values of the arguments from the DSI ServerRequest + request->arguments (arguments ACE_ENV_ARG_PARAMETER); + + // Use the NVList (with values) to create a DII Request... + CORBA::Request_var dii_request; + + CORBA::NamedValue *named_value = 0; + + this->orb_->create_named_value (named_value + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::ContextList *context_list = 0; + CORBA::ExceptionList *exceptions = 0; + + target_object->_create_request (CORBA::Context::_nil (), + operation_name.in (), + arguments, + named_value, /* Result */ + exceptions, + context_list, /* Context List */ + dii_request.inout (), + CORBA::Flags (0) + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Set the return type... + dii_request->set_return_type (result_typecode.in ()); + + ACE_TRY + { + // Make the DII request + dii_request->invoke (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // At this point the NVList contains all the out and inout + // arguments, but we need to extract the return value... + } + ACE_CATCH (CORBA::UnknownUserException, user_ex) + { + // Pass the exception back to the server request... + request->set_exception (user_ex.exception ()); + return; + } + ACE_CATCH (CORBA::SystemException, sys_ex) + { + CORBA::Any any; + any <<= sys_ex; + // Pass the exception back to the server request... + request->set_exception (any); + return; + } + ACE_CATCHANY; + ACE_ENDTRY; + + request->set_result (dii_request->return_value ()); + // Using the same NVList for both the DSI Server Request and the DII + // Request takes care of the out and inout arguments (whew!) +} + +CORBA::RepositoryId +Gateway_i::_primary_interface (const PortableServer::ObjectId &, + PortableServer::POA_ptr + ACE_ENV_ARG_DECL_NOT_USED) +{ + return 0; +} diff --git a/TAO/orbsvcs/examples/ORT/Gateway_i.h b/TAO/orbsvcs/examples/ORT/Gateway_i.h new file mode 100644 index 00000000000..a49d7a1e73a --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Gateway_i.h @@ -0,0 +1,50 @@ +// -*- C++ -*- +// +// $Id$ + +//============================================================================= +/** + * @file Gateway_i.h + * + * $Id$ + * + * Implementation header used for forwarding the requests from the + * gateway to the server and reply to the client + * + * @author Carlos O'Ryan <coryan@uci.edu> + * @author Priyanka Gontla <gontla_p@ociweb.com> + */ +//============================================================================= + +#ifndef GATEWAY_I_H +#define GATEWAY_I_H + +#include "tao/IFR_Client/IFR_Client_Adapter_Impl.h" +#include "tao/AnyTypeCode/AnyTypeCode_methods.h" +#include "tao/DynamicInterface/DII_CORBA_methods.h" +#include "tao/DynamicInterface/Dynamic_Implementation.h" +#include "tao/PortableServer/PortableServer.h" + +class Gateway_i + : public virtual PortableServer::DynamicImplementation +{ +public: + Gateway_i (CORBA::ORB_ptr orb, + PortableServer::Current_ptr poa_current); + + virtual void invoke (CORBA::ServerRequest_ptr request + ACE_ENV_ARG_DECL); + + virtual CORBA::RepositoryId _primary_interface ( + const PortableServer::ObjectId &oid, + PortableServer::POA_ptr poa + ACE_ENV_ARG_DECL); + + private: + + CORBA::ORB_ptr orb_; + + PortableServer::Current_ptr poa_current_; +}; + +#endif /* GATEWAY_I_H */ diff --git a/TAO/orbsvcs/examples/ORT/Makefile.am b/TAO/orbsvcs/examples/ORT/Makefile.am new file mode 100644 index 00000000000..03e2618d646 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Makefile.am @@ -0,0 +1,225 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_IDL = ACE_ROOT=$(ACE_ROOT) TAO_ROOT=$(TAO_ROOT) $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDL_DEP = $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDLFLAGS = -Ge 1 -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -I$(TAO_ROOT) -I$(srcdir) -g $(ACE_BUILDDIR)/apps/gperf/src/gperf +TAO_ROOT = $(top_srcdir) + +CLEANFILES = +noinst_PROGRAMS = +BUILT_SOURCES = + +## Makefile.ORT_Idl.am + +if !BUILD_MINIMUM_CORBA + +BUILT_SOURCES += \ + GatewayC.cpp \ + GatewayC.h \ + GatewayC.inl \ + GatewayS.cpp \ + GatewayS.h \ + GatewayS.inl + +CLEANFILES += \ + Gateway-stamp \ + GatewayC.cpp \ + GatewayC.h \ + GatewayC.inl \ + GatewayS.cpp \ + GatewayS.h \ + GatewayS.inl + +GatewayC.cpp GatewayC.h GatewayC.inl GatewayS.cpp GatewayS.h GatewayS.inl: Gateway-stamp + +Gateway-stamp: $(srcdir)/Gateway.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -Sa -St $(srcdir)/Gateway.idl + @touch $@ + +BUILT_SOURCES += \ + ObjectReferenceFactoryC.cpp \ + ObjectReferenceFactoryC.h \ + ObjectReferenceFactoryC.inl \ + ObjectReferenceFactoryS.cpp \ + ObjectReferenceFactoryS.h \ + ObjectReferenceFactoryS.inl + +CLEANFILES += \ + ObjectReferenceFactory-stamp \ + ObjectReferenceFactoryC.cpp \ + ObjectReferenceFactoryC.h \ + ObjectReferenceFactoryC.inl \ + ObjectReferenceFactoryS.cpp \ + ObjectReferenceFactoryS.h \ + ObjectReferenceFactoryS.inl + +ObjectReferenceFactoryC.cpp ObjectReferenceFactoryC.h ObjectReferenceFactoryC.inl ObjectReferenceFactoryS.cpp ObjectReferenceFactoryS.h ObjectReferenceFactoryS.inl: ObjectReferenceFactory-stamp + +ObjectReferenceFactory-stamp: $(srcdir)/ObjectReferenceFactory.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -Sa -St $(srcdir)/ObjectReferenceFactory.idl + @touch $@ + +BUILT_SOURCES += \ + sum_serverC.cpp \ + sum_serverC.h \ + sum_serverC.inl \ + sum_serverS.cpp \ + sum_serverS.h \ + sum_serverS.inl + +CLEANFILES += \ + sum_server-stamp \ + sum_serverC.cpp \ + sum_serverC.h \ + sum_serverC.inl \ + sum_serverS.cpp \ + sum_serverS.h \ + sum_serverS.inl + +sum_serverC.cpp sum_serverC.h sum_serverC.inl sum_serverS.cpp sum_serverS.h sum_serverS.inl: sum_server-stamp + +sum_server-stamp: $(srcdir)/sum_server.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -Sa -St $(srcdir)/sum_server.idl + @touch $@ + + +noinst_HEADERS = \ + Gateway.idl \ + ObjectReferenceFactory.idl \ + sum_server.idl + +endif !BUILD_MINIMUM_CORBA + +## Makefile.ORT_Gateway.am + +if BUILD_CORBA_MESSAGING +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += gateway_server + +gateway_server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +gateway_server_SOURCES = \ + GatewayC.cpp \ + GatewayS.cpp \ + Gateway_i.cpp \ + Object_Factory_i.cpp \ + gateway_server.cpp \ + Gateway_i.h \ + Object_Factory_i.h + +gateway_server_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_IFR_Client.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicInterface.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif BUILD_CORBA_MESSAGING + +## Makefile.ORT_Server.am + +if BUILD_CORBA_MESSAGING +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +server_SOURCES = \ + GatewayC.cpp \ + Gateway_ObjRef_Factory.cpp \ + ObjectReferenceFactoryC.cpp \ + Server_IORInterceptor.cpp \ + Server_IORInterceptor_ORBInitializer.cpp \ + server.cpp \ + sum_serverC.cpp \ + sum_serverS.cpp \ + sum_server_i.cpp \ + Gateway_ObjRef_Factory.h \ + Server_IORInterceptor.h \ + Server_IORInterceptor_ORBInitializer.h \ + sum_server_i.h + +server_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_IORInterceptor.la \ + $(TAO_BUILDDIR)/tao/libTAO_ObjRefTemplate.la \ + $(TAO_BUILDDIR)/tao/libTAO_IFR_Client.la \ + $(TAO_BUILDDIR)/tao/libTAO_DynamicInterface.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA +endif BUILD_CORBA_MESSAGING + +## Makefile.ORT_Client.am + +if !BUILD_MINIMUM_CORBA + +noinst_PROGRAMS += client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -DTAO_HAS_TYPED_EVENT_CHANNEL + +client_SOURCES = \ + client.cpp \ + sum_serverC.cpp \ + Gateway_ObjRef_Factory.h \ + Gateway_i.h \ + Object_Factory_i.h \ + Server_IORInterceptor.h \ + Server_IORInterceptor_ORBInitializer.h \ + sum_server_i.h + +client_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosEvent.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_MINIMUM_CORBA + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/ORT/ORT.mpc b/TAO/orbsvcs/examples/ORT/ORT.mpc new file mode 100644 index 00000000000..82fc927aab8 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/ORT.mpc @@ -0,0 +1,52 @@ +// $Id$ + +project(*idl): taoidldefaults, minimum_corba { + idl_files { + Gateway.idl + ObjectReferenceFactory.idl + sum_server.idl + } + custom_only = 1 +} + +project(*Gateway) : orbsvcsexe, dynamicinterface, ifr_client, minimum_corba { + after += *idl + + source_files { + GatewayC.cpp + GatewayS.cpp + gateway_server.cpp + Gateway_i.cpp + Object_Factory_i.cpp + } + idl_files { + } +} + +project(*Server) : orbsvcsexe, dynamicinterface, ifr_client, minimum_corba, iorinterceptor { + exename = server + after += *Gateway + source_files { + server.cpp + GatewayC.cpp + Gateway_ObjRef_Factory.cpp + sum_serverC.cpp + sum_serverS.cpp + sum_server_i.cpp + Server_IORInterceptor_ORBInitializer.cpp + Server_IORInterceptor.cpp + ObjectReferenceFactoryC.cpp + } + idl_files { + } +} + +project(*Client) : orbsvcsexe, event, minimum_corba { + after += *Idl *Server + source_files { + client.cpp + sum_serverC.cpp + } + idl_files { + } +} diff --git a/TAO/orbsvcs/examples/ORT/ObjectReferenceFactory.idl b/TAO/orbsvcs/examples/ORT/ObjectReferenceFactory.idl new file mode 100644 index 00000000000..0b7c8d10bee --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/ObjectReferenceFactory.idl @@ -0,0 +1,16 @@ +// -*- IDL -*- +// +// $Id$ + +#ifndef OBJECT_REFERENCE_FACTORY_IDL +#define OBJECT_REFERENCE_FACTORY_IDL + +#include "tao/ObjRefTemplate/ObjectReferenceTemplate_include.pidl" + +module ORT +{ + valuetype ObjectReferenceFactory + : PortableInterceptor::ObjectReferenceFactory {}; +}; + +#endif /* OBJECT_REFERENCE_FACTORY_IDL */ diff --git a/TAO/orbsvcs/examples/ORT/Object_Factory_i.cpp b/TAO/orbsvcs/examples/ORT/Object_Factory_i.cpp new file mode 100644 index 00000000000..32c4e9ce579 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Object_Factory_i.cpp @@ -0,0 +1,49 @@ +// $Id$ + +#include "Object_Factory_i.h" +#include "tao/PortableServer/Root_POA.h" + +Object_Factory_i::Object_Factory_i (CORBA::ORB_ptr orb, + PortableServer::POA_ptr gateway_poa) + : orb_ (CORBA::ORB::_duplicate (orb)), + gateway_poa_ (gateway_poa) +{ + /// Constructor +} + + +CORBA::Object_ptr +Object_Factory_i::create_object (const char *interface_repository_id, + CORBA::Object_ptr gatewayed_object + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CORBA::String_var stringified_object = + this->orb_->object_to_string (gatewayed_object ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + const PortableServer::ObjectId_var id = + PortableServer::string_to_ObjectId (stringified_object.in ()); + + const PortableInterceptor::ObjectId *obj_id = + reinterpret_cast<const PortableInterceptor::ObjectId *> (&id.in ()); + ACE_UNUSED_ARG(obj_id); + ACE_UNUSED_ARG(interface_repository_id); +/* + TAO_POA *poa = dynamic_cast <TAO_POA *> (this->gateway_poa_); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + PortableInterceptor::ObjectReferenceTemplate *ort_template = + poa->get_adapter_template(); + + TAO_ObjectReferenceTemplate *ort = + dynamic_cast <TAO_ObjectReferenceTemplate *> (ort_template); + + CORBA::Object_ptr object_ptr = + ort->make_object (interface_repository_id, + *obj_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ());*/ + + return CORBA::Object::_nil(); +} diff --git a/TAO/orbsvcs/examples/ORT/Object_Factory_i.h b/TAO/orbsvcs/examples/ORT/Object_Factory_i.h new file mode 100644 index 00000000000..add32112dbd --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Object_Factory_i.h @@ -0,0 +1,45 @@ +// $Id$ + +//============================================================================= +/** + * @file Object_Factory_i.h + * + * $Id$ + * + * Implementation header for the "Gateway" IDL interface for the + * ORT example. + * + * @author Carlos O'Ryan <coryan@uci.edu> + * @author Priyanka Gontla <gontla_p@ociweb.com> + */ +//============================================================================= + +#ifndef OBJECT_FACTORY_I_H +#define OBJECT_FACTORY_I_H + +#include "GatewayS.h" + +#include "tao/PortableServer/PortableServerC.h" +#include "tao/ORB.h" + +class Object_Factory_i : public virtual POA_Gateway::Object_Factory +{ + public: + + /// Constructor + Object_Factory_i (CORBA::ORB_ptr orb, + PortableServer::POA_ptr gateway_poa); + + CORBA::Object_ptr + create_object (const char *interface_repository_id, + CORBA::Object_ptr gatewayed_object + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + private: + + CORBA::ORB_ptr orb_; + PortableServer::POA_ptr gateway_poa_; +}; + +#endif /* OBJECT_FACTORY_I_H */ diff --git a/TAO/orbsvcs/examples/ORT/README b/TAO/orbsvcs/examples/ORT/README new file mode 100644 index 00000000000..2b1b313b3e6 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/README @@ -0,0 +1,69 @@ +$Id$ + +This example shows the use of ORT Template by a simple application. + +Scenario: +======== + +1. There's a server which has a dummy method that adds the two 'in' variables + and return the sum to the client. + +2. There is a Gateway which receives the requests on behalf of the + server and redirects to the server. So the client never knows about + the actual server but only the gateway. + +3. And, as always we will have a client that invokes the server + method. + +Files and Small Description +===================== + + +Gateway.idl IDL for the Gateway + +Gateway_IORInterceptor IORInterceptor for the Gateway. + +Gateway_i Implementation of the Gateway which changes the DSI to DII. + +Object_Factory_i Implementation for the + Gateway IDL method. This method + creates a reference which points to the gateway + instead of the server. + +gateway_server As the name means, gateway server + implementation. + +sum_server.idl idl for the sum_server. + +server The main server which is being + gatewayed by the gateway + +sum_server_i Implementation of sum_server.idl methods. + +client Simple client which invokes the sum_server + method add_variables. + +How to run the example +====================== + +1. First run the IFR_Service. + +% $IFR_Service + + It generates an ior in if_repo.ior by default. + +2. Then, run the tao_ifr passing sum_server.idl as its argument, + +% $tao_ifr sum_server.idl + +3. Run the gateway server + +% ./gateway_server -o gateway_ior -ORBInitRef IFR_Service=file://if_repo.ior + +4. Run the actual server. + +% ./server -o server_ior -ORBInitRef Gateway_Object_Factory=file://gateway_ior + +5. Run the client + +% ./client -k file://server_ior diff --git a/TAO/orbsvcs/examples/ORT/Server_IORInterceptor.cpp b/TAO/orbsvcs/examples/ORT/Server_IORInterceptor.cpp new file mode 100644 index 00000000000..2cd8117b443 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Server_IORInterceptor.cpp @@ -0,0 +1,85 @@ +// $Id$ + +#include "Server_IORInterceptor.h" +#include "Gateway_ObjRef_Factory.h" + +ACE_RCSID (ORT, + Server_IORInterceptor, + "$Id$") + + +Server_IORInterceptor:: +Server_IORInterceptor (Gateway::Object_Factory_ptr factory) + : gateway_object_factory_ (Gateway::Object_Factory::_duplicate (factory)) +{ +} + +Server_IORInterceptor::~Server_IORInterceptor (void) +{ + CORBA::release (this->gateway_object_factory_); +} + + +char * +Server_IORInterceptor::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::string_dup ("Server_IORInterceptor"); +} + +void +Server_IORInterceptor::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CORBA::release (this->gateway_object_factory_); + this->gateway_object_factory_ = Gateway::Object_Factory::_nil (); +} + +void +Server_IORInterceptor::establish_components ( + PortableInterceptor::IORInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +Server_IORInterceptor::components_established ( + PortableInterceptor::IORInfo_ptr ior_info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + Gateway_ObjRef_Factory *my_factory = 0; + + PortableInterceptor::ObjectReferenceFactory_var current_factory = + ior_info->current_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + ACE_NEW_THROW_EX (my_factory, + Gateway_ObjRef_Factory (this->gateway_object_factory_, + current_factory.in ()), + CORBA::NO_MEMORY ()); + ACE_CHECK; + + ior_info->current_factory (my_factory + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Server_IORInterceptor::adapter_manager_state_changed ( + const char *, + PortableInterceptor::AdapterState + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +Server_IORInterceptor:: adapter_state_changed ( + const PortableInterceptor::ObjectReferenceTemplateSeq &, + PortableInterceptor::AdapterState + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} diff --git a/TAO/orbsvcs/examples/ORT/Server_IORInterceptor.h b/TAO/orbsvcs/examples/ORT/Server_IORInterceptor.h new file mode 100644 index 00000000000..da243325d05 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Server_IORInterceptor.h @@ -0,0 +1,85 @@ +// -*- C++ -*- +// +//$Id$ + +#ifndef SERVER_IORINTERCEPTOR_H +#define SERVER_IORINTERCEPTOR_H + +#include "GatewayC.h" +#include "tao/IORInterceptor/IORInterceptor.h" +#include "tao/LocalObject.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +class Server_IORInterceptor + : public virtual PortableInterceptor::IORInterceptor_3_0, + public virtual TAO_Local_RefCounted_Object +{ +public: + + Server_IORInterceptor (Gateway::Object_Factory_ptr gateway_object_factory); + + /** + * @name Methods Required by the IOR Interceptor Interface + * + * These are methods that must be implemented since they are pure + * virtual in the abstract base class. They are the canonical + * methods required for all IOR interceptors. + */ + //@{ + /// Return the name of this IORInterceptor. + virtual char * name (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Cleanup resources acquired by this IORInterceptor. + virtual void destroy (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Add the tagged components to the IOR. + virtual void establish_components ( + PortableInterceptor::IORInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void components_established ( + PortableInterceptor::IORInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void adapter_manager_state_changed ( + const char * id, + PortableInterceptor::AdapterState state + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void adapter_state_changed ( + const PortableInterceptor::ObjectReferenceTemplateSeq & templates, + PortableInterceptor::AdapterState state + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + //@} + +protected: + + ~Server_IORInterceptor (void); + +private: + + Gateway::Object_Factory_ptr gateway_object_factory_; + +}; + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#endif /* SERVER_IORINTERCEPTOR_H */ diff --git a/TAO/orbsvcs/examples/ORT/Server_IORInterceptor_ORBInitializer.cpp b/TAO/orbsvcs/examples/ORT/Server_IORInterceptor_ORBInitializer.cpp new file mode 100644 index 00000000000..93fd158c07b --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Server_IORInterceptor_ORBInitializer.cpp @@ -0,0 +1,59 @@ +// $Id$ + +#include "Server_IORInterceptor_ORBInitializer.h" +#include "Server_IORInterceptor.h" +#include "tao/ORB_Constants.h" + +#include "GatewayC.h" + +ACE_RCSID (ORT, + Server_IORInterceptor_ORBInitializer, + "$Id: ") + +void +Server_IORInterceptor_ORBInitializer::pre_init ( + PortableInterceptor::ORBInitInfo_ptr /* info */ + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +Server_IORInterceptor_ORBInitializer::post_init ( + PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CORBA::Object_var obj = + info->resolve_initial_references ("Gateway_Object_Factory" + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + /// Narrow it down correctly. + Gateway::Object_Factory_var gateway_object_factory = + Gateway::Object_Factory::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + /// Check for nil reference + if (CORBA::is_nil (gateway_object_factory.in ())) + ACE_ERROR ((LM_ERROR, + "Unable to obtain reference to Gateway::Object_Factory " + "object.\n")); + + PortableInterceptor::IORInterceptor_ptr gateway; + ACE_NEW_THROW_EX (gateway, + Server_IORInterceptor (gateway_object_factory.in ()), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK; + + PortableInterceptor::IORInterceptor_var ior_interceptor = gateway; + + info->add_ior_interceptor (ior_interceptor.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} diff --git a/TAO/orbsvcs/examples/ORT/Server_IORInterceptor_ORBInitializer.h b/TAO/orbsvcs/examples/ORT/Server_IORInterceptor_ORBInitializer.h new file mode 100644 index 00000000000..5fd0887f014 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/Server_IORInterceptor_ORBInitializer.h @@ -0,0 +1,44 @@ +// $Id$ + +#ifndef SERVER_IOR_INTERCEPTOR_ORB_INITIALIZER_H +#define SERVER_IOR_INTERCEPTOR_ORB_INITIALIZER_H + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PI/PI.h" +#include "tao/LocalObject.h" + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +class Server_IORInterceptor_ORBInitializer + : public virtual PortableInterceptor::ORBInitializer, + public virtual TAO_Local_RefCounted_Object +{ + public: + + //@{ + /// The pre-initialization hook. + virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// The post-initialization hook. + virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + //@} + +}; + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#endif /* SERVER_IOR_INTERCEPTOR_ORB_INITIALIZER_H */ diff --git a/TAO/orbsvcs/examples/ORT/client.cpp b/TAO/orbsvcs/examples/ORT/client.cpp new file mode 100644 index 00000000000..699985a1993 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/client.cpp @@ -0,0 +1,85 @@ +// -*- C++ -*- + +#include "sum_serverC.h" +#include "ace/Get_Opt.h" + +ACE_RCSID (ORT, + client, + "$Id$") + +const char *ior = "file://test.ior"; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.optarg; + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s " + "-k IOR " + "\n", + argv[0]), + -1); + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "client_sum_orb" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) != 0) + return 1; + + CORBA::Object_var obj = + orb->string_to_object (ior ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ORT::sum_server_var server = + ORT::sum_server::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (server.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Object reference <%s> is nil.\n", + ior), + 1); + } + + CORBA::ULong a = 5; + CORBA::ULong b = 3; + + CORBA::ULong result = server->add_variables (a, + b + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (result != 8) + ACE_DEBUG ((LM_DEBUG, + "Error: Add Variables did not return the right value\n")); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "ORT example on client side :"); + return -1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/ORT/gateway_server.cpp b/TAO/orbsvcs/examples/ORT/gateway_server.cpp new file mode 100644 index 00000000000..d52bc63f0f2 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/gateway_server.cpp @@ -0,0 +1,189 @@ +// $Id$ + +#include "Object_Factory_i.h" +#include "Gateway_i.h" + +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" + +const char *ior_output_file = 0; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.optarg; + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s " + "-o <iorfile>" + "\n", + argv[0]), + -1); + } + + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + /// Initialize the ORB. + CORBA::ORB_var orb = CORBA::ORB_init (argc, + argv, + "gateway_server_orb" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) != 0) + return -1; + + /// Resolve reference to RootPOA + CORBA::Object_var obj = + orb->resolve_initial_references ("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + /// Narrow it down correctly. + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + /// Check for nil references + if (CORBA::is_nil (root_poa.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + "Unable to obtain RootPOA reference.\n"), + -1); + + /// Get poa_manager reference + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + /// Activate it. + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ///@} + + CORBA::PolicyList policies (3); + policies.length (3); + + policies [0] = + root_poa->create_servant_retention_policy (PortableServer::RETAIN + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + policies [1] = + root_poa->create_request_processing_policy (PortableServer::USE_DEFAULT_SERVANT + ACE_ENV_ARG_PARAMETER); + + ACE_TRY_CHECK; + + policies [2] = + root_poa->create_id_uniqueness_policy (PortableServer::MULTIPLE_ID + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POA_var gateway_poa = + root_poa->create_POA ("Gateway_POA", + poa_manager.in (), + policies + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + for (CORBA::ULong i = 0; i != policies.length (); ++i) { + policies[i]->destroy (); + } + + // Get the POA Current object reference + obj = + orb->resolve_initial_references ("POACurrent" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Narrow the object reference to a POA Current reference + PortableServer::Current_var poa_current = + PortableServer::Current::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + Gateway_i *gateway; + + ACE_NEW_THROW_EX (gateway, + Gateway_i (orb.in (), + poa_current.in ()), + CORBA::NO_MEMORY ()); + ACE_TRY_CHECK; + + gateway_poa->set_servant (gateway ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + /// Get the ObjectID + PortableServer::ObjectId_var oid = + PortableServer::string_to_ObjectId ("Object_Factory"); + + /// This class is used to create a object reference. + Object_Factory_i *object_factory; + + ACE_NEW_THROW_EX (object_factory, + Object_Factory_i (orb.in (), + gateway_poa.in ()), + CORBA::NO_MEMORY ()); + ACE_TRY_CHECK; + + /// Activate the Object_Factory_i Object + gateway_poa->activate_object_with_id (oid.in (), + object_factory + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Get the object reference. + CORBA::Object_var gateway_object_factory = + gateway_poa->id_to_reference (oid.in ()); + + /// Convert the object reference to a string format. + CORBA::String_var ior = + orb->object_to_string (gateway_object_factory.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + /// If the ior_output_file exists, output the IOR to it. + if (ior_output_file != 0) + { + FILE *output_file = ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing " + "IOR: %s", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + } + + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "ORT test (gateway_server):"); + + return -1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/ORT/run_test.pl b/TAO/orbsvcs/examples/ORT/run_test.pl new file mode 100755 index 00000000000..9554ac4bc46 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/run_test.pl @@ -0,0 +1,130 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "../../../../bin"; +use PerlACE::Run_Test; + +$status = 0; + +$ifr_iorfile= "if_repo.ior"; +$srv_iorfile = "iorfile.ior"; +$gateway_iorfile = "gateway_ior.ior"; +$test_idl = PerlACE::LocalFile ("sum_server.idl"); + +# find the tao_ifr executable. +# Its placement is dependent upon the OS and if MPC generated makefiles are used. +my $exec_extn=""; +if ($^O eq "MSWin32") { + $exec_extn=".exe"; +} + +$tao_ifr = "../../../../bin/tao_ifr"; +if (! -e $tao_ifr . $exec_extn ) { + $tao_ifr = "../../../IFR_Service/tao_ifr"; + if (! -e $tao_ifr . $exec_extn ) { + print STDERR "ERROR: tao_ifr compiler not found.\n"; + exit 1; + } +} + +$lookup_by_name = ""; +$other = ""; + +for ($i = 0; $i <= $#ARGV; $i++) { + if ($ARGV[$i] eq "-n") { + $lookup_by_name = "-n"; + } + else { + $other .= $ARGV[$i]; + } +} + +$TAO_IFR = new PerlACE::Process ($tao_ifr); +$IFR = new PerlACE::Process ("../../IFR_Service/IFR_Service", " -o $ifr_iorfile"); +$GATEWAYSV = new PerlACE::Process ("gateway_server", "-o $gateway_iorfile -ORBInitRef IFR_Service=file://$ifr_iorfile"); +$SV = new PerlACE::Process ("server", "-o $srv_iorfile -ORBInitRef Gateway_Object_Factory=file://$gateway_iorfile"); +$CL2 = new PerlACE::Process ("client", "-k file://$srv_iorfile"); + +unlink $ifr_iorfile; +unlink $svr_iorfile; +unlink $gateway_iorfile; + +$IFR->Spawn (); + +if (PerlACE::waitforfile_timed ($ifr_iorfile, 15) == -1) { + print STDERR "ERROR: cannot find file <$ifr_iorfile>\n"; + $IFR->Kill (); + exit 1; +} + +$TAO_IFR->Arguments ("-ORBInitRef InterfaceRepository=file://$ifr_iorfile $test_idl"); + +$tresult = $TAO_IFR->SpawnWaitKill (30); + +$GATEWAYSV->Spawn (); + +if (PerlACE::waitforfile_timed ($gateway_iorfile, 15) == -1) { + print STDERR "ERROR: cannot find file <$gateway_iorfile>\n"; + $IFR->Kill (); + $GATEWAYSV->Kill (); + exit 1; +} + +$SV->Spawn (); + +if (PerlACE::waitforfile_timed ($svr_iorfile, 1500) == -1) { + print STDERR "ERROR: cannot find file <$srv_iorfile>\n"; + $IFR->Kill (); + $GATEWAYSV->Kill (); + $SV->Kill (); + exit 1; +} + +if ($tresult != 0) { + print STDERR "ERROR: tao_ifr (test.idl) returned $tresult\n"; + $status = 1; +} + +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "ERROR: client returned $client\n"; + $status = 1; +} + +$tresult = $TAO_IFR->SpawnWaitKill (30); + +if ($tresult != 0) { + print STDERR "ERROR: tao_ifr (-r test.idl) returned $tresult\n"; + $status = 1; +} + +$gatewayserver = $GATEWAYSV->TerminateWaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: server returned $server\n"; + $status = 1; +} + +$server = $SV->TerminateWaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: server returned $server\n"; + $status = 1; +} +$server = $IFR->TerminateWaitKill (5); + +if ($server != 0) { + print STDERR "ERROR: IFR returned $server\n"; + $status = 1; +} + +unlink $ifr_iorfile; +unlink $srv_iorfile; +unlink $gateway_iorfile; + +exit $status; diff --git a/TAO/orbsvcs/examples/ORT/server.cpp b/TAO/orbsvcs/examples/ORT/server.cpp new file mode 100644 index 00000000000..1b76cecb393 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/server.cpp @@ -0,0 +1,152 @@ +// $Id$ + +#include "sum_server_i.h" +#include "Server_IORInterceptor_ORBInitializer.h" +#include "tao/ORBInitializer_Registry.h" + +#include "ace/Get_Opt.h" +#include "ace/OS_NS_stdio.h" + +const char *ior_output_file = 0; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.optarg; + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s " + "-o <iorfile>" + "\n", + argv[0]), + -1); + } + + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { +#if TAO_HAS_INTERCEPTORS == 1 + + PortableInterceptor::ORBInitializer_ptr orb_initializer = + PortableInterceptor::ORBInitializer::_nil (); + + ACE_NEW_RETURN (orb_initializer, + Server_IORInterceptor_ORBInitializer, + -1); // No CORBA exceptions yet! + + PortableInterceptor::ORBInitializer_var orb_initializer_var = + orb_initializer; + + PortableInterceptor::register_orb_initializer (orb_initializer_var.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + +#endif /* TAO_HAS_INTERCEPTORS == 1 */ + + // The usual initialization stuff + + // Initialize the ORB. + CORBA::ORB_var orb = CORBA::ORB_init (argc, + argv, + "server_sum_orb" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) != 0) + return -1; + + // Resolve reference to RootPOA + CORBA::Object_var obj = + orb->resolve_initial_references ("RootPOA" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Narrow it down correctly. + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Check for nil references + if (CORBA::is_nil (root_poa.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + "Unable to obtain RootPOA reference.\n"), + -1); + + // Get poa_manager reference + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Activate it. + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // initialize the sum_server + sum_server_i sum_server_impl; + + // Activate + obj = sum_server_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Narrow it down. + ORT::sum_server_var sum_server = + ORT::sum_server::_narrow (obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Check for nil reference + if (CORBA::is_nil (sum_server.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + "Unable to obtain reference to ORT::sum_server " + "object.\n"), + -1); + + // Convert the object reference to a string format. + CORBA::String_var ior = + orb->object_to_string (sum_server.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // If the ior_output_file exists, output the IOR to it. + if (ior_output_file != 0) + { + FILE *output_file = ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing " + "IOR: %s", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + } + + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_INFO, "Successful.\n")); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "ORT example server:"); + return -1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/ORT/sum_server.idl b/TAO/orbsvcs/examples/ORT/sum_server.idl new file mode 100644 index 00000000000..31c599c88e4 --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/sum_server.idl @@ -0,0 +1,10 @@ +// $Id$ + +module ORT +{ + interface sum_server + { + long add_variables (in long a, + in long b); + }; +}; diff --git a/TAO/orbsvcs/examples/ORT/sum_server_i.cpp b/TAO/orbsvcs/examples/ORT/sum_server_i.cpp new file mode 100644 index 00000000000..9b14117125e --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/sum_server_i.cpp @@ -0,0 +1,20 @@ +// $Id$ + +#include "sum_server_i.h" + +ACE_RCSID (ORT, + sum_server_i, + "$Id$") + +sum_server_i::sum_server_i () +{ +} + +CORBA::Long +sum_server_i::add_variables (CORBA::Long a, + CORBA::Long b + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return a+b; +} diff --git a/TAO/orbsvcs/examples/ORT/sum_server_i.h b/TAO/orbsvcs/examples/ORT/sum_server_i.h new file mode 100644 index 00000000000..ea38c4ae7ab --- /dev/null +++ b/TAO/orbsvcs/examples/ORT/sum_server_i.h @@ -0,0 +1,40 @@ +// $Id$ + +//============================================================================= +/** + * @file sum_server_i.h + * + * $Id$ + * + * Implementation header for the "server" IDL interface for the + * ORT example. + * + * @author Priyanka Gontla <gontla_p@ociweb.com> + */ +//============================================================================= + +#ifndef SUM_SERVER_I_H +#define SUM_SERVER_I_H + +#include "sum_serverS.h" + +// Must include this header file and link to TAO_IFR_Client.lib +// to dynamically load this necessary library. +#include "tao/IFR_Client/IFR_Client_Adapter_Impl.h" + +class sum_server_i : public virtual POA_ORT::sum_server +{ + public: + + /// Constructor + sum_server_i (); + + /// add variables method + CORBA::Long add_variables (CORBA::Long a, + CORBA::Long b + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + +}; + +#endif /* SUM_SERVER_I_H */ diff --git a/TAO/orbsvcs/examples/PSS/README b/TAO/orbsvcs/examples/PSS/README new file mode 100644 index 00000000000..bd87fa9ac2c --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/README @@ -0,0 +1,58 @@ + +This example show the usage of PSS for persistently saving data. + + +For this example, we will have a simple_naming.idl which will have just +two methods: bind and find. As you can guess, the bind function is to +be used for binding the name of an object with its object +reference. And, the find function helps find the object reference +related to the 'name'. To make it simple, we will just bind the +stringified form of a name to the stringified form of the object reference. + +How to Run +---------- + +As with the naming_service, we will first run the Simple_Naming + +% ./Simple_Naming -o simple_naming.ior + + +Next Run the server giving it the reference to Simple_Naming. As this +is an example, didnt bother about making the Simple_Naming multicast +enabled... kept it simple. + + +% ./server -ORBInitRef Simple_Naming=file://simple_naming.ior + +The Simple_Naming writes down the server -> IOR mapping to a file +(Data_Store) .. this serves as the database used to help make the PSS +persistent. + + +Then Run the Client + +% ./client -ORBInitRef Simple_Naming=file://simple_naming.ior + + +On Success, you will not get debug statements. + + +To test the persistency offered by the Persistent State Service, lets +keep the server running .. but kill the Simple_Naming. + +% kill -9 pid_of_simple_naming + +Now, restart the Simple_Naming as before + +% ./Simple_Naming + +And, run the client to see if the Simple_Naming can help get the +request sent to the correct server. + + +% ./client -ORBInitRef Simple_Naming=file://simple_naming.ior + + + +Note: If running the example fresh, make sure you remove the +previously generated 'Data_Store'. diff --git a/TAO/orbsvcs/examples/PSS/Server.idl b/TAO/orbsvcs/examples/PSS/Server.idl new file mode 100644 index 00000000000..b9edd30e302 --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/Server.idl @@ -0,0 +1,31 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/orbsvcs/examples/PSS +// +// = FILENAME +// Server.idl +// +// = AUTHOR +// Priyanka Gontla <gontla_p@ociweb.com> +// +// ============================================================================ + +#ifndef TAO_SERVER_IDL +#define TAO_SERVER_IDL + +#pragma prefix "omg.org" + +module Simple_Server +{ + interface Server + { + string get_status (); + }; + +}; + +#endif /* TAO_SERVER_IDL */ diff --git a/TAO/orbsvcs/examples/PSS/Server_i.cpp b/TAO/orbsvcs/examples/PSS/Server_i.cpp new file mode 100644 index 00000000000..0d5e1bcfe43 --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/Server_i.cpp @@ -0,0 +1,20 @@ +// $Id$ + +#include "Server_i.h" + +ACE_RCSID (PSS, Server_i, "$Id$") + +Server_i::Server_i (void) +{ +} + +Server_i::~Server_i (void) +{ +} + +char * +Server_i::get_status (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::string_dup ("active"); +} diff --git a/TAO/orbsvcs/examples/PSS/Server_i.h b/TAO/orbsvcs/examples/PSS/Server_i.h new file mode 100644 index 00000000000..5f5937e24a5 --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/Server_i.h @@ -0,0 +1,40 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/orbsvcs/examples/PSS +// +// = FILENAME +// Server_i.h +// +// = DESCRIPTION +// This class implements the get_status method in server.idl +// +// = AUTHORS +// Priyanka Gontla <gontla_p@ociweb.com> +// +// ============================================================================ + +#ifndef SERVER_I_H +#define SERVER_I_H +#include /**/ "ace/pre.h" + +#include "ServerS.h" + +class Server_i : public virtual POA_Simple_Server::Server +{ + public: + + Server_i (); + + ~Server_i (); + + virtual char *get_status (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); +}; + +#include /**/ "ace/post.h" +#endif /* SERVER_I_H */ + diff --git a/TAO/orbsvcs/examples/PSS/Simple_Naming.cpp b/TAO/orbsvcs/examples/PSS/Simple_Naming.cpp new file mode 100644 index 00000000000..91add5d9900 --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/Simple_Naming.cpp @@ -0,0 +1,164 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/orbsvcs/examples/PSS +// +// = FILENAME +// server.cpp +// +// = DESCRIPTION +// This class implements a simple CORBA server which uses the +// simple_naming.idl to bind and find a object reference and uses +// Persistent State Service to save the information persistently. +// Serves like a Simple naming service. +// +// = AUTHOR +// Priyanka Gontla <gontla_p@ociweb.com> +// ============================================================================ + +#include "Simple_Naming_i.h" +#include "ace/Get_Opt.h" + +ACE_RCSID (PSS, client, "$Id$") + +const char *ior_output_file = "simple_naming.ior"; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-o <iorfile>" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // Initialize the ORB. + CORBA::ORB_var orb = + CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) == -1) + return -1; + + // Get a reference to the RootPOA + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Narrow down to the correct reference + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Set a POA Manager + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Activate the POA Manager + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::PolicyList policies (2); + policies.length (2); + + // Id Assignment policy + policies[0] = + root_poa->create_id_assignment_policy (PortableServer::USER_ID + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Lifespan policy + policies[1] = + root_poa->create_lifespan_policy (PortableServer::PERSISTENT + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // We use a different POA, otherwise the user would have to change + // the object key each time it invokes the server. + PortableServer::POA_var poa = + root_poa->create_POA ("Simple_Naming", + poa_manager.in (), + policies + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Creation of the new POAs over, so destroy the Policy_ptr's. + for (CORBA::ULong i = 0; + i < policies.length (); + ++i) + { + CORBA::Policy_ptr policy = policies[i]; + policy->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + Naming_Context_i simple_naming_i (orb.in ()); + + // Activate it to obtain the reference + Simple_Naming::Naming_Context_var simple_naming = + simple_naming_i._this (); + + CORBA::String_var string_obj_ref = + orb->object_to_string (simple_naming.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Output the IOR to the <ior_output_file> + FILE *output_file= ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing IOR: %s", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", string_obj_ref.in ()); + ACE_OS::fclose (output_file); + + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Unexpected excpeption in PSS Test"); + return -1; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (-1); + + return 0; +} diff --git a/TAO/orbsvcs/examples/PSS/Simple_Naming.idl b/TAO/orbsvcs/examples/PSS/Simple_Naming.idl new file mode 100644 index 00000000000..e7728b70306 --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/Simple_Naming.idl @@ -0,0 +1,36 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/orbsvcs/examples/PSS +// +// = FILENAME +// Simple_Naming.idl +// +// = AUTHOR +// Priyanka Gontla <gontla_p@ociweb.com> +// +// ============================================================================ + +#ifndef TAO_SIMPLE_NAMING_IDL +#define TAO_SIMPLE_NAMING_IDL + +#pragma prefix "omg.org" + +module Simple_Naming +{ + typedef string Name; + typedef string Str_Obj; + + interface Naming_Context + { + long bind (in Name n, in Str_Obj obj); + + Str_Obj find (in Name n); + }; + +}; + +#endif /* TAO_SIMPLE_NAMING_IDL */ diff --git a/TAO/orbsvcs/examples/PSS/Simple_Naming_i.cpp b/TAO/orbsvcs/examples/PSS/Simple_Naming_i.cpp new file mode 100644 index 00000000000..41178b04976 --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/Simple_Naming_i.cpp @@ -0,0 +1,47 @@ +// $Id$ + +#include "Simple_Naming_i.h" +#include "orbsvcs/PSS/PSDL_Code_Gen.h" + +Naming_Context_i::Naming_Context_i (CORBA::ORB_ptr orb) + : code_gen_ (0), + orb_ (orb) +{ + // constructor + // An instance of TAO_PSDL_Code_Gen + ACE_NEW (this->code_gen_, + TAO_PSDL_Code_Gen (this->orb_.in ())); +} + +Naming_Context_i::~Naming_Context_i () +{ + delete this->code_gen_; +} + +int +Naming_Context_i::bind (const char *n, + const char *obj + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Save the binding to database. + int result = + this->code_gen_->set_name_obj_ref (n, obj ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + return result; +} + +char * +Naming_Context_i::find (const char *n + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Get the Stringified object reference corresponding to + // 'n' + CORBA::String_var obj_ref = + this->code_gen_->get_obj_ref (n ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + return CORBA::string_dup (obj_ref.in ()); +} diff --git a/TAO/orbsvcs/examples/PSS/Simple_Naming_i.h b/TAO/orbsvcs/examples/PSS/Simple_Naming_i.h new file mode 100644 index 00000000000..1306d245f9b --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/Simple_Naming_i.h @@ -0,0 +1,56 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/orbsvcs/examples/PSS +// +// = FILENAME +// simple_naming_i.h +// +// = DESCRIPTION +// This class implements the bind and find methods in +// simple_naming.idl which in turn use the PSDL implementation. +// +// = AUTHORS +// Priyanka Gontla <gontla_p@ociweb.com> +// +// ============================================================================ + +#ifndef SIMPLE_NAMING_I_H +#define SIMPLE_NAMING_I_H +#include /**/ "ace/pre.h" + +#include "Simple_NamingS.h" +#include "Simple_NamingC.h" + +class TAO_PSDL_Code_Gen; + +class Naming_Context_i : public virtual POA_Simple_Naming::Naming_Context +{ + public: + + Naming_Context_i (CORBA::ORB_ptr orb); + + ~Naming_Context_i (void); + + virtual int bind (const char *n, + const char *obj + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual char *find (const char *n + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + + TAO_PSDL_Code_Gen *code_gen_; + + CORBA::ORB_var orb_; +}; + + +#include /**/ "ace/post.h" +#endif /* SIMPLE_NAMING_I_H */ diff --git a/TAO/orbsvcs/examples/PSS/client.cpp b/TAO/orbsvcs/examples/PSS/client.cpp new file mode 100644 index 00000000000..a634a736993 --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/client.cpp @@ -0,0 +1,107 @@ +// $Id$ + +// + +// ============================================================================ +// +// = LIBRARY +// orbsvcs/examples/PSS +// +// = FILENAME +// client.cpp +// +// = DESCRIPTION +// This implements a simple CORBA client for the +// Server.idl +// +// = AUTHOR +// Priyanka Gontla <pgontla@ece.uci.edu> +// +// +// ============================================================================ + +#include "ServerC.h" +#include "Simple_Naming_i.h" + +int main (int argc, char *argv []) +{ + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, + argv, + "" /* the ORB name, it can be anything! */ + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Get a reference to the RootPOA + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Narrow down to the correct reference + PortableServer::POA_var poa = + PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Set a POA Manager + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Activate the POA Manager + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Get a reference to Simple_Naming + CORBA::Object_var simple_naming_object = + orb->resolve_initial_references ("Simple_Naming" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Narrow down the reference + Simple_Naming::Naming_Context_var simple_naming = + Simple_Naming::Naming_Context::_narrow (simple_naming_object.in() + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + Simple_Naming::Name name = CORBA::string_dup ("Server"); + + CORBA::String_var ior_string = + simple_naming->find (name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Connect to the server + CORBA::Object_var tmp = + orb->string_to_object(ior_string.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + Simple_Server::Server_var server = + Simple_Server::Server::_narrow (tmp.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::String_var status = + server->get_status (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (ACE_OS::strcmp (status.in (), "active") != 0) + { + ACE_DEBUG ((LM_ERROR, + "ERROR: The server didnt return the active status\n")); + return -1; + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Client raised an exception:\n"); + ACE_CHECK_RETURN (-1); + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/PSS/naming_data.psdl b/TAO/orbsvcs/examples/PSS/naming_data.psdl new file mode 100644 index 00000000000..65afe097ab5 --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/naming_data.psdl @@ -0,0 +1,5 @@ +struct Data + { + string name; + string obj_ref; + }; diff --git a/TAO/orbsvcs/examples/PSS/oldmpc_pss b/TAO/orbsvcs/examples/PSS/oldmpc_pss new file mode 100644 index 00000000000..c47c4b1992d --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/oldmpc_pss @@ -0,0 +1,44 @@ +project(*Simple_Naming) : orbsvcslib, portableserver, psdl { + source_files { + Simple_NamingC.cpp + Simple_NamingS.cpp + Simple_Naming_i.cpp + Simple_Naming.cpp + } + idl_files { + Simple_Naming.idl + } +} + +project(*Server) : orbsvcsexe, portableserver, psdl { + after += *Simple_Naming + source_files { + ServerC.cpp + ServerS.cpp + Server_i.cpp + Simple_NamingS.cpp + Simple_NamingC.cpp + Simple_Naming_i.cpp + server.cpp + } + idl_files { + Server.idl + Simple_Naming.idl + } +} + +project(*Client) : orbsvcsexe, psdl, portableserver { + after += *Server + source_files { + Simple_NamingS.cpp + Simple_NamingC.cpp + Simple_Naming_i.cpp + ServerC.cpp + client.cpp + } + idl_files { + Server.idl + Simple_Naming.idl + } +} + diff --git a/TAO/orbsvcs/examples/PSS/server.cpp b/TAO/orbsvcs/examples/PSS/server.cpp new file mode 100644 index 00000000000..0f305dfae1d --- /dev/null +++ b/TAO/orbsvcs/examples/PSS/server.cpp @@ -0,0 +1,108 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/orbsvcs/examples/PSS +// +// = FILENAME +// server.cpp +// +// = DESCRIPTION +// This class implements a simple CORBA server which uses the +// simple_naming.idl to bind and find a object reference and uses +// Persistent State Service to save the information persistently. +// Serves like a mini naming service. +// +// = AUTHOR +// Priyanka Gontla <gontla_p@ociweb.com> +// ============================================================================ + +#include "Simple_Naming_i.h" +#include "Server_i.h" +#include "ace/Get_Opt.h" + +ACE_RCSID (PSS, client, "$Id$") + +int +main (int argc, char *argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // Initialize the ORB. + CORBA::ORB_var orb = + CORBA::ORB_init (argc, + argv, + "" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Get a reference to the RootPOA + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Narrow down to the correct reference + PortableServer::POA_var poa = + PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Set a POA Manager + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Activate the POA Manager + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + Server_i server_i; + + Simple_Server::Server_var server = server_i._this (); + + CORBA::String_var string_obj_ref = + orb->object_to_string (server.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Get a reference to Simple_Naming + CORBA::Object_var simple_naming_object = + orb->resolve_initial_references ("Simple_Naming" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Narrow down the reference + Simple_Naming::Naming_Context_var simple_naming = + Simple_Naming::Naming_Context::_narrow (simple_naming_object.in() + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + Simple_Naming::Name name = CORBA::string_dup ("Server"); + + // Bind the name to stringified objecte refernce + simple_naming->bind (CORBA::string_dup (name), + string_obj_ref.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Unexpected excpeption in PSS Test"); + return -1; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (-1); + + return 0; +} diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.cpp b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.cpp new file mode 100644 index 00000000000..05b214aabbc --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.cpp @@ -0,0 +1,200 @@ +// $Id$ + +#include "Consumer.h" +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/Event_Utilities.h" +#include "orbsvcs/CosNamingC.h" +#include "ace/Arg_Shifter.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID (EC_Examples, + Consumer, + "$Id$") + +const RtecEventComm::EventSourceID MY_SOURCE_ID = ACE_ES_EVENT_SOURCE_ANY + 1; +const RtecEventComm::EventType MY_EVENT_TYPE = ACE_ES_EVENT_UNDEFINED + 1; + +static const char* ecname = 0; + +int +main (int argc, char* argv[]) +{ + Consumer consumer; + + return consumer.run (argc, argv); +} + +// **************************************************************** + +Consumer::Consumer (void) + : event_count_ (0) +{ +} + +int +Consumer::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // First parse our command line options + if (this->parse_args(argc, argv) != 0) + { + return -1; + } + + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Do *NOT* make a copy because we don't want the ORB to outlive + // the run() method. + this->orb_ = orb.in (); + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel from the naming service + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (naming_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to get the Naming Service.\n"), + 1); + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (ecname); + + CORBA::Object_var ec_obj = + naming_context->resolve (name ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::EventChannel_var event_channel = + RtecEventChannelAdmin::EventChannel::_narrow (ec_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (event_channel.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to get Event Channel.\n"), + 1); + + // The canonical protocol to connect to the EC + RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = + event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushSupplier_var supplier = + consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushConsumer_var consumer = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ConsumerQOS_Factory qos; + qos.start_disjunction_group (); + qos.insert (MY_SOURCE_ID, // Source ID + MY_EVENT_TYPE, // Event Type + 0); // handle to the rt_info + for (int i = 0; i < 10; i++) + { + qos.insert (MY_SOURCE_ID + i, // Source ID + MY_EVENT_TYPE + i, // Event Type + 0); // handle to the rt_info + } + supplier->connect_push_consumer (consumer.in (), qos + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Wait for events, using work_pending()/perform_work() may help + // or using another thread, this example is too simple for that. + orb->run (); + + // We don't do any cleanup, it is hard to do it after shutdown, + // and would complicate the example; plus it is almost + // impossible to do cleanup after ORB->run() because the POA is + // in the holding state. Applications should use + // work_pending()/perform_work() to do more interesting stuff. + // Check the supplier for the proper way to do cleanup. + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Consumer::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Consumer::push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (events.length () == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t) no events\n")); + return; + } + + this->event_count_ += events.length (); + if (this->event_count_ % 100 == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t): %d events received\n", + this->event_count_)); + } +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // In this example we shutdown the ORB when we disconnect from the + // EC (or rather the EC disconnects from us), but this doesn't have + // to be the case.... + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} + +int +Consumer::parse_args (int argc, char *argv[]) +{ + ACE_Arg_Shifter arg_shifter (argc, argv); + + while (arg_shifter.is_anything_left ()) + { + const char *arg = arg_shifter.get_current (); + + if (ACE_OS::strcmp (arg, "-e") == 0) + { + arg_shifter.consume_arg (); + ecname = arg_shifter.get_current (); + } + + arg_shifter.ignore_arg (); + } + + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.h b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.h new file mode 100644 index 00000000000..c8268e1c3ea --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Consumer.h @@ -0,0 +1,57 @@ +/* -*- C++ -*- */ +/** + * @file Consumer.h + * + * $Id$ + * + * @author Carlos O'Ryan (coryan@cs.wustl.edu) + * + * Consumer + */ + +#ifndef CONSUMER_H +#define CONSUMER_H + +#include "orbsvcs/RtecEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class Consumer + * + * @brief Simple consumer object + * + * This class is a consumer of events. It simply registers for one event type. + */ +class Consumer : public POA_RtecEventComm::PushConsumer +{ +public: + /// Constructor + Consumer (void); + + /// Run the test + int run (int argc, char* argv[]); + + // = The RtecEventComm::PushConsumer methods + + // The skeleton methods. + virtual void push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + int parse_args (int argc, char *argv[]); + + /// Keep track of the number of events received. + CORBA::ULong event_count_; + + /// The orb, just a pointer because the ORB does not outlive the + /// run() method... + CORBA::ORB_ptr orb_; +}; + +#endif /* CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.cpp b/TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.cpp new file mode 100644 index 00000000000..a25e9f67569 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.cpp @@ -0,0 +1,159 @@ +// $Id$ + +#include "EC.h" +#include "orbsvcs/Event/EC_Event_Channel.h" +#include "orbsvcs/Event/EC_Default_Factory.h" +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/Event/EC_Gateway.h" +#include "ace/Arg_Shifter.h" + +ACE_RCSID (EC_Examples, + Supplier, + "$Id$") + +static const char* ecname = 0; + +int +main (int argc, char* argv[]) +{ + EC channel; + + return channel.run (argc, argv); +} + +// **************************************************************** + +EC::EC (void) +{ +} + +int +EC::run (int argc, char* argv[]) +{ + TAO_EC_Default_Factory::init_svcs (); + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // First parse our command line options + if (this->parse_args(argc, argv) != 0) + { + return -1; + } + + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POA_var rootpoa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POAManager_var root_poa_manager = + rootpoa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Create persistent POA + CORBA::PolicyList policies (2); + policies.length (2); + + policies[0] = + rootpoa->create_id_assignment_policy (PortableServer::USER_ID + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + policies[1] = + rootpoa->create_lifespan_policy (PortableServer::PERSISTENT + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_CString poaname = "POA"; + PortableServer::POA_var child_poa_ = + rootpoa->create_POA (poaname.c_str (), + root_poa_manager.in (), + policies + ACE_ENV_ARG_PARAMETER); + + // Create a local event channel and register it with the RootPOA. + TAO_EC_Event_Channel_Attributes attributes (rootpoa.in (), rootpoa.in ()); + attributes.consumer_reconnect = 1; + attributes.supplier_reconnect = 1; + + TAO_EC_Event_Channel ec_impl (attributes); + ec_impl.activate (); + + PortableServer::ObjectId_var ecId = PortableServer::string_to_ObjectId(ecname); + + child_poa_->activate_object_with_id(ecId.in(), &ec_impl ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var ec_obj = child_poa_->id_to_reference(ecId.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::EventChannel_var ec = + RtecEventChannelAdmin::EventChannel::_narrow(ec_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Find the Naming Service. + object = orb->resolve_initial_references("NameService" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::NamingContextExt_var naming_context = + CosNaming::NamingContextExt::_narrow(object.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Create a name. + CosNaming::Name name; + name.length (1); + name[0].id = CORBA::string_dup (ecname); + name[0].kind = CORBA::string_dup (""); + + // Register with the name server + naming_context->rebind (name, ec.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + root_poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Wait for events, using work_pending()/perform_work() may help + // or using another thread, this example is too simple for that. + orb->run (); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "EC::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +int +EC::parse_args (int argc, char *argv[]) +{ + ACE_Arg_Shifter arg_shifter (argc, argv); + + while (arg_shifter.is_anything_left ()) + { + const char *arg = arg_shifter.get_current (); + + if (ACE_OS::strcmp (arg, "-e") == 0) + { + arg_shifter.consume_arg (); + ecname = arg_shifter.get_current (); + } + + arg_shifter.ignore_arg (); + } + + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.h b/TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.h new file mode 100644 index 00000000000..2734de1dcd0 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/EC.h @@ -0,0 +1,39 @@ +/* -*- C++ -*- */ +/** + * @file EC.h + * + * $Id$ + * + * @author Carlos O'Ryan (coryan@cs.wustl.edu) + * + * Event channel + */ + +#ifndef EC_H +#define EC_H + +#include "orbsvcs/RtecEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class EC + * + * @brief Simple event channel + */ +class EC +{ +public: + /// Constructor + EC (void); + + /// Run the test + int run (int argc, char* argv[]); + +private: + int parse_args (int argc, char *argv[]); +}; + +#endif /* EC_H */ diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.cpp b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.cpp new file mode 100644 index 00000000000..c1be767ffd8 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.cpp @@ -0,0 +1,185 @@ +// $Id$ + +#include "Gateway.h" +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/Event/EC_Gateway_IIOP.h" +#include "orbsvcs/Event/EC_Gateway_IIOP_Factory.h" +#include "ace/Arg_Shifter.h" +#include "ace/Dynamic_Service.h" + +ACE_RCSID (EC_Examples, + Supplier, + "$Id$") + +static const char* supplierec = 0; +static const char* consumerec = 0; + +int +main (int argc, char* argv[]) +{ + Gateway gateway; + + return gateway.run (argc, argv); +} + +// **************************************************************** + +Gateway::Gateway (void) +{ +} + +int +Gateway::run (int argc, char* argv[]) +{ + TAO_EC_Gateway_IIOP_Factory::init_svcs (); + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // First parse our command line options + if (this->parse_args(argc, argv) != 0) + { + return -1; + } + + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel from the naming service + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (naming_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to get the Naming Service.\n"), + 1); + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name supplierecname (1); + supplierecname.length (1); + supplierecname[0].id = CORBA::string_dup (supplierec); + + CORBA::Object_var supplierec_obj = + naming_context->resolve (supplierecname ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name consumerecname (1); + consumerecname.length (1); + consumerecname[0].id = CORBA::string_dup (consumerec); + + CORBA::Object_var consumerec_obj = + naming_context->resolve (consumerecname ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::EventChannel_var supplier_event_channel = + RtecEventChannelAdmin::EventChannel::_narrow (supplierec_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (supplier_event_channel.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to get the supplier event channel.\n"), + 1); + + RtecEventChannelAdmin::EventChannel_var consumer_event_channel = + RtecEventChannelAdmin::EventChannel::_narrow (consumerec_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (consumer_event_channel.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to get the consumer event channel.\n"), + 1); + + TAO_EC_Gateway_IIOP gateway; + + gateway.init(supplier_event_channel.in(), consumer_event_channel.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::ObjectId_var gateway_oid = + poa->activate_object(&gateway ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var gateway_obj = + poa->id_to_reference(gateway_oid.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::Observer_var obs = + RtecEventChannelAdmin::Observer::_narrow(gateway_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::Observer_Handle local_ec_obs_handle = + consumer_event_channel->append_observer (obs.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Wait for events, using work_pending()/perform_work() may help + // or using another thread, this example is too simple for that. + orb->run (); + + consumer_event_channel->remove_observer (local_ec_obs_handle + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + poa->deactivate_object (gateway_oid.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the POA + poa->destroy (1, 0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Gateway::run"); + return 1; + } + ACE_ENDTRY; + + return 0; +} + +int +Gateway::parse_args (int argc, char *argv[]) +{ + ACE_Arg_Shifter arg_shifter (argc, argv); + + while (arg_shifter.is_anything_left ()) + { + const char *arg = arg_shifter.get_current (); + + if (ACE_OS::strcmp (arg, "-s") == 0) + { + arg_shifter.consume_arg (); + supplierec = arg_shifter.get_current (); + } + if (ACE_OS::strcmp (arg, "-c") == 0) + { + arg_shifter.consume_arg (); + consumerec = arg_shifter.get_current (); + } + + arg_shifter.ignore_arg (); + } + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.h b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.h new file mode 100644 index 00000000000..6c7d931d988 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Gateway.h @@ -0,0 +1,38 @@ +/* -*- C++ -*- */ +/** + * @file Gateway.h + * + * $Id$ + * + * @author Johnny Willemsen (jwillemsen@remedy.nl) + * + * IIOP Gateway + */ +#ifndef GATEWAY_H +#define GATEWAY_H + +#include "orbsvcs/RtecEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class Gateway + * + * @brief Simple gateway + */ +class Gateway +{ +public: + /// Constructor + Gateway (void); + + /// Run the test + int run (int argc, char* argv[]); + +private: + int parse_args (int argc, char *argv[]); +}; + +#endif /* GATEWAY_H */ diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Makefile.am b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Makefile.am new file mode 100644 index 00000000000..73c1ace16cb --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Makefile.am @@ -0,0 +1,166 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.RtEC_IIOPGateway.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += Gateway + +Gateway_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +Gateway_SOURCES = \ + Gateway.cpp \ + Gateway.h + +Gateway_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Makefile.RtEC_IIOPGateway_Consumer.am + +if BUILD_CORBA_MESSAGING + +noinst_PROGRAMS += Consumer + +Consumer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +Consumer_SOURCES = \ + Consumer.cpp \ + Consumer.h + +Consumer_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_CORBA_MESSAGING + +## Makefile.RtEC_IIOPGateway_EC.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += EC + +EC_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +EC_SOURCES = \ + EC.cpp \ + EC.h + +EC_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Makefile.RtEC_IIOPGateway_Supplier.am + +if BUILD_CORBA_MESSAGING + +noinst_PROGRAMS += Supplier + +Supplier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +Supplier_SOURCES = \ + Supplier.cpp \ + Supplier.h + +Supplier_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/README b/TAO/orbsvcs/examples/RtEC/IIOPGateway/README new file mode 100644 index 00000000000..501bc694e31 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/README @@ -0,0 +1,19 @@ +# $Id$ + + This directory contains an example of the real-time event service +and the IIOP Gateway. There are four executables, the consumer, supplier, +the channel and the gateway. + + The idea is that we have a supplier that pushes to event channel +channel1, this channel1 pushes the events to the gateway, the gateway to +channel2 and then channel2 to the real consumer. + + Run using the run_test.pl script. + + In the script consumerec_crash script channel2 and the consumer +are killed and restarted after a few seconds. When the gateway uses the +reconnect policy you will see that after the timeout in the gateway has +expired the consumer receives events again. + + More advanced tests are available in +$TAO_ROOT/orbsvcs/tests/Event and $TAO_ROOT/orbsvcs/EC_* diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/RtEC_IIOPGateway.mpc b/TAO/orbsvcs/examples/RtEC/IIOPGateway/RtEC_IIOPGateway.mpc new file mode 100644 index 00000000000..2ece2c2a38d --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/RtEC_IIOPGateway.mpc @@ -0,0 +1,35 @@ +// -*- MPC -*- +// $Id$ + +project(*Consumer): messaging, rteventexe, naming { + requires += corba_messaging + + Source_Files { + Consumer.cpp + } +} + +project(*Supplier): messaging, rteventexe, naming { + requires += corba_messaging + + Source_Files { + Supplier.cpp + } +} + +project(*): messaging, rteventexe, rtevent_serv, naming { + requires += corba_messaging + + Source_Files { + Gateway.cpp + } +} + +project(*EC): messaging, rteventexe, rtevent_serv, naming { + requires += corba_messaging + + Source_Files { + EC.cpp + } +} + diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.cpp b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.cpp new file mode 100644 index 00000000000..aad09c037e8 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.cpp @@ -0,0 +1,195 @@ +// $Id$ + +#include "Supplier.h" +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/Event_Utilities.h" +#include "orbsvcs/CosNamingC.h" +#include "ace/Arg_Shifter.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID (EC_Examples, + Supplier, + "$Id$") + +const RtecEventComm::EventSourceID MY_SOURCE_ID = ACE_ES_EVENT_SOURCE_ANY + 1; +const RtecEventComm::EventType MY_EVENT_TYPE = ACE_ES_EVENT_UNDEFINED + 1; + +static const char* ecname = 0; + +int +main (int argc, char* argv[]) +{ + Supplier supplier; + + return supplier.run (argc, argv); +} + +// **************************************************************** + +Supplier::Supplier (void) +{ +} + +int +Supplier::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // First parse our command line options + if (this->parse_args(argc, argv) != 0) + { + return -1; + } + + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel from the naming service + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (naming_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to get the Naming Service.\n"), + 1); + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup (ecname); + + CORBA::Object_var ec_obj = + naming_context->resolve (name ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::EventChannel_var event_channel = + RtecEventChannelAdmin::EventChannel::_narrow (ec_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The canonical protocol to connect to the EC + RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = + event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushConsumer_var consumer = + supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushSupplier_var supplier = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Publish the events the supplier provides. + ACE_SupplierQOS_Factory qos; + qos.insert (MY_SOURCE_ID, // Supplier's unique id + MY_EVENT_TYPE, // Event type + 0, // handle to the rt_info structure + 1); // number of calls + + consumer->connect_push_supplier (supplier.in (), qos + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Push the events... + ACE_Time_Value sleep_time (0, 10000); // 10 milliseconds + + RtecEventComm::EventSet event (1); + event.length (1); + for (int j = 0; j < 1; j++) + { + event[j].header.source = MY_SOURCE_ID; + event[j].header.ttl = 1; + event[j].header.type = MY_EVENT_TYPE; + } + + for (int i = 1; i != 4000; ++i) + { + if (i % 100 == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Supplier (%P|%t): %d events send\n", + i)); + } + consumer->push (event ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_OS::sleep (sleep_time); + } + + // Disconnect from the EC + consumer->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the EC.... + event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Deactivate this object... + PortableServer::ObjectId_var id = + poa->servant_to_id (this ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the POA + poa->destroy (1, 0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Supplier::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +int +Supplier::parse_args (int argc, char *argv[]) +{ + ACE_Arg_Shifter arg_shifter (argc, argv); + + while (arg_shifter.is_anything_left ()) + { + const char *arg = arg_shifter.get_current (); + + if (ACE_OS::strcmp (arg, "-e") == 0) + { + arg_shifter.consume_arg (); + ecname = arg_shifter.get_current (); + } + + arg_shifter.ignore_arg (); + } + + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.h b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.h new file mode 100644 index 00000000000..98e87ec39d2 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/Supplier.h @@ -0,0 +1,46 @@ +/* -*- C++ -*- */ +/** + * @file Supplier.h + * + * $Id$ + * + * @author Carlos O'Ryan (coryan@cs.wustl.edu) + * + * IIOP Gateway + */ +#ifndef SUPPLIER_H +#define SUPPLIER_H + +#include "orbsvcs/RtecEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +/** + * @class Supplier + * + * @brief Simple supplier object + * + * This class is a supplier of events. It simply publishes one event type. + */ +class Supplier : public POA_RtecEventComm::PushSupplier +{ +public: + /// Constructor + Supplier (void); + + /// Run the test + int run (int argc, char* argv[]); + + // = The RtecEventComm::PushSupplier methods + + /// The skeleton methods. + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + int parse_args (int argc, char *argv[]); +}; + +#endif /* SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/consumerec_crash.pl b/TAO/orbsvcs/examples/RtEC/IIOPGateway/consumerec_crash.pl new file mode 100755 index 00000000000..3267bd38a30 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/consumerec_crash.pl @@ -0,0 +1,150 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../../bin'; +use PerlACE::Run_Test; + +$status = 0; + +$ns_ior = PerlACE::LocalFile ("ns.ior"); +$conffile = PerlACE::LocalFile ("ec" . "$PerlACE::svcconf_ext"); +$gatewayconffile = PerlACE::LocalFile ("gateway" . "$PerlACE::svcconf_ext"); + +unlink $ns_ior; + +$NS = new PerlACE::Process ("../../../Naming_Service/Naming_Service", + "-o $ns_ior"); + +$T1 = new PerlACE::Process ("EC", + "-ORBInitRef NameService=file://$ns_ior " + . "-ORBsvcconf $conffile " +# . "-ORBDebug -ORBDebugLevel 10 -ORBLogFile supplierec.log " + . "-e channel1 "); + +$T2 = new PerlACE::Process ("EC", + "-ORBInitRef NameService=file://$ns_ior -ORBEndpoint iiop://localhost:6000 " + . "-ORBsvcconf $conffile " +# . "-ORBDebug -ORBDebugLevel 10 -ORBLogFile consumerec.log " + . "-e channel2 "); + +$G = new PerlACE::Process ("Gateway", + "-ORBInitRef NameService=file://$ns_ior " + . "-ORBSvcconf $gatewayconffile " + . "-c channel2 " +# . "-ORBDebug -ORBDebugLevel 10 -ORBLogFile gateway.log " + . "-s channel1 "); + +$C = new PerlACE::Process ("Consumer", + "-ORBInitRef NameService=file://$ns_ior " +# . "-ORBDebug -ORBDebugLevel 10 -ORBLogFile consumer.log " + . "-e channel2 "); + +$S = new PerlACE::Process ("Supplier", + "-ORBInitRef NameService=file://$ns_ior " +# . "-ORBDebug -ORBDebugLevel 10 -ORBLogFile supplier.log " + . "-e channel1 "); + +print STDOUT "Starting name server\n"; +$NS->Spawn (); + +if (PerlACE::waitforfile_timed ($ns_ior, 15) == -1) { + print STDERR "ERROR: cannot find file <$ns_ior>\n"; + $NS->Kill (); + exit 1; +} + +print STDOUT "Starting event channel 1\n"; +$T1->Spawn (); + +sleep 2; + +print STDOUT "Starting event channel 2\n"; +$T2->Spawn (); + +sleep 2; + +print STDOUT "Starting gateway\n"; +$G->Spawn (); + +sleep 2; + +print STDOUT "Starting consumer\n"; +$C->Spawn (); + +sleep 1; + +print STDOUT "Starting supplier\n"; +#$supplier = $S->SpawnWaitKill (12000); +$S->Spawn(); + +sleep 1; + +if ($supplier != 0) { + print STDERR "ERROR: supplier returned $supplier\n"; + $status = 1; +} + +#$consumer = $C->WaitKill (10); +# +#if ($consumer != 0) { +# print STDERR "ERROR: consumer returned $consumer\n"; +# $status = 1; +#} + +print STDOUT "Terminating event channel 2 and consumer in 10 seconds...\n"; +#$service = $T2->TerminateWaitKill (5); +$service = $T2->WaitKill (10); +$C->Kill(); + +if ($service != 0) { + print STDERR "ERROR: service returned $service\n"; + $status = 1; +} + +sleep 10; + +print STDOUT "Starting event channel 2 again...\n"; +$T2->Spawn (); + +sleep 2; + +print STDOUT "Starting consumer again...\n"; +$C->Spawn (); + +#$supplier = $C->WaitKill (15); +# +#if ($supplier != 0) { +# print STDERR "ERROR: supplier returned $supplier\n"; +# $status = 1; +#} + +print STDOUT "1500 seconds before termination...\n"; +sleep 1500; + +print STDOUT "Terminating supplier...\n"; +$S->TerminateWaitKill (5); + +print STDOUT "Terminating consumer...\n"; +$C->TerminateWaitKill (5); + +print STDOUT "Terminating gateway...\n"; +$G->TerminateWaitKill (5); + +print STDOUT "Terminating event channels...\n"; +$T1->TerminateWaitKill (5); +$T2->TerminateWaitKill (5); + +$nserver = $NS->TerminateWaitKill (5); + +if ($nserver != 0) { + print STDERR "ERROR: name server returned $nserver\n"; + $status = 1; +} + +unlink $ns_ior; + +exit $status; diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/ec.conf b/TAO/orbsvcs/examples/RtEC/IIOPGateway/ec.conf new file mode 100644 index 00000000000..73633a3f946 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/ec.conf @@ -0,0 +1,4 @@ +# $Id$ +#static EC_Factory "-ECobserver basic -ECDispatching reactive -ECFiltering basic -ECSupplierFiltering per-supplier -ECProxyConsumerLock thread -ECProxySupplierLock thread -ECConsumerControl reactive -ECSupplierControl reactive -ECConsumerControlPeriod 50000 -ECSupplierControlPeriod 50000" +static EC_Factory "-ECobserver basic " +#static EC_Gateway_IIOP "-ECGIIOPConsumerECControl reactive" diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/ec.conf.xml b/TAO/orbsvcs/examples/RtEC/IIOPGateway/ec.conf.xml new file mode 100644 index 00000000000..8c526f5a8cb --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/ec.conf.xml @@ -0,0 +1,5 @@ +<?xml version='1.0'?> +<ACE_Svc_Conf> + <!-- $Id$ --> + <static id="static EC_Factory "-ECobserver basic ""/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/gateway.conf b/TAO/orbsvcs/examples/RtEC/IIOPGateway/gateway.conf new file mode 100644 index 00000000000..8319c781e4e --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/gateway.conf @@ -0,0 +1,6 @@ +# $Id$ +#static EC_Factory "-ECobserver basic -ECDispatching reactive -ECFiltering basic -ECSupplierFiltering per-supplier -ECProxyConsumerLock thread -ECProxySupplierLock thread -ECConsumerControl reactive -ECSupplierControl reactive -ECConsumerControlPeriod 50000 -ECSupplierControlPeriod 50000" +#static EC_Factory "-ECobserver basic " +#dynamic Logger Service_Object * ACE:_make_ACE_Logging_Strategy() "-f STDERR|VERBOSE_LITE" +static EC_Gateway_IIOP_Factory "-ECGIIOPConsumerECControl reconnect -ECGIIOPConsumerECControlPeriod 1000000 -ECGIIOPConsumerECControlTimeout 500000 -ECGIIOPUseConsumerProxyMap 0" +#static EC_Gateway_IIOP_Factory "-ECGIIOPConsumerECControl reactive -ECGIIOPConsumerECControlPeriod 100000 -ECGIIOPConsumerECControlTimeout 50000" diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/gateway.conf.xml b/TAO/orbsvcs/examples/RtEC/IIOPGateway/gateway.conf.xml new file mode 100644 index 00000000000..39ef790c9d7 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/gateway.conf.xml @@ -0,0 +1,5 @@ +<?xml version='1.0'?> +<ACE_Svc_Conf> + <!-- $Id$ --> + <static id="static EC_Gateway_IIOP_Factory "-ECGIIOPConsumerECControl reconnect -ECGIIOPConsumerECControlPeriod 1000000 -ECGIIOPConsumerECControlTimeout 500000 -ECGIIOPUseConsumerProxyMap 0"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/RtEC/IIOPGateway/run_test.pl b/TAO/orbsvcs/examples/RtEC/IIOPGateway/run_test.pl new file mode 100755 index 00000000000..ba1896e9eb6 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/IIOPGateway/run_test.pl @@ -0,0 +1,124 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../../bin'; +use PerlACE::Run_Test; + +$status = 0; + +$ns_ior = PerlACE::LocalFile ("ns.ior"); +$conffile = PerlACE::LocalFile ("ec" . "$PerlACE::svcconf_ext"); +$gatewayconffile = PerlACE::LocalFile ("gateway" . "$PerlACE::svcconf_ext"); + +unlink $ns_ior; + +$NS = new PerlACE::Process ("../../../Naming_Service/Naming_Service", + "-o $ns_ior "); + +$T1 = new PerlACE::Process ("EC", + "-ORBInitRef NameService=file://$ns_ior " +# . "-ORBDebug -ORBDebugLevel 10 -ORBLogFile supplierec.log " + . "-ORBsvcconf $conffile " + . "-e channel1 "); + +$T2 = new PerlACE::Process ("EC", + "-ORBInitRef NameService=file://$ns_ior " +# . "-ORBDebug -ORBDebugLevel 10 -ORBLogFile consumerec.log " + . "-ORBsvcconf $conffile " + . "-e channel2 "); + +$G = new PerlACE::Process ("Gateway", + "-ORBInitRef NameService=file://$ns_ior " +# . "-ORBDebug -ORBDebugLevel 10 -ORBLogFile gateway.log " + . "-ORBSvcconf $gatewayconffile " + . "-c channel2 " + . "-s channel1 "); + +$C = new PerlACE::Process ("Consumer", + "-ORBInitRef NameService=file://$ns_ior " +# . "-ORBDebug -ORBDebugLevel 10 -ORBLogFile consumer.log " + . "-e channel2 "); + +$S = new PerlACE::Process ("Supplier", + "-ORBInitRef NameService=file://$ns_ior " +# . "-ORBDebug -ORBDebugLevel 10 -ORBLogFile supplier.log " + . "-e channel1 "); + +print STDOUT "Starting name server\n"; +$NS->Spawn (); + +if (PerlACE::waitforfile_timed ($ns_ior, 15) == -1) { + print STDERR "ERROR: cannot find file <$ns_ior>\n"; + $NS->Kill (); + exit 1; +} + +print STDOUT "Starting event channel 1\n"; +$T1->Spawn (); + +sleep 2; + +print STDOUT "Starting event channel 2\n"; +$T2->Spawn (); + +sleep 2; + +print STDOUT "Starting gateway\n"; +$G->Spawn (); + +sleep 2; + +print STDOUT "Starting consumer\n"; +$C->Spawn (); + +sleep 1; + +print STDOUT "Starting supplier\n"; +#$supplier = $S->SpawnWaitKill (12000); +$S->Spawn(); + +sleep 1; + +if ($supplier != 0) { + print STDERR "ERROR: supplier returned $supplier\n"; + $status = 1; +} + +$consumer = $C->WaitKill (10); + +if ($consumer != 0) { + print STDERR "ERROR: consumer returned $consumer\n"; + $status = 1; +} + +$service = $T2->TerminateWaitKill (5); + +if ($service != 0) { + print STDERR "ERROR: service returned $service\n"; + $status = 1; +} + +#$supplier = $C->WaitKill (15); +# +#if ($supplier != 0) { +# print STDERR "ERROR: supplier returned $supplier\n"; +# $status = 1; +#} + +print STDOUT "15 seconds before termination...\n"; +sleep 15; + +$nserver = $NS->TerminateWaitKill (5); + +if ($nserver != 0) { + print STDERR "ERROR: name server returned $nserver\n"; + $status = 1; +} + +unlink $ns_ior; + +exit $status; diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/Consumer.cpp b/TAO/orbsvcs/examples/RtEC/Kokyu/Consumer.cpp new file mode 100644 index 00000000000..4f23249c145 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Kokyu/Consumer.cpp @@ -0,0 +1,32 @@ +// $Id$ + +#include "Consumer.h" + +ACE_RCSID(EC_Examples, Consumer, "$Id$") + +Consumer::Consumer (void) +{ +} + +void +Consumer::push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (events.length () == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t) no events\n")); + return; + } + + ACE_DEBUG ((LM_DEBUG, "Consumer (%P|%t) we received event type %d\n", + events[0].header.type)); +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/Consumer.h b/TAO/orbsvcs/examples/RtEC/Kokyu/Consumer.h new file mode 100644 index 00000000000..bdbdbaad894 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Kokyu/Consumer.h @@ -0,0 +1,55 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Consumer +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef CONSUMER_H +#define CONSUMER_H + +#include "orbsvcs/RtecEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Consumer : public POA_RtecEventComm::PushConsumer +{ + // = TITLE + // Simple consumer object + // + // = DESCRIPTION + // This class is a consumer of events. + // It simply register for two event typesone event type + // The class is just a helper to simplify common tasks in EC + // tests, such as subscribing for a range of events, disconnecting + // from the EC, informing the driver of shutdown messages, etc. + // + // There are several ways to connect and disconnect this class, + // and it is up to the driver program to use the right one. + // +public: + Consumer (void); + // Constructor + + // = The RtecEventComm::PushConsumer methods + + virtual void push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. +}; + +#endif /* CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/Makefile.am b/TAO/orbsvcs/examples/RtEC/Kokyu/Makefile.am new file mode 100644 index 00000000000..f2e00e44bc0 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Kokyu/Makefile.am @@ -0,0 +1,67 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.RtECKokyu.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS = Service + +Service_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs \ + -I$(ACE_ROOT)/Kokyu + +Service_SOURCES = \ + Consumer.cpp \ + Service.cpp \ + Supplier.cpp \ + Consumer.h \ + Supplier.h + +Service_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTKokyuEvent.la \ + $(ACE_BUILDDIR)/Kokyu/libKokyu.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTSched.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/README b/TAO/orbsvcs/examples/RtEC/Kokyu/README new file mode 100644 index 00000000000..f7a98f7acc7 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Kokyu/README @@ -0,0 +1,66 @@ +# $Id$ + +Shows how to use the scheduling service in conjunction with +the real-time event channel. The test also uses the Kokyu +dispatching module within the RTEC, which provides the +dispatching queues for the isolation of events based on +their preemption priority generated by the scheduler. The +test has two consumers and two suppliers. The test also +demonstrates how to use timers in the EC to trigger timeout +events for timeout consumers which inturn act as suppliers +to other consumers. The following shows the test setup. + + +LO_CRIT |-----| +1Hz EC Timer1 ----> TimerConsumer1 ---> Supplier1 --->| |---> Consumer1 + | EC | + | | +1/3Hz EC Timer2 ----> TimerConsumer2 ---> Supplier2 --->| |---> Consumer2 +HI_CRIT |-----| + +The event-channel cooperates with the scheduling service to +compute a schedule and assign priorities to each event. The event +channel will use different queues for those events, each queue +serviced by threads at different priorities. In the above +test case, there will be two dispatching queues, one for each +flow. The 1Hz flow will have higher priority than the 1/3Hz flow +wirh plain RMS scheduling. With MUF scheduling, the HI_CRIT +flow will have higher priority than the LO_CRIT flow. + +The example can be run as follows: + +$ ./Service -s<rms|muf> + +Please make sure you run the example with root privileges. + +Expected output for RMS +----------------------- +You should see the 1Hz events dispatched by a higher priority +thread than the 1/3Hz events. Sample output is shown below. Here +2051 is the thread id of the thread dispatching 1/3Hz events +and 1026 is the thread id of the thread dispatching 1Hz events. +The latter runs at a higher real-time thread priority than the +former under RMS scheduling strategy. + +Consumer (27703|2051) we received event type 17 +Consumer (27703|1026) we received event type 16 +Consumer (27703|1026) we received event type 16 +Consumer (27703|1026) we received event type 16 +Consumer (27703|2051) we received event type 17 + +Expected output for MUF +----------------------- +You should see the 1/3Hz events dispatched by a higher priority +thread than the 1Hz events since the former is more critical +than the latter. Sample output is shown below. Here +2051 is the thread id of the thread dispatching 1Hz events +and 1026 is the thread id of the thread dispatching 1/3Hz events. +The latter runs at a higher real-time thread priority than the +former under MUF scheduling strategy. + +Consumer (28191|2051) we received event type 16 +Consumer (28191|2051) we received event type 16 +Consumer (28191|2051) we received event type 16 +Consumer (28191|1026) we received event type 17 +Consumer (28191|2051) we received event type 16 + diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/RtECKokyu.mpc b/TAO/orbsvcs/examples/RtEC/Kokyu/RtECKokyu.mpc new file mode 100644 index 00000000000..88d36ead38f --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Kokyu/RtECKokyu.mpc @@ -0,0 +1,3 @@ +// $Id$ +project: orbsvcsexe, rtkokyuevent, rtevent_serv { +} diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/Service.cpp b/TAO/orbsvcs/examples/RtEC/Kokyu/Service.cpp new file mode 100644 index 00000000000..3a01a04e9c0 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Kokyu/Service.cpp @@ -0,0 +1,522 @@ +// $Id$ + +#include "orbsvcs/Sched/Reconfig_Scheduler.h" +#include "orbsvcs/Runtime_Scheduler.h" +//#include "orbsvcs/Event/Module_Factory.h" +//#include "orbsvcs/Event/Event_Channel.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/Event_Utilities.h" +#include "orbsvcs/Scheduler_Factory.h" +#include "orbsvcs/Event/EC_Event_Channel.h" +#include "orbsvcs/Event/EC_Default_Factory.h" +#include "orbsvcs/Event/EC_Kokyu_Factory.h" +#include "Consumer.h" +#include "Supplier.h" + + +#include "ace/Get_Opt.h" +#include "ace/Sched_Params.h" +#include "ace/Auto_Ptr.h" +#include "ace/SString.h" +#include "ace/OS_NS_strings.h" +#include "ace/Thread.h" + +ACE_RCSID(EC_Examples, Service, "$Id$") + +namespace +{ + int config_run = 0; + ACE_CString sched_type ="rms"; +} + +inline RtecScheduler::Period_t time_val_to_period (const ACE_Time_Value &tv) +{ + //100s of nanoseconds + return (tv.sec () * 1000000 + tv.usec ())*10; +} + +int parse_args (int argc, char *argv[]); + +typedef TAO_Reconfig_Scheduler<TAO_RMS_FAIR_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX> RECONFIG_RMS_SCHED_TYPE; + +typedef TAO_Reconfig_Scheduler<TAO_MUF_FAIR_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX> RECONFIG_MUF_SCHED_TYPE; + +int +main (int argc, char* argv[]) +{ + //TAO_EC_Default_Factory::init_svcs (); + + TAO_EC_Kokyu_Factory::init_svcs (); + + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) == -1) + { + ACE_ERROR ((LM_ERROR, + "Usage: Service [-o IOR_file_name]\n")); + return 1; + } + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************************************************************** + + // Create an scheduling service + POA_RtecScheduler::Scheduler* sched_impl = 0; + + if (ACE_OS::strcasecmp(sched_type.c_str(), "rms") == 0) + { + ACE_DEBUG ((LM_DEBUG, "Creating RMS scheduler\n")); + ACE_NEW_RETURN (sched_impl, + RECONFIG_RMS_SCHED_TYPE, + 1); + } + else if (ACE_OS::strcasecmp(sched_type.c_str(), "muf") == 0) + { + ACE_DEBUG ((LM_DEBUG, "Creating MUF scheduler\n")); + ACE_NEW_RETURN (sched_impl, + RECONFIG_MUF_SCHED_TYPE, + 1); + } + + RtecScheduler::Scheduler_var scheduler = + sched_impl->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************************************************************** + TAO_EC_Event_Channel_Attributes attributes (poa.in (), + poa.in ()); + attributes.scheduler = scheduler.in (); // no need to dup + + TAO_EC_Event_Channel ec_impl (attributes); + RtecEventChannelAdmin::EventChannel_var event_channel = + ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + // **************************************************************** + + // Create a consumer, intialize its RT_Info structures, and + // connnect to the event channel.... + + Consumer consumer_impl1, consumer_impl2; + + RtecScheduler::handle_t consumer1_rt_info = + scheduler->create ("consumer1" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecScheduler::handle_t consumer2_rt_info = + scheduler->create ("consumer2" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + //consumer's rate will get propagated from the supplier. + //so no need to specify a period here. Specifying + //criticality is crucial since it propagates from + //consumer to supplier. + ACE_Time_Value tv (0,0); + TimeBase::TimeT tmp; + ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); + scheduler->set (consumer1_rt_info, + RtecScheduler::VERY_LOW_CRITICALITY, + tmp, tmp, tmp, + time_val_to_period (tv), + RtecScheduler::VERY_LOW_IMPORTANCE, + tmp, + 0, + RtecScheduler::OPERATION + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + scheduler->set (consumer2_rt_info, + RtecScheduler::VERY_HIGH_CRITICALITY, + tmp, tmp, tmp, + time_val_to_period (tv), + RtecScheduler::VERY_HIGH_IMPORTANCE, + tmp, + 0, + RtecScheduler::OPERATION + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ConsumerQOS_Factory consumer_qos1, consumer_qos2; + //consumer_qos.start_disjunction_group (); + // The types int the range [0,ACE_ES_EVENT_UNDEFINED) are + // reserved for the EC... + consumer_qos1.insert_type (ACE_ES_EVENT_UNDEFINED, + consumer1_rt_info); + + RtecEventChannelAdmin::ConsumerQOS qos = + consumer_qos1.get_ConsumerQOS (); +/* + for (int i=0;i<qos.dependencies.length (); ++i) + { + ACE_DEBUG ((LM_DEBUG, + "consumer_qos1[%d] event.header.type = %d, " + "consumer_qos1[%d] rt_info = %d, " + "consumer_qos1[%d] event.header.source = %d\n", + i,qos.dependencies[i].event.header.type, + i,qos.dependencies[i].rt_info, + i,qos.dependencies[i].event.header.source)); + } +*/ + + consumer_qos2.insert_type (ACE_ES_EVENT_UNDEFINED + 1, + consumer2_rt_info); + + // The canonical protocol to connect to the EC + RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = + event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy1 = + consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy2 = + consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushConsumer_var consumer1 = + consumer_impl1._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushConsumer_var consumer2 = + consumer_impl2._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "connecting consumers\n")); + ACE_DEBUG ((LM_DEBUG, "connecting consumer1\n")); + supplier_proxy1->connect_push_consumer (consumer1.in (), + consumer_qos1.get_ConsumerQOS () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "connecting consumer2\n")); + supplier_proxy2->connect_push_consumer (consumer2.in (), + consumer_qos2.get_ConsumerQOS () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "consumers connected\n")); + + // **************************************************************** + + RtecScheduler::handle_t supplier1_rt_info = + scheduler->create ("supplier1" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecScheduler::handle_t supplier2_rt_info = + scheduler->create ("supplier2" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::EventSourceID supplier_id1 = 1, supplier_id2 = 2; + ACE_SupplierQOS_Factory supplier_qos1, supplier_qos2; + supplier_qos1.insert (supplier_id1, + ACE_ES_EVENT_UNDEFINED, + supplier1_rt_info, + 1 /* number of calls, but what does that mean? */); + supplier_qos2.insert (supplier_id2, + ACE_ES_EVENT_UNDEFINED + 1, + supplier2_rt_info, + 1 /* number of calls, but what does that mean? */); + + // The canonical protocol to connect to the EC + RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = + event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy1 = + supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy2 = + supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + Supplier supplier_impl1(supplier_id1, consumer_proxy1.in ()); + Supplier supplier_impl2(supplier_id2, consumer_proxy2.in ()); + + RtecEventComm::PushSupplier_var supplier1 = + supplier_impl1._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushSupplier_var supplier2 = + supplier_impl2._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "connecting suppliers\n")); + ACE_DEBUG ((LM_DEBUG, "connecting supplier1\n")); + consumer_proxy1->connect_push_supplier (supplier1.in (), + supplier_qos1.get_SupplierQOS () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "connecting supplier2\n")); + consumer_proxy2->connect_push_supplier (supplier2.in (), + supplier_qos2.get_SupplierQOS () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG ((LM_DEBUG, "suppliers connected\n")); + + // **************************************************************** + + //Timer Registration part + + //Timeout consumers for the two suppliers. + Timeout_Consumer timeout_consumer_impl1(&supplier_impl1); + Timeout_Consumer timeout_consumer_impl2(&supplier_impl2); + + RtecScheduler::handle_t supplier1_timeout_consumer_rt_info = + scheduler->create ("supplier1_timeout_consumer" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + //Period = 1sec + tv.set (1,0); + ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); + + scheduler->set (supplier1_timeout_consumer_rt_info, + RtecScheduler::VERY_LOW_CRITICALITY, + tmp, tmp, tmp, + time_val_to_period (tv), + RtecScheduler::VERY_LOW_IMPORTANCE, + tmp, + 0, + RtecScheduler::OPERATION + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecScheduler::handle_t supplier2_timeout_consumer_rt_info = + scheduler->create ("supplier2_timeout_consumer" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + //Period = 3sec + tv.set (3, 0); + ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); + + scheduler->set (supplier2_timeout_consumer_rt_info, + RtecScheduler::VERY_HIGH_CRITICALITY, + tmp, tmp, tmp, + time_val_to_period (tv), + RtecScheduler::VERY_HIGH_IMPORTANCE, + tmp, + 0, + RtecScheduler::OPERATION + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ConsumerQOS_Factory timer_qos1, timer_qos2; + timer_qos1.insert_time (ACE_ES_EVENT_INTERVAL_TIMEOUT, + 10000000, //in 100s of nanosec + supplier1_timeout_consumer_rt_info); + timer_qos2.insert_time (ACE_ES_EVENT_INTERVAL_TIMEOUT, + 30000000, //in 100s of nanosec + supplier2_timeout_consumer_rt_info); + + RtecEventChannelAdmin::ProxyPushSupplier_var timeout_supplier_proxy1 = + consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushSupplier_var timeout_supplier_proxy2 = + consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushConsumer_var safe_timeout_consumer1 = + timeout_consumer_impl1._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushConsumer_var safe_timeout_consumer2 = + timeout_consumer_impl2._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "connecting timeout consumers\n")); + timeout_supplier_proxy1-> + connect_push_consumer (safe_timeout_consumer1.in (), + timer_qos1.get_ConsumerQOS () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + timeout_supplier_proxy2-> + connect_push_consumer (safe_timeout_consumer2.in (), + timer_qos2.get_ConsumerQOS () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "timeout consumers connected\n")); + + // **************************************************************** + //Registering dependency between timeout consumers and our suppliers + //with the scheduler + + scheduler->add_dependency (supplier1_timeout_consumer_rt_info, + supplier1_rt_info, + 1, + RtecBase::TWO_WAY_CALL + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + scheduler->add_dependency (supplier2_timeout_consumer_rt_info, + supplier2_rt_info, + 1, + RtecBase::TWO_WAY_CALL + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************************************************************** + + // At this point the consumer and supplier are connected to the + // EC, they have provided their QoS info to the Scheduling + // Service and the EC has informed the Scheduler about the + // dependencies between them. + // We can now compute the schedule for this configuration... + + // The schedule is returned in this variables.... + + ACE_DEBUG ((LM_DEBUG, "Computing schedule\n")); + RtecScheduler::RT_Info_Set_var infos; + RtecScheduler::Config_Info_Set_var configs; + RtecScheduler::Dependency_Set_var dependencies; + RtecScheduler::Scheduling_Anomaly_Set unsafe_anomalies; + RtecScheduler::Scheduling_Anomaly_Set_var anomalies; + + scheduler->get_rt_info_set (infos.out() ); + scheduler->get_dependency_set (dependencies.out() ); + scheduler->get_config_info_set (configs.out() ); + + ACE_DEBUG ((LM_DEBUG, "Printing intermediate results\n")); + ACE_Scheduler_Factory::dump_schedule (infos.in (), + dependencies.in (), + configs.in (), + unsafe_anomalies, + "schedule.out"); + + // Obtain the range of valid priorities in the current + // platform, the scheduler hard-code this values in the + // generated file, but in the future we may just use the + // "logical" priorities and define the mapping to OS + // priorities at run-time. + int min_os_priority = + ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, + ACE_SCOPE_THREAD); + int max_os_priority = + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO, + ACE_SCOPE_THREAD); + scheduler->compute_scheduling (min_os_priority, + max_os_priority, + infos.out (), + dependencies.out (), + configs.out (), + anomalies.out () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Dump the schedule to a file.. + ACE_Scheduler_Factory::dump_schedule (infos.in (), + dependencies.in (), + configs.in (), + anomalies.in (), + "schedule.out"); + + // **************************************************************** + ACE_DEBUG ((LM_DEBUG, "Pushing events\n")); + + ACE_hthread_t thr_handle; + ACE_Thread::self (thr_handle); + + int prio = ACE_Sched_Params::priority_max (ACE_SCHED_FIFO); + ACE_OS::thr_setprio (thr_handle, prio); + +// // Generate a few events.... +// RtecEventComm::EventSet event1 (1); +// event1.length (1); +// event1[0].header.type = ACE_ES_EVENT_UNDEFINED; +// event1[0].header.source = supplier_id1; +// event1[0].header.ttl = 1; + +// RtecEventComm::EventSet event2 (1); +// event2.length (1); +// event2[0].header.type = ACE_ES_EVENT_UNDEFINED + 1; +// event2[0].header.source = supplier_id2; +// event2[0].header.ttl = 1; + +// for (int i = 0; i != 200; ++i) +// { +// if (i % 2 == 0) +// { +// consumer_proxy1->push (event1 ACE_ENV_ARG_PARAMETER); +// ACE_TRY_CHECK; +// } +// else +// { +// consumer_proxy2->push (event2 ACE_ENV_ARG_PARAMETER); +// ACE_TRY_CHECK; +// } + +// ACE_Time_Value rate (0, 10000); +// ACE_OS::sleep (rate); +// } + + ACE_DEBUG ((LM_DEBUG, "(%t) activating EC\n")); + ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG ((LM_DEBUG, "EC activated\n")); + + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + + // **************************************************************** + + // We should do a lot of cleanup (disconnect from the EC, + // deactivate all the objects with the POA, etc.) but this is + // just a simple demo so we are going to be lazy. + + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +// **************************************************************** + +int parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "cs:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 's': + sched_type = ACE_TEXT_ALWAYS_CHAR(get_opts.opt_arg ()); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s %s" + "\n", + argv [0], + "-s <rms|muf>"), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/Supplier.cpp b/TAO/orbsvcs/examples/RtEC/Kokyu/Supplier.cpp new file mode 100644 index 00000000000..11b8f70666b --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Kokyu/Supplier.cpp @@ -0,0 +1,71 @@ +// $Id$ + +#include "Supplier.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/Event/EC_Event_Channel.h" +#include "orbsvcs/RtecEventCommC.h" + +ACE_RCSID(EC_Examples, Supplier, "$Id$") + +Supplier::Supplier (RtecEventComm::EventSourceID id, + const RtecEventChannelAdmin::ProxyPushConsumer_ptr consumer_proxy) +:id_ (id), + consumer_proxy_ (consumer_proxy) +{ +} + +void +Supplier::timeout_occured (ACE_ENV_SINGLE_ARG_DECL) +{ + RtecEventComm::EventSet event (1); + if (id_ == 1) + { + event.length (1); + event[0].header.type = ACE_ES_EVENT_UNDEFINED; + event[0].header.source = id_; + event[0].header.ttl = 1; + } + else + { + event.length (1); + event[0].header.type = ACE_ES_EVENT_UNDEFINED + 1; + event[0].header.source = id_; + event[0].header.ttl = 1; + } + + consumer_proxy_->push (event ACE_ENV_ARG_PARAMETER); +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +Timeout_Consumer::Timeout_Consumer (Supplier* supplier) + :supplier_impl_ (supplier) +{ +} + +void +Timeout_Consumer::push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (events.length () == 0) + { + ACE_DEBUG ((LM_DEBUG, + "TimeoutConsumer (%t) no events\n")); + return; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) Timeout Event received\n")); + supplier_impl_->timeout_occured (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +void +Timeout_Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/Supplier.h b/TAO/orbsvcs/examples/RtEC/Kokyu/Supplier.h new file mode 100644 index 00000000000..977586a3ec0 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Kokyu/Supplier.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Supplier +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef SUPPLIER_H +#define SUPPLIER_H + +#include "orbsvcs/RtecEventCommS.h" +#include "orbsvcs/Event/EC_Event_Channel.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Supplier : public POA_RtecEventComm::PushSupplier +{ + // = TITLE + // Simple supplier object + // + // = DESCRIPTION + // This class is a supplier of events. + // It simply register for two event typesone event type + // The class is just a helper to simplify common tasks in EC + // tests, such as subscribing for a range of events, disconnecting + // from the EC, informing the driver of shutdown messages, etc. + // + // There are several ways to connect and disconnect this class, + // and it is up to the driver program to use the right one. + // +public: + Supplier (RtecEventComm::EventSourceID id, + const RtecEventChannelAdmin::ProxyPushConsumer_ptr consumer_proxy); + // Constructor + + // = The RtecEventComm::PushSupplier methods + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + + void timeout_occured (ACE_ENV_SINGLE_ARG_DECL); + +private: + RtecEventComm::EventSourceID id_; + const RtecEventChannelAdmin::ProxyPushConsumer_ptr consumer_proxy_; +}; + +class Timeout_Consumer : public POA_RtecEventComm::PushConsumer +{ + // = TITLE + // Timer consumer object + // + // = DESCRIPTION + // This class is a consumer of timeout events from EC. + // It registers for timeout event with EC and calls + // the + // +public: + Timeout_Consumer (Supplier * supplier_impl); + // Constructor + + // = The RtecEventComm::PushConsumer methods + + virtual void push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: + Supplier *supplier_impl_; +}; + +#endif /* SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/svc.conf b/TAO/orbsvcs/examples/RtEC/Kokyu/svc.conf new file mode 100644 index 00000000000..60b006dd1ef --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Kokyu/svc.conf @@ -0,0 +1,3 @@ +# $Id$ +#change SCHED_OTHER to SCHED_FIFO or SCHED_RR to run in Real time class +static EC_Factory "-ECProxyPushConsumerCollection mt:immediate:list -ECProxyPushSupplierCollection mt:immediate:list -ECdispatching kokyu SCHED_OTHER -ECscheduling kokyu -ECfiltering kokyu -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier" diff --git a/TAO/orbsvcs/examples/RtEC/Kokyu/svc.conf.xml b/TAO/orbsvcs/examples/RtEC/Kokyu/svc.conf.xml new file mode 100644 index 00000000000..41409e40ec9 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Kokyu/svc.conf.xml @@ -0,0 +1,7 @@ +<?xml version='1.0'?> +<!-- Converted from svc.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <!-- change SCHED_OTHER to SCHED_FIFO or SCHED_RR to run in Real time class --> + <static id="EC_Factory" params="-ECProxyPushConsumerCollection mt:immediate:list -ECProxyPushSupplierCollection mt:immediate:list -ECdispatching kokyu SCHED_OTHER -ECscheduling kokyu -ECfiltering kokyu -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/RtEC/MCast/AddrServer.cpp b/TAO/orbsvcs/examples/RtEC/MCast/AddrServer.cpp new file mode 100644 index 00000000000..05fd4d9c983 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/AddrServer.cpp @@ -0,0 +1,19 @@ +// $Id$ + +#include "AddrServer.h" + +ACE_RCSID(EC_Examples, AddrServer, "$Id$") + +AddrServer::AddrServer (const RtecUDPAdmin::UDP_Addr& addr) + : addr_ (addr) +{ +} + +void +AddrServer::get_addr (const RtecEventComm::EventHeader&, + RtecUDPAdmin::UDP_Addr_out addr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + addr = this->addr_; +} diff --git a/TAO/orbsvcs/examples/RtEC/MCast/AddrServer.h b/TAO/orbsvcs/examples/RtEC/MCast/AddrServer.h new file mode 100644 index 00000000000..8439914f22b --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/AddrServer.h @@ -0,0 +1,53 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Consumer +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef ADDRSERVER_H +#define ADDRSERVER_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/RtecUDPAdminS.h" + +class AddrServer : public POA_RtecUDPAdmin::AddrServer +{ + // = TITLE + // A simple AddrServer + // + // = DESCRIPTION + // The EC is able to use multiple multicast groups to transmit its + // data, the is given control over the mapping between the Event + // (type,source) pair and the (ipaddr,port) pair using a + // AddrServer. + // This class implements a very simple server that simply maps the + // <type> component to the <ipaddr> and uses a fixed <port>, + // provided at initialization time. + // +public: + AddrServer (const RtecUDPAdmin::UDP_Addr& addr); + // Constructor + + // = The RtecUDPAdmin::AddrServer methods + virtual void get_addr (const RtecEventComm::EventHeader& header, + RtecUDPAdmin::UDP_Addr_out addr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + RtecUDPAdmin::UDP_Addr addr_; + // The address +}; + +#include /**/ "ace/post.h" +#endif /* ADDRSERVER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/MCast/Consumer.cpp b/TAO/orbsvcs/examples/RtEC/MCast/Consumer.cpp new file mode 100644 index 00000000000..b85abca57ee --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/Consumer.cpp @@ -0,0 +1,104 @@ +// $Id$ + +#include "Consumer.h" +#include "orbsvcs/RtecEventChannelAdminS.h" +#include "orbsvcs/Event_Service_Constants.h" + +ACE_RCSID (EC_Examples, + Consumer, + "$Id$") + +Consumer::Consumer (void) + : event_count_ (0) +{ +} + +void +Consumer::connect (RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin + ACE_ENV_ARG_DECL) +{ + this->proxy_ = + consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + RtecEventComm::PushConsumer_var me = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Simple subscription, but usually the helper classes in + // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this. + RtecEventChannelAdmin::ConsumerQOS qos; + qos.is_gateway = 0; + + qos.dependencies.length (2); + RtecEventComm::EventHeader& h0 = + qos.dependencies[0].event.header; + h0.type = ACE_ES_DISJUNCTION_DESIGNATOR; + h0.source = 1; // The disjunction has one element + + RtecEventComm::EventHeader& h1 = + qos.dependencies[1].event.header; + h1.type = ACE_ES_EVENT_UNDEFINED; // first free event type + h1.source = ACE_ES_EVENT_SOURCE_ANY; // Any source is OK + + this->proxy_->connect_push_consumer (me.in (), qos + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Consumer::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_TRY + { + // Disconnect from the proxy + this->proxy_->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // Ignore exceptions + } + ACE_ENDTRY; + this->proxy_ = RtecEventChannelAdmin::ProxyPushSupplier::_nil (); + + // Deactivate this object + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + // Get the Object Id used for the servant.. + PortableServer::ObjectId_var oid = + poa->servant_to_id (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + // Deactivate the object + poa->deactivate_object (oid.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Consumer::push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (events.length () == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t) no events\n")); + return; + } + + this->event_count_ += events.length (); + if (this->event_count_ % 100 == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t): %d events received\n", + this->event_count_)); + } +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/examples/RtEC/MCast/Consumer.h b/TAO/orbsvcs/examples/RtEC/MCast/Consumer.h new file mode 100644 index 00000000000..536404b824b --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/Consumer.h @@ -0,0 +1,64 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Consumer +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef CONSUMER_H +#define CONSUMER_H + +#include "orbsvcs/RtecEventCommS.h" +#include "orbsvcs/RtecEventChannelAdminC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Consumer : public POA_RtecEventComm::PushConsumer +{ + // = TITLE + // Simple consumer object + // + // = DESCRIPTION + // This class is a consumer of events. + // It simply subscribes to one event type. + // +public: + Consumer (void); + // Constructor + + void connect (RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin + ACE_ENV_ARG_DECL); + // Connect to the Event Channel + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the event channel + + // = The RtecEventComm::PushConsumer methods + + virtual void push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: + CORBA::ULong event_count_; + // Keep track of the number of events received. + + RtecEventChannelAdmin::ProxyPushSupplier_var proxy_; + // The proxy +}; + +#endif /* CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/MCast/MCast.cpp b/TAO/orbsvcs/examples/RtEC/MCast/MCast.cpp new file mode 100644 index 00000000000..f61cb958eeb --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/MCast.cpp @@ -0,0 +1,379 @@ +// $Id$ + + +#include "Consumer.h" +#include "Supplier.h" +#include "AddrServer.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/Event/EC_Event_Channel.h" +#include "orbsvcs/Event/EC_Default_Factory.h" +#include "orbsvcs/Event/ECG_Mcast_EH.h" +#include "orbsvcs/Event/ECG_UDP_Sender.h" +#include "orbsvcs/Event/ECG_UDP_Receiver.h" +#include "orbsvcs/Event/ECG_UDP_Out_Endpoint.h" +#include "tao/ORB_Core.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID (EC_Examples, + MCast, + "$Id$") + +const char *udp_mcast_address = + ACE_DEFAULT_MULTICAST_ADDR ":10001"; + +int parse_args (int argc, char *argv[]); + +int +main (int argc, char* argv[]) +{ + // Register the default factory in the Service Configurator. + // If your platform supports static constructors then you can + // simply using the ACE_STATIC_SVC_DEFINE() macro, unfortunately TAO + // must run on platforms where static constructors do not work well, + // so we have to explicitly invoke this function. + TAO_EC_Default_Factory::init_svcs (); + + // The exception macros are described in $ACE_ROOT/docs/exceptions.html + // and defined in $ACE_ROOT/ace/CORBA_macros.h. + // If your platform supports native exceptions, and TAO was compiled + // with native exception support then you can simply use try/catch + // and avoid the ACE_ENV_SINGLE_ARG_PARAMETER argument. + // Unfortunately many embedded systems cannot use exceptions due to + // the space and time overhead. + // + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // **************** HERE STARTS THE ORB SETUP + + // Create the ORB, pass the argv list for parsing. + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Parse the arguments, you usually want to do this after + // invoking ORB_init() because ORB_init() will remove all the + // -ORB options from the command line. + if (parse_args (argc, argv) == -1) + { + ACE_ERROR ((LM_ERROR, + "Usage: Service [-m udp_mcast_addr]\n")); + return 1; + } + + // This is the standard code to get access to the POA and + // activate it. + // The POA starts in the holding state, if it is not activated + // it will not process any requests. + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETS THE ORB SETUP + + // **************** HERE START THE LOCAL EVENT CHANNEL SETUP + + // This structure is used to define the startup time event + // channel configuration. + // This structure is described in + // + // $TAO_ROOT/docs/ec_options.html + // + TAO_EC_Event_Channel_Attributes attributes (poa.in (), + poa.in ()); + + // Create the Event Channel implementation class + TAO_EC_Event_Channel ec_impl (attributes); + + // Activate the Event Channel, depending on the configuration + // that may involve creating some threads. + // But it should always be invoked because several internal data + // structures are initialized at that point. + ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The event channel is activated as any other CORBA servant. + // In this case we use the simple implicit activation with the + // RootPOA + RtecEventChannelAdmin::EventChannel_var event_channel = + ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE LOCAL EVENT CHANNEL SETUP + + // **************** HERE STARTS THE FEDERATION SETUP + + // The next step is to setup the multicast gateways. + // There are two gateways involved, one sends the locally + // generated events to the federated peers, the second gateway + // receives multicast traffic and turns it into local events. + + // The sender requires a helper object to select what + // multicast group will carry what traffic, this is the + // so-called 'Address Server'. + // The intention is that advanced applications can use different + // multicast groups for different events, this can exploit + // network interfaces that filter unwanted multicast traffic. + // The helper object is accessed through an IDL interface, so it + // can reside remotely. + // In this example, and in many application, using a fixed + // multicast group is enough, and a local address server is the + // right approach. + + // First we convert the string into an INET address, then we + // convert that into the right IDL structure: + ACE_INET_Addr udp_addr (udp_mcast_address); + ACE_DEBUG ((LM_DEBUG, + "Multicast address is: %s\n", + udp_mcast_address)); + RtecUDPAdmin::UDP_Addr addr; + addr.ipaddr = udp_addr.get_ip_address (); + addr.port = udp_addr.get_port_number (); + + // Now we create and activate the servant + AddrServer as_impl (addr); + RtecUDPAdmin::AddrServer_var address_server = + as_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // We need a local socket to send the data, open it and check + // that everything is OK: + TAO_ECG_Refcounted_Endpoint endpoint(new TAO_ECG_UDP_Out_Endpoint); + if (endpoint->dgram ().open (ACE_Addr::sap_any) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, "Cannot open send endpoint\n"), + 1); + } + + // Now we setup the sender: + TAO_EC_Servant_Var<TAO_ECG_UDP_Sender> sender = TAO_ECG_UDP_Sender::create(); + sender->init (event_channel.in (), + address_server.in (), + endpoint + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Now we connect the sender as a consumer of events, it will + // receive any event from any source and send it to the "right" + // multicast group, as defined by the address server set above: + RtecEventChannelAdmin::ConsumerQOS sub; + sub.is_gateway = 1; + + sub.dependencies.length (1); + sub.dependencies[0].event.header.type = + ACE_ES_EVENT_ANY; // first free event type + sub.dependencies[0].event.header.source = + ACE_ES_EVENT_SOURCE_ANY; // Any source is OK + + sender->connect (sub ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // To receive events we need to setup an event handler: + TAO_EC_Servant_Var<TAO_ECG_UDP_Receiver> receiver = TAO_ECG_UDP_Receiver::create(); + TAO_ECG_Mcast_EH mcast_eh (&(*receiver)); + + // The event handler uses the ORB reactor to wait for multicast + // traffic: + mcast_eh.reactor (orb->orb_core ()->reactor ()); + + // The multicast Event Handler needs to know to what multicast + // groups it should listen to. To do so it becomes an observer + // with the event channel, to determine the list of events + // required by all the local consumer. + // Then it register for the multicast groups that carry those + // events: + mcast_eh.open (event_channel.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Again the receiver connects to the event channel as a + // supplier of events, using the Observer features to detect + // local consumers and their interests: + receiver->init (event_channel.in (), + endpoint, + address_server.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The Receiver is also a supplier of events. The exact type of + // events is only known to the application, because it depends + // on the traffic carried by all the multicast groups that the + // different event handlers subscribe to. + // In this example we choose to simply describe our publications + // using wilcards, any event from any source. More advanced + // application could use the Observer features in the event + // channel to update this information (and reduce the number of + // multicast groups that each receive subscribes to). + // In a future version the event channel could perform some of + // those tasks automatically + RtecEventChannelAdmin::SupplierQOS pub; + pub.publications.length (1); + pub.publications[0].event.header.type = ACE_ES_EVENT_ANY; + pub.publications[0].event.header.source = ACE_ES_EVENT_SOURCE_ANY; + pub.is_gateway = 1; + + receiver->connect (pub ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE FEDERATION SETUP + + // **************** HERE STARTS THE CLIENT SETUP + + // First let us create a consumer and connect it to the event + // channel + Consumer consumer; + RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = + event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + consumer.connect (consumer_admin.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // And now create a supplier + Supplier supplier; + RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = + event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + supplier.connect (supplier_admin.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE CLIENT SETUP + + // **************** HERE STARTS THE EVENT LOOP + + // Wait for events, including incoming multicast data. + // We could also use orb->run(), but that will not let us + // terminate the application in a nice way. + for (int i = 0; i != 1000; ++i) + { + CORBA::Boolean there_is_work = + orb->work_pending (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + if (there_is_work) + { + // We use a TAO extension. The CORBA mechanism does not + // provide any decent way to control the duration of + // perform_work() or work_pending(), so just calling + // them results in a spin loop. + ACE_Time_Value tv (0, 50000); + orb->perform_work (tv ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_Time_Value tv (0, 100000); + ACE_OS::sleep (tv); + supplier.perform_push (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + // **************** THAT COMPLETES THE EVENT LOOP + + // **************** HERE STARTS THE CLEANUP CODE + + // First the easy ones + supplier.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + consumer.disconnect (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Now let us close the Receiver + receiver->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + int r = mcast_eh.shutdown (); + + if (r == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Closing MCast event handler\n"), 1); + } + + // And also close the sender of events + sender->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The event channel must be destroyed, so it can release its + // resources, and inform all the clients that are still + // connected that it is going away. + event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Deactivating the event channel implementation is not strictly + // required, the POA will do it for us, but it is good manners: + { + // Using _this() activates with the default POA, we must gain + // access to that POA to deactivate the object. + // Notice that we 'know' that the default POA for this servant + // is the root POA, but the code is more robust if we don't + // rely on that. + PortableServer::POA_var poa = + ec_impl._default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + // Get the Object Id used for the servant.. + PortableServer::ObjectId_var oid = + poa->servant_to_id (&ec_impl ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + // Deactivate the object + poa->deactivate_object (oid.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + // Now we can destroy the POA, the flags mean that we want to + // wait until the POA is really destroyed + poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Finally destroy the ORB + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************** THAT COMPLETES THE CLEANUP CODE + + ACE_DEBUG ((LM_DEBUG, + "MCast example terminated\n")); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +// **************************************************************** + +int parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "m:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'm': + udp_mcast_address = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "[-m udp_mcast_address]" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/examples/RtEC/MCast/Makefile.am b/TAO/orbsvcs/examples/RtEC/MCast/Makefile.am new file mode 100644 index 00000000000..48805140016 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/Makefile.am @@ -0,0 +1,66 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.RtEC_MCast.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS = MCast + +MCast_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +MCast_SOURCES = \ + AddrServer.cpp \ + Consumer.cpp \ + MCast.cpp \ + Supplier.cpp \ + AddrServer.h \ + Consumer.h \ + Supplier.h + +MCast_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTSched.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/RtEC/MCast/README b/TAO/orbsvcs/examples/RtEC/MCast/README new file mode 100644 index 00000000000..55aad804e20 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/README @@ -0,0 +1,26 @@ +# $Id$ + + This directory contains a very simple example of a +multicast-based federation of event services. + + The example is a single process that contains: + +1) An event service +2) A supplier +3) A consumer +4) The gateways required to send and receive data through the + multicast group. + + The tests should be executed as follows: + +$ MCast + + If you need to set the multicast group and port you can use +the -m option: + +$ MCast -m 224.100.2.1:12345 + + Run the test in multiple machines on the same network. If +there is only one process you should only receive 1000 events in the +local consumer. If there is more than one machine you should receive +more events. diff --git a/TAO/orbsvcs/examples/RtEC/MCast/RtEC_MCast.mpc b/TAO/orbsvcs/examples/RtEC/MCast/RtEC_MCast.mpc new file mode 100644 index 00000000000..ebe69a8ddbc --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/RtEC_MCast.mpc @@ -0,0 +1,5 @@ +// -*- MPC -*- +// $Id$ + +project : orbsvcsexe, rtevent_serv, rtsched { +} diff --git a/TAO/orbsvcs/examples/RtEC/MCast/Supplier.cpp b/TAO/orbsvcs/examples/RtEC/MCast/Supplier.cpp new file mode 100644 index 00000000000..f835dcb6daa --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/Supplier.cpp @@ -0,0 +1,94 @@ +// $Id$ + +#include "Supplier.h" +#include "orbsvcs/RtecEventChannelAdminS.h" +#include "orbsvcs/Event_Service_Constants.h" + +ACE_RCSID (EC_Examples, + Supplier, + "$Id$") + +Supplier::Supplier (void) +{ +} + +void +Supplier::connect (RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin + ACE_ENV_ARG_DECL) +{ + this->proxy_ = + supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + RtecEventComm::PushSupplier_var me = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Simple publication, but usually the helper classes in + // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this. + RtecEventChannelAdmin::SupplierQOS qos; + qos.is_gateway = 0; + + qos.publications.length (1); + RtecEventComm::EventHeader& h0 = + qos.publications[0].event.header; + h0.type = ACE_ES_EVENT_UNDEFINED; // first free event type + h0.source = 1; // first free event source + + this->proxy_->connect_push_supplier (me.in (), qos + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::disconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + // Disconnect from the EC + ACE_TRY + { + this->proxy_->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + } + ACE_ENDTRY; + + PortableServer::POA_var poa = + this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + PortableServer::ObjectId_var id = + poa->servant_to_id (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + +void +Supplier::perform_push (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_TRY + { + // The event type and source must match our publications + RtecEventComm::EventSet event (1); + event.length (1); + event[0].header.type = ACE_ES_EVENT_UNDEFINED; + event[0].header.source = 1; + // Avoid loops throught the event channel federations + event[0].header.ttl = 1; + + this->proxy_->push (event ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + } + ACE_ENDTRY; +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/examples/RtEC/MCast/Supplier.h b/TAO/orbsvcs/examples/RtEC/MCast/Supplier.h new file mode 100644 index 00000000000..7c591f5fdb7 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/Supplier.h @@ -0,0 +1,62 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Supplier +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef SUPPLIER_H +#define SUPPLIER_H + +#include "orbsvcs/RtecEventCommS.h" +#include "orbsvcs/RtecEventChannelAdminC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Supplier : public POA_RtecEventComm::PushSupplier +{ + // = TITLE + // Simple supplier object + // + // = DESCRIPTION + // This class is a supplier of events. + // It simply publishes one event type, when the perform_push() + // method is invoked it pushes the event through the event service + // +public: + Supplier (void); + // Constructor + + void connect (RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin + ACE_ENV_ARG_DECL); + // Connect to the event channel + + void disconnect (ACE_ENV_SINGLE_ARG_DECL); + // Disconnect from the event channel + + void perform_push (ACE_ENV_SINGLE_ARG_DECL); + // Push a single event + + // = The RtecEventComm::PushSupplier methods + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: + RtecEventChannelAdmin::ProxyPushConsumer_var proxy_; + // The proxy +}; + +#endif /* SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/MCast/svc.conf b/TAO/orbsvcs/examples/RtEC/MCast/svc.conf new file mode 100644 index 00000000000..d0297d4649e --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/svc.conf @@ -0,0 +1,2 @@ +# $Id$ +static EC_Factory "-ECObserver basic -ECProxyPushConsumerCollection mt:copy_on_write:list -ECProxyPushSupplierCollection mt:copy_on_write:list -ECDispatching reactive -ECScheduling null -ECFiltering prefix -ECSupplierFilter per-supplier" diff --git a/TAO/orbsvcs/examples/RtEC/MCast/svc.conf.xml b/TAO/orbsvcs/examples/RtEC/MCast/svc.conf.xml new file mode 100644 index 00000000000..159faa97abc --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/MCast/svc.conf.xml @@ -0,0 +1,6 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/examples/RtEC/MCast/svc.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <static id="EC_Factory" params="-ECObserver basic -ECProxyPushConsumerCollection mt:copy_on_write:list -ECProxyPushSupplierCollection mt:copy_on_write:list -ECDispatching reactive -ECScheduling null -ECFiltering prefix -ECSupplierFilter per-supplier"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/RtEC/Makefile.am b/TAO/orbsvcs/examples/RtEC/Makefile.am new file mode 100644 index 00000000000..7fc730d6850 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Makefile.am @@ -0,0 +1,17 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + IIOPGateway \ + Kokyu \ + MCast \ + Schedule \ + Simple + diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/Consumer.cpp b/TAO/orbsvcs/examples/RtEC/Schedule/Consumer.cpp new file mode 100644 index 00000000000..4f23249c145 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/Consumer.cpp @@ -0,0 +1,32 @@ +// $Id$ + +#include "Consumer.h" + +ACE_RCSID(EC_Examples, Consumer, "$Id$") + +Consumer::Consumer (void) +{ +} + +void +Consumer::push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (events.length () == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t) no events\n")); + return; + } + + ACE_DEBUG ((LM_DEBUG, "Consumer (%P|%t) we received event type %d\n", + events[0].header.type)); +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/Consumer.h b/TAO/orbsvcs/examples/RtEC/Schedule/Consumer.h new file mode 100644 index 00000000000..bdbdbaad894 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/Consumer.h @@ -0,0 +1,55 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Consumer +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef CONSUMER_H +#define CONSUMER_H + +#include "orbsvcs/RtecEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Consumer : public POA_RtecEventComm::PushConsumer +{ + // = TITLE + // Simple consumer object + // + // = DESCRIPTION + // This class is a consumer of events. + // It simply register for two event typesone event type + // The class is just a helper to simplify common tasks in EC + // tests, such as subscribing for a range of events, disconnecting + // from the EC, informing the driver of shutdown messages, etc. + // + // There are several ways to connect and disconnect this class, + // and it is up to the driver program to use the right one. + // +public: + Consumer (void); + // Constructor + + // = The RtecEventComm::PushConsumer methods + + virtual void push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. +}; + +#endif /* CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/Makefile.am b/TAO/orbsvcs/examples/RtEC/Schedule/Makefile.am new file mode 100644 index 00000000000..84401da731f --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/Makefile.am @@ -0,0 +1,65 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + + +## Makefile.RtEC_Schedule.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS = Service + +Service_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +Service_SOURCES = \ + Consumer.cpp \ + Service.cpp \ + Supplier.cpp \ + Consumer.h \ + Schedule.h \ + Supplier.h + +Service_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTSched.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/README b/TAO/orbsvcs/examples/RtEC/Schedule/README new file mode 100644 index 00000000000..8435319a51b --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/README @@ -0,0 +1,23 @@ +# $Id$ + + Shows how to use the scheduling service in conjunction with +the real-time event channel. The test has a single consumer that +subscribes for two event types, using different RT_Infos for each. A +supplier pushes those events also using different RT_Infos. + The event-channel cooperates with the scheduling service to +compute a schedule and assign priorities to each event. The event +channel will use different queues for those events, each queue +serviced by threads at different priorities. + + The example can be run using a pre-computed schedule: + +$ ./Service + + or it can generate the schedule again: + +$ ./Service -c + + + NOTE: the current version uses the old event channel because +we haven't coimpleted the integration between the new EC and the +scheduling service. diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/RtEC_Schedule.mpc b/TAO/orbsvcs/examples/RtEC/Schedule/RtEC_Schedule.mpc new file mode 100644 index 00000000000..ebe69a8ddbc --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/RtEC_Schedule.mpc @@ -0,0 +1,5 @@ +// -*- MPC -*- +// $Id$ + +project : orbsvcsexe, rtevent_serv, rtsched { +} diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/Schedule.h b/TAO/orbsvcs/examples/RtEC/Schedule/Schedule.h new file mode 100644 index 00000000000..3a6d4463fa3 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/Schedule.h @@ -0,0 +1,42 @@ +// $Id$ + +// This file was automatically generated by the Scheduler_Factory. +// Before editing the file please consider generating it again. + +#include "orbsvcs/Scheduler_Factory.h" + + +// There were no scheduling anomalies. + + +static ACE_Scheduler_Factory::POD_RT_Info infos[] = { +{"Dispatching_Task-250000.us", 1, 0, 0, 0, 250000, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 1, 58, 4, 1, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{"Dispatching_Task-500000.us", 2, 0, 0, 0, 500000, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 1, 58, 5, 1, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{"Dispatching_Task-1000000.us", 3, 0, 0, 0, 1000000, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 1, 58, 6, 1, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{"Dispatching_Task-2000000.us", 4, 0, 0, 0, 2000000, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 1, 58, 7, 1, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{"Dispatching_Task-10000000.us", 5, 0, 0, 0, 10000000, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 1, 58, 8, 1, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{ "consumer_event_1", 6, 20000, 20000, 20000, 0, (RtecScheduler::Criticality_t) 4, (RtecScheduler::Importance_t) 0, 20000, 0, 59, 0, 0, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{ "consumer_event_2", 7, 10000, 10000, 10000, 0, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 10000, 0, 58, 1, 1, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{"(consumer_event_1#rep||consumer_event_2#rep)", 8, 0, 0, 0, 0, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 0, 58, 3, 1, (RtecScheduler::Info_Type_t) 2 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{"consumer_event_1#rep", 9, 0, 0, 0, 0, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 0, 58, 0, 1, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{"consumer_event_2#rep", 10, 0, 0, 0, 0, (RtecScheduler::Criticality_t) 0, (RtecScheduler::Importance_t) 0, 0, 0, 58, 2, 1, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{ "supplier_event_1", 11, 0, 0, 0, 100000, (RtecScheduler::Criticality_t) 4, (RtecScheduler::Importance_t) 0, 0, 1, 59, 1, 0, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED }, +{ "supplier_event_2", 12, 0, 0, 0, 200000, (RtecScheduler::Criticality_t) 4, (RtecScheduler::Importance_t) 0, 0, 1, 59, 2, 0, (RtecScheduler::Info_Type_t) 0 , (RtecScheduler::RT_Info_Enabled_Type_t) RtecScheduler::RT_INFO_ENABLED } +}; + +static int infos_size = sizeof(infos)/sizeof(infos[0]); + + +static ACE_Scheduler_Factory::POD_Config_Info configs[] = { + { 0, 59, (RtecScheduler::Dispatching_Type_t) 2 }, + { 1, 58, (RtecScheduler::Dispatching_Type_t) 2 } +}; + +static int configs_size = sizeof(configs)/sizeof(configs[0]); + + +// This sets up Scheduler_Factory to use the runtime version. +int scheduler_factory_setup = + ACE_Scheduler_Factory::use_runtime (configs_size, configs, infos_size, infos); + +// EOF diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/Service.cpp b/TAO/orbsvcs/examples/RtEC/Schedule/Service.cpp new file mode 100644 index 00000000000..bb27f0bad68 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/Service.cpp @@ -0,0 +1,408 @@ +// $Id$ + +#include "orbsvcs/Sched/Reconfig_Scheduler.h" +#include "orbsvcs/Runtime_Scheduler.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/Event_Utilities.h" +#include "orbsvcs/Event/EC_Event_Channel.h" +#include "orbsvcs/Event/EC_Default_Factory.h" +#include "Consumer.h" +#include "Supplier.h" + +#include "Schedule.h" + +#include "ace/Get_Opt.h" +#include "ace/Sched_Params.h" +#include "ace/Auto_Ptr.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(EC_Examples, Service, "$Id$") + +int config_run = 0; + +int parse_args (int argc, char *argv[]); + +typedef TAO_Reconfig_Scheduler<TAO_MUF_FAIR_Reconfig_Sched_Strategy, TAO_SYNCH_MUTEX> RECONFIG_SCHED_TYPE; + +int +main (int argc, char* argv[]) +{ + TAO_EC_Default_Factory::init_svcs (); + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) == -1) + { + ACE_ERROR ((LM_ERROR, + "Usage: Service [-o IOR_file_name]\n")); + return 1; + } + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************************************************************** + +#if 0 + // Obtain a reference to the naming service... + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; +#endif /* 0 */ + + // **************************************************************** + + // Create an scheduling service + POA_RtecScheduler::Scheduler* sched_impl = 0; + if (config_run) + { + ACE_NEW_RETURN (sched_impl, + RECONFIG_SCHED_TYPE, + 1); + } + else + { + ACE_NEW_RETURN (sched_impl, + RECONFIG_SCHED_TYPE (configs_size, + configs, + infos_size, + infos, + 0, 0, + 0), + 1); + } + + RtecScheduler::Scheduler_var scheduler = + sched_impl->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + +#if 0 + // Bind the scheduler with the naming service so clients + // (consumers and suppliers) can resolve it, some (old) + // implementations of the EC will try to do the same thing + // (yikes!) + CosNaming::Name schedule_name (1); + schedule_name.length (1); + schedule_name[0].id = CORBA::string_dup ("ScheduleService"); + // Register the servant with the Naming Context.... + naming_context->rebind (schedule_name, scheduler.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; +#endif /* 0 */ + + // **************************************************************** + + TAO_EC_Event_Channel_Attributes attributes (poa.in (), + poa.in ()); + attributes.scheduler = scheduler.in (); // no need to dup + + TAO_EC_Event_Channel ec_impl (attributes); + ACE_DEBUG ((LM_DEBUG, "activating EC\n")); + ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG ((LM_DEBUG, "EC activated\n")); + + RtecEventChannelAdmin::EventChannel_var event_channel = + ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // **************************************************************** + + // Create a consumer, intialize its RT_Info structures, and + // connnect to the event channel.... + + Consumer consumer_impl; + + RtecScheduler::handle_t consumer_rt_info1 = + scheduler->create ("consumer_event_1" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Let's say that the execution time for event 1 is 2 + // milliseconds... + ACE_Time_Value tv (0, 2000); + TimeBase::TimeT time; + ORBSVCS_Time::Time_Value_to_TimeT (time, tv); + scheduler->set (consumer_rt_info1, + RtecScheduler::VERY_HIGH_CRITICALITY, + time, time, time, + 0, + RtecScheduler::VERY_LOW_IMPORTANCE, + time, + 0, + RtecScheduler::OPERATION + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecScheduler::handle_t consumer_rt_info2 = + scheduler->create ("consumer_event_2" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Let's say that the execution time for event 2 is 1 + // milliseconds... + tv.set (0, 1000); + ORBSVCS_Time::Time_Value_to_TimeT (time, tv); + scheduler->set (consumer_rt_info2, + RtecScheduler::VERY_LOW_CRITICALITY, + time, time, time, + 0, + RtecScheduler::VERY_LOW_IMPORTANCE, + time, + 0, + RtecScheduler::OPERATION + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_ConsumerQOS_Factory consumer_qos; + consumer_qos.start_disjunction_group (); + // The types int the range [0,ACE_ES_EVENT_UNDEFINED) are + // reserved for the EC... + consumer_qos.insert_type (ACE_ES_EVENT_UNDEFINED, + consumer_rt_info1); + consumer_qos.insert_type (ACE_ES_EVENT_UNDEFINED + 1, + consumer_rt_info2); + + // The canonical protocol to connect to the EC + RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = + event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy = + consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushConsumer_var consumer = + consumer_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "connecting consumer\n")); + supplier_proxy->connect_push_consumer (consumer.in (), + consumer_qos.get_ConsumerQOS () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG ((LM_DEBUG, "consumer connected\n")); + + // **************************************************************** + + Supplier supplier_impl; + + RtecScheduler::handle_t supplier_rt_info1 = + scheduler->create ("supplier_event_1" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The execution times are set to reasonable values, but + // actually they are changed on the real execution, i.e. we + // lie to the scheduler to obtain right priorities; but we + // don't care if the set is schedulable. + tv.set (0, 10000); + TimeBase::TimeT tmp; + ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); + RtecScheduler::Period_t rate = ACE_U64_TO_U32(tmp); + + scheduler->set (supplier_rt_info1, + RtecScheduler::VERY_HIGH_CRITICALITY, + 0, 0, 0, + rate, + RtecScheduler::VERY_LOW_IMPORTANCE, + 0, + 1, + RtecScheduler::OPERATION + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecScheduler::handle_t supplier_rt_info2 = + scheduler->create ("supplier_event_2" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The execution times are set to reasonable values, but + // actually they are changed on the real execution, i.e. we + // lie to the scheduler to obtain right priorities; but we + // don't care if the set is schedulable. + tv.set (0, 20000); + ORBSVCS_Time::Time_Value_to_TimeT (tmp, tv); + rate = ACE_U64_TO_U32(tmp); + + scheduler->set (supplier_rt_info2, + RtecScheduler::VERY_HIGH_CRITICALITY, + 0, 0, 0, + rate, + RtecScheduler::VERY_LOW_IMPORTANCE, + 0, + 1, + RtecScheduler::OPERATION + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::EventSourceID supplier_id = 1; + ACE_SupplierQOS_Factory supplier_qos; + supplier_qos.insert (supplier_id, + ACE_ES_EVENT_UNDEFINED, + supplier_rt_info1, + 1 /* number of calls, but what does that mean? */); + supplier_qos.insert (supplier_id, + ACE_ES_EVENT_UNDEFINED + 1, + supplier_rt_info2, + 1 /* number of calls, but what does that mean? */); + + // The canonical protocol to connect to the EC + RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = + event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy = + supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushSupplier_var supplier = + supplier_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "connecting supplier\n")); + consumer_proxy->connect_push_supplier (supplier.in (), + supplier_qos.get_SupplierQOS () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG ((LM_DEBUG, "supplier connected\n")); + + // **************************************************************** + + // At this point the consumer and supplier are connected to the + // EC, they have provided their QoS info to the Scheduling + // Service and the EC has informed the Scheduler about the + // dependencies between them. + // We can now compute the schedule for this configuration... + + // The schedule is returned in this variables.... + + if (config_run) + { + ACE_DEBUG ((LM_DEBUG, "Computing schedule\n")); + RtecScheduler::RT_Info_Set_var infos; + RtecScheduler::Dependency_Set_var deps; + RtecScheduler::Config_Info_Set_var configs; + RtecScheduler::Scheduling_Anomaly_Set_var anomalies; + + // Obtain the range of valid priorities in the current + // platform, the scheduler hard-code this values in the + // generated file, but in the future we may just use the + // "logical" priorities and define the mapping to OS + // priorities at run-time. + int min_os_priority = + ACE_Sched_Params::priority_min (ACE_SCHED_FIFO, + ACE_SCOPE_THREAD); + int max_os_priority = + ACE_Sched_Params::priority_max (ACE_SCHED_FIFO, + ACE_SCOPE_THREAD); + scheduler->compute_scheduling (min_os_priority, + max_os_priority, + infos.out (), + deps.out (), + configs.out (), + anomalies.out () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Dump the schedule to a file.. + ACE_Scheduler_Factory::dump_schedule (infos.in (), + deps.in (), + configs.in (), + anomalies.in (), + "schedule.out"); + } + + // **************************************************************** + + ACE_DEBUG ((LM_DEBUG, "Pushing events\n")); + + // Generate a few events.... + + RtecEventComm::EventSet event1 (1); + event1.length (1); + event1[0].header.type = ACE_ES_EVENT_UNDEFINED; + event1[0].header.source = supplier_id; + event1[0].header.ttl = 1; + + RtecEventComm::EventSet event2 (1); + event2.length (1); + event2[0].header.type = ACE_ES_EVENT_UNDEFINED + 1; + event2[0].header.source = supplier_id; + event2[0].header.ttl = 1; + + for (int i = 0; i != 200; ++i) + { + if (i % 2 == 0) + { + consumer_proxy->push (event1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + else + { + consumer_proxy->push (event2 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + ACE_Time_Value rate (0, 10000); + ACE_OS::sleep (rate); + } + + // **************************************************************** + + // We should do a lot of cleanup (disconnect from the EC, + // deactivate all the objects with the POA, etc.) but this is + // just a simple demo so we are going to be lazy. + + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +// **************************************************************** + +int parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "c"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'c': + config_run = 1; + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-c (config run)" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/Supplier.cpp b/TAO/orbsvcs/examples/RtEC/Schedule/Supplier.cpp new file mode 100644 index 00000000000..947378d616a --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/Supplier.cpp @@ -0,0 +1,18 @@ +// $Id$ + +#include "Supplier.h" + +ACE_RCSID (EC_Examples, + Supplier, + "$Id$") + +Supplier::Supplier (void) +{ +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/Supplier.h b/TAO/orbsvcs/examples/RtEC/Schedule/Supplier.h new file mode 100644 index 00000000000..b0391f7602b --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/Supplier.h @@ -0,0 +1,54 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Supplier +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef SUPPLIER_H +#define SUPPLIER_H + +#include "orbsvcs/RtecEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Supplier : public POA_RtecEventComm::PushSupplier +{ + // = TITLE + // Simple supplier object + // + // = DESCRIPTION + // This class is a supplier of events. + // It simply register for two event typesone event type + // The class is just a helper to simplify common tasks in EC + // tests, such as subscribing for a range of events, disconnecting + // from the EC, informing the driver of shutdown messages, etc. + // + // There are several ways to connect and disconnect this class, + // and it is up to the driver program to use the right one. + // +public: + Supplier (void); + // Constructor + + // = The RtecEventComm::PushSupplier methods + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: +}; + +#endif /* SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/svc.conf b/TAO/orbsvcs/examples/RtEC/Schedule/svc.conf new file mode 100644 index 00000000000..c0bbc7fc673 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/svc.conf @@ -0,0 +1,2 @@ +# $Id$ +static EC_Factory "-ECProxyPushConsumerCollection mt:immediate:list -ECProxyPushSupplierCollection mt:immediate:list -ECdispatching priority -ECscheduling priority -ECfiltering priority -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier" diff --git a/TAO/orbsvcs/examples/RtEC/Schedule/svc.conf.xml b/TAO/orbsvcs/examples/RtEC/Schedule/svc.conf.xml new file mode 100644 index 00000000000..8d634c164f8 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Schedule/svc.conf.xml @@ -0,0 +1,6 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/examples/RtEC/Schedule/svc.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <static id="EC_Factory" params="-ECProxyPushConsumerCollection mt:immediate:list -ECProxyPushSupplierCollection mt:immediate:list -ECdispatching priority -ECscheduling priority -ECfiltering priority -ECproxyconsumerlock thread -ECproxysupplierlock thread -ECsupplierfiltering per-supplier"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/RtEC/Simple/Consumer.cpp b/TAO/orbsvcs/examples/RtEC/Simple/Consumer.cpp new file mode 100644 index 00000000000..e8af9a77ed8 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/Consumer.cpp @@ -0,0 +1,162 @@ +// $Id$ + +#include "Consumer.h" +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/CosNamingC.h" + +ACE_RCSID (EC_Examples, + Consumer, + "$Id$") + +int +main (int argc, char* argv[]) +{ + Consumer consumer; + + return consumer.run (argc, argv); +} + +// **************************************************************** + +Consumer::Consumer (void) + : event_count_ (0) +{ +} + +int +Consumer::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Do *NOT* make a copy because we don't want the ORB to outlive + // the run() method. + this->orb_ = orb.in (); + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel from the naming service + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (naming_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to get the Naming Service.\n"), + 1); + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup ("EventService"); + + CORBA::Object_var ec_obj = + naming_context->resolve (name ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::EventChannel_var event_channel = + RtecEventChannelAdmin::EventChannel::_narrow (ec_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The canonical protocol to connect to the EC + RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin = + event_channel->for_consumers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushSupplier_var supplier = + consumer_admin->obtain_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushConsumer_var consumer = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Simple subscription, but usually the helper classes in + // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this. + RtecEventChannelAdmin::ConsumerQOS qos; + qos.dependencies.length (2); + RtecEventComm::EventHeader& h0 = + qos.dependencies[0].event.header; + h0.type = ACE_ES_DISJUNCTION_DESIGNATOR; + h0.source = ACE_ES_EVENT_SOURCE_ANY; + + RtecEventComm::EventHeader& h1 = + qos.dependencies[1].event.header; + h1.type = ACE_ES_EVENT_UNDEFINED; // first free event type + h1.source = ACE_ES_EVENT_SOURCE_ANY; + + supplier->connect_push_consumer (consumer.in (), qos + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Wait for events, using work_pending()/perform_work() may help + // or using another thread, this example is too simple for that. + orb->run (); + + // We don't do any cleanup, it is hard to do it after shutdown, + // and would complicate the example; plus it is almost + // impossible to do cleanup after ORB->run() because the POA is + // in the holding state. Applications should use + // work_pending()/perform_work() to do more interesting stuff. + // Check the supplier for the proper way to do cleanup. + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Consumer::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Consumer::push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + if (events.length () == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t) no events\n")); + return; + } + + this->event_count_ += events.length (); + if (this->event_count_ % 100 == 0) + { + ACE_DEBUG ((LM_DEBUG, + "Consumer (%P|%t): %d events received\n", + this->event_count_)); + } +} + +void +Consumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // In this example we shutdown the ORB when we disconnect from the + // EC (or rather the EC disconnects from us), but this doesn't have + // to be the case.... + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} + diff --git a/TAO/orbsvcs/examples/RtEC/Simple/Consumer.h b/TAO/orbsvcs/examples/RtEC/Simple/Consumer.h new file mode 100644 index 00000000000..19005b96ec1 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/Consumer.h @@ -0,0 +1,60 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Consumer +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef CONSUMER_H +#define CONSUMER_H + +#include "orbsvcs/RtecEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Consumer : public POA_RtecEventComm::PushConsumer +{ + // = TITLE + // Simple consumer object + // + // = DESCRIPTION + // This class is a consumer of events. + // It simply registers for one event type. + // +public: + Consumer (void); + // Constructor + + int run (int argc, char* argv[]); + // Run the test + + // = The RtecEventComm::PushConsumer methods + + virtual void push (const RtecEventComm::EventSet& events + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: + CORBA::ULong event_count_; + // Keep track of the number of events received. + + CORBA::ORB_ptr orb_; + // The orb, just a pointer because the ORB does not outlive the + // run() method... +}; + +#endif /* CONSUMER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/Simple/Makefile.am b/TAO/orbsvcs/examples/RtEC/Simple/Makefile.am new file mode 100644 index 00000000000..d9066e3eddc --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/Makefile.am @@ -0,0 +1,130 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.RtEC_Simple_Consumer.am + +if BUILD_CORBA_MESSAGING + +noinst_PROGRAMS += Consumer + +Consumer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +Consumer_SOURCES = \ + Consumer.cpp \ + Consumer.h + +Consumer_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_CORBA_MESSAGING + +## Makefile.RtEC_Simple_Service.am + +if BUILD_CORBA_MESSAGING +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += Service + +Service_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +Service_SOURCES = \ + Service.cpp \ + Consumer.h \ + Supplier.h + +Service_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Serv.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO +endif BUILD_CORBA_MESSAGING + +## Makefile.RtEC_Simple_Supplier.am + +if BUILD_CORBA_MESSAGING + +noinst_PROGRAMS += Supplier + +Supplier_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) \ + -I$(TAO_ROOT)/orbsvcs \ + -I$(TAO_BUILDDIR)/orbsvcs + +Supplier_SOURCES = \ + Supplier.cpp \ + Supplier.h + +Supplier_LDADD = \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_CosNaming.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent_Skel.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_RTEvent.la \ + $(TAO_BUILDDIR)/orbsvcs/orbsvcs/libTAO_Svc_Utils.la \ + $(TAO_BUILDDIR)/tao/libTAO_Messaging.la \ + $(TAO_BUILDDIR)/tao/libTAO_PI.la \ + $(TAO_BUILDDIR)/tao/libTAO_CodecFactory.la \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_Valuetype.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif BUILD_CORBA_MESSAGING + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/RtEC/Simple/README b/TAO/orbsvcs/examples/RtEC/Simple/README new file mode 100644 index 00000000000..96dae4b1cca --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/README @@ -0,0 +1,15 @@ +# $Id$ + + This directory contains possibly the most simple example of +the real-time event service. It contains three executables; a +consumer, supplier and a program to create the event channel itself. + + Run using the run_test.pl script or: + +$ ../../../Naming_Service/Naming_Service +$ ./Service +$ ./Consumer +$ ./Supplier + + more advanced tests are available in +$TAO_ROOT/orbsvcs/tests/Event and $TAO_ROOT/orbsvcs/tests/EC_* diff --git a/TAO/orbsvcs/examples/RtEC/Simple/RtEC_Simple.mpc b/TAO/orbsvcs/examples/RtEC/Simple/RtEC_Simple.mpc new file mode 100644 index 00000000000..b98ff0f88e4 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/RtEC_Simple.mpc @@ -0,0 +1,20 @@ +// -*- MPC -*- +// $Id$ + +project(*Service) : orbsvcsexe, rtevent_serv, naming { + source_files { + Service.cpp + } +} + +project(*Supplier) : orbsvcsexe, rtevent_skel, naming { + source_files { + Supplier.cpp + } +} + +project(*Consumer) : orbsvcsexe, rtevent_skel, naming { + source_files { + Consumer.cpp + } +} diff --git a/TAO/orbsvcs/examples/RtEC/Simple/Service.cpp b/TAO/orbsvcs/examples/RtEC/Simple/Service.cpp new file mode 100644 index 00000000000..a3bd5e5740d --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/Service.cpp @@ -0,0 +1,141 @@ +// $Id$ + +#include "orbsvcs/Event/EC_Event_Channel.h" +#include "orbsvcs/Event/EC_Default_Factory.h" +#include "ace/Get_Opt.h" +#include "orbsvcs/CosNamingC.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID (EC_Examples, + Service, + "$Id$") + +const char *ior_output_file = "ec.ior"; + +int parse_args (int argc, char *argv[]); + +int +main (int argc, char* argv[]) +{ + TAO_EC_Default_Factory::init_svcs (); + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the naming service + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (naming_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to get the Naming Service.\n"), + 1); + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + TAO_EC_Event_Channel_Attributes attributes (poa.in (), + poa.in ()); + + TAO_EC_Event_Channel ec_impl (attributes); + ec_impl.activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::EventChannel_var event_channel = + ec_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Create a name. + CosNaming::Name name; + name.length (1); + name[0].id = CORBA::string_dup ("EventService"); + name[0].kind = CORBA::string_dup (""); + + // Register with the name server + naming_context->bind (name, event_channel.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Example code: How to write ior to file + CORBA::String_var ior = + orb->object_to_string (event_channel.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG ((LM_DEBUG, "Activated as <%s>\n", ior.in ())); + // If the ior_output_file exists, output the ior to it + if (ior_output_file != 0) + { + FILE *output_file= ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing IOR: %s", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + } + + // Wait for events, using work_pending()/perform_work() may help + // or using another thread, this example is too simple for that. + orb->run (); + + // We don't do any cleanup, it is hard to do it after shutdown, + // and would complicate the example; plus it is almost + // impossible to do cleanup after ORB->run() because the POA is + // in the holding state. Applications should use + // work_pending()/perform_work() to do more interesting stuff. + // Check the supplier for the proper way to do cleanup. + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Service"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +// **************************************************************** + +int parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.opt_arg (); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-o <iorfile>" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + diff --git a/TAO/orbsvcs/examples/RtEC/Simple/Supplier.cpp b/TAO/orbsvcs/examples/RtEC/Simple/Supplier.cpp new file mode 100644 index 00000000000..21ced08639e --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/Supplier.cpp @@ -0,0 +1,152 @@ +// $Id$ + +#include "Supplier.h" +#include "orbsvcs/RtecEventChannelAdminC.h" +#include "orbsvcs/Event_Service_Constants.h" +#include "orbsvcs/CosNamingC.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID (EC_Examples, + Supplier, + "$Id$") + +int +main (int argc, char* argv[]) +{ + Supplier supplier; + + return supplier.run (argc, argv); +} + +// **************************************************************** + +Supplier::Supplier (void) +{ +} + +int +Supplier::run (int argc, char* argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // ORB initialization boiler plate... + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POA_var poa = + PortableServer::POA::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Obtain the event channel from the naming service + CORBA::Object_var naming_obj = + orb->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (naming_obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to get the Naming Service.\n"), + 1); + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name name (1); + name.length (1); + name[0].id = CORBA::string_dup ("EventService"); + + CORBA::Object_var ec_obj = + naming_context->resolve (name ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::EventChannel_var event_channel = + RtecEventChannelAdmin::EventChannel::_narrow (ec_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // The canonical protocol to connect to the EC + RtecEventChannelAdmin::SupplierAdmin_var supplier_admin = + event_channel->for_suppliers (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventChannelAdmin::ProxyPushConsumer_var consumer = + supplier_admin->obtain_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RtecEventComm::PushSupplier_var supplier = + this->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Simple publication, but usually the helper classes in + // $TAO_ROOT/orbsvcs/Event_Utils.h are a better way to do this. + RtecEventChannelAdmin::SupplierQOS qos; + qos.publications.length (1); + RtecEventComm::EventHeader& h0 = + qos.publications[0].event.header; + h0.type = ACE_ES_EVENT_UNDEFINED; // first free event type + h0.source = 1; // first free event source + + consumer->connect_push_supplier (supplier.in (), qos + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Push the events... + ACE_Time_Value sleep_time (0, 10000); // 10 milliseconds + + RtecEventComm::EventSet event (1); + event.length (1); + event[0].header.type = ACE_ES_EVENT_UNDEFINED; + event[0].header.source = 1; + event[0].header.ttl = 1; + + for (int i = 0; i != 2000; ++i) + { + consumer->push (event ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_OS::sleep (sleep_time); + } + + // Disconnect from the EC + consumer->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the EC.... + event_channel->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Deactivate this object... + PortableServer::ObjectId_var id = + poa->servant_to_id (this ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + poa->deactivate_object (id.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Destroy the POA + poa->destroy (1, 0 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Supplier::run"); + return 1; + } + ACE_ENDTRY; + return 0; +} + +void +Supplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + diff --git a/TAO/orbsvcs/examples/RtEC/Simple/Supplier.h b/TAO/orbsvcs/examples/RtEC/Simple/Supplier.h new file mode 100644 index 00000000000..b1fce544ccc --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/Supplier.h @@ -0,0 +1,51 @@ +/* -*- C++ -*- */ +// $Id$ +// +// ============================================================================ +// +// = LIBRARY +// ORBSVCS Real-time Event Channel examples +// +// = FILENAME +// Supplier +// +// = AUTHOR +// Carlos O'Ryan (coryan@cs.wustl.edu) +// +// ============================================================================ + +#ifndef SUPPLIER_H +#define SUPPLIER_H + +#include "orbsvcs/RtecEventCommS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class Supplier : public POA_RtecEventComm::PushSupplier +{ + // = TITLE + // Simple supplier object + // + // = DESCRIPTION + // This class is a supplier of events. + // It simply publishes one event type. + // +public: + Supplier (void); + // Constructor + + int run (int argc, char* argv[]); + // Run the test + + // = The RtecEventComm::PushSupplier methods + + virtual void disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + // The skeleton methods. + +private: +}; + +#endif /* SUPPLIER_H */ diff --git a/TAO/orbsvcs/examples/RtEC/Simple/ec.conf b/TAO/orbsvcs/examples/RtEC/Simple/ec.conf new file mode 100644 index 00000000000..d3d61260f68 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/ec.conf @@ -0,0 +1,2 @@ +# $Id$ +static EC_Factory "-ECDispatching reactive -ECFiltering basic -ECSupplierFiltering per-supplier -ECProxyConsumerLock thread -ECProxySupplierLock thread -ECConsumerControl reactive -ECSupplierControl reactive -ECConsumerControlPeriod 50000 -ECSupplierControlPeriod 50000" diff --git a/TAO/orbsvcs/examples/RtEC/Simple/ec.conf.xml b/TAO/orbsvcs/examples/RtEC/Simple/ec.conf.xml new file mode 100644 index 00000000000..63807cba8d3 --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/ec.conf.xml @@ -0,0 +1,6 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/examples/RtEC/Simple/ec.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <static id="EC_Factory" params="-ECDispatching reactive -ECFiltering basic -ECSupplierFiltering per-supplier -ECProxyConsumerLock thread -ECProxySupplierLock thread -ECConsumerControl reactive -ECSupplierControl reactive -ECConsumerControlPeriod 50000 -ECSupplierControlPeriod 50000"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/RtEC/Simple/run_test.pl b/TAO/orbsvcs/examples/RtEC/Simple/run_test.pl new file mode 100755 index 00000000000..ca45c8b972e --- /dev/null +++ b/TAO/orbsvcs/examples/RtEC/Simple/run_test.pl @@ -0,0 +1,83 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../../bin'; +use PerlACE::Run_Test; + +$status = 0; + +$ns_ior = PerlACE::LocalFile ("ns.ior"); +$conffile = PerlACE::LocalFile ("ec" . "$PerlACE::svcconf_ext"); + +unlink $ns_ior; + +$NS = new PerlACE::Process ("../../../Naming_Service/Naming_Service", + "-o $ns_ior "); + +$T = new PerlACE::Process ("Service", + "-ORBInitRef NameService=file://$ns_ior " + . "-ORBsvcconf $conffile"); + +$C = new PerlACE::Process ("Consumer", + "-ORBInitRef NameService=file://$ns_ior "); + +$S = new PerlACE::Process ("Supplier", + "-ORBInitRef NameService=file://$ns_ior "); + + + +print STDOUT "Starting name server\n"; +$NS->Spawn (); + +if (PerlACE::waitforfile_timed ($ns_ior, 15) == -1) { + print STDERR "ERROR: cannot find file <$ns_ior>\n"; + $NS->Kill (); + exit 1; +} + +print STDOUT "Starting event server\n"; +$T->Spawn (); + +sleep 2; + +print STDOUT "Starting consumer\n"; +$C->Spawn (); + +sleep 1; + +print STDOUT "Starting supplier\n"; +$supplier = $S->SpawnWaitKill (120); + +if ($supplier != 0) { + print STDERR "ERROR: supplier returned $supplier\n"; + $status = 1; +} + +$consumer = $C->WaitKill (15); + +if ($consumer != 0) { + print STDERR "ERROR: consumer returned $consumer\n"; + $status = 1; +} + +$service = $T->TerminateWaitKill (5); + +if ($service != 0) { + print STDERR "ERROR: service returned $service\n"; + $status = 1; +} + +$nserver = $NS->TerminateWaitKill (5); + +if ($nserver != 0) { + print STDERR "ERROR: name server returned $nserver\n"; + $status = 1; +} + +unlink $ns_ior; + +exit $status; diff --git a/TAO/orbsvcs/examples/Security/Makefile.am b/TAO/orbsvcs/examples/Security/Makefile.am new file mode 100644 index 00000000000..9772a9daeed --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Makefile.am @@ -0,0 +1,13 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +SUBDIRS = \ + Send_File + diff --git a/TAO/orbsvcs/examples/Security/README b/TAO/orbsvcs/examples/Security/README new file mode 100644 index 00000000000..db13c886738 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/README @@ -0,0 +1,9 @@ +# $Id$ + +TAO CORBA Security Service Examples +=================================== + +Directory Description +--------- ----------- +Send_File Example that demonstrates use of SSLIOP pluggable protocol + diff --git a/TAO/orbsvcs/examples/Security/SecurityLevel1/README b/TAO/orbsvcs/examples/Security/SecurityLevel1/README new file mode 100644 index 00000000000..a29c58d2ee7 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/SecurityLevel1/README @@ -0,0 +1,47 @@ +$Id$ + +* README * + + + In this example, the server will have some (or may be just +one, if that will serve the purpose .. anyways since these will be +just simple dummy methods, it shouldnt matter) methods with different +levels of authorization. When a client wants to invoke any of these +methods, it has to be authenticated first(I am not sure, as of now, +the way for authenticating or the fact if this is really needed +.. well for starters, I will leave authentication). Then based on the +principals privilege attributes, the invocation will be +successful or denied. + +This test makes use of the Current::get_attributes to get the +attributes of the prinicipal which are used to provide or deny +access. + +We will check the values for all the possible attribute types that a +server could check in the remote case. And, as in the example, run +clients with both valid and invalid credentials. + +Also, we also need to make sure that the server is actually +returning the correct credentials and not garbling or giving some +random values. + +This will prove that + +1. Authorization is working. +2. All the attribute types which are supposed to work are working + properly. +3. Authentication is already working but we could also check that once + again. But, authentication is not limited to the ORB. It could be + checked using an outside agent too. + + + Since, the only thing that the SecurityLevel1 does is to get the +credentials of the initiating principal, to test the implementation, +in my view, + +1. We need to see if the method is returning the correct credentials. +2. If all the attribute types are working... ie.. show what are the + different types of attributes and what can be valid values for them + etc. +3. We need to show how one can make use of these values to provide or + deny access to the initiating principal. diff --git a/TAO/orbsvcs/examples/Security/SecurityLevel1/SLevel1_Test.idl b/TAO/orbsvcs/examples/Security/SecurityLevel1/SLevel1_Test.idl new file mode 100644 index 00000000000..f2c1b7ecbdf --- /dev/null +++ b/TAO/orbsvcs/examples/Security/SecurityLevel1/SLevel1_Test.idl @@ -0,0 +1,10 @@ +/* + * $Id$ + */ + +interface SLevel1_Server +{ + boolean authorize_level1 (); + + boolean authorize_level2 (); +}; diff --git a/TAO/orbsvcs/examples/Security/SecurityLevel1/SLevel1_Test_i.cpp b/TAO/orbsvcs/examples/Security/SecurityLevel1/SLevel1_Test_i.cpp new file mode 100644 index 00000000000..2153014c111 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/SecurityLevel1/SLevel1_Test_i.cpp @@ -0,0 +1,122 @@ +// $Id$ + +#include "SLevel1_Test_i.h" + +#if !defined(__ACE_INLINE__) +#include "test_i.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (SecurityLevel1, + SLevel1_Test_i, + "$Id$") + +static int authorize_1 = 1; +static int authorize_2 = 1; + +CORBA::Boolean +SLevel1_Server_i::authorize_level1 (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + + /// Get a reference to the SecurityCurrent object. + CORBA::Object_var obj = + orb->resolve_initial_references ("SecurityCurrent" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + /// Narrow it down correctly. + SecurityLevel1::Current_var current = + SecurityLevel1::Current::_narrow (obj.in ()); + + /// Check for nil reference. + if (CORBA::is_nil (current.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the SecurityCurrent object\n"), + 1); + + Security::AttributeType desired_attribute_1; + + /// @@ Need to check more abt this variable + desired_attribute.attribute_family.family_definer = 0; + + /// Implies Privilege Attributes + desired_attribute.attribute_family.family = 1; + + /// AccessId: the identity of the principal used for access + /// control + desired_attribute.attibute_type = 2; + + // Second desired attribute + Security::AttributeType desired_attribute_2; + + /// @@ Need to check more abt this variable + desired_attribute.attribute_family.family_definer = 0; + + /// Implies Privilege Attributes. + desired_attribute.attribute_family.family = 1; + + /// Primary Group ID. + /// @@ I am not sure if Ossama will have all these attribute types + /// If it is not the same, one might have to change the comments + /// to show the attribute_type that is checked and change the + /// number accordingly. + desired_attribute.attibute_type = 3; + + /// Define the AttributeTypeList + Security::AttributeTypeList attribute_type_list; + attribute_type_list.length (2); + attribute_type_list[0] = &desired_attribute_1; + attribute_type_list[1] = &desired_attribute_2; + + /// Get the desired security attributes + Security::AttributeList_var attribute_list = + current->get_attributes (attribute_type_list); + + /* @@ What did we do till now ?? + * We set attribute_type_list so that we get the values of + * the variables we are interested in. Depending on how Ossama + * implements, the valid values of family_definer, family and the + * attribute type and its values all change .. but the process is + * similar. + * The type which is returned from the get_attribute method is a + * sequence of the AttributeList struct. This struct has three + * members: the attribute type, the defining_authority and the + * value of the attribute type. + * + * @@ What should we do now ?? + * Compare the returned values with the values we, as in the + * server, decided and check if they are the same. + + * Once we retrieve this sequence, we can invoke a method which + * has a generic list of attribute_types and corresponding values + * which are valid to authorize access to the requested + * invocation. Or complete this stuff with a single if condition + * make things easier. + * + */ + + if ((attribute_type == 1) && (attribute_value == 10)) + { + // Lets say, this is the valid case. + authorize_1 = 0; + } + + /// If the owner of this invocation is authorized to invoke this + /// method, return 0 else return 1. + if (authorize_1 == 0) + return 0; + else + return 1; +} + + +CORBA::Boolean +SLevel1_Server_i::authorize_level2 (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + /// If the owner of this invocation is authorized to invoke this + /// method, return 0 else return 1. + if (authorize_2 == 0) + return 0; + else + return 1; +} diff --git a/TAO/orbsvcs/examples/Security/SecurityLevel1/SLevel1_Test_i.h b/TAO/orbsvcs/examples/Security/SecurityLevel1/SLevel1_Test_i.h new file mode 100644 index 00000000000..d284e65c293 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/SecurityLevel1/SLevel1_Test_i.h @@ -0,0 +1,39 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// orbsvcs/examples/Security/SecurityLevel1 +// +// = FILENAME +// SLevel1_Test_i.h +// +// = AUTHOR +// Priyanka Gontla <gontla_p@ociweb.com> +// +// ============================================================================ + +#ifndef TAO_SLEVEL1_TEST_I_H +#define TAO_SLEVEL1_TEST_I_H + +#include "SLevel1_TestS.h" + +class SLevel1_Server_i : public POA_SLevel1_Server +{ + public: + /// Constructor + SLevel1_Server_i (); + + /// + CORBA::Boolean authorize_level1 (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + + CORBA::Boolean authorize_level2 (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + + static int authorized_1; + static int authorized_2; + +}; + +#endif /* TAO_SLEVEL1_TEST_I_H */ diff --git a/TAO/orbsvcs/examples/Security/SecurityLevel1/client.cpp b/TAO/orbsvcs/examples/Security/SecurityLevel1/client.cpp new file mode 100644 index 00000000000..b7779c65615 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/SecurityLevel1/client.cpp @@ -0,0 +1,89 @@ +// $Id$ + +#include "SLevel1_TestC.h" + +ACE_RCSID (SecurityLevel1, client, "$Id$") + +const char *ior = "file://test.ior"; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-k <ior> " + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv []) +{ + ACE_TRY_NEW_ENV + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) != 0) + return 1; + + CORBA::Object_var object = + orb->string_to_object (ior ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + SLevel1_Server_var server = + SLevel1_Server::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (server.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Object reference <%s> is nil\n", + ior), + 1); + } + + CORBA::Boolean authorized = + server->authorize_level1 (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (authorized == 0) + ACE_DEBUG ((LM_DEBUG, + "AUTHORIZED\n")); + else if (authorized == 1) + ACE_DEBUG ((LM_DEBUG, + "DENIED: You Do NOT have enough privileges\n")); + + server->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Caught exception:"); + return 1; + } + ACE_ENDTRY; + + return 0; +} + diff --git a/TAO/orbsvcs/examples/Security/SecurityLevel1/server.cpp b/TAO/orbsvcs/examples/Security/SecurityLevel1/server.cpp new file mode 100644 index 00000000000..2b39bda82e3 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/SecurityLevel1/server.cpp @@ -0,0 +1,75 @@ +// $Id$ + +#include "SLevel1_Test_i.h" + +ACE_RCSID (SecurityLevel1, + server, + "$Id$") + +const char *ior_output_file = 0; + +int +main (int argc, char *argv[]) +{ + ACE_TRY_NEW_ENV + { + /// Our regular ORB Initialization. + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + /// Get a reference to the RootPOA. + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + /// Narrow down the reference to the currect interface. + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + SLevel1_Server_i level1_server (); + + SLevel1_Server_var server = + level1_server._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::String_var ior = + orb->object_to_string (server.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // If the ior_output_file exists, output the ior to it + if (ior_output_file != 0) + { + FILE *output_file= ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing IOR: %s", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + } + + // Start the ORB + orb->run (); + + root_poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + } + ACE_CATCH (CORBA::SytemException, ex) + { + ACE_DEBUG ((LM_DEBUG, + "System Exception raised: %s", ex)); + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Security/Send_File/Makefile.am b/TAO/orbsvcs/examples/Security/Send_File/Makefile.am new file mode 100644 index 00000000000..c65c9708777 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/Makefile.am @@ -0,0 +1,100 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ../bin/mwc.pl -type automake -noreldefs TAO.mwc + +ACE_BUILDDIR = $(top_builddir)/.. +ACE_ROOT = $(top_srcdir)/.. +TAO_BUILDDIR = $(top_builddir) +TAO_IDL = ACE_ROOT=$(ACE_ROOT) TAO_ROOT=$(TAO_ROOT) $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDL_DEP = $(TAO_BUILDDIR)/TAO_IDL/tao_idl +TAO_IDLFLAGS = -Ge 1 -Wb,pre_include=ace/pre.h -Wb,post_include=ace/post.h -I$(TAO_ROOT) -I$(srcdir) -g $(ACE_BUILDDIR)/apps/gperf/src/gperf +TAO_ROOT = $(top_srcdir) + +## Makefile.Security_Send_File_Idl.am + +BUILT_SOURCES = \ + testC.cpp \ + testC.h \ + testC.inl \ + testS.cpp \ + testS.h \ + testS.inl + +CLEANFILES = \ + test-stamp \ + testC.cpp \ + testC.h \ + testC.inl \ + testS.cpp \ + testS.h \ + testS.inl + +testC.cpp testC.h testC.inl testS.cpp testS.h testS.inl: test-stamp + +test-stamp: $(srcdir)/test.idl $(TAO_IDL_DEP) + $(TAO_IDL) $(TAO_IDLFLAGS) -Sa -St $(srcdir)/test.idl + @touch $@ + + +noinst_HEADERS = \ + test.idl + +## Makefile.Security_Send_File_Client.am + +noinst_PROGRAMS = client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +client_SOURCES = \ + client.cpp \ + testC.cpp \ + test_i.h \ + test_i.i + +client_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Security_Send_File_Server.am + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -I$(TAO_ROOT) \ + -I$(TAO_BUILDDIR) + +server_SOURCES = \ + server.cpp \ + testC.cpp \ + testS.cpp \ + test_i.cpp \ + test_i.h \ + test_i.i + +server_LDADD = \ + $(TAO_BUILDDIR)/tao/libTAO_PortableServer.la \ + $(TAO_BUILDDIR)/tao/libTAO_AnyTypeCode.la \ + $(TAO_BUILDDIR)/tao/libTAO.la \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/TAO/orbsvcs/examples/Security/Send_File/README b/TAO/orbsvcs/examples/Security/Send_File/README new file mode 100644 index 00000000000..c02ca187f21 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/README @@ -0,0 +1,73 @@ +# $Id$ + +Description: + + This is a simple test for SSLIOP, it sends a file, +line-per-line to the server, using truss we can take a look at the +buffers and verify that they are giberish. + +Expected output: + The server prints out the IOR of the object it serves. Later +it prints all the lines sent by the client. The client shouldn't +print out anything, it returns 0 on success. + +How to run: + +# Setup the environment and add the fake CA to your trusted list: +$ SSL_CERT_FILE=cacert.pem +$ export SSL_CERT_FILE + + Now run the simplest test: + +# Run the server +$ server -ORBSvcConf server_nopasswd.conf -o test.ior + +# Run the client +$ client -ORBSvcConf client_nopasswd.conf -k file://test.ior < myfile + + notice that this test uses unsecure private key files. This +could be appropriate if the keys are kept is a very trusted system, +but usually you will want to use a pass phrase protected key: + +$ server -ORBSvcConf server.conf -o test.ior +$ client -ORBSvcConf client.conf -k file://test.ior < myfile + + In this case both the client and the server ask for the pass +phrase (it is 'test'). + +======= Testing IIOP interoperability + + We also want to verify that the client and server (assuming + "-SSLNoProtection" flag is set in server's `server.conf' file) + can interoperate with regular IIOP servers and clients. + First setup a pure IIOP server: + +$ server -o test.ior +$ client -ORBSvcConf client.conf -k file://test.ior < myfile + + next a pure IIOP client (assuming "-SSLNoProtection" flag is + set in server's `server.conf' file): + +$ server -ORBSvcConf server.conf -o test.ior +$ client -k file://test.ior < myfile + + and finally both are pure IIOP: + +$ server -o test.ior +$ client -k file://test.ior < certificate.pem + +======= Testing failed authentications: + + To test failed server authentications we simply run the client +and server as indicated below, but we enter invalid pass phrases in +the client and/or server. + +$ server -ORBSvcConf server.conf -o test.ior +$ client -ORBSvcConf client.conf -k file://test.ior < myfile + +======= Testing connections without client authentication: + + We run the server and client as follows: + +$ server -ORBSvcConf server_none.conf -o test.ior +$ client -ORBSvcConf client.conf -k file://test.ior < myfile diff --git a/TAO/orbsvcs/examples/Security/Send_File/Security_Send_File.mpc b/TAO/orbsvcs/examples/Security/Send_File/Security_Send_File.mpc new file mode 100644 index 00000000000..7752e40754b --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/Security_Send_File.mpc @@ -0,0 +1,31 @@ +// -*- MPC -*- +// $Id$ + +project(*Idl) : taoidldefaults { + IDL_Files { + test.idl + } + custom_only = 1 +} + +project(*Client) : orbsvcsexe, portableserver { + after += *Idl + source_files { + client.cpp + testC.cpp + } + IDL_Files { + } +} + +project(*Server) : orbsvcsexe, portableserver { + after += *Idl + source_files { + server.cpp + test_i.cpp + testS.cpp + testC.cpp + } + IDL_Files { + } +} diff --git a/TAO/orbsvcs/examples/Security/Send_File/cacert.pem b/TAO/orbsvcs/examples/Security/Send_File/cacert.pem new file mode 100644 index 00000000000..a9e905f4e6c --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/cacert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDfTCCAuagAwIBAgIBADANBgkqhkiG9w0BAQQFADCBjDELMAkGA1UEBhMCVVMx +CzAJBgNVBAgTAkNBMQ8wDQYDVQQHEwZJcnZpbmUxEjAQBgNVBAoTCURPQyBHcm91 +cDEQMA4GA1UECxYHVUNJX0RPQzERMA8GA1UEAxMIUHJpeWFua2ExJjAkBgkqhkiG +9w0BCQEWF3Bnb250bGFAZG9jLmVjZS51Y2kuZWR1MB4XDTAxMDYxMTE3MjI0MVoX +DTExMDYwOTE3MjI0MVowgYwxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEPMA0G +A1UEBxMGSXJ2aW5lMRIwEAYDVQQKEwlET0MgR3JvdXAxEDAOBgNVBAsWB1VDSV9E +T0MxETAPBgNVBAMTCFByaXlhbmthMSYwJAYJKoZIhvcNAQkBFhdwZ29udGxhQGRv +Yy5lY2UudWNpLmVkdTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyFiCRDUH +nGJqQG9jT/2PhZUAgfwXvIwfDM8m/WujCt/buDcrOz767shBsk4HZhW91Vm4mE03 +K1zfCzojRigf28uyB/rlp60p2Fq0wvZBNNU5Muia6esleR4unb4QslOpcFhct/9n +UPnlnnsZOTaGWaELNKEjYfHqPh8PQ0lYurECAwEAAaOB7DCB6TAdBgNVHQ4EFgQU +0Y6IZjkLbLbtZ5aoKLcfd7Yc/kYwgbkGA1UdIwSBsTCBroAU0Y6IZjkLbLbtZ5ao +KLcfd7Yc/kahgZKkgY8wgYwxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEPMA0G +A1UEBxMGSXJ2aW5lMRIwEAYDVQQKEwlET0MgR3JvdXAxEDAOBgNVBAsWB1VDSV9E +T0MxETAPBgNVBAMTCFByaXlhbmthMSYwJAYJKoZIhvcNAQkBFhdwZ29udGxhQGRv +Yy5lY2UudWNpLmVkdYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GB +AHYi8ulIzUI3p3+Ma16rumZxvKcmkJJbU6fpAv4ZvK6AWyy+6Ja0GD5N3SGEx+xU +nMffTR+LePa9PAZiR7dNkF6ikPxXZu4jn8KY2zFT3SB/VjCoEetR9i9QI//O0Fea +3yZ0NygNWe5cyVDLCb4meucJpsClfyL28DWzMwD2liX3 +-----END CERTIFICATE----- diff --git a/TAO/orbsvcs/examples/Security/Send_File/client.conf b/TAO/orbsvcs/examples/Security/Send_File/client.conf new file mode 100644 index 00000000000..5847fa22a03 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/client.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:client_key.pem -SSLCertificate PEM:client_cert.pem" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/examples/Security/Send_File/client.conf.xml b/TAO/orbsvcs/examples/Security/Send_File/client.conf.xml new file mode 100644 index 00000000000..957235c7149 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/client.conf.xml @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/examples/Security/Send_File/client.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <dynamic id="SSLIOP_Factory" type="Service_Object"> + <initializer path="TAO_SSLIOP" init="_make_TAO_SSLIOP_Protocol_Factory" params="-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:client_key.pem -SSLCertificate PEM:client_cert.pem"/> + </dynamic> + <static id="Resource_Factory" params="-ORBProtocolFactory SSLIOP_Factory"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/Security/Send_File/client.cpp b/TAO/orbsvcs/examples/Security/Send_File/client.cpp new file mode 100644 index 00000000000..507bdde5847 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/client.cpp @@ -0,0 +1,90 @@ +// $Id$ + +#include "ace/Get_Opt.h" +#include "ace/Read_Buffer.h" +#include "testC.h" + +ACE_RCSID(Send_File, client, "$Id$") + +const char *ior = "file://test.ior"; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + ior = get_opts.opt_arg (); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-k <ior> " + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_TRY_NEW_ENV + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) != 0) + return 1; + + CORBA::Object_var object = + orb->string_to_object (ior ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + Simple_Server_var server = + Simple_Server::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (server.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Object reference <%s> is nil\n", + ior), + 1); + } + + while (!feof (stdin)) + { + ACE_Read_Buffer buf (stdin, 0); + char *line = buf.read ('\n'); + if (line == 0) + break; + server->send_line (line ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + buf.alloc ()->free (line); + } + + server->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Caught exception:"); + return 1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Security/Send_File/client_cert.pem b/TAO/orbsvcs/examples/Security/Send_File/client_cert.pem new file mode 100644 index 00000000000..0bebb696cfc --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/client_cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICgzCCAewCAQYwDQYJKoZIhvcNAQEEBQAwgYwxCzAJBgNVBAYTAlVTMQswCQYD +VQQIEwJDQTEPMA0GA1UEBxMGSXJ2aW5lMRIwEAYDVQQKEwlET0MgR3JvdXAxEDAO +BgNVBAsWB1VDSV9ET0MxETAPBgNVBAMTCFByaXlhbmthMSYwJAYJKoZIhvcNAQkB +FhdwZ29udGxhQGRvYy5lY2UudWNpLmVkdTAeFw0wMTA2MTExODEwMzRaFw0xMTA2 +MDkxODEwMzRaMIGGMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExDzANBgNVBAcT +BklydmluZTEQMA4GA1UEChMHVEFPK09DSTEMMAoGA1UECxMDT0NJMREwDwYDVQQD +EwhQcml5YW5rYTEmMCQGCSqGSIb3DQEJARYXcGdvbnRsYUBkb2MuZWNlLnVjaS5l +ZHUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6f8pBX7Mi3FPY/OYBOq+kb +wQ3WX0Z8+nDxd7AiWDAx2AL5EaX8xnUiRi96OJ+CYPCYOUlavGVzZkRVMFdOuHAn +RvY2sCpvU2rkKpEx9Pd50l7FLnXJuflnRc6zIEKOvuQcPJvsP4AaxaFxTnZExXQJ +kDEiQP3mGID/eXtUzywbAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAuvSoOnMB6sxj +ft9YbdLeyATTPzHbxAb6zQo72DUmM3roNowUrefHymU8jZoC6HeaROeKCU0MkVes +l/jYlz/OwSYkbyGNIUkq4DHEWKzXEg8M603fsWK6IK3T5iPBHY+l/mYSEHJPfypZ +fl/y4YSNJZlrz6kCIHTcwfHXDRC1mjM= +-----END CERTIFICATE----- diff --git a/TAO/orbsvcs/examples/Security/Send_File/client_key.pem b/TAO/orbsvcs/examples/Security/Send_File/client_key.pem new file mode 100644 index 00000000000..1428b501712 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/client_key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQC+n/KQV+zItxT2PzmATqvpG8EN1l9GfPpw8XewIlgwMdgC+RGl +/MZ1IkYvejifgmDwmDlJWrxlc2ZEVTBXTrhwJ0b2NrAqb1Nq5CqRMfT3edJexS51 +ybn5Z0XOsyBCjr7kHDyb7D+AGsWhcU52RMV0CZAxIkD95hiA/3l7VM8sGwIDAQAB +AoGABGaa6fwtqkCXykuRX0XxsBME9PXTA0SVX5AjjDxuvsYXz5HCd4uLZV7iMexn +bD9NT6CkCe5/VPRCEyfIUuutVFc7lkPwuRw5FvNcf4gMH9ltufQfH/KeR7d2Jvge +zrTOH7nicshy67mfOEOaoDphWoT9uy+7ayym+EsJLJU37VkCQQD6xLRu5r9tKX2/ +NfIQsGxF3TZyXgxcuxMh9JOq5E9nBwhr1JaXDbXktXfIK/F3XWHLFS8CIg6PhgGY +i/+UtGzvAkEAwpoHp89U2jLdVRoIcwy5o7Ocwk3HCXem3UgFWXzzunGM1x+ozDFA +uo5nyXiAO6Buka9C2czje275kE18BbqLlQJBAMJNf/EeYdzXdVOfHPzJdlt72CAt +ty5y1ZRNyc10MgIGdQP4KObJ/NJFuZYkVmjCtm+A7neco+OZVcs5TsOOOYkCQBHQ +6EKEyM/xODJCX+OolpZWK1PeqwpC2hQIM/Uta2L2Yl6Pl3SaTcLGptnbHmJXHchY +s1YdW/ZBArgjX+dmXMECQApTKWbVLmNsEoOlHU/I/KhGsfuojrzBMMe3FKLiHpmu +u86L3vu3OGZFcPgjazxWZcip8JekeJ7c+6suLNNRQ5I= +-----END RSA PRIVATE KEY----- diff --git a/TAO/orbsvcs/examples/Security/Send_File/client_key_nopasswd.pem b/TAO/orbsvcs/examples/Security/Send_File/client_key_nopasswd.pem new file mode 100644 index 00000000000..35e449a2493 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/client_key_nopasswd.pem @@ -0,0 +1,16 @@ +RSA key ok +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDBuQXJQhW75XZJfatysGHE3/RXFeMSB8TOk/geXhlUAQTaHj/0 ++eQLNnz2ed8XFoyZFJYioUrcAHyC3LGv7CemhPAW0ZEBgXG8QX1eG8T+NlPh5pC8 +pMg8R67aVr/Rs3jvXsh7lI5rqCQ6Mr1fCg6qVdnJyH04gKKv4b0Iu29FDQIDAQAB +AoGADRU7yM3HvfrPNENicspqr+sYC1GVFkCkD/d6SEK+nye6diiY1SiTOBaj9dlh +MaP6NtRnF0uhTJ5TylqxPVpLixs6Dot/lX0Mu/bD80Zez1bWdQFivszOcDnxylHX +j4z3Sv5nSPWoOgssDVxWNpI9QHcC2E7zII094drJEG/UZIECQQDy0axJBAahSgMX +9CfpWJjXEMKD58RwddbiS2tGboLzdYXUVaE1qr4GN70jypGC4HmWZ6XV5HX4+fy3 +QltXF3GdAkEAzD0VpmOCan7jLty6+qklEwpyzMDJ9VH9QwfMyS5oSO4Dh08lC6WT +Ss+nQlXFwFYszKxd6kznEECGPlKybiC+MQJBANFdsKuUaRMQ+fHhd7hfyAlITi/l +2x8MvCeK2Ah2qTq6jpYy7zmS6x35WYBO3YB3hN8Gp5rxzjbLdfedo5xIfpECQGkk +ASM5EwhT7gxP4YnszYMx28uAa/d4j9KUD156H4F71iEwIzgNsvfOUqKZmUXclw9+ +pJJbqI/7R6CJ3gVHoeECQGpfgurJz2V5Z2/qsZIDJXgxFoW6vY9rZbZU80ZYx3Cb +RINCjB0G0ThsqH7FqCC3PAkEt0xThXqT2SM8ezVlENM= +-----END RSA PRIVATE KEY----- diff --git a/TAO/orbsvcs/examples/Security/Send_File/client_nopasswd.conf b/TAO/orbsvcs/examples/Security/Send_File/client_nopasswd.conf new file mode 100644 index 00000000000..b351c69d88a --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/client_nopasswd.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate NONE -SSLPrivateKey PEM:client_key.pem -SSLCertificate PEM:client_cert.pem" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/examples/Security/Send_File/client_nopasswd.conf.xml b/TAO/orbsvcs/examples/Security/Send_File/client_nopasswd.conf.xml new file mode 100644 index 00000000000..a008b48bff7 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/client_nopasswd.conf.xml @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/examples/Security/Send_File/client_nopasswd.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <dynamic id="SSLIOP_Factory" type="Service_Object"> + <initializer path="TAO_SSLIOP" init="_make_TAO_SSLIOP_Protocol_Factory" params="-SSLAuthenticate NONE -SSLPrivateKey PEM:client_key.pem -SSLCertificate PEM:client_cert.pem"/> + </dynamic> + <static id="Resource_Factory" params="-ORBProtocolFactory SSLIOP_Factory"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/Security/Send_File/run_test.pl b/TAO/orbsvcs/examples/Security/Send_File/run_test.pl new file mode 100755 index 00000000000..b7b2ed47fea --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/run_test.pl @@ -0,0 +1,52 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use Env (ACE_ROOT); + +unshift @INC, "$ACE_ROOT/bin"; +require ACEutils; + +$status = 0; + +# Set the SSL environment +$ENV{'SSL_CERT_FILE'} = 'cacert.pem'; + +$iorfile = "server.ior"; +unlink $iorfile; +$SV = Process::Create ($EXEPREFIX."server$EXE_EXT ", + " -ORBSvcConf server_nopasswd" . + "$PerlACE::svcconf_ext " . + " -o $iorfile"); + +if (ACE::waitforfile_timed ($iorfile, 5) == -1) { + print STDERR "ERROR: cannot find file <$iorfile>\n"; + $SV->Kill (); $SV->TimedWait (1); + exit 1; +} + +$CL = Process::Create ($EXEPREFIX."client$EXE_EXT ", + " -ORBSvcConf client_nopasswd" . + "$PerlACE::svcconf_ext " . + " -k file://$iorfile < client.cpp"); + +$client = $CL->TimedWait (60); +if ($client == -1) { + print STDERR "ERROR: client timedout\n"; + $CL->Kill (); $CL->TimedWait (1); + $status = 1; +} + +$server = $SV->TimedWait (15); +if ($server == -1) { + print STDERR "ERROR: server timedout\n"; + $SV->Kill (); $SV->TimedWait (1); + $status = 1; +} + +unlink $iorfile; + +exit $status; diff --git a/TAO/orbsvcs/examples/Security/Send_File/server.conf b/TAO/orbsvcs/examples/Security/Send_File/server.conf new file mode 100644 index 00000000000..e178933feb9 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/server.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem -SSLNoProtection" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/examples/Security/Send_File/server.conf.xml b/TAO/orbsvcs/examples/Security/Send_File/server.conf.xml new file mode 100644 index 00000000000..ffcee284699 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/server.conf.xml @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/examples/Security/Send_File/server.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <dynamic id="SSLIOP_Factory" type="Service_Object"> + <initializer path="TAO_SSLIOP" init="_make_TAO_SSLIOP_Protocol_Factory" params="-SSLAuthenticate SERVER_AND_CLIENT -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem"/> + </dynamic> + <static id="Resource_Factory" params="-ORBProtocolFactory SSLIOP_Factory"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/Security/Send_File/server.cpp b/TAO/orbsvcs/examples/Security/Send_File/server.cpp new file mode 100644 index 00000000000..97a4beace1c --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/server.cpp @@ -0,0 +1,113 @@ +// $Id$ + +#include "ace/Get_Opt.h" +#include "test_i.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(Send_File, server, "$Id$") + +const char *ior_output_file = 0; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_output_file = get_opts.opt_arg (); + break; + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s " + "-o <iorfile>" + "\n", + argv [0]), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_TRY_NEW_ENV + { + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (parse_args (argc, argv) != 0) + return 1; + + Simple_Server_i server_impl (orb.in ()); + + Simple_Server_var server = + server_impl._this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::String_var ior = + orb->object_to_string (server.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "Activated as <%s>\n", ior.in ())); + + // If the ior_output_file exists, output the ior to it + if (ior_output_file != 0) + { + FILE *output_file= ACE_OS::fopen (ior_output_file, "w"); + if (output_file == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file for writing IOR: %s", + ior_output_file), + 1); + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + } + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "event loop finished\n")); + + root_poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_OS::sleep (5); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Caught exception:"); + return 1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/examples/Security/Send_File/server_cert.pem b/TAO/orbsvcs/examples/Security/Send_File/server_cert.pem new file mode 100644 index 00000000000..0fc394c24d7 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/server_cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICgzCCAewCAQMwDQYJKoZIhvcNAQEEBQAwgYwxCzAJBgNVBAYTAlVTMQswCQYD +VQQIEwJDQTEPMA0GA1UEBxMGSXJ2aW5lMRIwEAYDVQQKEwlET0MgR3JvdXAxEDAO +BgNVBAsWB1VDSV9ET0MxETAPBgNVBAMTCFByaXlhbmthMSYwJAYJKoZIhvcNAQkB +FhdwZ29udGxhQGRvYy5lY2UudWNpLmVkdTAeFw0wMTA2MTExNzQ4NTVaFw0xMTA2 +MDkxNzQ4NTVaMIGGMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExDzANBgNVBAcT +BklydmluZTEMMAoGA1UEChMDT0NJMRAwDgYDVQQLEwdUQU8rT0NJMREwDwYDVQQD +EwhQcml5YW5rYTEmMCQGCSqGSIb3DQEJARYXcGdvbnRsYUBkb2MuZWNlLnVjaS5l +ZHUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANKXmudWiLVu/zdBlSr0/dlr +pRe+Ie26cPyMo5lKiYNY77tABTiOXe5qLUEryjQ/fZ74gmBe4AYFwb7nu/f58X4A +0tzSg2M4spWM7N4tzf+YbcUipRt9sEISxwfUxNNWTKnLxvCmkzOsISisukdzTkqJ +fdzEcPfhO2BZKOdmlg1hAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAjUl3ami01tPY +P1vMp2642dsIKLZis0TmeWp6HNpm52TbiGZOCqDrvtSQ9+2vGz0BkHvGqWKtD+wv +zJH23fNnqFuzy1C1xtjoeqhXECTsWVTVdoEox8hSWxPiYRE2dioraZQQ5ENDosh+ +V9YcqJJpnKDUOSGVGuyaU7DpR8yK0pc= +-----END CERTIFICATE----- diff --git a/TAO/orbsvcs/examples/Security/Send_File/server_key.pem b/TAO/orbsvcs/examples/Security/Send_File/server_key.pem new file mode 100644 index 00000000000..567a41da6dc --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/server_key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDSl5rnVoi1bv83QZUq9P3Za6UXviHtunD8jKOZSomDWO+7QAU4 +jl3uai1BK8o0P32e+IJgXuAGBcG+57v3+fF+ANLc0oNjOLKVjOzeLc3/mG3FIqUb +fbBCEscH1MTTVkypy8bwppMzrCEorLpHc05KiX3cxHD34TtgWSjnZpYNYQIDAQAB +AoGAC/TxpZrjLjH8KZ3+oy6/zv1upTd1Y7MHQT+W9lgmEKAXFHGhGkHzEVtT8HRV +CbxlHIaNmH0qiQ0AoB82K/E0BdIMvE+y2qQwlpMfBMX6/TACORReJN3NXGsXwHP4 +/pNlS4LX7/NZbxlReAlDNP+FO8sdKZTyM3VXHFWJbmm4wsECQQD06zQ4uthp0zI9 +WTZiiAUgYwOcnLnXwfWOLAr8RCnYgwiS7MBCcmhZAgWX5SZJYVCwEJ12DAHy02NJ +EhiSgo+JAkEA3B7PcS5FqZFi6wVjEG6yF8OuSb/rl+FZfV6utZdCVdMPxacEVxlD +q7H/dk23O4WwASBriU0PR9/KG3T/LvKBGQJAaYRn1EUTdcxKqcmkt6CYbNKbvL59 +BqqGq4DoHrUTPjd92ybq0fXOZQKM/Fr6OsUVaTVPUYtsz3wpG1MTiRN82QJACX6+ +vggb8yuVU8QAuPW9cu769q1zsTKEVLcf3C9xKhiXppQEyOkLFT3xYh4KGGQ06meG +m/6Z+SS7KCIM2+6UCQJBANHIzgxDWtrLuWJviNh9EbCsdMioxBH+LGaqFKLC70xD +Pyoqn+QJQu/ekT+FUb0BeFJfGPzFjh1mFYn4tXxWqMs= +-----END RSA PRIVATE KEY----- diff --git a/TAO/orbsvcs/examples/Security/Send_File/server_key_nopasswd.pem b/TAO/orbsvcs/examples/Security/Send_File/server_key_nopasswd.pem new file mode 100644 index 00000000000..2381bdcc6df --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/server_key_nopasswd.pem @@ -0,0 +1,16 @@ +RSA key ok +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDOtfLxhcWktrjY/U9Mdsy9WaUeqFZGWkz2gknKMNrfJnKAdmuU +RaP2G9X565FhgyrEpb5bYJUC3aTLhdr5NsDFt3V1hhs9rev6WSeONmiAlOrUrKCB +cpF3K0HyU4bVp06/FgtWFUp8ja88B8zLhwak6KAGYBUQZXVtMsaJliYLNQIDAQAB +AoGAXIqghPg6j48uGhbtlXHqHysu/Ran6T8sDYAuwNI2aoiv4kshxnOW/+teVFDd ++SXb08XP/uCyVWIdEPCQI9obWppALzQhF5kALhchnlEATkVxkdx6T5PyGnFq5rpc +NCfb3Q68T5bcFvsgup9Lt8JpGBQGvjYJZYkJuMvWmH6Bc9ECQQD4TwB+p5MjRALX +lcMI8pURt6CKxpWLyFUUkQi6HksXzxeh4PDErLxsyFexKec7TOap5xnWZMPkjl76 +BdW65abrAkEA1R0XSCfu3B4LnX4zlDi+nUXG8YvquuZ21TRrNg3YmVcyF+jvkM1f +4MGRPRF3hnTuZhnlD+wEubpmpcoNnNTOXwJBAIfZOQ0SAzblC6UE42puxU2nJ+ck +1EZgeOPCoYKp9i11eJlw5mjDlGbziL59jWttHDlSHVmlUWMm3SFutcsFv7cCQQCK +i+UM5dklhOrsMpV5sQJK4IgblGi/pQBwTym79HhyB/vrC2ZjbwD77xtq5iYcZXxv +KDqAhWH1FLeS5K7A3KBlAkEAqwIhKyV1kK0EtvpNMprfIGNccRjNX8TJEQsN49EE +luhKkAam4CoA1R2wZc0VHfWqilK0qhrezXxlo4OeElxiRg== +-----END RSA PRIVATE KEY----- diff --git a/TAO/orbsvcs/examples/Security/Send_File/server_none.conf b/TAO/orbsvcs/examples/Security/Send_File/server_none.conf new file mode 100644 index 00000000000..e445c19615f --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/server_none.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate NONE -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/examples/Security/Send_File/server_none.conf.xml b/TAO/orbsvcs/examples/Security/Send_File/server_none.conf.xml new file mode 100644 index 00000000000..bb29d1e558d --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/server_none.conf.xml @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/examples/Security/Send_File/server_none.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <dynamic id="SSLIOP_Factory" type="Service_Object"> + <initializer path="TAO_SSLIOP" init="_make_TAO_SSLIOP_Protocol_Factory" params="-SSLAuthenticate NONE -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem"/> + </dynamic> + <static id="Resource_Factory" params="-ORBProtocolFactory SSLIOP_Factory"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/Security/Send_File/server_nopasswd.conf b/TAO/orbsvcs/examples/Security/Send_File/server_nopasswd.conf new file mode 100644 index 00000000000..e445c19615f --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/server_nopasswd.conf @@ -0,0 +1,4 @@ +# $Id$ + +dynamic SSLIOP_Factory Service_Object * TAO_SSLIOP:_make_TAO_SSLIOP_Protocol_Factory() "-SSLAuthenticate NONE -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem" +static Resource_Factory "-ORBProtocolFactory SSLIOP_Factory" diff --git a/TAO/orbsvcs/examples/Security/Send_File/server_nopasswd.conf.xml b/TAO/orbsvcs/examples/Security/Send_File/server_nopasswd.conf.xml new file mode 100644 index 00000000000..9e391e67290 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/server_nopasswd.conf.xml @@ -0,0 +1,9 @@ +<?xml version='1.0'?> +<!-- Converted from ./orbsvcs/examples/Security/Send_File/server_nopasswd.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- $Id$ --> + <dynamic id="SSLIOP_Factory" type="Service_Object"> + <initializer path="TAO_SSLIOP" init="_make_TAO_SSLIOP_Protocol_Factory" params="-SSLAuthenticate NONE -SSLPrivateKey PEM:server_key.pem -SSLCertificate PEM:server_cert.pem"/> + </dynamic> + <static id="Resource_Factory" params="-ORBProtocolFactory SSLIOP_Factory"/> +</ACE_Svc_Conf> diff --git a/TAO/orbsvcs/examples/Security/Send_File/test.idl b/TAO/orbsvcs/examples/Security/Send_File/test.idl new file mode 100644 index 00000000000..a62d8becc91 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/test.idl @@ -0,0 +1,10 @@ +/* + * $Id$ + */ + +interface Simple_Server +{ + void send_line (in string line); + + oneway void shutdown (); +}; diff --git a/TAO/orbsvcs/examples/Security/Send_File/test_i.cpp b/TAO/orbsvcs/examples/Security/Send_File/test_i.cpp new file mode 100644 index 00000000000..62d1ff2e04a --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/test_i.cpp @@ -0,0 +1,24 @@ +// $Id$ + +#include "test_i.h" + +#if !defined(__ACE_INLINE__) +#include "test_i.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(Send_File, test_i, "$Id$") + +void +Simple_Server_i::send_line (const char *line + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, "%s\n", line)); +} + +void +Simple_Server_i::shutdown (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->orb_->shutdown (0); +} diff --git a/TAO/orbsvcs/examples/Security/Send_File/test_i.h b/TAO/orbsvcs/examples/Security/Send_File/test_i.h new file mode 100644 index 00000000000..10b18e60116 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/test_i.h @@ -0,0 +1,49 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/tests/Send_File +// +// = FILENAME +// test_i.h +// +// = AUTHOR +// Carlos O'Ryan +// +// ============================================================================ + +#ifndef TAO_SEND_FILE_TEST_I_H +#define TAO_SEND_FILE_TEST_I_H + +#include "testS.h" + +class Simple_Server_i : public POA_Simple_Server +{ + // = TITLE + // Simpler Server implementation + // + // = DESCRIPTION + // Implements the Simple_Server interface in test.idl + // +public: + Simple_Server_i (CORBA::ORB_ptr orb); + // ctor + + // = The Simple_Server methods. + void send_line (const char *line + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + + void shutdown (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + CORBA::ORB_var orb_; +}; + +#if defined(__ACE_INLINE__) +#include "test_i.i" +#endif /* __ACE_INLINE__ */ + +#endif /* TAO_SEND_FILE_TEST_I_H */ diff --git a/TAO/orbsvcs/examples/Security/Send_File/test_i.i b/TAO/orbsvcs/examples/Security/Send_File/test_i.i new file mode 100644 index 00000000000..97524552ff4 --- /dev/null +++ b/TAO/orbsvcs/examples/Security/Send_File/test_i.i @@ -0,0 +1,7 @@ +// $Id$ + +ACE_INLINE +Simple_Server_i::Simple_Server_i (CORBA::ORB_ptr orb) + : orb_ (CORBA::ORB::_duplicate (orb)) +{ +} diff --git a/TAO/orbsvcs/examples/examples.mwc b/TAO/orbsvcs/examples/examples.mwc new file mode 100644 index 00000000000..dd297256b34 --- /dev/null +++ b/TAO/orbsvcs/examples/examples.mwc @@ -0,0 +1,5 @@ +// -*- MPC -*- +// $Id$ + +workspace { +} |