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