diff options
-rw-r--r-- | TAO/ChangeLog | 22 | ||||
-rw-r--r-- | TAO/tao/IORManipulation/IORManip_Filter.cpp | 82 | ||||
-rw-r--r-- | TAO/tao/IORManipulation/IORManip_Filter.h | 68 | ||||
-rw-r--r-- | TAO/tao/IORManipulation/IORManip_IIOP_Filter.cpp | 247 | ||||
-rw-r--r-- | TAO/tao/IORManipulation/IORManip_IIOP_Filter.h | 88 | ||||
-rw-r--r-- | TAO/tests/IORManipulation/filter/IORManip_Filter_Test.mpc | 6 | ||||
-rw-r--r-- | TAO/tests/IORManipulation/filter/Test.idl | 7 | ||||
-rwxr-xr-x | TAO/tests/IORManipulation/filter/run_test.pl | 29 | ||||
-rw-r--r-- | TAO/tests/IORManipulation/filter/server.cpp | 87 |
9 files changed, 635 insertions, 1 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 4086e8be57b..ff62da54ca2 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,23 @@ +Mon May 7 11:46:47 UTC 2007 Chad Elliott <elliott_c@ociweb.com> + + * tao/IORManipulation/IORManip_Filter.h: + * tao/IORManipulation/IORManip_Filter.cpp: + * tao/IORManipulation/IORManip_IIOP_Filter.h: + * tao/IORManipulation/IORManip_IIOP_Filter.cpp: + + Added a filter class that allows users to create new object + references based on existing multi-profile object references by + filtering out profiles using user defined criteria. The use of + -ORBUseSharedProfile 0 is required for this to function. + + * tests/IORManipulation/filter/IORManip_Filter_Test.mpc: + * tests/IORManipulation/filter/Test.idl: + * tests/IORManipulation/filter/run_test.pl: + * tests/IORManipulation/filter/server.cpp: + + Added a test to demonstrate the functionality of the filtering + ability. + Fri May 4 14:43:37 UTC 2007 Johnny Willemsen <jwillemsen@remedy.nl> * orbsvcs/orbsvcs/Trader/Trader.cpp: @@ -8,7 +28,7 @@ Fri May 4 14:43:37 UTC 2007 Johnny Willemsen <jwillemsen@remedy.nl> Fri May 4 14:06:39 UTC 2007 Ciju John <johnc at ociweb dot com> * tao/Transport_Connector.cpp: - Made TransportCleanupGuard exception safe. + Made TransportCleanupGuard exception safe. Fri May 4 09:12:37 UTC 2007 Johnny Willemsen <jwillemsen@remedy.nl> diff --git a/TAO/tao/IORManipulation/IORManip_Filter.cpp b/TAO/tao/IORManipulation/IORManip_Filter.cpp new file mode 100644 index 00000000000..3f70b119f08 --- /dev/null +++ b/TAO/tao/IORManipulation/IORManip_Filter.cpp @@ -0,0 +1,82 @@ +// $Id$ + +#include "tao/IORManipulation/IORManip_Filter.h" +#include "tao/IORManipulation/IORManip_Loader.h" +#include "tao/MProfile.h" +#include "tao/ORB_Core.h" +#include "tao/Stub.h" + +ACE_RCSID (IORManip_Filter, IORManip_Filter, "$Id$") + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_IORManip_Filter::TAO_IORManip_Filter (void) +{ +} + + +TAO_IORManip_Filter::~TAO_IORManip_Filter (void) +{ +} + + +CORBA::Object_ptr +TAO_IORManip_Filter::sanitize_profiles (CORBA::Object_ptr object, + TAO_Profile* profile) +{ + return this->sanitize (object, profile); +} + + +CORBA::Object_ptr +TAO_IORManip_Filter::sanitize (CORBA::Object_ptr object, + TAO_Profile* guideline) +{ + TAO_MProfile profiles = object->_stubobj ()->base_profiles (); + TAO_MProfile new_profiles (profiles.profile_count ()); + TAO_Profile* profile = 0; + + while ((profile = profiles.get_next ()) != 0) + { + // Call the filter implementation + this->filter_and_add (profile, new_profiles, guideline); + } + + // The remainder of this code has been lifted from IORManipulation.cpp + CORBA::String_var id = + CORBA::string_dup (object->_stubobj ()->type_id.in ()); + + TAO_ORB_Core *orb_core = object->_stubobj ()->orb_core (); + if (orb_core == 0) + orb_core = TAO_ORB_Core_instance (); + + TAO_Stub *stub = orb_core->create_stub (id.in (), // give the id string to stub + new_profiles); + + // Make the stub memory allocation exception safe for the duration + // of this method. + TAO_Stub_Auto_Ptr safe_stub (stub); + + // Create the CORBA level proxy + CORBA::Object_ptr temp_obj = CORBA::Object::_nil (); + ACE_NEW_THROW_EX (temp_obj, + CORBA::Object (safe_stub.get ()), + CORBA::NO_MEMORY ()); + + CORBA::Object_var new_obj = temp_obj; + + + // Clean up in case of errors. + if (CORBA::is_nil (new_obj.in ())) + { + throw TAO_IOP::Invalid_IOR (); + } + + // Release ownership of the pointers protected by the auto_ptrs since + // they no longer need to be protected by this point. + stub = safe_stub.release (); + + return new_obj._retn (); +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/IORManipulation/IORManip_Filter.h b/TAO/tao/IORManipulation/IORManip_Filter.h new file mode 100644 index 00000000000..e5b98736a97 --- /dev/null +++ b/TAO/tao/IORManipulation/IORManip_Filter.h @@ -0,0 +1,68 @@ +// $Id$ + +// ========================================================================= +// +// = LIBRARY +// TAO +// +// = FILENAME +// IORManip_Filter.h +// +// = AUTHOR +// Chad Elliott <elliott_c@ociweb.com> +// +// ========================================================================= + +#ifndef TAO_IORMANIP_FILTER_H +#define TAO_IORMANIP_FILTER_H +#include /**/ "ace/pre.h" + +#include "tao/GIOP_Message_State.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/corbafwd.h" +#include "tao/IORManipulation/ior_manip_export.h" +#include "tao/Environment.h" +#include "ace/CORBA_macros.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +class TAO_Profile; +class TAO_MProfile; + +class TAO_IORManip_Export TAO_IORManip_Filter +{ +public: + /// Constructor. + TAO_IORManip_Filter (void); + + /// Destructor. + virtual ~TAO_IORManip_Filter (void); + + /// Perform filtering using the profile passed in as a guide. + /// If no profile is provided, filter using the profile_matches() method. + CORBA::Object_ptr sanitize_profiles (CORBA::Object_ptr object, + TAO_Profile* profile = 0); + +protected: + + /// This will be the bulk of the filtering code. + virtual void filter_and_add (TAO_Profile* profile, + TAO_MProfile& profiles, + TAO_Profile* guideline = 0) = 0; + + +private: + + /// The sanitize_profiles() methods call this to do the work. + CORBA::Object_ptr sanitize (CORBA::Object_ptr object, + TAO_Profile* profile); +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* TAO_IORMANIP_FILTER_H */ diff --git a/TAO/tao/IORManipulation/IORManip_IIOP_Filter.cpp b/TAO/tao/IORManipulation/IORManip_IIOP_Filter.cpp new file mode 100644 index 00000000000..d159130192b --- /dev/null +++ b/TAO/tao/IORManipulation/IORManip_IIOP_Filter.cpp @@ -0,0 +1,247 @@ +// $Id$ + +#include "tao/IORManipulation/IORManip_IIOP_Filter.h" +#include "tao/IORManipulation/IORManip_Loader.h" +#include "tao/IIOP_Profile.h" +#include "tao/MProfile.h" + +ACE_RCSID (IORManip_IIOP_Filter, IORManip_IIOP_Filter, "$Id$") + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_IORManip_IIOP_Filter::TAO_IORManip_IIOP_Filter (void) +{ +} + + +TAO_IORManip_IIOP_Filter::~TAO_IORManip_IIOP_Filter (void) +{ +} + + +CORBA::Boolean +TAO_IORManip_IIOP_Filter::compare_profile_info ( + const TAO_IORManip_IIOP_Filter::Profile_Info& left, + const TAO_IORManip_IIOP_Filter::Profile_Info& right) +{ + return (left.version_.major == right.version_.major && + left.version_.minor == right.version_.minor && + left.port_ == right.port_ && + left.host_name_ == right.host_name_); +} + + +CORBA::Boolean +TAO_IORManip_IIOP_Filter::profile_info_matches ( + const TAO_IORManip_IIOP_Filter::Profile_Info&) +{ + return true; +} + + +void +TAO_IORManip_IIOP_Filter::filter_and_add (TAO_Profile* profile, + TAO_MProfile& new_profiles, + TAO_Profile* guideline) +{ + TAO_IORManip_IIOP_Filter::Profile_Info ginfo; + TAO_IORManip_IIOP_Filter::Profile_Info pinfo; + TAO::IIOPEndpointSequence endpoints; + + this->fill_profile_info (guideline, ginfo); + this->get_endpoints (profile, endpoints); + if (endpoints.length () == 0) + { + CORBA::Boolean matches = false; + this->fill_profile_info (profile, pinfo); + + if (guideline == 0) + { + matches = this->profile_info_matches (pinfo); + } + else + { + // Compare the current profile with the guideline profile + matches = this->compare_profile_info (pinfo, ginfo); + } + + if (matches) + { + if (new_profiles.add_profile (profile) == -1) + { + throw CORBA::NO_MEMORY (); + } + } + } + else + { + // Create a new profile with just the + // components we are looking for + TAO_IIOP_Profile* new_profile = + this->create_profile (profile); + + // Set pinfo to match the current profile + this->fill_profile_info (profile, pinfo); + + // Add each endpoint if it matches. Begin from the end + // of the sequence to preserve endpoint order, since <add_endpoint> + // method reverses the order of endpoints in the list. + for (CORBA::Long i = endpoints.length () - 1; i >= 0; i--) { + // Set pinfo host name to the current endpoint host name + pinfo.host_name_ = endpoints[i].host.in (); + pinfo.port_ = endpoints[i].port; + + CORBA::Boolean matches = false; + if (guideline == 0) + { + matches = this->profile_info_matches (pinfo); + } + else + { + // Compare the current profile with the guideline profile + matches = this->compare_profile_info (pinfo, ginfo); + } + + if (matches) + { + // Set the main endpoint on the profile + if (i == 0) + { + TAO_IIOP_Endpoint* ep = dynamic_cast<TAO_IIOP_Endpoint*> ( + new_profile->endpoint ()); + if (ep == 0) + { + new_profile->_decr_refcnt (); + return; + } + else + { + ep->host (CORBA::string_dup (endpoints[i].host)); + ep->port (endpoints[i].port); + ep->priority (endpoints[i].priority); + } + } + else + { + TAO_IIOP_Endpoint *endpoint = 0; + ACE_NEW (endpoint, + TAO_IIOP_Endpoint (endpoints[i].host, + endpoints[i].port, + endpoints[i].priority)); + if (endpoint == 0) + { + new_profile->_decr_refcnt (); + return; + } + + new_profile->add_endpoint (endpoint); + } + } + } + + if (new_profiles.add_profile (new_profile) == -1) + { + throw CORBA::NO_MEMORY (); + } + + new_profile->encode_endpoints (); + + // After adding the profile to the MProfile, + // we must decrement the reference to avoid a memory leak + new_profile->_decr_refcnt (); + } +} + + +int +TAO_IORManip_IIOP_Filter::fill_profile_info ( + TAO_Profile* profile, + TAO_IORManip_IIOP_Filter::Profile_Info& pinfo) +{ + static const int host_length = 384; + int status = 0; + if (profile != 0) + { + char host[host_length] = ""; + if (profile->endpoint ()->addr_to_string (host, host_length) != -1) + { + char* delim = ACE_OS::strchr (host, ':'); + if (delim != 0) + { + *delim = '\0'; + pinfo.port_ = ACE_OS::atoi (delim + 1); + status = 1; + } + } + + pinfo.host_name_ = host; + pinfo.version_ = profile->version (); + } + + return status; +} + + +int +TAO_IORManip_IIOP_Filter::get_endpoints (TAO_Profile* profile, + TAO::IIOPEndpointSequence& endpoints) +{ + // Reset the endpoints + endpoints.length (0); + + // Get the endpoints tagged component + const TAO_Tagged_Components& comps = profile->tagged_components (); + IOP::TaggedComponent tagged_component; + tagged_component.tag = TAO_TAG_ENDPOINTS; + comps.get_component (tagged_component); + + // Prepare the CDR for endpoint extraction + const CORBA::Octet *buf = + tagged_component.component_data.get_buffer (); + + TAO_InputCDR in_cdr (reinterpret_cast<const char*> (buf), + tagged_component.component_data.length ()); + + // Extract the Byte Order. + CORBA::Boolean byte_order; + if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0) + return 0; + in_cdr.reset_byte_order (static_cast<int> (byte_order)); + + // Extract endpoints sequence. + if ((in_cdr >> endpoints) == 0) + return 0; + + return 1; +} + + +TAO_IIOP_Profile* +TAO_IORManip_IIOP_Filter::create_profile (TAO_Profile* profile) +{ + ACE_INET_Addr addr; + TAO_IIOP_Profile* new_profile = 0; + ACE_NEW_THROW_EX (new_profile, + TAO_IIOP_Profile (addr, + profile->object_key (), + profile->version (), + profile->orb_core ()), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + 0, + ENOMEM), + CORBA::COMPLETED_NO)); + + // Copy all of the tagged components + const TAO_Tagged_Components& comps = profile->tagged_components (); + new_profile->tagged_components () = comps; + + // Set the endpoints component to an empty list + IOP::TaggedComponent tagged_component; + tagged_component.tag = TAO_TAG_ENDPOINTS; + new_profile->tagged_components ().set_component (tagged_component); + + return new_profile; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/IORManipulation/IORManip_IIOP_Filter.h b/TAO/tao/IORManipulation/IORManip_IIOP_Filter.h new file mode 100644 index 00000000000..06e602b1e8c --- /dev/null +++ b/TAO/tao/IORManipulation/IORManip_IIOP_Filter.h @@ -0,0 +1,88 @@ +// $Id$ + +// ========================================================================= +// +// = LIBRARY +// TAO +// +// = FILENAME +// IORManip_IIOP_Filter.h +// +// = AUTHOR +// Chad Elliott <elliott_c@ociweb.com> +// +// ========================================================================= + +#ifndef TAO_IORMANIP_IIOP_FILTER_H +#define TAO_IORMANIP_IIOP_FILTER_H +#include /**/ "ace/pre.h" + +#include "IORManip_Filter.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/IIOP_EndpointsC.h" +#include "ace/SString.h" + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +class TAO_IIOP_Profile; +namespace TAO +{ + class IIOPEndpointSequence; +} + +class TAO_IORManip_Export TAO_IORManip_IIOP_Filter: public TAO_IORManip_Filter +{ +public: + struct Profile_Info + { + ACE_CString host_name_; + TAO_GIOP_Message_Version version_; + CORBA::UShort port_; + }; + + /// Constructor. + TAO_IORManip_IIOP_Filter (void); + + /// Destructor. + virtual ~TAO_IORManip_IIOP_Filter (void); + + /// Compares the profile to the profile info. + virtual CORBA::Boolean compare_profile_info ( + const TAO_IORManip_IIOP_Filter::Profile_Info& left, + const TAO_IORManip_IIOP_Filter::Profile_Info& right); + + /// Empty virtual method to match on the profile info. + /// Users must provide an implementation to use the first + /// form of sanitize_profiles(). + virtual CORBA::Boolean profile_info_matches ( + const TAO_IORManip_IIOP_Filter::Profile_Info& pinfo); + +protected: + + /// This is the bulk of the filtering code. + virtual void filter_and_add (TAO_Profile* profile, + TAO_MProfile& profiles, + TAO_Profile* guideline = 0); + +private: + + /// Fill in the Profile_Info with information from the profile. + int fill_profile_info (TAO_Profile* profile, + TAO_IORManip_IIOP_Filter::Profile_Info& pinfo); + + /// Get the endpoint sequence from the profile. + int get_endpoints (TAO_Profile* profile, + TAO::IIOPEndpointSequence& endpoints); + + /// Allocate a new IIOP Profile based on the profile passed in. + TAO_IIOP_Profile* create_profile (TAO_Profile* profile); +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + +#include /**/ "ace/post.h" +#endif /* TAO_IORMANIP_IIOP_FILTER_H */ diff --git a/TAO/tests/IORManipulation/filter/IORManip_Filter_Test.mpc b/TAO/tests/IORManipulation/filter/IORManip_Filter_Test.mpc new file mode 100644 index 00000000000..8be787dc40c --- /dev/null +++ b/TAO/tests/IORManipulation/filter/IORManip_Filter_Test.mpc @@ -0,0 +1,6 @@ +// -*- MPC -*- +// $Id$ + +project(*Server): taoexe, portableserver, iormanip { + exename = server +} diff --git a/TAO/tests/IORManipulation/filter/Test.idl b/TAO/tests/IORManipulation/filter/Test.idl new file mode 100644 index 00000000000..922ccde863b --- /dev/null +++ b/TAO/tests/IORManipulation/filter/Test.idl @@ -0,0 +1,7 @@ +// $Id$ +module Test +{ + interface Hello + { + }; +}; diff --git a/TAO/tests/IORManipulation/filter/run_test.pl b/TAO/tests/IORManipulation/filter/run_test.pl new file mode 100755 index 00000000000..8b8709e9638 --- /dev/null +++ b/TAO/tests/IORManipulation/filter/run_test.pl @@ -0,0 +1,29 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use strict; +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::Run_Test; +use Sys::Hostname; + +my $status = 0; +my $host = hostname(); +my $class = (PerlACE::is_vxworks_test() ? 'PerlACE::ProcessVX' : + 'PerlACE::Process'); +my $SV = $class->new('server', + '-ORBUseSharedProfiles 0 ' . + '-ORBEndpoint iiop://localhost ' . + "-ORBEndpoint iiop://${host}"); + +my $server = $SV->SpawnWaitKill(20); + +if ($server != 0) { + print STDERR "ERROR: server returned $server \n"; + $status = 1; +} + +exit($status); diff --git a/TAO/tests/IORManipulation/filter/server.cpp b/TAO/tests/IORManipulation/filter/server.cpp new file mode 100644 index 00000000000..02a565eecdf --- /dev/null +++ b/TAO/tests/IORManipulation/filter/server.cpp @@ -0,0 +1,87 @@ +// $Id$ + +#include "TestS.h" +#include "tao/IORManipulation/IORManip_IIOP_Filter.h" +#include "tao/Stub.h" + +ACE_RCSID (Hello, + server, + "$Id$") + +class Filter_Localhost: public TAO_IORManip_IIOP_Filter +{ +public: + virtual CORBA::Boolean profile_info_matches ( + const TAO_IORManip_IIOP_Filter::Profile_Info& pinfo); + +}; + +CORBA::Boolean +Filter_Localhost::profile_info_matches ( + const TAO_IORManip_IIOP_Filter::Profile_Info& pinfo) +{ + static const ACE_CString localhost ("localhost"); + static const ACE_CString localip ("127.0.0.1"); + return (pinfo.host_name_ != localhost && pinfo.host_name_ != localip); +} + +class Hello: public POA_Test::Hello +{ +}; + +int +main (int argc, char *argv[]) +{ + int status = 0; + try + { + CORBA::ORB_var orb = CORBA::ORB_init (argc, argv); + + CORBA::Object_var poa_object = + orb->resolve_initial_references("RootPOA"); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in ()); + + if (CORBA::is_nil (root_poa.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Panic: nil RootPOA\n"), + 1); + + Hello *hello_impl; + ACE_NEW_RETURN (hello_impl, + Hello, + 1); + PortableServer::ServantBase_var owner_transfer(hello_impl); + + PortableServer::ObjectId_var id = + root_poa->activate_object (hello_impl); + + CORBA::Object_var obj = root_poa->id_to_reference (id.in ()); + + Test::Hello_var hello = Test::Hello::_narrow (obj.in ()); + + Filter_Localhost filter; + obj = filter.sanitize_profiles (hello.in ()); + Test::Hello_var after = Test::Hello::_narrow(obj.in()); + + if (hello->_stubobj ()->base_profiles ().profile_count () == + after->_stubobj ()->base_profiles ().profile_count ()) + { + ACE_ERROR ((LM_ERROR, + "ERROR: profiles were not correctly filtered\n")); + status++; + } + + root_poa->destroy (1, 1); + + orb->destroy (); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Exception caught:"); + status++; + } + + return status; +} |