summaryrefslogtreecommitdiff
path: root/swift/test/Ice/location/TestI.swift
blob: 80eb1ebf2e3fe4acf182c22e64ca99f69cd84ee1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
import Ice
import PromiseKit
import TestCommon

class HelloI: Hello {
    func sayHello(current _: Ice.Current) {}
}

class TestI: TestIntf {
    var _adapter1: Ice.ObjectAdapter
    var _adapter2: Ice.ObjectAdapter
    var _registry: ServerLocatorRegistry

    init(adapter1: Ice.ObjectAdapter,
         adapter2: Ice.ObjectAdapter,
         registry: ServerLocatorRegistry) throws {
        _adapter1 = adapter1
        _adapter2 = adapter2
        _registry = registry

        try _registry.addObject(_adapter1.add(servant: HelloDisp(HelloI()), id: Ice.stringToIdentity("hello")))
    }

    func shutdown(current _: Ice.Current) throws {
        _adapter1.getCommunicator().shutdown()
    }

    func getHello(current _: Ice.Current) throws -> HelloPrx? {
        return try uncheckedCast(prx: _adapter1.createIndirectProxy(Ice.stringToIdentity("hello")),
                                 type: HelloPrx.self)
    }

    func getReplicatedHello(current _: Ice.Current) throws -> HelloPrx? {
        return try uncheckedCast(prx: _adapter1.createProxy(Ice.stringToIdentity("hello")),
                                 type: HelloPrx.self)
    }

    func migrateHello(current _: Ice.Current) throws {
        let id = try Ice.stringToIdentity("hello")
        do {
            try _registry.addObject(_adapter2.add(servant: _adapter1.remove(id), id: id))
        } catch is Ice.NotRegisteredException {
            try _registry.addObject(_adapter1.add(servant: _adapter2.remove(id), id: id))
        }
    }
}

class ServerManagerI: ServerManager {
    var _registry: ServerLocatorRegistry
    var _helper: TestHelper
    var _communicators = [Ice.Communicator]()
    var _nextPort: Int32 = 1

    init(registry: ServerLocatorRegistry, helper: TestHelper) {
        _registry = registry
        _helper = helper
    }

    func startServer(current _: Ice.Current) throws {
        for c in _communicators {
            c.waitForShutdown()
            c.destroy()
        }
        _communicators.removeAll()

        //
        // Simulate a server: create a new communicator and object
        // adapter. The object adapter is started on a system allocated
        // port. The configuration used here contains the Ice.Locator
        // configuration variable. The new object adapter will register
        // its endpoints with the locator and create references containing
        // the adapter id instead of the endpoints.
        //
        var initData = Ice.InitializationData()
        let properties = _helper.communicator().getProperties().clone()
        properties.setProperty(key: "TestAdapter.AdapterId", value: "TestAdapter")
        properties.setProperty(key: "TestAdapter.ReplicaGroupId", value: "ReplicatedAdapter")
        properties.setProperty(key: "TestAdapter2.AdapterId", value: "TestAdapter2")
        initData.properties = properties

        let serverCommunicator = try _helper.initialize(initData)
        _communicators.append(serverCommunicator)

        //
        // Use fixed port to ensure that OA re-activation doesn't re-use previous port from
        // another OA(e.g.: TestAdapter2 is re-activated using port of TestAdapter).
        //
        for i in 1 ... 10 {
            var adapter: Ice.ObjectAdapter!
            var adapter2: Ice.ObjectAdapter!

            do {
                _nextPort += 1
                serverCommunicator.getProperties().setProperty(key: "TestAdapter.Endpoints",
                                                               value: _helper.getTestEndpoint(num: _nextPort))

                _nextPort += 1
                serverCommunicator.getProperties().setProperty(key: "TestAdapter2.Endpoints",
                                                               value: _helper.getTestEndpoint(num: _nextPort))

                adapter = try serverCommunicator.createObjectAdapter("TestAdapter")
                adapter2 = try serverCommunicator.createObjectAdapter("TestAdapter2")

                let locator = try serverCommunicator.stringToProxy("locator:\(_helper.getTestEndpoint(num: 0))")!
                try adapter.setLocator(uncheckedCast(prx: locator, type: Ice.LocatorPrx.self))
                try adapter2.setLocator(uncheckedCast(prx: locator, type: Ice.LocatorPrx.self))

                let object = try TestI(adapter1: adapter, adapter2: adapter2, registry: _registry)
                try _registry.addObject(adapter.add(servant: TestIntfDisp(object), id: Ice.stringToIdentity("test")))
                try _registry.addObject(adapter.add(servant: TestIntfDisp(object), id: Ice.stringToIdentity("test2")))
                _ = try adapter.add(servant: TestIntfDisp(object), id: Ice.stringToIdentity("test3"))

                try adapter.activate()
                try adapter2.activate()
                break
            } catch let ex as Ice.SocketException {
                if i == 10 {
                    throw ex
                }

                // Retry, if OA creation fails with EADDRINUSE(this can occur when running with JS web
                // browser clients if the driver uses ports in the same range as this test, ICE-8148)
                if adapter != nil {
                    adapter.destroy()
                }

                if adapter2 != nil {
                    adapter2.destroy()
                }
            }
        }
    }

    func shutdown(current: Ice.Current) throws {
        for c in _communicators {
            c.destroy()
        }
        _communicators.removeAll()
        current.adapter!.getCommunicator().shutdown()
    }
}

class ServerLocator: TestLocator {
    var _registry: ServerLocatorRegistry
    var _registryPrx: Ice.LocatorRegistryPrx
    var _requestCount: Int32

    init(registry: ServerLocatorRegistry, registryPrx: Ice.LocatorRegistryPrx) {
        _registry = registry
        _registryPrx = registryPrx
        _requestCount = 0
    }

    func findAdapterByIdAsync(id: String, current: Ice.Current) -> Promise<ObjectPrx?> {
        _requestCount += 1
        if id == "TestAdapter10" || id == "TestAdapter10-2" {
            precondition(current.encoding == Ice.Encoding_1_0)
            return Promise<ObjectPrx?> { seal in
                do {
                    try seal.fulfill(_registry.getAdapter("TestAdapter"))
                } catch {
                    seal.reject(error)
                }
            }
        } else {
            // We add a small delay to make sure locator request queuing gets tested when
            // running the test on a fast machine
            Thread.sleep(forTimeInterval: 0.1)
            return Promise<ObjectPrx?> { seal in
                do {
                    try seal.fulfill(_registry.getAdapter(id))
                } catch {
                    seal.reject(error)
                }
            }
        }
    }

    func findObjectByIdAsync(id: Ice.Identity, current _: Ice.Current) -> Promise<ObjectPrx?> {
        _requestCount += 1
        // We add a small delay to make sure locator request queuing gets tested when
        // running the test on a fast machine
        Thread.sleep(forTimeInterval: 0.1)
        return Promise<ObjectPrx?> { seal in
            do {
                try seal.fulfill(_registry.getObject(id))
            } catch {
                seal.reject(error)
            }
        }
    }

    func getRegistry(current _: Ice.Current) throws -> Ice.LocatorRegistryPrx? {
        return _registryPrx
    }

    func getRequestCount(current _: Ice.Current) throws -> Int32 {
        return _requestCount
    }
}

class ServerLocatorRegistry: TestLocatorRegistry {
    var _adapters = [String: Ice.ObjectPrx]()
    var _objects = [Ice.Identity: Ice.ObjectPrx]()
    var _lock = os_unfair_lock()

    func setAdapterDirectProxyAsync(id: String, proxy: ObjectPrx?, current _: Current) -> Promise<Void> {
        return Promise<Void> { seal in
            withLock(&_lock) {
                if let obj = proxy {
                    self._adapters[id] = obj
                } else {
                    self._adapters.removeValue(forKey: id)
                }
            }
            seal.fulfill(())
        }
    }

    func setReplicatedAdapterDirectProxyAsync(adapterId adapter: String,
                                              replicaGroupId replica: String,
                                              p: Ice.ObjectPrx?,
                                              current _: Ice.Current) -> Promise<Void> {
        return Promise<Void> { seal in
            withLock(&_lock) {
                if let obj = p {
                    _adapters[adapter] = obj
                    _adapters[replica] = obj
                } else {
                    _adapters.removeValue(forKey: adapter)
                    _adapters.removeValue(forKey: replica)
                }
            }
            seal.fulfill(())
        }
    }

    func setServerProcessProxyAsync(id _: String, proxy _: Ice.ProcessPrx?, current _: Ice.Current) -> Promise<Void> {
        return Promise<Void> { seal in
            seal.fulfill(())
        }
    }

    func addObject(_ obj: Ice.ObjectPrx?) {
        withLock(&_lock) {
            _objects[obj!.ice_getIdentity()] = obj
        }
    }

    func addObject(obj: Ice.ObjectPrx?, current _: Ice.Current) throws {
        addObject(obj)
    }

    func getAdapter(_ id: String) throws -> Ice.ObjectPrx {
        guard let obj = _adapters[id] else {
            throw Ice.AdapterNotFoundException()
        }
        return obj
    }

    func getObject(_ id: Ice.Identity) throws -> Ice.ObjectPrx {
        guard let obj = _objects[id] else {
            throw Ice.ObjectNotFoundException()
        }
        return obj
    }
}