392838c4b8eaeca62c88c90f916dcc5401f5168f
[netconf.git] / opendaylight / netconf / netconf-topology / src / test / java / org / opendaylight / netconf / topology / ActorTest.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netconf.topology;
10
11 import static com.jayway.awaitility.Awaitility.await;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Mockito.when;
14
15 import akka.actor.ActorRef;
16 import akka.actor.ActorSystem;
17 import akka.actor.TypedActor;
18 import akka.actor.TypedActorExtension;
19 import akka.actor.TypedProps;
20 import akka.japi.Creator;
21 import com.google.common.base.Optional;
22 import com.google.common.base.Preconditions;
23 import com.google.common.collect.Lists;
24 import com.google.common.util.concurrent.FutureCallback;
25 import com.google.common.util.concurrent.Futures;
26 import com.google.common.util.concurrent.ListenableFuture;
27 import com.google.common.util.concurrent.SettableFuture;
28 import com.typesafe.config.ConfigFactory;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.List;
32 import java.util.concurrent.Callable;
33 import java.util.concurrent.ExecutorService;
34 import java.util.concurrent.Executors;
35 import java.util.concurrent.TimeUnit;
36 import javassist.ClassPool;
37 import javax.annotation.Nonnull;
38 import org.junit.Before;
39 import org.junit.Ignore;
40 import org.junit.Test;
41 import org.mockito.Mock;
42 import org.mockito.MockitoAnnotations;
43 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
44 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
45 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
46 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
47 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
48 import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
49 import org.opendaylight.netconf.topology.TopologyManagerCallback.TopologyManagerCallbackFactory;
50 import org.opendaylight.netconf.topology.example.ExampleNodeManagerCallback;
51 import org.opendaylight.netconf.topology.example.ExampleTopologyManagerCallback;
52 import org.opendaylight.netconf.topology.example.LoggingSalNodeWriter;
53 import org.opendaylight.netconf.topology.impl.NetconfNodeOperationalDataAggregator;
54 import org.opendaylight.netconf.topology.util.BaseTopologyManager;
55 import org.opendaylight.netconf.topology.util.NoopRoleChangeStrategy;
56 import org.opendaylight.netconf.topology.util.TopologyRoleChangeStrategy;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.$YangModuleInfoImpl;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.ClusteredConnectionStatusBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatus.Status;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.clustered.connection.status.NodeStatusBuilder;
68 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
69 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
70 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
71 import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
72 import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
73 import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
74 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
75 import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
76 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
77 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
78 import org.slf4j.Logger;
79 import org.slf4j.LoggerFactory;
80
81 public class ActorTest {
82
83     private static final Logger LOG = LoggerFactory.getLogger(ActorTest.class);
84
85     private static final String TOPOLOGY_NETCONF = "TopologyNetconf";
86
87     @Mock
88     private EntityOwnershipService entityOwnershipService;
89
90     @Mock
91     private DataBroker dataBroker;
92
93     private static final BindingNormalizedNodeCodecRegistry CODEC_REGISTRY;
94
95     static {
96         final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
97         moduleInfoBackedContext.addModuleInfos(Collections.singletonList($YangModuleInfoImpl.getInstance()));
98         final Optional<SchemaContext> schemaContextOptional = moduleInfoBackedContext.tryToCreateSchemaContext();
99         Preconditions.checkState(schemaContextOptional.isPresent());
100         final SchemaContext topologySchemaCtx = schemaContextOptional.get();
101
102         final JavassistUtils javassist = JavassistUtils.forClassPool(ClassPool.getDefault());
103         CODEC_REGISTRY = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(javassist));
104         CODEC_REGISTRY.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(moduleInfoBackedContext, topologySchemaCtx));
105     }
106
107     private static final String PATH_MASTER = "akka.tcp://NetconfNode@127.0.0.1:2552/user/TopologyNetconf";
108     private static final String PATH_SLAVE1 = "akka.tcp://NetconfNode@127.0.0.1:2553/user/TopologyNetconf";
109     private static final String PATH_SLAVE2 = "akka.tcp://NetconfNode@127.0.0.1:2554/user/TopologyNetconf";
110
111     private static final List<String> PATHS_MASTER = Lists.newArrayList(PATH_SLAVE1, PATH_SLAVE2);
112     private static final List<String> PATHS_SLAVE1 = Lists.newArrayList(PATH_MASTER, PATH_SLAVE2);
113     private static final List<String> PATHS_SLAVE2 = Lists.newArrayList(PATH_MASTER, PATH_SLAVE1);
114
115     private static final ActorSystem ACTOR_SYSTEM = ActorSystem.create("NetconfNode", ConfigFactory.load("netconf-node1"));
116     private static final ActorSystem ACTOR_SYSTEM_SLAVE1 = ActorSystem.create("NetconfNode", ConfigFactory.load("netconf-node2"));
117     private static final ActorSystem ACTOR_SYSTEM_SLAVE2 = ActorSystem.create("NetconfNode", ConfigFactory.load("netconf-node3"));
118
119     private static final ExecutorService callbackExecutor = Executors.newFixedThreadPool(8);
120
121     private TopologyManager master = null;
122
123     @Before
124     public void setup() {
125         MockitoAnnotations.initMocks(this);
126         when(dataBroker.registerDataChangeListener(
127                 any(LogicalDatastoreType.class),
128                 any(InstanceIdentifier.class),
129                 any(DataChangeListener.class),
130                 any(DataChangeScope.class))).thenReturn(null);
131     }
132
133     private void setMaster(final TopologyManager manager) {
134
135     }
136
137     @Test
138     public void testRealActors() throws Exception {
139
140         EntityOwnershipService topoOwnership = new TestingEntityOwnershipService();
141         // load from config
142         final TopologyManager master = createManagerWithOwnership(ACTOR_SYSTEM, TOPOLOGY_NETCONF, true, createRealTopoTestingNodeCallbackFactory(), new TopologyRoleChangeStrategy(dataBroker, topoOwnership, TOPOLOGY_NETCONF, "topology-manager"));
143         Thread.sleep(1000);
144         final TopologyManager slave1 = createManagerWithOwnership(ACTOR_SYSTEM_SLAVE1, TOPOLOGY_NETCONF, false, createRealTopoTestingNodeCallbackFactory(), new TopologyRoleChangeStrategy(dataBroker, topoOwnership, TOPOLOGY_NETCONF, "topology-manager"));
145         final TopologyManager slave2 = createManagerWithOwnership(ACTOR_SYSTEM_SLAVE2, TOPOLOGY_NETCONF, false, createRealTopoTestingNodeCallbackFactory(), new TopologyRoleChangeStrategy(dataBroker, topoOwnership, TOPOLOGY_NETCONF, "topology-manager"));
146
147         await().atMost(30L, TimeUnit.SECONDS).until(new Callable<Boolean>() {
148             @Override
149             public Boolean call() throws Exception {
150                 return master.hasAllPeersUp();
151             }
152         });
153
154         final List<ListenableFuture<Node>> futures = new ArrayList<>();
155         for (int i = 0; i <= 1; i++) {
156             final String nodeid = "testing-node" + i;
157             final Node testingNode = new NodeBuilder()
158                     .setNodeId(new NodeId(nodeid))
159                     .addAugmentation(NetconfNode.class,
160                             new NetconfNodeBuilder()
161                                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
162                                     .setPort(new PortNumber(10000 + i))
163                                     .build())
164                     .build();
165             final ListenableFuture<Node> nodeListenableFuture = master.onNodeCreated(new NodeId(nodeid), testingNode);
166             futures.add(nodeListenableFuture);
167             Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
168                 @Override
169                 public void onSuccess(Node result) {
170                     LOG.warn("Node {} created succesfully on all nodes", result.getNodeId().getValue());
171                 }
172
173                 @Override
174                 public void onFailure(Throwable t) {
175                     LOG.warn("Node creation failed. ", t);
176                 }
177             });
178         }
179
180         for (int i = 0; i <= 1; i++) {
181             final String nodeid = "testing-node" + i;
182             final Node testingNode = new NodeBuilder()
183                     .setNodeId(new NodeId(nodeid))
184                     .addAugmentation(NetconfNode.class,
185                             new NetconfNodeBuilder()
186                                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
187                                     .setPort(new PortNumber(10000 + i))
188                                     .build())
189                     .build();
190             final ListenableFuture<Node> nodeListenableFuture = master.onNodeUpdated(new NodeId(nodeid), testingNode);
191             futures.add(nodeListenableFuture);
192             Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
193                 @Override
194                 public void onSuccess(Node result) {
195                     LOG.warn("Node {} updated succesfully on all nodes", result.getNodeId().getValue());
196                 }
197
198                 @Override
199                 public void onFailure(Throwable t) {
200                     LOG.warn("Node update failed. ", t);
201                 }
202             });
203         }
204
205
206         final List<ListenableFuture<Void>> deleteFutures = new ArrayList<>();
207         for (int i = 0; i <= 1; i++) {
208             final String nodeid = "testing-node" + i;
209             final ListenableFuture<Void> nodeListenableFuture = master.onNodeDeleted(new NodeId(nodeid));
210             deleteFutures.add(nodeListenableFuture);
211             Futures.addCallback(nodeListenableFuture, new FutureCallback<Void>() {
212                 @Override
213                 public void onSuccess(Void result) {
214                     LOG.warn("Node {} succesfully deleted on all nodes", nodeid);
215                 }
216
217                 @Override
218                 public void onFailure(Throwable t) {
219                     LOG.warn("Node delete failed. ", t);
220                 }
221             });
222
223         }
224         LOG.warn("All tasks submitted");
225         Futures.allAsList(futures).get();
226         Futures.allAsList(deleteFutures).get();
227
228         TypedActor.get(ACTOR_SYSTEM).stop(master);
229         TypedActor.get(ACTOR_SYSTEM_SLAVE1).stop(slave1);
230         TypedActor.get(ACTOR_SYSTEM_SLAVE2).stop(slave2);
231
232     }
233
234     // TODO seems like stopping actors is not enough to create an actor with same name, split this into multiple classes?
235     @Ignore
236     @Test
237     public void testWithDummyOwnershipService() throws Exception {
238
239         final TestingEntityOwnershipService ownershipService = new TestingEntityOwnershipService();
240         // load from config
241         final TopologyManager master = createNoopRoleChangeNode(ACTOR_SYSTEM, TOPOLOGY_NETCONF, true, createRealTopoCallbackFactory(ownershipService));
242         final TopologyManager slave1 = createNoopRoleChangeNode(ACTOR_SYSTEM_SLAVE1, TOPOLOGY_NETCONF, false, createRealTopoCallbackFactory(ownershipService));
243         final TopologyManager slave2 = createNoopRoleChangeNode(ACTOR_SYSTEM_SLAVE2, TOPOLOGY_NETCONF, false, createRealTopoCallbackFactory(ownershipService));
244
245         await().atMost(10L, TimeUnit.SECONDS).until(new Callable<Boolean>() {
246             @Override
247             public Boolean call() throws Exception {
248                 return master.hasAllPeersUp();
249             }
250         });
251
252         final List<ListenableFuture<Node>> futures = new ArrayList<>();
253         for (int i = 0; i <= 0; i++) {
254             final String nodeid = "testing-node" + i;
255             final Node testingNode = new NodeBuilder()
256                     .setNodeId(new NodeId(nodeid))
257                     .addAugmentation(NetconfNode.class,
258                             new NetconfNodeBuilder()
259                                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
260                                     .setPort(new PortNumber(10000 + i))
261                                     .build())
262                     .build();
263             final ListenableFuture<Node> nodeListenableFuture = master.onNodeCreated(new NodeId(nodeid), testingNode);
264             futures.add(nodeListenableFuture);
265             Futures.addCallback(nodeListenableFuture, new FutureCallback<Node>() {
266                 @Override
267                 public void onSuccess(Node result) {
268                     LOG.warn("Node {} created succesfully on all nodes", result.getNodeId().getValue());
269                 }
270
271                 @Override
272                 public void onFailure(Throwable t) {
273                     LOG.warn("Node creation failed. ", t);
274                 }
275             });
276         }
277
278         Futures.allAsList(futures).get();
279         ownershipService.distributeOwnership();
280
281         Thread.sleep(30000);
282         TypedActor.get(ACTOR_SYSTEM).stop(master);
283         TypedActor.get(ACTOR_SYSTEM_SLAVE1).stop(slave1);
284         TypedActor.get(ACTOR_SYSTEM_SLAVE2).stop(slave2);
285     }
286
287     private TopologyManager createNoopRoleChangeNode(final ActorSystem actorSystem, final String topologyId, final boolean isMaster,
288                                                      final TopologyManagerCallbackFactory topologyManagerCallbackFactory) {
289
290         final TypedActorExtension typedActorExtension = TypedActor.get(actorSystem);
291         return typedActorExtension.typedActorOf(new TypedProps<>(TopologyManager.class, new Creator<BaseTopologyManager>() {
292             @Override
293             public BaseTopologyManager create() throws Exception {
294                 return new BaseTopologyManager(actorSystem,
295                         CODEC_REGISTRY,
296                         dataBroker,
297                         topologyId,
298                         topologyManagerCallbackFactory,
299                         new TestingSuccesfulStateAggregator(),
300                         new LoggingSalNodeWriter(),
301                         new NoopRoleChangeStrategy(),
302                         isMaster);
303             }
304         }), TOPOLOGY_NETCONF);
305     }
306
307     private TopologyManager createManagerWithOwnership(final ActorSystem actorSystem, final String topologyId, final boolean isMaster,
308                                                        final TopologyManagerCallbackFactory topologyManagerCallbackFactory, final RoleChangeStrategy roleChangeStrategy) {
309         final TypedActorExtension typedActorExtension = TypedActor.get(actorSystem);
310         return typedActorExtension.typedActorOf(new TypedProps<>(TopologyManager.class, new Creator<BaseTopologyManager>() {
311             @Override
312             public BaseTopologyManager create() throws Exception {
313                 return new BaseTopologyManager(actorSystem,
314                         CODEC_REGISTRY,
315                         dataBroker,
316                         topologyId,
317                         topologyManagerCallbackFactory,
318                         new NetconfNodeOperationalDataAggregator(),
319                         new LoggingSalNodeWriter(),
320                         roleChangeStrategy,
321                         isMaster);
322             }
323         }), TOPOLOGY_NETCONF);
324     }
325
326     private TopologyManagerCallbackFactory createRealTopoTestingNodeCallbackFactory() {
327         final NodeManagerCallbackFactory nodeManagerCallbackFactory = new NodeManagerCallbackFactory() {
328             @Override
329             public NodeManagerCallback create(String nodeId, String topologyId, ActorSystem actorSystem) {
330                 return new LoggingNodeManagerCallback();
331             }
332         };
333
334         return new TopologyManagerCallbackFactory() {
335             @Override
336             public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
337                 return new ExampleTopologyManagerCallback(actorSystem, dataBroker, topologyId, nodeManagerCallbackFactory, new LoggingSalNodeWriter());
338             }
339         };
340     }
341
342     private TopologyManagerCallbackFactory createRealTopoCallbackFactory(final EntityOwnershipService entityOwnershipService) {
343         final NodeManagerCallbackFactory nodeManagerCallbackFactory = new NodeManagerCallbackFactory() {
344             @Override
345             public NodeManagerCallback create(String nodeId, String topologyId, ActorSystem actorSystem) {
346                 return new ExampleNodeManagerCallback();
347             }
348         };
349
350         return new TopologyManagerCallbackFactory() {
351             @Override
352             public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
353                 return new ExampleTopologyManagerCallback(actorSystem, dataBroker, topologyId, nodeManagerCallbackFactory);
354             }
355         };
356     }
357
358     private TopologyManagerCallbackFactory createTestingTopoCallbackFactory() {
359         return new TopologyManagerCallbackFactory() {
360             @Override
361             public TopologyManagerCallback create(ActorSystem actorSystem, String topologyId) {
362                 return new TestingTopologyManagerCallback();
363             }
364         };
365     }
366
367     public static class LoggingNodeManagerCallback implements NodeManagerCallback {
368
369         @Nonnull
370         @Override
371         public Node getInitialState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
372             final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
373             return new NodeBuilder()
374                     .setNodeId(nodeId)
375                     .addAugmentation(NetconfNode.class,
376                             new NetconfNodeBuilder()
377                                     .setHost(netconfNode.getHost())
378                                     .setPort(netconfNode.getPort())
379                                     .setConnectionStatus(ConnectionStatus.Connecting)
380                                     .setClusteredConnectionStatus(
381                                             new ClusteredConnectionStatusBuilder()
382                                                     .setNodeStatus(
383                                                             Lists.newArrayList(
384                                                                     new NodeStatusBuilder()
385                                                                             .setNode("testing-node")
386                                                                             .setStatus(Status.Unavailable)
387                                                                             .build()))
388                                                     .build())
389                                     .build())
390                     .build();
391         }
392
393         @Nonnull
394         @Override
395         public Node getFailedState(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
396             final NetconfNode netconfNode = configNode.getAugmentation(NetconfNode.class);
397             return new NodeBuilder()
398                     .setNodeId(nodeId)
399                     .addAugmentation(NetconfNode.class,
400                             new NetconfNodeBuilder()
401                                     .setHost(netconfNode.getHost())
402                                     .setPort(netconfNode.getPort())
403                                     .setConnectionStatus(ConnectionStatus.UnableToConnect)
404                                     .setClusteredConnectionStatus(
405                                             new ClusteredConnectionStatusBuilder()
406                                                     .setNodeStatus(
407                                                             Collections.singletonList(
408                                                                     new NodeStatusBuilder()
409                                                                             .setNode("testing-node")
410                                                                             .setStatus(Status.Failed)
411                                                                             .build()))
412                                                     .build())
413                                     .build())
414                     .build();
415         }
416
417         @Nonnull
418         @Override
419         public ListenableFuture<Node> onNodeCreated(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
420             LOG.debug("Creating node {} with config {}", nodeId, configNode);
421             final NetconfNode augmentation = configNode.getAugmentation(NetconfNode.class);
422             return Futures.immediateFuture(new NodeBuilder()
423                     .setNodeId(nodeId)
424                     .addAugmentation(NetconfNode.class,
425                             new NetconfNodeBuilder()
426                                     .setConnectionStatus(ConnectionStatus.Connected)
427                                     .setHost(augmentation.getHost())
428                                     .setPort(augmentation.getPort())
429                                     .setClusteredConnectionStatus(
430                                             new ClusteredConnectionStatusBuilder()
431                                                     .setNodeStatus(
432                                                             Collections.singletonList(
433                                                                     new NodeStatusBuilder()
434                                                                             .setNode("testing-node")
435                                                                             .setStatus(Status.Connected)
436                                                                             .build()))
437                                                     .build())
438                                     .build())
439                     .build());
440         }
441
442         @Nonnull
443         @Override
444         public ListenableFuture<Node> onNodeUpdated(@Nonnull NodeId nodeId, @Nonnull Node configNode) {
445             LOG.debug("Updating node {} with config {}", nodeId, configNode);
446             final NetconfNode augmentation = configNode.getAugmentation(NetconfNode.class);
447             return Futures.immediateFuture(new NodeBuilder()
448                     .setNodeId(nodeId)
449                     .addAugmentation(NetconfNode.class,
450                             new NetconfNodeBuilder()
451                                     .setConnectionStatus(ConnectionStatus.Connected)
452                                     .setHost(augmentation.getHost())
453                                     .setPort(augmentation.getPort())
454                                     .setClusteredConnectionStatus(
455                                             new ClusteredConnectionStatusBuilder()
456                                                     .setNodeStatus(
457                                                             Collections.singletonList(
458                                                                     new NodeStatusBuilder()
459                                                                             .setNode("testing-node")
460                                                                             .setStatus(Status.Connected)
461                                                                             .build()))
462                                                     .build())
463                                     .build())
464                     .build());
465         }
466
467         @Nonnull
468         @Override
469         public ListenableFuture<Void> onNodeDeleted(@Nonnull NodeId nodeId) {
470             LOG.debug("Deleting node {}", nodeId);
471             return Futures.immediateFuture(null);
472         }
473
474         @Nonnull
475         @Override
476         public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
477             return null;
478         }
479
480         @Override
481         public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
482
483         }
484
485         @Override
486         public void onReceive(Object o, ActorRef actorRef) {
487
488         }
489     }
490
491     public static class TestingTopologyManagerCallback implements TopologyManagerCallback {
492
493         public TestingTopologyManagerCallback() {
494
495         }
496
497         @Override
498         public ListenableFuture<Node> onNodeCreated(NodeId nodeId, Node node) {
499             LOG.warn("Actor system that called this: {}", TypedActor.context().system().settings().toString());
500             return Futures.immediateFuture(new NodeBuilder()
501                     .setNodeId(nodeId)
502                     .addAugmentation(NetconfNode.class,
503                             new NetconfNodeBuilder()
504                                     .setConnectionStatus(ConnectionStatus.Connected)
505                                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
506                                     .setPort(new PortNumber(2555))
507                                     .build())
508                     .build());
509         }
510
511         @Override
512         public ListenableFuture<Node> onNodeUpdated(NodeId nodeId, Node node) {
513             LOG.warn("Actor system that called this: {}", TypedActor.context().system().settings().toString());
514             LOG.debug("Update called on node {}, with config {}", nodeId.getValue(), node);
515             return Futures.immediateFuture(new NodeBuilder()
516                     .setNodeId(nodeId)
517                     .addAugmentation(NetconfNode.class,
518                             new NetconfNodeBuilder()
519                                     .setConnectionStatus(ConnectionStatus.Connected)
520                                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
521                                     .setPort(new PortNumber(65535))
522                                     .build())
523                     .build());
524         }
525
526         @Override
527         public ListenableFuture<Void> onNodeDeleted(NodeId nodeId) {
528             LOG.debug("Delete called on node {}", nodeId.getValue());
529             return Futures.immediateFuture(null);
530         }
531
532         @Nonnull
533         @Override
534         public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
535             return null;
536         }
537
538         @Override
539         public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
540
541         }
542
543         @Override
544         public void onReceive(Object o, ActorRef actorRef) {
545
546         }
547     }
548
549     public class TestingSuccesfulStateAggregator implements StateAggregator {
550
551         @Override
552         public ListenableFuture<Node> combineCreateAttempts(List<ListenableFuture<Node>> stateFutures) {
553             final SettableFuture<Node> future = SettableFuture.create();
554             final ListenableFuture<List<Node>> allAsList = Futures.allAsList(stateFutures);
555             Futures.addCallback(allAsList, new FutureCallback<List<Node>>() {
556                 @Override
557                 public void onSuccess(List<Node> result) {
558                     for (int i = 0; i < result.size() - 1; i++) {
559                         if (!result.get(i).equals(result.get(i + 1))) {
560                             LOG.warn("Node 1 {}: {}", result.get(i).getClass(), result.get(i));
561                             LOG.warn("Node 2 {}: {}", result.get(i + 1).getClass(), result.get(i + 1));
562                             future.setException(new IllegalStateException("Create futures have different result"));
563                             LOG.warn("Future1 : {}  Future2 : {}", result.get(i), result.get(i+1));
564                         }
565                     }
566                     future.set(result.get(0));
567                 }
568
569                 @Override
570                 public void onFailure(Throwable t) {
571                     LOG.error("One of the combined create attempts failed {}", t);
572                     future.setException(t);
573                 }
574             }, TypedActor.context().dispatcher());
575
576             return future;
577         }
578
579         @Override
580         public ListenableFuture<Node> combineUpdateAttempts(List<ListenableFuture<Node>> stateFutures) {
581             final SettableFuture<Node> future = SettableFuture.create();
582             final ListenableFuture<List<Node>> allAsList = Futures.allAsList(stateFutures);
583             Futures.addCallback(allAsList, new FutureCallback<List<Node>>() {
584                 @Override
585                 public void onSuccess(List<Node> result) {
586                     for (int i = 0; i < result.size() - 1; i++) {
587                         if (!result.get(i).equals(result.get(i + 1))) {
588                             future.setException(new IllegalStateException("Update futures have different result"));
589                         }
590                     }
591                     future.set(result.get(0));
592                 }
593
594                 @Override
595                 public void onFailure(Throwable t) {
596                     LOG.error("One of the combined update attempts failed {}", t);
597                     future.setException(t);
598                 }
599             });
600             return future;
601         }
602
603         @Override
604         public ListenableFuture<Void> combineDeleteAttempts(List<ListenableFuture<Void>> stateFutures) {
605             final SettableFuture<Void> future = SettableFuture.create();
606             final ListenableFuture<List<Void>> allAsList = Futures.allAsList(stateFutures);
607             Futures.addCallback(allAsList, new FutureCallback<List<Void>>() {
608                 @Override
609                 public void onSuccess(List<Void> result) {
610                     future.set(null);
611                 }
612
613                 @Override
614                 public void onFailure(Throwable t) {
615                     LOG.error("One of the combined delete attempts failed {}", t);
616                     future.setException(t);
617                 }
618             });
619             return future;
620         }
621     }
622 }