Topology manager - implementation of NodeChangeListener
[openflowplugin.git] / applications / topology-manager / src / main / java / org / opendaylight / openflowplugin / applications / topology / manager / FlowCapableTopologyProvider.java
1 /*
2  * Copyright (c) 2013 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 package org.opendaylight.openflowplugin.applications.topology.manager;
9
10 import java.util.concurrent.ExecutionException;
11
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
16 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
17 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
18 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
19 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
20 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
21 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
22 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
23 import org.opendaylight.yangtools.concepts.ListenerRegistration;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
25 import org.opendaylight.yangtools.yang.binding.NotificationListener;
26 import org.osgi.framework.BundleContext;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 public class FlowCapableTopologyProvider extends AbstractBindingAwareProvider implements AutoCloseable {
31     private final static Logger LOG = LoggerFactory.getLogger(FlowCapableTopologyProvider.class);
32     private ListenerRegistration<NotificationListener> listenerRegistration;
33     private Thread thread;
34     private LinkChangeListenerImpl linkChangeListener;
35     private NodeChangeListenerImpl nodeChangeListener;
36
37     /**
38      * Gets called on start of a bundle.
39      *
40      * @param session
41      */
42     @Override
43     public synchronized void onSessionInitiated(final ProviderContext session) {
44         final DataBroker dataBroker = session.getSALService(DataBroker.class);
45         final NotificationProviderService notificationService = session.getSALService(NotificationProviderService.class);
46
47         final String name = "flow:1";
48         final TopologyKey key = new TopologyKey(new TopologyId(name));
49         final InstanceIdentifier<Topology> path = InstanceIdentifier
50                 .create(NetworkTopology.class)
51                 .child(Topology.class, key);
52
53         final OperationProcessor processor = new OperationProcessor(dataBroker);
54         final FlowCapableTopologyExporter listener = new FlowCapableTopologyExporter(processor, path);
55         this.listenerRegistration = notificationService.registerNotificationListener(listener);
56         linkChangeListener = new LinkChangeListenerImpl(dataBroker, processor);
57         nodeChangeListener = new NodeChangeListenerImpl(dataBroker, processor);
58
59         final ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
60         tx.put(LogicalDatastoreType.OPERATIONAL, path, new TopologyBuilder().setKey(key).build(), true);
61         try {
62             tx.submit().get();
63         } catch (InterruptedException | ExecutionException e) {
64             LOG.warn("Initial topology export failed, continuing anyway", e);
65         }
66
67         thread = new Thread(processor);
68         thread.setDaemon(true);
69         thread.setName("FlowCapableTopologyExporter-" + name);
70         thread.start();
71     }
72
73     @Override
74     public synchronized void close() throws InterruptedException {
75         LOG.info("FlowCapableTopologyProvider stopped.");
76         if (this.listenerRegistration != null) {
77             try {
78                 this.listenerRegistration.close();
79             } catch (Exception e) {
80                 LOG.error("Failed to close listener registration", e);
81             }
82             listenerRegistration = null;
83         }
84         unregisterListener(linkChangeListener);
85         unregisterListener(nodeChangeListener);
86         if (thread != null) {
87             thread.interrupt();
88             thread.join();
89             thread = null;
90         }
91     }
92
93     private void unregisterListener(final AutoCloseable listenerToClose) {
94         if (listenerToClose != null) {
95             try {
96                 listenerToClose.close();
97             } catch (Exception e) {
98                 LOG.error("Failed to close listener registration", e);
99             }
100         }
101     }
102
103     /**
104      * Gets called during stop bundle
105      *
106      * @param context The execution context of the bundle being stopped.
107      */
108     @Override
109     public void stopImpl(final BundleContext context) {
110         try {
111             this.close();
112         } catch (InterruptedException e) {
113             LOG.error("Failed to stop provider", e);
114         }
115     }
116 }