Merge "Sonar bug fixes for SwitchManager.java"
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / OFOverlayRenderer.java
1 /*
2  * Copyright (c) 2014 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.groupbasedpolicy.renderer.ofoverlay;
10
11 import java.util.concurrent.Executors;
12 import java.util.concurrent.ScheduledExecutorService;
13
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
16 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
17 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
18 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
21 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
22 import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig;
24 import org.opendaylight.yangtools.concepts.ListenerRegistration;
25 import org.opendaylight.yangtools.yang.binding.DataObject;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import com.google.common.base.Optional;
31 import com.google.common.util.concurrent.FutureCallback;
32 import com.google.common.util.concurrent.Futures;
33 import com.google.common.util.concurrent.ListenableFuture;
34
35 /**
36  * Renderer that uses OpenFlow and OVSDB to implement an overlay network
37  * using Open vSwitch.
38
39  */
40 public class OFOverlayRenderer implements AutoCloseable, DataChangeListener {
41     private static final Logger LOG =
42             LoggerFactory.getLogger(OFOverlayRenderer.class);
43
44     private final DataBroker dataBroker;
45     private final PolicyResolver policyResolver;
46     private final SwitchManager switchManager;
47     private final EndpointManager endpointManager;
48     private final PolicyManager policyManager;
49
50     private final short tableOffset;
51
52     private final ScheduledExecutorService executor;
53
54     private static final InstanceIdentifier<OfOverlayConfig> configIid =
55             InstanceIdentifier.builder(OfOverlayConfig.class).build();
56
57     private OfOverlayConfig config;
58     ListenerRegistration<DataChangeListener> configReg;
59
60     public OFOverlayRenderer(DataBroker dataProvider,
61                              RpcProviderRegistry rpcRegistry,
62                              NotificationService notificationService,
63                              short tableOffset) {
64         super();
65         this.dataBroker = dataProvider;
66         this.tableOffset=tableOffset;
67
68         int numCPU = Runtime.getRuntime().availableProcessors();
69         //TODO: Consider moving to groupbasedpolicy-ofoverlay-config so as to be user configurable in distribution.
70         executor = Executors.newScheduledThreadPool(numCPU * 2);
71
72         switchManager = new SwitchManager(dataProvider);
73         endpointManager = new EndpointManager(dataProvider, rpcRegistry, notificationService,
74                                               executor, switchManager);
75         policyResolver = new PolicyResolver(dataProvider, executor);
76
77         policyManager = new PolicyManager(dataProvider,
78                                           policyResolver,
79                                           switchManager,
80                                           endpointManager,
81                                           rpcRegistry,
82                                           executor,
83                                           tableOffset);
84
85         configReg =
86                 dataProvider.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
87                                                         configIid,
88                                                         this,
89                                                         DataChangeScope.SUBTREE);
90         readConfig();
91         LOG.info("Initialized OFOverlay renderer");
92
93     }
94
95     // *************
96     // AutoCloseable
97     // *************
98
99     @Override
100     public void close() throws Exception {
101         executor.shutdownNow();
102         if (configReg != null) configReg.close();
103         if (policyResolver != null) policyResolver.close();
104         if (switchManager != null) switchManager.close();
105         if (endpointManager != null) endpointManager.close();
106     }
107
108     // ******************
109     // DataChangeListener
110     // ******************
111
112     @Override
113     public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>,
114                                                    DataObject> change) {
115         readConfig();
116     }
117
118     // **************
119     // Implementation
120     // **************
121
122     private void readConfig() {
123         ListenableFuture<Optional<OfOverlayConfig>> dao =
124                 dataBroker.newReadOnlyTransaction()
125                     .read(LogicalDatastoreType.CONFIGURATION, configIid);
126         Futures.addCallback(dao, new FutureCallback<Optional<OfOverlayConfig>>() {
127             @Override
128             public void onSuccess(final Optional<OfOverlayConfig> result) {
129                 if (!result.isPresent()) return;
130                 if (result.get() instanceof OfOverlayConfig) {
131                     config = result.get();
132                     applyConfig();
133                 }
134             }
135
136             @Override
137             public void onFailure(Throwable t) {
138                 LOG.error("Failed to read configuration", t);
139             }
140         }, executor);
141     }
142
143     private void applyConfig() {
144         switchManager.setEncapsulationFormat(config.getEncapsulationFormat());
145         endpointManager.setLearningMode(config.getLearningMode());
146         policyManager.setLearningMode(config.getLearningMode());
147     }
148 }