1#!/usr/local/bin/python3.8
2#
3# Copyright (c) ZeroC, Inc. All rights reserved.
4#
5
6import Ice
7from TestHelper import TestHelper
8TestHelper.loadSlice("Test.ice")
9import Test
10
11
12class ServerLocatorRegistry(Test.TestLocatorRegistry):
13    def __init__(self):
14        self._adapters = {}
15        self._objects = {}
16
17    def setAdapterDirectProxy(self, adapter, obj, current=None):
18        if obj:
19            self._adapters[adapter] = obj
20        else:
21            self._adapters.pop(adapter)
22        return None
23
24    def setReplicatedAdapterDirectProxy(self, adapter, replica, obj, current=None):
25        if obj:
26            self._adapters[adapter] = obj
27            self._adapters[replica] = obj
28        else:
29            self._adapters.pop(adapter)
30            self._adapters.pop(replica)
31        return None
32
33    def setServerProcessProxy(self, id, proxy, current=None):
34        return None
35
36    def addObject(self, obj, current=None):
37        self._objects[obj.ice_getIdentity()] = obj
38
39    def getAdapter(self, adapter):
40        if adapter not in self._adapters:
41            raise Ice.AdapterNotFoundException()
42        return self._adapters[adapter]
43
44    def getObject(self, id):
45        if id not in self._objects:
46            raise Ice.ObjectNotFoundException()
47        return self._objects[id]
48
49
50class ServerLocator(Test.TestLocator):
51
52    def __init__(self, registry, registryPrx):
53        self._registry = registry
54        self._registryPrx = registryPrx
55        self._requestCount = 0
56
57    def findObjectById(self, id, current=None):
58        self._requestCount += 1
59        return Ice.Future.completed(self._registry.getObject(id))
60
61    def findAdapterById(self, id, current=None):
62        self._requestCount += 1
63        return Ice.Future.completed(self._registry.getAdapter(id))
64
65    def getRegistry(self, current=None):
66        return self._registryPrx
67
68    def getRequestCount(self, current=None):
69        return self._requestCount
70
71
72class ServerManagerI(Test.ServerManager):
73    def __init__(self, registry, initData, helper):
74        self._registry = registry
75        self._communicators = []
76        self._initData = initData
77        self._nextPort = 1
78        self._helper = helper;
79        self._initData.properties.setProperty("TestAdapter.AdapterId", "TestAdapter")
80        self._initData.properties.setProperty("TestAdapter.ReplicaGroupId", "ReplicatedAdapter")
81        self._initData.properties.setProperty("TestAdapter2.AdapterId", "TestAdapter2")
82
83    def startServer(self, current=None):
84
85        #
86        # Simulate a server: create a new communicator and object
87        # adapter. The object adapter is started on a system allocated
88        # port. The configuration used here contains the Ice.Locator
89        # configuration variable. The new object adapter will register
90        # its endpoints with the locator and create references containing
91        # the adapter id instead of the endpoints.
92        #
93        serverCommunicator = Ice.initialize(self._initData)
94        self._communicators.append(serverCommunicator)
95
96        nRetry = 10
97        while --nRetry > 0:
98            adapter = None
99            adapter2 = None
100            try:
101                serverCommunicator.getProperties().setProperty("TestAdapter.Endpoints",
102                                                               self._helper.getTestEndpoint(num=self._nextPort))
103                self._nextPort += 1
104                serverCommunicator.getProperties().setProperty("TestAdapter2.Endpoints",
105                                                               self._helper.getTestEndpoint(num=self._nextPort))
106                self._nextPort += 1
107
108                adapter = serverCommunicator.createObjectAdapter("TestAdapter")
109                adapter2 = serverCommunicator.createObjectAdapter("TestAdapter2")
110
111                locator = serverCommunicator.stringToProxy("locator:{0}".format(self._helper.getTestEndpoint()))
112                adapter.setLocator(Ice.LocatorPrx.uncheckedCast(locator))
113                adapter2.setLocator(Ice.LocatorPrx.uncheckedCast(locator))
114
115                object = TestI(adapter, adapter2, self._registry)
116                self._registry.addObject(adapter.add(object, Ice.stringToIdentity("test")))
117                self._registry.addObject(adapter.add(object, Ice.stringToIdentity("test2")))
118                adapter.add(object, Ice.stringToIdentity("test3"))
119
120                adapter.activate()
121                adapter2.activate()
122                break
123            except Ice.SocketException as ex:
124                if nRetry == 0:
125                    raise ex
126
127                # Retry, if OA creation fails with EADDRINUSE (this can occur when running with JS web
128                # browser clients if the driver uses ports in the same range as this test, ICE-8148)
129                if adapter:
130                    adapter.destroy()
131                if adapter2:
132                    adapter2.destroy()
133
134    def shutdown(self, current=None):
135        for i in self._communicators:
136            i.destroy()
137        current.adapter.getCommunicator().shutdown()
138
139
140class HelloI(Test.Hello):
141    def sayHello(self, current=None):
142        pass
143
144
145class TestI(Test.TestIntf):
146    def __init__(self, adapter, adapter2, registry):
147        self._adapter1 = adapter
148        self._adapter2 = adapter2
149        self._registry = registry
150        self._registry.addObject(self._adapter1.add(HelloI(), Ice.stringToIdentity("hello")))
151
152    def shutdown(self, current=None):
153        self._adapter1.getCommunicator().shutdown()
154
155    def getHello(self, current=None):
156        return Test.HelloPrx.uncheckedCast(self._adapter1.createIndirectProxy(Ice.stringToIdentity("hello")))
157
158    def getReplicatedHello(self, current=None):
159        return Test.HelloPrx.uncheckedCast(self._adapter1.createProxy(Ice.stringToIdentity("hello")))
160
161    def migrateHello(self, current=None):
162        id = Ice.stringToIdentity("hello")
163        try:
164            self._registry.addObject(self._adapter2.add(self._adapter1.remove(id), id))
165        except Ice.NotRegisteredException:
166            self._registry.addObject(self._adapter1.add(self._adapter2.remove(id), id))
167
168
169class Server(TestHelper):
170
171    def run(self, args):
172
173        initData = Ice.InitializationData()
174        initData.properties = self.createTestProperties(args)
175
176        with self.initialize(initData=initData) as communicator:
177            #
178            # Register the server manager. The server manager creates a new
179            # 'server' (a server isn't a different process, it's just a new
180            # communicator and object adapter).
181            #
182            communicator.getProperties().setProperty("Ice.ThreadPool.Server.Size", "2")
183            communicator.getProperties().setProperty("ServerManager.Endpoints", self.getTestEndpoint())
184
185            adapter = communicator.createObjectAdapter("ServerManager")
186
187            #
188            # We also register a sample server locator which implements the
189            # locator interface, this locator is used by the clients and the
190            # 'servers' created with the server manager interface.
191            #
192            registry = ServerLocatorRegistry()
193            registry.addObject(adapter.createProxy(Ice.stringToIdentity("ServerManager")))
194            adapter.add(ServerManagerI(registry, initData, self), Ice.stringToIdentity("ServerManager"))
195
196            registryPrx = Ice.LocatorRegistryPrx.uncheckedCast(adapter.add(registry, Ice.stringToIdentity("registry")))
197
198            locator = ServerLocator(registry, registryPrx)
199            adapter.add(locator, Ice.stringToIdentity("locator"))
200
201            adapter.activate()
202            communicator.waitForShutdown()
203