1//
2// Copyright (c) ZeroC, Inc. All rights reserved.
3//
4
5#import <objc/Ice.h>
6#import <location/TestI.h>
7
8@implementation ServerManagerI
9-(id) init:(ServerLocatorRegistry*)registry initData:(ICEInitializationData*)initData
10{
11    self = [super init];
12    if(!self)
13    {
14        return nil;
15    }
16    registry_ = registry;
17    initData_ = initData;
18    nextPort_ = 1;
19
20    [initData_.properties setProperty:@"TestAdapter.AdapterId" value:@"TestAdapter"];
21    [initData_.properties setProperty:@"TestAdapter.ReplicaGroupId" value:@"ReplicatedAdapter"];
22
23    [initData_.properties setProperty:@"TestAdapter2.AdapterId" value:@"TestAdapter2"];
24
25    [initData_.properties setProperty:@"Ice.PrintAdapterReady" value:@"0"];
26    return self;
27}
28
29#if defined(__clang__) && !__has_feature(objc_arc)
30-(void) dealloc
31{
32    [communicators_ release];
33    [super dealloc];
34}
35#endif
36
37-(NSString*) getTestEndpoint:(int)port
38{
39    return [NSString stringWithFormat:@"default -p %d", 12010 + port];
40}
41-(void) startServer:(ICECurrent*)__unused current
42{
43    for(id<ICECommunicator> c in communicators_)
44    {
45        [c waitForShutdown];
46        [c destroy];
47    }
48    ICE_RELEASE(communicators_);
49    communicators_ = [[NSMutableArray alloc] init];
50
51    //
52    // Simulate a server: create a [[communicator alloc] init] and object
53    // adapter. The object adapter is started on a system allocated
54    // port. The configuration used here contains the Ice.Locator
55    // configuration variable. The [[object alloc] init] adapter will register
56    // its endpoints with the locator and create references containing
57    // the adapter id instead of the endpoints.
58    //
59    int nRetry = 10;
60    while(nRetry > 0)
61    {
62        id<ICEObjectAdapter> adapter = nil;
63        id<ICEObjectAdapter> adapter2 = nil;
64        @try
65        {
66            id<ICECommunicator> serverCommunicator = [ICEUtil createCommunicator:initData_];
67            [communicators_ addObject:serverCommunicator];
68
69            [[serverCommunicator getProperties] setProperty:@"TestAdapter.Endpoints" value:[self getTestEndpoint:nextPort_++]];
70            [[serverCommunicator getProperties] setProperty:@"TestAdapter2.Endpoints" value:[self getTestEndpoint:nextPort_++]];
71
72            adapter = [serverCommunicator createObjectAdapter:@"TestAdapter"];
73            adapter2 = [serverCommunicator createObjectAdapter:@"TestAdapter2"];
74
75            id<ICEObjectPrx> locator = [serverCommunicator stringToProxy:@"locator:default -p 12010"];
76            [adapter setLocator:[ICELocatorPrx uncheckedCast:locator]];
77            [adapter2 setLocator:[ICELocatorPrx uncheckedCast:locator]];
78
79            ICEObject* object = ICE_AUTORELEASE([[TestLocationI alloc] init:adapter adapter2:adapter2 registry:registry_]);
80            [registry_ addObject:[adapter add:object identity:[ICEUtil stringToIdentity:@"test"]]];
81            [registry_ addObject:[adapter add:object identity:[ICEUtil stringToIdentity:@"test2"]]];
82            [adapter add:object identity:[ICEUtil stringToIdentity:@"test3"]];
83
84            [adapter activate];
85            [adapter2 activate];
86            break;
87        }
88        @catch(ICESocketException* ex)
89        {
90            if(nRetry == 0)
91            {
92                @throw ex;
93            }
94
95            // Retry, if OA creation fails with EADDRINUSE (this can occur when running with JS web
96            // browser clients if the driver uses ports in the same range as this test, ICE-8148)
97            if(adapter != nil)
98            {
99                [adapter destroy];
100            }
101            if(adapter2 != nil)
102            {
103                [adapter2 destroy];
104            }
105        }
106    }
107}
108
109-(void) shutdown:(ICECurrent*)current
110{
111    for(id<ICECommunicator> c in communicators_)
112    {
113        [c destroy];
114    }
115    [communicators_ removeAllObjects];
116    [[current.adapter getCommunicator] shutdown];
117}
118
119-(void) terminate
120{
121    for(id<ICECommunicator> c in communicators_)
122    {
123        [c destroy];
124    }
125    [communicators_ removeAllObjects];
126}
127@end
128
129@implementation TestLocationI
130-(id) init:(id<ICEObjectAdapter>)adapter
131  adapter2:(id<ICEObjectAdapter>)adapter2
132  registry:(ServerLocatorRegistry*)registry
133{
134    self = [super init];
135    if(!self)
136    {
137        return nil;
138    }
139    adapter1_ = ICE_RETAIN(adapter);
140    adapter2_ = ICE_RETAIN(adapter2);
141    registry_ = registry;
142    [registry_ addObject:[adapter1_ add:[HelloI hello] identity:[ICEUtil stringToIdentity:@"hello"]]];
143    return self;
144}
145
146#if defined(__clang__) && !__has_feature(objc_arc)
147-(void) dealloc
148{
149    [adapter1_ release];
150    [adapter2_ release];
151    [super dealloc];
152}
153#endif
154
155-(void) shutdown:(ICECurrent*)__unused current
156{
157    [[adapter1_ getCommunicator] shutdown];
158}
159
160-(id<TestLocationHelloPrx>) getHello:(ICECurrent*)__unused current
161{
162    return [TestLocationHelloPrx uncheckedCast:[adapter1_ createIndirectProxy:[ICEUtil stringToIdentity:@"hello"]]];
163}
164
165-(id<TestLocationHelloPrx>) getReplicatedHello:(ICECurrent*)__unused current
166{
167    return [TestLocationHelloPrx uncheckedCast:[adapter1_ createProxy:[ICEUtil stringToIdentity:@"hello"]]];
168}
169
170-(void) migrateHello:(ICECurrent*)__unused current
171{
172    ICEIdentity* ident = [ICEUtil stringToIdentity:@"hello"];
173    @try
174    {
175        [registry_ addObject:[adapter2_ add:[adapter1_ remove:ident] identity:ident]];
176    }
177    @catch(ICENotRegisteredException*)
178    {
179        [registry_ addObject:[adapter1_ add:[adapter2_ remove:ident] identity:ident]];
180    }
181}
182@end
183
184@implementation HelloI
185-(void) sayHello:(ICECurrent*)__unused current
186{
187}
188@end
189