Merge "Use ClusteredDataTreeListener in hwvtepsb"
[netvirt.git] / openstack / net-virt-providers / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / providers / NetvirtProvidersProvider.java
1 /*
2  * Copyright (c) 2014, 2015 Red Hat, 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.ovsdb.openstack.netvirt.providers;
10
11 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
12
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
15 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
16 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
17 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
18 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
19 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
20 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
21 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
22 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
23 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
25 import org.osgi.framework.BundleContext;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 import java.util.concurrent.atomic.AtomicBoolean;
30
31 /**
32  * @author Sam Hague (shague@redhat.com)
33  */
34 public class NetvirtProvidersProvider implements BindingAwareProvider, AutoCloseable {
35     private static final Logger LOG = LoggerFactory.getLogger(NetvirtProvidersProvider.class);
36
37     private BundleContext bundleContext = null;
38     private static DataBroker dataBroker = null;
39     private ConfigActivator activator;
40     private static ProviderContext providerContext = null;
41     private static EntityOwnershipService entityOwnershipService;
42     private ProviderEntityListener providerEntityListener = null;
43     private static AtomicBoolean hasProviderEntityOwnership = new AtomicBoolean(false);
44     private static short tableOffset;
45     private NetvirtProvidersConfigImpl netvirtProvidersConfig = null;
46
47     public NetvirtProvidersProvider(BundleContext bundleContext, EntityOwnershipService eos, short tableOffset) {
48         LOG.info("NetvirtProvidersProvider: bundleContext: {}", bundleContext);
49         this.bundleContext = bundleContext;
50             entityOwnershipService = eos;
51         setTableOffset(tableOffset);
52     }
53
54     public static DataBroker getDataBroker() {
55         return dataBroker;
56     }
57
58     public static ProviderContext getProviderContext() {
59         return providerContext;
60     }
61
62     public static boolean isMasterProviderInstance() {
63         return hasProviderEntityOwnership.get();
64     }
65
66     public static void setTableOffset(short tableOffset) {
67         try {
68             new TableId((short) (tableOffset + Service.L2_FORWARDING.getTable()));
69         } catch (IllegalArgumentException e) {
70             LOG.warn("Invalid table offset: {}", tableOffset, e);
71             return;
72         }
73
74         LOG.info("setTableOffset: changing from {} to {}",
75                 NetvirtProvidersProvider.tableOffset, tableOffset);
76         NetvirtProvidersProvider.tableOffset = tableOffset;
77     }
78
79     public static short getTableOffset() {
80         return tableOffset;
81     }
82
83     @Override
84     public void close() throws Exception {
85         LOG.info("NetvirtProvidersProvider closed");
86         activator.stop(bundleContext);
87         providerEntityListener.close();
88     }
89
90     @Override
91     public void onSessionInitiated(ProviderContext providerContextRef) {
92         dataBroker = providerContextRef.getSALService(DataBroker.class);
93         providerContext = providerContextRef;
94         LOG.info("NetvirtProvidersProvider: onSessionInitiated dataBroker: {}", dataBroker);
95         this.activator = new ConfigActivator(providerContextRef);
96         try {
97             activator.start(bundleContext);
98         } catch (Exception e) {
99             LOG.warn("Failed to start Netvirt: ", e);
100         }
101         providerEntityListener = new ProviderEntityListener(this, entityOwnershipService);
102     }
103
104     private void handleOwnershipChange(EntityOwnershipChange ownershipChange) {
105         if (ownershipChange.isOwner()) {
106             LOG.info("*This* instance of OVSDB netvirt provider is a MASTER instance");
107             hasProviderEntityOwnership.set(true);
108         } else {
109             LOG.info("*This* instance of OVSDB netvirt provider is a SLAVE instance");
110             hasProviderEntityOwnership.set(false);
111         }
112     }
113
114     private class ProviderEntityListener implements EntityOwnershipListener {
115         private NetvirtProvidersProvider provider;
116         private EntityOwnershipListenerRegistration listenerRegistration;
117         private EntityOwnershipCandidateRegistration candidateRegistration;
118
119         ProviderEntityListener(NetvirtProvidersProvider provider,
120                                EntityOwnershipService entityOwnershipService) {
121             this.provider = provider;
122             this.listenerRegistration =
123                     entityOwnershipService.registerListener(Constants.NETVIRT_OWNER_ENTITY_TYPE, this);
124
125             //register instance entity to get the ownership of the netvirt provider
126             Entity instanceEntity = new Entity(
127                     Constants.NETVIRT_OWNER_ENTITY_TYPE, Constants.NETVIRT_OWNER_ENTITY_TYPE);
128             try {
129                 this.candidateRegistration = entityOwnershipService.registerCandidate(instanceEntity);
130             } catch (CandidateAlreadyRegisteredException e) {
131                 LOG.warn("OVSDB Netvirt Provider instance entity {} was already "
132                         + "registered for ownership", instanceEntity, e);
133             }
134         }
135
136         public void close() {
137             this.listenerRegistration.close();
138             this.candidateRegistration.close();
139         }
140
141         @Override
142         public void ownershipChanged(EntityOwnershipChange ownershipChange) {
143             provider.handleOwnershipChange(ownershipChange);
144         }
145     }
146 }