Spec-Zone .ru
спецификации, руководства, описания, API
|
Последнее обновление: 25.04.2002
ЗАМЕТЬТЕ: Этот документ предназначается для усовершенствованных разработчиков CORBA.
Посредник запросов к объектам CORBA Java (ШАР) обеспечивает рычаги, или точки перехвата, через которые службы ШАРА могут прервать нормальный поток выполнения ШАРА. Эти Переносимые Перехватчики обеспечивают механизм для того, чтобы он включил дополнительное поведение ШАРА, или, изменяя связь между клиентом и сервером, для того, чтобы изменить поведение ШАРА. Пример, который следует за шоу различные способы использовать Переносимые Перехватчики.
Поддержка Переносимых Перехватчиков является главным недавним дополнением к спецификации CORBA. Используя RequestInterceptors, можно легко записать и присоединить переносимые рычаги ШАРА, которые прервут любой УСТАНОВЛЕННЫЙ ШАРОМ вызов. Используя IORInterceptors, можно записать код, чтобы аннотировать ссылки на объект CORBA.
Это настоятельно рекомендуется это, Вы читаете Переносимую Спецификацию Перехватчиков в
Следующие темы включаются в этот документ:
ORBInitializers
в Java
Есть в настоящий момент три типа перехватчиков, которые могут быть зарегистрированы, как показано ниже. Примеры каждого показывают в примере, который следует.
IORInterceptor
В некоторых случаях переносимая реализация службы ШАРА, возможно, должна добавить информацию, описывающую ШАР сервера или объекта связанные со службой возможности к ссылкам на объект, чтобы позволить реализации службы ШАРА в клиенте функционировать должным образом. Это поддерживается через интерфейсы IORInfo и IORInterceptor. Перехватчик IOR используется, чтобы установить теговые компоненты в профилях в пределах Взаимодействующей Ссылки на объект (IOR).
Пример Перехватчика IOR показывают в файле AServiceIORInterceptor.java в примере, который следует.
ClientRequestInterceptor
Перехватчик запроса разрабатывается, чтобы прервать поток последовательности запроса/ответа через ШАР в отдельных моментах так, чтобы службы могли запросить информацию о запросе и управлять контекстами службы, которые распространяются между клиентами и серверами. Основное использование Перехватчиков запроса должно позволить службам ШАРА передать контекстную информацию между клиентами и серверами.
A ClientRequestInterceptor
прерывает поток последовательности запроса/ответа через ШАР на клиентской стороне.
Пример ClientRequestInterceptor показывают в файле LoggingServiceClientInterceptor.java в примере, который следует.
ServerRequestInterceptor
A ServerRequestInterceptor
прерывает поток последовательности запроса/ответа через ШАР на серверной стороне.
Пример ServerRequestInterceptor показывают в файле LoggingServiceServerInterceptor.java в примере, который следует.
ORBInitializers
в Java ORBInitializer
интерфейс облегчает регистрацию перехватчика и инициализацию ШАРА.
Перехватчики предназначаются, чтобы быть средством, которым службы ШАРА получают доступ к обработке ШАРА, эффективно становясь частью ШАРА. Так как перехватчики являются частью ШАРА, когда ORB.init
возвращает ШАР, перехватчики должны быть зарегистрированы. Перехватчики не могут быть зарегистрированы на ШАРЕ после того, как он был возвращен звонком ORB.init
.
ORBInitializers
регистрируются через свойства ORB Java. Перехватчик регистрируется, регистрируя связанное ORBInitializer
объект, который реализует ORBInitializer
интерфейс. Когда ШАР инициализирует, он должен вызвать, каждый зарегистрировался ORBInitializer
, передача этого ORBInitInfo
объект, который используется, чтобы зарегистрировать его перехватчик.
Имена свойства имеют форму:
org.omg.PortableInterceptor.ORBInitializerClass.<Service>
где <Service>
имя строки класса, который реализует
org.omg.PortableInterceptor.ORBInitializerЧтобы избежать коллизий имени, обратное соглашение о присвоении имен DNS должно использоваться. Например, если компания
Example
имеет три инициализатора, это могло определить следующие свойства: org.omg.PortableInterceptor.ORBInitializerClass.com.example.Init1
org.omg.PortableInterceptor.ORBInitializerClass.com.example.Init2
org.omg.PortableInterceptor.ORBInitializerClass.com.example.Init3
Отметьте: Любые значения, связанные с ORBInitializerClass
свойства игнорируются.
Во время ORB.init, эти свойства ORB, которые начинаются org.omg.PortableInterceptor.ORBInitializerClass
буду собран, <Service>
часть каждого свойства должна быть извлечена, объект нужно инстанцировать с <Service>
представьте в виде строки как его имя класса, и pre_init
и post_init
к методам нужно обратиться тот объект. Если будут какие-либо исключения, то ШАР должен проигнорировать их и продолжиться.
ORB.init
с обеспеченным orb_id
). Так как регистрация происходит во время инициализации ШАРА, результаты вызовов на этом ШАРЕ, в то время как это находится в этом состоянии, неопределены.Объект PortableInterceptor::Current (в дальнейшем именуемый PICurrent) является объектом Current, который используется определенно переносимыми Перехватчиками, чтобы передать контекстную информацию потока контексту запроса. Переносимые Перехватчики не обязаны использовать PICurrent, но если информация от контекста потока клиента запрашивается в точках перехвата Перехватчика, то PICurrent может использоваться, чтобы распространить ту информацию. PICurrent позволяет переносимому служебному коду быть записанным независимо от модели потоков ШАРА.
Отметьте: PICurrent обычно НЕ используется непосредственно клиентом CORBA или серверным кодом. Вместо этого это обычно используется реализациями службы на основе перехватчика как демонстрирующийся в перехватчике AService в качестве примера, который следует.
Прежде, чем вызов делается, PICurrent получается через звонок в ORB::resolve_initial_references ( PICurrent ). Изнутри точек перехвата данные на PICurrent, который переместился от контекста потока до контекста запроса, доступны через работу get_slot на объекте RequestInfo. PICurrent может все еще быть получен через resolve_initial_references, но это - контекст потока Перехватчика PICurrent.
PICurrent контекста потока (TSC) является PICurrent, который существует в пределах контекста потока. Контекстом запроса PICurrent (RSC) является PICurrent, связанный с запросом. На клиентской стороне контекст потока, PICurrent логически копируется в запрос, определяет контекст PICurrent от потока s контекст, когда запрос начинает и присоединен к объекту ClientRequestInfo. На серверной стороне контекст запроса PICurrent присоединен к ServerRequestInfo и следует за обработкой запросов. Это логически копируется в контекст потока PICurrent после того, как список точек перехвата receive_request_service_contexts обрабатывается. См.
Этот раздел содержит пример, регистрирующий сервисное приложение. Пример кода для этого приложения вполне усложняется, потому что это покрывает даже тонкие "угловые случаи". Следующие сценарии покрываются этим примером приложения:
Отметьте: Эти примеры явно регистрируют ORBInitializers, чтобы сделать код легче экспериментировать с и установка. Обычно это не было бы сделано. Вместо этого эту информацию передали бы как свойства -D к виртуальной машине Java, когда приложения запускаются. Тем путем приложения не связываются с фактом, что любой, служба существует (например, служба журналирования) или что служба, которую они явно используют (например, интерфейс AService) реализуется как перехватчик.
Цель примера службы журналирования состоит в том, чтобы показать, как избежать бесконечной рекурсии, делая outcalls (то есть, вызовы на ссылках CORBA) изнутри точек перехвата. Это, оказывается, вполне включается, когда все угловые случаи покрываются.
Цель "пустого" примера службы состоит в том, чтобы показать, как реализовать службы, которые текут контекстная информация от клиента к серверу и назад.
Типичная служба на основе перехватчика будет течь контекстная информация между клиентами и серверами. Пример AService показывает, как эта информация течется от клиентского потока в клиентские перехватчики, через провод в перехватчики сервера, к потоку слуги и назад.
Важно отметить, что ни клиент, ни слуга не знают, что служба реализуется, используя перехватчики. Вместо этого они взаимодействуют со службой через локальные ссылки на объект (ссылка aService в этом примере).
Схема AService
Описание шагов схемы AService:
1.a. aService.begin() устанавливает контекстную информацию службы в слоте, который это зарезервировало в PICurrent.
Некоторые службы, возможно, должны сделать вызовы на других ссылках на объект CORBA изнутри точек перехвата. Делая outcalls изнутри точек перехвата, шаги должны быть сделаны, чтобы избежать бесконечной рекурсии, так как те outcalls будут течь через точки перехвата. Пример LoggingService иллюстрирует этот случай.
LoggingService example состоит из ClientRequestInterceptors, зарегистрированного в клиентской программе, и ServerRequestInterceptors, зарегистрированном в программе сервера. Эти перехватчики отправляют информацию от клиента и сервера до LoggingService implemenation, который регистрирует эту информацию.
Однако, так как реализация LoggingService является самостоятельно сервером CORBA, мы должны гарантировать, что не регистрируем звонки в регистратор. Следующие схемы иллюстрируют шаги, сделанные, чтобы избежать бесконечной рекурсии.
Следующая схема показывает самый простой случай ухода от рекурсии, вызывая внешний регистратор изнутри перехватчиков. Эти шаги полезны для случая, где клиентский ШАР только содержит ClientRequestInterceptors, ШАР сервера только содержит ServerRequestInterceptors, и LoggingService является внешним обоим ШАРЫ клиента и сервера.
Схема LoggingService
Описание шагов схемы LoggingService:
Следующая схема иллюстрирует случай, где LoggingService может быть colocated в том же самом ШАРЕ как ссылка, вызываемая клиентом. Вообще, не возможно знать, что определенная ссылка на объект НЕ является colocated с любыми другими объектами, размещенными тем ШАРОМ. Поэтому, чтобы покрыть все угловые случаи, больше шагов должно быть сделано.
Эта схема показывает только серверную сторону. Шаги клиентской стороны идентичны тем в предыдущей схеме.
Схема LoggingServiceColocated
Описание шагов схемы LoggingServiceColocated:
После Шага 13 будет обслуживаться исходный запрос, который кончил в Шаге 3.
Основной момент, иллюстрированный в этом примере, является потребностью использования и перехватчики клиента и сервера в соединении со слотами PICurrent и контексты службы, чтобы указать на outcall.
Более простой способ избежать рекурсии состоит в том, чтобы гарантировать, что outcall ссылки связываются с различным ШАРОМ, которому не регистрировали перехватчики журналирования. Тем путем outcall вызовы никогда не проходят через перехватчики.
Это походит на простое решение, но, вообще, перехватчики регистрируются через свойства, которые передают к VM во время запуска. Это означает, что все ШАРЫ, создаваемые, в котором VM будет содержать все перехватчики так это решение, не будут работать.
Это решение будет только работать, где перехватчики явно регистрируются в клиентском коде во время ORB.init. Однако, это не ни типичное, ни рекомендуемый способ зарегистрировать службы на основе перехватчиков.
Следующие файлы содержат код, который иллюстрируют вышеупомянутые схемы. Инструкции для компиляции и выполнения этих примеров следуют за кодом. Файлы, включенные в этот пример:
serviceexample.idl
LoggingServiceClientORBInitializer.java
LoggingServiceClientInterceptor.java
LoggingServiceServerORBInitializer.java
LoggingServiceServerInterceptor.java
LoggingServiceImpl.java
AServiceORBInitializer.java
AServiceImpl.java
AServiceInterceptor.java
AServiceIORInterceptor.java
ArbitaryObjectImpl.java
Client.java
ColocatedServers.java
serviceexample.idl
Это - Язык определения интерфейсов (IDL) файл, который содержит определения произвольного объекта, на котором можно сделать вызовы и две службы, которые обслужат звонки в произвольный объект.
// serviceexample.idl // Copyright and License module pi { module serviceexample { // Create some arbitrary object to call. Those calls // will be serviced by the service implemented using interceptors. exception ArbitraryObjectException { string reason; }; interface ArbitraryObject { string arbitraryOperation1 ( in string a1 ); oneway void arbitraryOperation2 ( in long a1 ); void arbitraryOperation3 ( in string a1 ) raises (ArbitraryObjectException); }; // This would typically be in a file separate from the "ArbitraryObject" // and probably unknown to it. interface LoggingService { void log ( in string a1 ); }; // This would also typically be in a file of its own. // IMPORTANT: the interface should be a local object to avoid // unnecessary overhead. /*local*/ interface AService { void begin(); void end(); void verify(); }; // Tagged component for adding to an IOR to indicate that // the AService must be in effect when invocations are made // on the object containing this tagged component. // Note: we explicitly declare the tag type rather than using // the IOP typedef (commented out) to simplify compiling this // example (i.e., to avoid includes and make include path directives). //const IOP::ComponentId TAG_ASERVICE_COMPONENT = 2345; const unsigned long TAG_ASERVICE_COMPONENT = 2345; struct ASERVICE_COMPONENT { boolean requiresAService; }; }; // module serviceexample }; // module pi
LoggingServiceClientORBInitializer.java
Этот файл создает и регистрирует перехватчик службы журналирования, используемый объектными клиентами.
// LoggingServiceClientORBInitializer.java // Copyright and License package pi.serviceexample; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.PortableInterceptor.Current; import org.omg.PortableInterceptor.CurrentHelper; import org.omg.PortableInterceptor.ORBInitInfo; public class LoggingServiceClientORBInitializer extends org.omg.CORBA.LocalObject implements org.omg.PortableInterceptor.ORBInitializer { public void pre_init(ORBInitInfo info) { } public void post_init(ORBInitInfo info) { try { // Get a reference to the LoggingService object. NamingContext nameService = NamingContextHelper.narrow( info.resolve_initial_references("NameService")); NameComponent path[] = { new NameComponent("LoggingService", "") }; LoggingService loggingService = LoggingServiceHelper.narrow(nameService.resolve(path)); // Get a reference to TSC PICurrent. Current piCurrent = CurrentHelper.narrow( info.resolve_initial_references("PICurrent")); // Allocate a slot id to use for the interceptor to indicate // that it is making an outcall. This is used to avoid // infinite recursion. int outCallIndicatorSlotId = info.allocate_slot_id(); // Create (with the above data) and register the client // side interceptor. LoggingServiceClientInterceptor interceptor = new LoggingServiceClientInterceptor(loggingService, piCurrent, outCallIndicatorSlotId); info.add_client_request_interceptor(interceptor); } catch (Throwable t) { System.out.println("Exception handling not shown."); } } }
LoggingServiceClientInterceptor.java
Этот перехватчик регистрирует точки перехвата клиентской стороны. Это иллюстрирует, как сделать вызовы на других объектах изнутри перехватчика и как избежать бесконечной рекурсии во время тех "outcall" вызовов.
// LoggingServiceClientInterceptor.java // Copyright and License package pi.serviceexample; import org.omg.CORBA.Any; import org.omg.CORBA.ORB; import org.omg.CORBA.TCKind; import org.omg.IOP.ServiceContext; import org.omg.PortableInterceptor.ClientRequestInterceptor; import org.omg.PortableInterceptor.ClientRequestInfo; import org.omg.PortableInterceptor.Current; import org.omg.PortableInterceptor.InvalidSlot; public class LoggingServiceClientInterceptor extends org.omg.CORBA.LocalObject implements ClientRequestInterceptor { private LoggingService loggingService; private Current piCurrent; private int outCallIndicatorSlotId; public LoggingServiceClientInterceptor(LoggingService loggingService, Current piCurrent, int outCallIndicatorSlotId) { this.loggingService = loggingService; this.piCurrent = piCurrent; this.outCallIndicatorSlotId = outCallIndicatorSlotId; } // // Interceptor operations // public String name() { return "LoggingServiceClientInterceptor"; } public void destroy() { } // // ClientRequestInterceptor operations // public void send_request(ClientRequestInfo ri) { log(ri, "send_request"); } public void send_poll(ClientRequestInfo ri) { log(ri, "send_poll"); } public void receive_reply(ClientRequestInfo ri) { log(ri, "receive_reply"); } public void receive_exception(ClientRequestInfo ri) { log(ri, "receive_exception"); } public void receive_other(ClientRequestInfo ri) { log(ri, "receive_other"); } // // Utilities. // public void log(ClientRequestInfo ri, String point) { // IMPORTANT: Always set the TSC out call indicator in case // other interceptors make outcalls for this request. // Otherwise the outcall will not be set for the other interceptor's // outcall resulting in infinite recursion. Any indicator = ORB.init().create_any(); indicator.insert_boolean(true); try { piCurrent.set_slot(outCallIndicatorSlotId, indicator); } catch (InvalidSlot e) { } try { indicator = ri.get_slot(outCallIndicatorSlotId); // If the RSC out call slot is not set then log this invocation. // If it is set that indicates the interceptor is servicing the // invocation of loggingService itself. In that case do // nothing (to avoid infinite recursion). if (indicator.type().kind().equals(TCKind.tk_null)) { loggingService.log(ri.operation() + " " + point); } } catch (InvalidSlot e) { System.out.println("Exception handling not shown."); } } }
LoggingServiceServerORBInitializer.java
// LoggingServiceServerORBInitializer.java // Copyright and License package pi.serviceexample; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.PortableInterceptor.Current; import org.omg.PortableInterceptor.CurrentHelper; import org.omg.PortableInterceptor.ORBInitInfo; public class LoggingServiceServerORBInitializer extends org.omg.CORBA.LocalObject implements org.omg.PortableInterceptor.ORBInitializer { public void pre_init(ORBInitInfo info) { } public void post_init(ORBInitInfo info) { try { // Create and register the logging service interceptor. // Give that interceptor references to the NameService and // PICurrent to avoid further lookups (i.e., optimization). // More importantly, allocate and give the interceptor // a slot id which is will use to tell itself not to // log calls that the interceptor makes to the logging process. NamingContext nameService = NamingContextHelper.narrow( info.resolve_initial_references("NameService")); Current piCurrent = CurrentHelper.narrow( info.resolve_initial_references("PICurrent")); int outCallIndicatorSlotId = info.allocate_slot_id(); LoggingServiceServerInterceptor interceptor = new LoggingServiceServerInterceptor(nameService, piCurrent, outCallIndicatorSlotId); info.add_client_request_interceptor(interceptor); info.add_server_request_interceptor(interceptor); } catch (Throwable t) { System.out.println("Exception handling not shown."); } } }
LoggingServiceServerInterceptor.java
Этот перехватчик регистрирует точки перехвата серверной стороны, и реализуется и как ClientRequestInterceptor и как ServerRequestInterceptor, чтобы иллюстрировать потребность установить, некоторые "вызывают" данные контекста службы (в дополнение к установке слот вызова), чтобы избежать бесконечной рекурсии для случая, отмеченного в описании LoggingServiceServerORBInitializer.java.
// LoggingServiceServerInterceptor.java // Copyright and License package pi.serviceexample; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.Any; import org.omg.CORBA.BAD_PARAM; import org.omg.CORBA.ORB; import org.omg.CORBA.TCKind; import org.omg.IOP.ServiceContext; import org.omg.PortableInterceptor.ClientRequestInterceptor; import org.omg.PortableInterceptor.ClientRequestInfo; import org.omg.PortableInterceptor.Current; import org.omg.PortableInterceptor.InvalidSlot; import org.omg.PortableInterceptor.ServerRequestInterceptor; import org.omg.PortableInterceptor.ServerRequestInfo; public class LoggingServiceServerInterceptor extends org.omg.CORBA.LocalObject implements ClientRequestInterceptor, ServerRequestInterceptor { private NamingContext nameService; private LoggingService loggingService; private Current piCurrent; private int outCallIndicatorSlotId; private static final int serviceContextId = 100001; private static final byte[] serviceContextData = {1}; // Returns a reference to the logging process. private LoggingService loggingService() { if (loggingService == null) { NameComponent path[] = { new NameComponent("LoggingService", "") }; try { loggingService = LoggingServiceHelper.narrow(nameService.resolve(path)); } catch (Throwable t) { System.out.println("Exception handling not shown."); } } return loggingService; } public LoggingServiceServerInterceptor(NamingContext nameService, Current piCurrent, int outCallIndicatorSlotId) { this.nameService = nameService; this.piCurrent = piCurrent; this.outCallIndicatorSlotId = outCallIndicatorSlotId; } // // Interceptor operations // public String name() { return "LoggingServiceServerInterceptor"; } public void destroy() { } // // ClientRequestInterceptor operations // public void send_request(ClientRequestInfo ri) { // If the server interceptor sets the recursion slot then // put in the service context so the server doesn't make // the call again in the case where the server side interceptor // is colocated in the same ORB as the object being invoked. try { Any indicator = ri.get_slot(outCallIndicatorSlotId); if (indicator.type().kind().equals(TCKind.tk_boolean)) { ServiceContext serviceContext = new ServiceContext(serviceContextId, serviceContextData); ri.add_request_service_context(serviceContext, false); } } catch (InvalidSlot e) { System.out.println("Exception handling not shown."); } } public void send_poll(ClientRequestInfo ri) { } public void receive_reply(ClientRequestInfo ri) { } public void receive_exception(ClientRequestInfo ri) { } public void receive_other(ClientRequestInfo ri) { } // // ServerRequestInterceptor operations // public void receive_request_service_contexts(ServerRequestInfo ri) { log(ri, "receive_request_service_contexts"); } public void receive_request(ServerRequestInfo ri) { log(ri, "receive_request"); } public void send_reply(ServerRequestInfo ri) { log(ri, "send_reply"); } public void send_exception(ServerRequestInfo ri) { log(ri, "send_exception"); } public void send_other(ServerRequestInfo ri) { log(ri, "send_other"); } // // Utilities. // public void log(ServerRequestInfo ri, String point) { // This is only relevant for the colocated example. // Do not attempt to log until the logging service object // has been bound in naming. Otherwise the attempt to call // rebind on naming will call log which will fail. if (! ColocatedServers.colocatedBootstrapDone) { return; } // IMPORTANT: // The conditional logging of the invocation is only necessary // if there is a chance that the object being invoked is colocated // in the same ORB as this interceptor. Otherwise the outcall to // the logging service can be made unconditionally. // Always set the recursion slot. Any indicator = ORB.init().create_any(); indicator.insert_boolean(true); try { piCurrent.set_slot(outCallIndicatorSlotId, indicator); } catch (InvalidSlot e) { System.out.println("Exception handling not shown."); } // Make the out call if you have not already done so. try { // Only the presence of the service context counts. // The data is ignored. ri.get_request_service_context(serviceContextId); } catch (BAD_PARAM e) { // Recursion indicator not set so make the call. loggingService().log(ri.operation() + " " + point); } } }
LoggingServiceImpl.java
// // Copyright and License package pi.serviceexample; import org.omg.CORBA.ORB; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.PortableServer.POAHelper; import java.util.Properties; class LoggingServiceImpl extends LoggingServicePOA { public static ORB orb; // // The IDL operations. // public void log(String a1) { System.out.println(a1); } // // The server. // public static void main(String[] av) { try { if (orb == null) { orb = ORB.init(av, null); } POA rootPOA = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); rootPOA.the_POAManager().activate(); byte[] objectId = rootPOA.activate_object(new LoggingServiceImpl()); org.omg.CORBA.Object ref = rootPOA.id_to_reference(objectId); NamingContext nameService = NamingContextHelper.narrow( orb.resolve_initial_references("NameService")); NameComponent path[] = { new NameComponent("LoggingService", "") }; nameService.rebind(path, ref); // Only relevant for colocated example. ColocatedServers.colocatedBootstrapDone = true; System.out.println("LoggingService ready."); orb.run(); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } System.exit(0); } }
AServiceORBInitializer.java
// AServiceORBInitializer.java // Copyright and License package pi.serviceexample; import org.omg.IOP.Codec; import org.omg.IOP.CodecFactory; import org.omg.IOP.CodecFactoryHelper; import org.omg.IOP.Encoding; import org.omg.PortableInterceptor.Current; import org.omg.PortableInterceptor.CurrentHelper; import org.omg.PortableInterceptor.ORBInitInfo; public class AServiceORBInitializer extends org.omg.CORBA.LocalObject implements org.omg.PortableInterceptor.ORBInitializer { private AServiceImpl aServiceImpl; private AServiceInterceptor aServiceInterceptor; public void pre_init(ORBInitInfo info) { try { int id = info.allocate_slot_id(); aServiceInterceptor = new AServiceInterceptor(id); info.add_client_request_interceptor(aServiceInterceptor); info.add_server_request_interceptor(aServiceInterceptor); // Create and register a reference to the service to be // used by client code. aServiceImpl = new AServiceImpl(id); info.register_initial_reference("AService", aServiceImpl); } catch (Throwable t) { System.out.println("Exception handling not shown."); } } public void post_init(ORBInitInfo info) { try { Current piCurrent = CurrentHelper.narrow( info.resolve_initial_references("PICurrent")); aServiceImpl.setPICurrent(piCurrent); CodecFactory codecFactory = CodecFactoryHelper.narrow( info.resolve_initial_references("CodecFactory")); Encoding encoding = new Encoding((short)0, (byte)1, (byte)2); Codec codec = codecFactory.create_codec(encoding); aServiceInterceptor.setCodec(codec); AServiceIORInterceptor aServiceIORInterceptor = new AServiceIORInterceptor(codec); info.add_ior_interceptor(aServiceIORInterceptor); } catch (Throwable t) { System.out.println("Exception handling not shown."); } } }
AServiceImpl.java
// // Copyright and License package pi.serviceexample; import org.omg.CORBA.Any; import org.omg.CORBA.TCKind; import org.omg.CORBA.LocalObject; import org.omg.CORBA.ORB; import org.omg.PortableInterceptor.Current; import org.omg.PortableInterceptor.InvalidSlot; class AServiceImpl extends LocalObject implements AService { private int slotId; private int currentServiceId = 0; private Current piCurrent; private Any NOT_IN_EFFECT; public AServiceImpl(int slotId) { this.slotId = slotId; NOT_IN_EFFECT = ORB.init().create_any(); } // Package protected so the AService ORBInitializer can access this // non-IDL defined method. void setPICurrent(Current piCurrent) { this.piCurrent = piCurrent; } public void begin() { Any any = ORB.init().create_any(); any.insert_long(++currentServiceId); setSlot(any); } public void end() { setSlot(NOT_IN_EFFECT); } public void verify() { try { Any any = piCurrent.get_slot(slotId); if (any.type().kind().equals(TCKind.tk_long)) { System.out.println("Service present: " + any.extract_long()); } else { System.out.println("Service not present"); } } catch (InvalidSlot e) { System.out.println("Exception handling not shown."); } } // Synchronized because two threads in the same ORB could be // sharing this object. synchronized private void setSlot(Any any) { try { piCurrent.set_slot(slotId, any); } catch (InvalidSlot e) { System.out.println("Exception handling not shown."); } } }
AServiceInterceptor.java
Этот перехватчик ответственен за расположение передать клиентскую сторону информация о AService стороне службы.
На клиентской стороне, если AService.begin() вызвали, точка send_request(ri) будет видеть идентификатор службы в слоте RSC. В этом случае это вставляет значение того идентификатора службы в org.omg.CORBA.ServiceContext и добавляет что контекст службы к данным, которые передадут наряду с вызовом.
На серверной стороне receive_request_service_context(ri) ищет присутствие того контекста службы. Когда существующий, это извлекает значение идентификатора службы из ServiceContext и устанавливает слот RSC в то значение. Когда слуга выполняется, значение которого слот RSC доступен в слоте TSC.
// AServiceInterceptor.java // Copyright and License package pi.serviceexample; import org.omg.CORBA.Any; import org.omg.CORBA.BAD_PARAM; import org.omg.CORBA.ORB; import org.omg.CORBA.TCKind; import org.omg.IOP.Codec; import org.omg.IOP.CodecPackage.FormatMismatch; import org.omg.IOP.CodecPackage.TypeMismatch; import org.omg.IOP.ServiceContext; import org.omg.IOP.TaggedComponent; import org.omg.PortableInterceptor.ClientRequestInterceptor; import org.omg.PortableInterceptor.ClientRequestInfo; import org.omg.PortableInterceptor.InvalidSlot; import org.omg.PortableInterceptor.ServerRequestInterceptor; import org.omg.PortableInterceptor.ServerRequestInfo; public class AServiceInterceptor extends org.omg.CORBA.LocalObject implements ClientRequestInterceptor, ServerRequestInterceptor { private int slotId; private Codec codec; private static final int serviceContextId = 1234; public AServiceInterceptor(int slotId) { this.slotId = slotId; } void setCodec(Codec codec) { this.codec = codec; } // // Interceptor operations // public String name() { return "AServiceInterceptor"; } public void destroy() { } // // ClientRequestInterceptor operations // public void send_request(ClientRequestInfo ri) { // // See if the target object contains an ASERVICE_COMPONENT. // try { TaggedComponent taggedComponent = ri.get_effective_component(TAG_ASERVICE_COMPONENT.value); Any sAny = null; try { sAny = codec.decode_value(taggedComponent.component_data, ASERVICE_COMPONENTHelper.type()); } catch (TypeMismatch e) { System.out.println("Exception handling not shown."); } catch (FormatMismatch e) { System.out.println("Exception handling not shown."); } ASERVICE_COMPONENT aServiceComponent = ASERVICE_COMPONENTHelper.extract(sAny); // // Only send the service context if the target object requires it. // if (aServiceComponent.requiresAService) { try { Any any = ri.get_slot(slotId); if (any.type().kind().equals(TCKind.tk_long)) { int serviceId = any.extract_long(); byte[] serviceContextData = { // Little endian to make it // easier to see in debugger. (byte)((serviceId >>> 0) & 0xFF), (byte)((serviceId >>> 8) & 0xFF), (byte)((serviceId >>> 16) & 0xFF), (byte)((serviceId >>> 24) & 0xFF) }; ri.add_request_service_context( new ServiceContext(serviceContextId, serviceContextData), false); } } catch (InvalidSlot e) { System.out.println("Exception handling not shown."); } } } catch (BAD_PARAM e) { // If it is not present, do nothing. ; } } public void send_poll(ClientRequestInfo ri) { } public void receive_reply(ClientRequestInfo ri) { } public void receive_exception(ClientRequestInfo ri) { } public void receive_other(ClientRequestInfo ri) { } // // ServerRequestInterceptor operations // public void receive_request_service_contexts(ServerRequestInfo ri) { try { ServiceContext serviceContext = ri.get_request_service_context(serviceContextId); byte[] data = serviceContext.context_data; int b1, b2, b3, b4; b4 = (data[0] << 0) & 0x000000FF; b3 = (data[1] << 8) & 0x0000FF00; b2 = (data[2] << 16) & 0x00FF0000; b1 = (data[3] << 24) & 0xFF000000; int serviceId = (b1 | b2 | b3 | b4); Any any = ORB.init().create_any(); any.insert_long(serviceId); ri.set_slot(slotId, any); } catch (BAD_PARAM e) { // Not present means service is not in effect. // Do nothing. ; } catch (InvalidSlot e) { System.out.println("Exception handling not shown."); } } public void receive_request(ServerRequestInfo ri) { } public void send_reply(ServerRequestInfo ri) { } public void send_exception(ServerRequestInfo ri) { } public void send_other(ServerRequestInfo ri) { } }
AServiceIORInterceptor.java
// AServiceIORInterceptor.java // Copyright and License package pi.serviceexample; import org.omg.CORBA.Any; import org.omg.CORBA.LocalObject; import org.omg.CORBA.ORB; import org.omg.IOP.TaggedComponent; import org.omg.IOP.Codec; import org.omg.IOP.CodecPackage.InvalidTypeForEncoding; import org.omg.PortableInterceptor.IORInfo; import org.omg.PortableInterceptor.IORInterceptor; public class AServiceIORInterceptor extends org.omg.CORBA.LocalObject implements IORInterceptor { private Codec codec; public AServiceIORInterceptor(Codec codec) { this.codec = codec; } // // Interceptor operations // public String name() { return "AServiceInterceptor"; } public void destroy() { } // // IOR Interceptor operations // public void establish_components(IORInfo info) { // // Note: typically, rather than just inserting a tagged component // this interceptor would check info.get_effective_policy(int) // to determine if a tagged component reflecting that policy // should be added to the IOR. That is not shown in this example. // ASERVICE_COMPONENT aServiceComponent = new ASERVICE_COMPONENT(true); Any any = ORB.init().create_any(); ASERVICE_COMPONENTHelper.insert(any, aServiceComponent); byte[] value = null; try { value = codec.encode_value(any); } catch (InvalidTypeForEncoding e) { System.out.println("Exception handling not shown."); } TaggedComponent taggedComponent = new TaggedComponent(TAG_ASERVICE_COMPONENT.value, value); info.add_ior_component(taggedComponent); } }
ArbitaryObjectImpl.java
Этот файл является реализацией и сервером для интерфейса IDL ArbitraryObject. Реализации операций интерфейса IDL явно вызывают метод AServiceImpl.verify(), чтобы иллюстрировать непрерывную передачу данных от клиента (через AService.begin()) слуге.
// ArbitaryObjectImpl.java // Copyright and License package pi.serviceexample; import org.omg.CORBA.ORB; import org.omg.CORBA.ORBPackage.InvalidName; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.PortableServer.POAHelper; import java.util.Properties; class ArbitraryObjectImpl extends ArbitraryObjectPOA { public static ORB orb; private AService aService; // // The IDL operations. // public String arbitraryOperation1(String a1) { verifyService(); return "I got this from the client: " + a1; } public void arbitraryOperation2 (int a1) { verifyService(); } public void arbitraryOperation3(String a1) throws ArbitraryObjectException { verifyService(); if (a1.equals("throw exception")) { throw new ArbitraryObjectException("because you told me to"); } } private void verifyService() { getAService().verify(); } private AService getAService() { // Only look up the service once, then cache it. if (aService == null) { try { aService = AServiceHelper.narrow( orb.resolve_initial_references("AService")); } catch (InvalidName e) { System.out.println("Exception handling not shown."); } } return aService; } // // The server. // public static void main(String[] av) { try { if (orb == null) { Properties props = new Properties(); props.put("org.omg.PortableInterceptor.ORBInitializerClass." + "pi.serviceexample.AServiceORBInitializer", ""); props.put("org.omg.PortableInterceptor.ORBInitializerClass." + "pi.serviceexample.LoggingServiceServerORBInitializer", ""); orb = ORB.init(av, props); } POA rootPOA = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); // Create a POA so the IOR interceptor executes. POA childPOA = rootPOA.create_POA("childPOA", null, null); childPOA.the_POAManager().activate(); byte[] objectId = childPOA.activate_object(new ArbitraryObjectImpl()); org.omg.CORBA.Object ref = childPOA.id_to_reference(objectId); NamingContext nameService = NamingContextHelper.narrow( orb.resolve_initial_references("NameService")); NameComponent path[] = { new NameComponent("ArbitraryObject", "") }; nameService.rebind(path, ref); System.out.println("ArbitaryObject ready."); orb.run(); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } System.exit(0); } }
Client.java
Это - клиент, который вызывает методы на ArbitraryObject. Это выполняет некоторые из тех вызовов в пределах контекста AService и некоторых за пределами его контекста. Это не сознает существование перехватчика журналирования (за исключением того, что это явно регистрирует LoggingServerClientORBInitializer как отмечено выше).
// Client.java // Copyright and License package pi.serviceexample; import org.omg.CORBA.ORB; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import java.util.Properties; public class Client { public static void main(String av[]) { try { Properties props = new Properties(); props.put("org.omg.PortableInterceptor.ORBInitializerClass." + "pi.serviceexample.AServiceORBInitializer", ""); props.put("org.omg.PortableInterceptor.ORBInitializerClass." + "pi.serviceexample.LoggingServiceClientORBInitializer", ""); ORB orb = ORB.init(av, props); // // The client obtains a reference to a service. // The client does not know the service is implemented // using interceptors. // AService aService = AServiceHelper.narrow( orb.resolve_initial_references("AService")); // // The client obtains a reference to some object that // it will invoke. // NamingContext nameService = NamingContextHelper.narrow( orb.resolve_initial_references("NameService")); NameComponent arbitraryObjectPath[] = { new NameComponent("ArbitraryObject", "") }; ArbitraryObject arbitraryObject = ArbitraryObjectHelper.narrow(nameService.resolve(arbitraryObjectPath)); // // The client begins the service so that invocations of // any object will be done with that service in effect. // aService.begin(); arbitraryObject.arbitraryOperation1("one"); arbitraryObject.arbitraryOperation2(2); // // The client ends the service so that further invocations // of any object will not be done with that service in effect. // aService.end(); // This invocation is not serviced by aService since // it is outside the begin/end. arbitraryObject.arbitraryOperation3("just return"); aService.begin(); try { arbitraryObject.arbitraryOperation3("throw exception"); throw new RuntimeException("should not see this"); } catch (ArbitraryObjectException e) { // Expected in this example, so do nothing. } aService.end(); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } System.out.println("Client done."); System.exit(0); } }
ColocatedServers.java
Это - сервер, который выполняет и ArbitraryObject и LoggingService в том же самом ШАРЕ. Это означает, что эти объекты являются colocated.
Сервер создается этот путь, чтобы осуществить код в LoggingServiceServerInterceptor, который иллюстрирует, когда перехватчики разбирают звонки в объекты colocated в том же самом ШАРЕ, дополнительные шаги должны быть сделаны, чтобы избежать бесконечной рекурсии.
// ColocatedServers.java // Copyright and License package pi.serviceexample; import org.omg.CORBA.ORB; import java.util.Properties; public class ColocatedServers { public static ORB orb; public static boolean colocatedBootstrapDone = false; public static void main (String[] av) { try { // // Share an ORB between objects servers. // Properties props = new Properties(); props.put("org.omg.PortableInterceptor.ORBInitializerClass." + "pi.serviceexample.AServiceORBInitializer", ""); props.put("org.omg.PortableInterceptor.ORBInitializerClass." + "pi.serviceexample.LoggingServiceServerORBInitializer", ""); ORB orb = ORB.init(av, props); ArbitraryObjectImpl.orb = orb; LoggingServiceImpl.orb = orb; // // Start both object servers. // ServerThread ServerThread = new ServerThread(av); ServerThread.start(); ArbitraryObjectImpl.main(av); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } } } class ServerThread extends Thread { String[] av; ServerThread (String[] av) { this.av = av; } public void run () { LoggingServiceImpl.main(av); } }
Пример кода, который содержит пример журналирования и пример службы, может быть скомпилирован и выполняет использование Make-файла такой как тот показанный ниже:
# Makefile for the Example Files # Copyright and License JAVA_HOME=/path_to_J2SE_installation CLASSPATH=. JAVAC=$(JAVA_HOME)/bin/javac JAVA=$(JAVA_HOME)/bin/java ORB_INITIAL_PORT=1050 IDLJ=$(JAVA_HOME)/bin/idlj IDLJ_FLAGS=-fall -td $(CLASSPATH) -verbose ORBD=${JAVA_HOME}/bin/orbd -ORBInitialPort ${ORB_INITIAL_PORT} build: $(IDLJ) $(IDLJ_FLAGS) serviceexample.idl $(JAVAC) -d $(CLASSPATH) *.java $(JAVAC) pi/serviceexample/*.java runorbd: $(ORBD) runloggingservice: $(JAVA) -classpath $(CLASSPATH) pi.serviceexample.LoggingServiceImpl \ -ORBInitialPort ${ORB_INITIAL_PORT} runarbitraryobject: $(JAVA) -classpath $(CLASSPATH) pi.serviceexample.ArbitraryObjectImpl \ -ORBInitialPort ${ORB_INITIAL_PORT} runcolocatedservers: $(JAVA) -classpath $(CLASSPATH) pi.serviceexample.ColocatedServers \ -ORBInitialPort ${ORB_INITIAL_PORT} runclient: $(JAVA) -classpath $(CLASSPATH) pi.serviceexample.Client \ -ORBInitialPort ${ORB_INITIAL_PORT} clean: rm -rf pi rm -rf orb.db # Order of steps: # Build: clean build # Remote: runorbd runloggingservice runarbitraryobjectimpl runclient # Colocated: runorbd runcolocatedservers runclient
Следующие шаги показывают, как создать и выполнить пример на операционной системе Соляриса, используя вышеупомянутый Make-файл. От командной строки, выполненной эти команды как показано. %
символ используется в качестве напоминания, что они - команды, которые должны быть выполнены от командной строки.
После этого шага Вы будете видеть, выводит, такие как это:
resolve send_request resolve receive_reply arbitraryOperation1 send_request Service present: 1 arbitraryOperation1 receive_reply arbitraryOperation2 send_request Service present: 1 arbitraryOperation2 receive_other arbitraryOperation3 send_request Service not present arbitraryOperation3 receive_reply arbitraryOperation3 send_request Service present: 2 arbitraryOperation3 receive_exception Client done.
После этого шага Вы будете видеть, выводит, такие как это:
[1] Running make runorbd & [2]- Running make runloggingservice & [3]+ Running make runarbitraryobject &
После этого шага Вы будете видеть, выводит, такие как это:
log receive_request_service_contexts log receive_request resolve send_request log send_reply log receive_request_service_contexts log receive_request resolve receive_reply log send_reply log receive_request_service_contexts log receive_request arbitraryOperation1 send_request log send_reply arbitraryOperation1 receive_request_service_contexts arbitraryOperation1 receive_request Service present: 1 arbitraryOperation1 send_reply log receive_request_service_contexts log receive_request arbitraryOperation1 receive_reply log send_reply log receive_request_service_contexts log receive_request arbitraryOperation2 send_request log send_reply arbitraryOperation2 receive_request_service_contexts arbitraryOperation2 receive_request log receive_request_service_contexts Service present: 1 arbitraryOperation2 send_reply log receive_request arbitraryOperation2 receive_other log send_reply log receive_request_service_contexts log receive_request arbitraryOperation3 send_request log send_reply arbitraryOperation3 receive_request_service_contexts arbitraryOperation3 receive_request Service not present arbitraryOperation3 send_reply log receive_request_service_contexts log receive_request arbitraryOperation3 receive_reply log send_reply log receive_request_service_contexts log receive_request arbitraryOperation3 send_request log send_reply arbitraryOperation3 receive_request_service_contexts arbitraryOperation3 receive_request Service present: 2 arbitraryOperation3 send_exception log receive_request_service_contexts log receive_request arbitraryOperation3 receive_exception log send_reply Client done.
После этого шага Вы будете видеть, выводит, такие как это:
[1]- Running make runorbd & [4]+ Running make runcolocatedservers &
ORBInitInfo