Вечная жизнь. Неуязвимость объектной ссылки
Вадим Годунко <>, 2007–2008 г.
Поигравшись с первым примером можно заметить, что после перезапуска сервера все объектные ссылки теряют свою актуальность. Однако в реальной системе информация о пользователях должна оставаться доступной после перезапуска сервера. Попробуем реализовать такую функциональность.
Сначала будет необходимо настроить ORB и POA таким образом, что бы объектные ссылки не теряли свою актуальность после перезапуска сервера. Поскольку корневой POA не позволяет изменять его характеристики потребуется создать собственный объектный адаптер. CORBA позволяет создавать любое количество POA для удобства организовывая их в иерархию. При создании POA необходимо указывать его имя, которое должно быть уникальным среди потомков одного родительского адаптера.
Добавим в главную подпрограмм создание собственного объектного адаптера и изменим реализацию фабрики для использования этого адаптера.
with Ada.Containers.Vectors;
with PortableServer.POA;
with Users.User;
package Globals is
package User_Vectors is
new Ada.Containers.Vectors (Positive, Users.User.Ref, Users.User."=");
Users : User_Vectors.Vector;
User_POA : PortableServer.POA.Local_Ref;
end Globals;
with Ada.Text_IO;
with CORBA.Object;
with CORBA.ORB;
with CORBA.Policy;
with PortableServer.POA.Helper;
with PortableServer.POAManager;
with PolyORB.Setup.No_Tasking_Server;
with Globals;
with Users.UserFactory.Impl;
with Users.UserFinder.Impl;
procedure Server is
begin
declare
Argv : CORBA.ORB.Arg_List := CORBA.ORB.Command_Line_Arguments;
begin
CORBA.ORB.Init (CORBA.ORB.To_CORBA_String ("ORB"), Argv);
end;
declare
Root_POA : PortableServer.POA.Local_Ref;
begin
Root_POA :=
PortableServer.POA.Helper.To_Local_Ref
(CORBA.ORB.Resolve_Initial_References
(CORBA.ORB.To_CORBA_String ("RootPOA")));
PortableServer.POAManager.Activate
(PortableServer.POA.Get_The_POAManager (Root_POA));
declare
Policies : CORBA.Policy.PolicyList;
begin
Globals.User_POA :=
PortableServer.POA.Local_Ref
(PortableServer.POA.Create_POA
(Root_POA,
CORBA.To_CORBA_String ("UserPOA"),
PortableServer.POA.Get_The_POAManager (Root_POA),
Policies));
end;
declare
Ref : CORBA.Object.Ref;
begin
Ref :=
PortableServer.POA.Servant_To_Reference
(Root_POA,
new Users.UserFactory.Impl.Object);
Ada.Text_IO.Put_Line
("'"
& CORBA.To_Standard_String (CORBA.Object.Object_To_String (Ref))
& "'");
end;
declare
Ref : CORBA.Object.Ref;
begin
Ref :=
PortableServer.POA.Servant_To_Reference
(Root_POA,
new Users.UserFinder.Impl.Object);
Ada.Text_IO.Put_Line
("'"
& CORBA.To_Standard_String (CORBA.Object.Object_To_String (Ref))
& "'");
end;
end;
CORBA.ORB.Run;
end Server;
with Ada.Characters.Conversions;
with Ada.Wide_Text_IO;
with CORBA.ORB;
with PortableServer.POA.Helper;
with Globals;
with Users.User.Impl;
with Users.User.Helper;
with Users.UserFactory.Skel;
package body Users.UserFactory.Impl is
function create
(Self : access Object;
name : in CORBA.Wide_String;
surname : in CORBA.Wide_String)
return Users.User.Ref
is
Root_POA : PortableServer.POA.Local_Ref;
Result : Users.User.Ref;
begin
Result :=
Users.User.Helper.To_Ref
(PortableServer.POA.Servant_To_Reference
(Globals.User_POA,
PortableServer.Servant
(Users.User.Impl.New_User (name, surname))));
Ada.Wide_Text_IO.Put_Line
("User ("
& CORBA.To_Wide_String (name)
& ", "
& CORBA.To_Wide_String (surname)
& ") created. IOR '"
& Ada.Characters.Conversions.To_Wide_String
(CORBA.To_Standard_String
(CORBA.Object.Object_To_String (Result)))
& "'");
Globals.User_Vectors.Append (Globals.Users, Result);
return Result;
end create;
end Users.UserFactory.Impl;
Просматривая объектные ссылки объектов‐пользователей можно обнаружить, что объектные ключи стали чуть длинее — в них стала указываться дополнительная информация об объектном адаптере.
Имея в наличии собственный объектный адаптер можно приступать к его настройке. Для отключения ограничения срока действия объектных ссылок временем работы сервера необходимо указать значение PERSISTENT для политики Lifespan объектного адаптера. Доработаем код создания объектного адаптера соответствующим образом:
with Ada.Text_IO;
with CORBA.Object;
with CORBA.ORB;
with CORBA.Policy;
with PortableServer.LifespanPolicy;
with PortableServer.POA.Helper;
with PortableServer.POAManager;
with PolyORB.Setup.No_Tasking_Server;
with Globals;
with Users.UserFactory.Impl;
with Users.UserFinder.Impl;
procedure Server is
begin
declare
Argv : CORBA.ORB.Arg_List := CORBA.ORB.Command_Line_Arguments;
begin
CORBA.ORB.Init (CORBA.ORB.To_CORBA_String ("ORB"), Argv);
end;
declare
Root_POA : PortableServer.POA.Local_Ref;
begin
Root_POA :=
PortableServer.POA.Helper.To_Local_Ref
(CORBA.ORB.Resolve_Initial_References
(CORBA.ORB.To_CORBA_String ("RootPOA")));
PortableServer.POAManager.Activate
(PortableServer.POA.Get_The_POAManager (Root_POA));
declare
Policies : CORBA.Policy.PolicyList;
Lifespan : PortableServer.LifespanPolicy.Ref
:= PortableServer.POA.Create_Lifespan_Policy
(PortableServer.PERSISTENT);
begin
CORBA.Policy.IDL_SEQUENCE_Policy.Append
(Policies, CORBA.Policy.Ref (Lifespan));
Globals.User_POA :=
PortableServer.POA.Local_Ref
(PortableServer.POA.Create_POA
(Root_POA,
CORBA.To_CORBA_String ("UserPOA"),
PortableServer.POA.Get_The_POAManager (Root_POA),
Policies));
end;
declare
Ref : CORBA.Object.Ref;
begin
Ref :=
PortableServer.POA.Servant_To_Reference
(Root_POA,
new Users.UserFactory.Impl.Object);
Ada.Text_IO.Put_Line
("'"
& CORBA.To_Standard_String (CORBA.Object.Object_To_String (Ref))
& "'");
end;
declare
Ref : CORBA.Object.Ref;
begin
Ref :=
PortableServer.POA.Servant_To_Reference
(Root_POA,
new Users.UserFinder.Impl.Object);
Ada.Text_IO.Put_Line
("'"
& CORBA.To_Standard_String (CORBA.Object.Object_To_String (Ref))
& "'");
end;
end;
CORBA.ORB.Run;
end Server;
И остался последний шаг — настройка ORB. Настройка ORB сводится к указанию фиксированной точки доступа. Поскольку у нас используется транспортный протокол TCP/IP необходимо указать адрес и порт в файле polyorb.conf:
## Фиксация точки доступа.
[iiop]
polyorb.protocols.iiop.default_addr=127.0.0.1
polyorb.protocols.iiop.default_port=6543
## Управление точками доступа.
[access_points]
srp=disable
soap=disable
iiop=enable
iiop.ssliop=disable
diop=disable
uipmc=disable
## Управление поддерживаемыми протоколами.
[modules]
binding_data.srp=disable
binding_data.soap=disable
binding_data.iiop=enable
binding_data.iiop.ssliop=disable
binding_data.diop=disable
binding_data.uipmc=disable
Перезапуская сервер и сравнивая создаваемые объектные ссылки объектов‐пользователей, можно убедиться, что теперь каждый раз объектная ссылка имеет одну и ту же «расшифровку», выполненную программой po_catref (нужно заметить, что текстовое представление объектных ссылок совершенно не обязательно будет совпадать; это объясняется наличием в формате ссылки незначаших позиций, заполняющихся мусором).
|