2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.netconf.topology.util;
11 import akka.actor.ActorContext;
12 import akka.actor.ActorRef;
13 import akka.actor.ActorSystem;
14 import akka.actor.TypedActor;
15 import akka.actor.TypedProps;
16 import akka.japi.Creator;
17 import com.google.common.base.Preconditions;
18 import com.google.common.util.concurrent.ListenableFuture;
19 import javax.annotation.Nonnull;
20 import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
21 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
22 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
23 import org.opendaylight.netconf.topology.NodeManager;
24 import org.opendaylight.netconf.topology.NodeManagerCallback;
25 import org.opendaylight.netconf.topology.NodeManagerCallback.NodeManagerCallbackFactory;
26 import org.opendaylight.netconf.topology.RoleChangeStrategy;
27 import org.opendaylight.netconf.topology.util.messages.NormalizedNodeMessage;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
30 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import scala.concurrent.Future;
35 public final class BaseNodeManager implements NodeManager {
37 private static final Logger LOG = LoggerFactory.getLogger(BaseNodeManager.class);
39 private final String nodeId;
40 private final String topologyId;
41 private final ActorSystem actorSystem;
43 private boolean isMaster = false;
44 private NodeManagerCallback delegate;
46 private BaseNodeManager(final String nodeId,
47 final String topologyId,
48 final ActorSystem actorSystem,
49 final NodeManagerCallbackFactory delegateFactory,
50 final RoleChangeStrategy roleChangeStrategy) {
51 LOG.debug("Creating BaseNodeManager, id: {}, {}", topologyId, nodeId );
53 this.topologyId = topologyId;
54 this.actorSystem = actorSystem;
55 this.delegate = delegateFactory.create(nodeId, topologyId, actorSystem);
56 // if we want to override the place election happens,
57 // we need to override this with noop election strategy and implement election in callback
58 // cannot leak "this" here! have to use TypedActor.self()
59 roleChangeStrategy.registerRoleCandidate((NodeManager) TypedActor.self());
62 @Nonnull @Override public Node getInitialState(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
63 LOG.trace("Retrieving Node {} initial state", nodeId);
64 return delegate.getInitialState(nodeId, configNode);
67 @Nonnull @Override public Node getFailedState(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
68 LOG.trace("Retrieving Node {} failed state", nodeId);
69 return delegate.getFailedState(nodeId, configNode);
72 @Nonnull @Override public ListenableFuture<Node> onNodeCreated(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
73 LOG.debug("Creating Node {}, with configuration: {}", nodeId.getValue(), configNode);
74 return delegate.onNodeCreated(nodeId, configNode);
77 @Nonnull @Override public ListenableFuture<Node> onNodeUpdated(@Nonnull final NodeId nodeId, @Nonnull final Node configNode) {
78 LOG.debug("Updating Node {}, with configuration: {}", nodeId.getValue(), configNode);
79 return delegate.onNodeUpdated(nodeId, configNode);
82 @Nonnull @Override public ListenableFuture<Void> onNodeDeleted(@Nonnull final NodeId nodeId) {
83 LOG.debug("Deleting Node {}", nodeId.getValue());
84 return delegate.onNodeDeleted(nodeId);
89 public ListenableFuture<Node> getCurrentStatusForNode(@Nonnull NodeId nodeId) {
90 LOG.debug("Getting current status for node: {}", nodeId.getValue());
91 return delegate.getCurrentStatusForNode(nodeId);
95 public void onRoleChanged(RoleChangeDTO roleChangeDTO) {
96 LOG.debug("Node {} role has changed from: {} to {}", nodeId,
97 (roleChangeDTO.wasOwner() ? "master" : "slave"),
98 (roleChangeDTO.isOwner() ? "master" : "slave"));
100 isMaster = roleChangeDTO.isOwner();
101 delegate.onRoleChanged(roleChangeDTO);
105 public void onReceive(Object o, ActorRef actorRef) {
106 delegate.onReceive(o, actorRef);
110 public Future<NormalizedNodeMessage> onRemoteNodeCreated(final NormalizedNodeMessage message) {
115 public Future<NormalizedNodeMessage> onRemoteNodeUpdated(final NormalizedNodeMessage message) {
120 public Future<Void> onRemoteNodeDeleted(final NodeId nodeId) {
125 public Future<NormalizedNodeMessage> remoteGetCurrentStatusForNode(final NodeId nodeId) {
130 public void onDeviceConnected(SchemaContext remoteSchemaContext, NetconfSessionPreferences netconfSessionPreferences, DOMRpcService deviceRpc) {
131 delegate.onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, deviceRpc);
135 public void onDeviceDisconnected() {
136 delegate.onDeviceDisconnected();
140 public void onDeviceFailed(Throwable throwable) {
141 delegate.onDeviceFailed(throwable);
145 public void onNotification(DOMNotification domNotification) {
146 delegate.onNotification(domNotification);
150 public void close() {
155 * Builder of BaseNodeManager instances that are proxied as TypedActors
157 public static class BaseNodeManagerBuilder {
158 private String nodeId;
159 private String topologyId;
160 private NodeManagerCallbackFactory delegateFactory;
161 private RoleChangeStrategy roleChangeStrategy;
162 private ActorContext actorContext;
165 public BaseNodeManagerBuilder setNodeId(final String nodeId) {
166 this.nodeId = nodeId;
170 public BaseNodeManagerBuilder setTopologyId(final String topologyId) {
171 this.topologyId = topologyId;
175 public BaseNodeManagerBuilder setDelegateFactory(final NodeManagerCallbackFactory delegateFactory) {
176 this.delegateFactory = delegateFactory;
180 public BaseNodeManagerBuilder setRoleChangeStrategy(final RoleChangeStrategy roleChangeStrategy) {
181 this.roleChangeStrategy = roleChangeStrategy;
185 public BaseNodeManagerBuilder setActorContext(final ActorContext actorContext) {
186 this.actorContext = actorContext;
190 public NodeManager build() {
191 Preconditions.checkNotNull(nodeId);
192 Preconditions.checkNotNull(topologyId);
193 Preconditions.checkNotNull(delegateFactory);
194 Preconditions.checkNotNull(roleChangeStrategy);
195 Preconditions.checkNotNull(actorContext);
196 LOG.debug("Creating typed actor with id: {}", nodeId);
198 return TypedActor.get(actorContext).typedActorOf(new TypedProps<>(NodeManager.class, new Creator<BaseNodeManager>() {
200 public BaseNodeManager create() throws Exception {
201 return new BaseNodeManager(nodeId, topologyId, actorContext.system(), delegateFactory, roleChangeStrategy);