effd6835207745a5d31a5cb68a483f7671dc0df7
[netvirt.git] / vpnservice / elanmanager / elanmanager-impl / src / main / java / org / opendaylight / netvirt / elan / internal / ElanInstanceManager.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.netvirt.elan.internal;
10
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
20 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
21 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
22 import org.opendaylight.genius.mdsalutil.MDSALUtil;
23 import org.opendaylight.netvirt.elan.ElanException;
24 import org.opendaylight.netvirt.elan.utils.ElanConstants;
25 import org.opendaylight.netvirt.elan.utils.ElanUtils;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstance;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.state.Elan;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 public class ElanInstanceManager extends AsyncDataTreeChangeListenerBase<ElanInstance, ElanInstanceManager>
42         implements AutoCloseable {
43
44     private static final Logger LOG = LoggerFactory.getLogger(ElanInstanceManager.class);
45
46     private final DataBroker broker;
47     private final IdManagerService idManager;
48     private final IInterfaceManager interfaceManager;
49     private final ElanInterfaceManager elanInterfaceManager;
50
51     public ElanInstanceManager(final DataBroker dataBroker, final IdManagerService managerService,
52                                final ElanInterfaceManager elanInterfaceManager,
53                                final IInterfaceManager interfaceManager) {
54         super(ElanInstance.class, ElanInstanceManager.class);
55         this.broker = dataBroker;
56         this.idManager = managerService;
57         this.elanInterfaceManager = elanInterfaceManager;
58         this.interfaceManager = interfaceManager;
59     }
60
61     public void init() {
62         registerListener(LogicalDatastoreType.CONFIGURATION, broker);
63     }
64
65     @Override
66     protected void remove(InstanceIdentifier<ElanInstance> identifier, ElanInstance deletedElan) {
67         LOG.trace("Remove ElanInstance - Key: {}, value: {}", identifier, deletedElan);
68         List<ListenableFuture<Void>> futures = new ArrayList<>();
69         String elanName = deletedElan.getElanInstanceName();
70         // check the elan Instance present in the Operational DataStore
71         Elan existingElan = ElanUtils.getElanByName(broker, elanName);
72         long elanTag = deletedElan.getElanTag();
73         // Cleaning up the existing Elan Instance
74         if (existingElan != null) {
75             List<String> elanInterfaces = existingElan.getElanInterfaces();
76             if (elanInterfaces != null && !elanInterfaces.isEmpty()) {
77                 for (String elanInterfaceName : elanInterfaces) {
78                     InstanceIdentifier<ElanInterface> elanInterfaceId = ElanUtils
79                             .getElanInterfaceConfigurationDataPathId(elanInterfaceName);
80                     InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(elanInterfaceName);
81                     elanInterfaceManager.removeElanInterface(futures, deletedElan, elanInterfaceName,
82                             interfaceInfo, false);
83                     ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
84                             elanInterfaceId);
85                 }
86             }
87             ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL,
88                     ElanUtils.getElanInstanceOperationalDataPath(elanName));
89             Optional<ElanDpnInterfacesList> elanDpnInterfaceList = MDSALUtil.read(broker,
90                     LogicalDatastoreType.OPERATIONAL,
91                     ElanUtils.getElanDpnOperationDataPath(elanName));
92             if (elanDpnInterfaceList.isPresent()) {
93                 ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL,
94                     getElanDpnOperationDataPath(elanName));
95             }
96             ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL,
97                     ElanUtils.getElanInfoEntriesOperationalDataPath(elanTag));
98         }
99         // Release tag
100         ElanUtils.releaseId(idManager, ElanConstants.ELAN_ID_POOL_NAME, elanName);
101         if (deletedElan.getAugmentation(EtreeInstance.class) != null) {
102             removeEtreeInstance(deletedElan);
103         }
104     }
105
106     private void removeEtreeInstance(ElanInstance deletedElan) {
107         // Release leaves tag
108         ElanUtils.releaseId(idManager, ElanConstants.ELAN_ID_POOL_NAME,
109                 deletedElan.getElanInstanceName() + ElanConstants.LEAVES_POSTFIX);
110
111         ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL,
112                 ElanUtils.getElanInfoEntriesOperationalDataPath(
113                 deletedElan.getAugmentation(EtreeInstance.class).getEtreeLeafTagVal().getValue()));
114     }
115
116     @Override
117     protected void update(InstanceIdentifier<ElanInstance> identifier, ElanInstance original, ElanInstance update) {
118         Long existingElanTag = original.getElanTag();
119         if (existingElanTag != null && existingElanTag == update.getElanTag()) {
120             return;
121         } else if (update.getElanTag() == null) {
122             // update the elan-Instance with new properties
123             WriteTransaction tx = broker.newWriteOnlyTransaction();
124             ElanUtils.updateOperationalDataStore(broker, idManager,
125                     update, new ArrayList<String>(), tx);
126             ElanUtils.waitForTransactionToComplete(tx);
127             return;
128         }
129         try {
130             elanInterfaceManager.handleunprocessedElanInterfaces(update);
131         } catch (ElanException e) {
132             LOG.error("update() failed for ElanInstance: " + identifier.toString(), e);
133         }
134     }
135
136     @Override
137     protected void add(InstanceIdentifier<ElanInstance> identifier, ElanInstance elanInstanceAdded) {
138         String elanInstanceName  = elanInstanceAdded.getElanInstanceName();
139         Elan elanInfo = ElanUtils.getElanByName(broker, elanInstanceName);
140         if (elanInfo == null) {
141             WriteTransaction tx = broker.newWriteOnlyTransaction();
142             ElanUtils.updateOperationalDataStore(broker, idManager,
143                 elanInstanceAdded, new ArrayList<String>(), tx);
144             ElanUtils.waitForTransactionToComplete(tx);
145         }
146     }
147
148     public ElanInstance getElanInstanceByName(String elanInstanceName) {
149         InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
150         return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
151     }
152
153     public List<DpnInterfaces> getElanDPNByName(String elanInstanceName) {
154         InstanceIdentifier<ElanDpnInterfacesList> elanIdentifier = getElanDpnOperationDataPath(elanInstanceName);
155         return MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, elanIdentifier).transform(
156                 ElanDpnInterfacesList::getDpnInterfaces).or(Collections.emptyList());
157     }
158
159     private InstanceIdentifier<ElanDpnInterfacesList> getElanDpnOperationDataPath(String elanInstanceName) {
160         return InstanceIdentifier.builder(ElanDpnInterfaces.class)
161                 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName)).build();
162     }
163
164     private InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
165         return InstanceIdentifier.builder(ElanInstances.class)
166                 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
167     }
168
169     @Override
170     protected InstanceIdentifier<ElanInstance> getWildCardPath() {
171         return InstanceIdentifier.create(ElanInstances.class).child(ElanInstance.class);
172     }
173
174     @Override
175     protected ElanInstanceManager getDataTreeChangeListener() {
176         return this;
177     }
178 }