manually cherry pick this patch https://git.opendaylight.org/gerrit/#/c/34579/
[unimgr.git] / impl / src / main / java / org / opendaylight / unimgr / impl / UnimgrProvider.java
1 /*
2  * Copyright (c) 2016 CableLabs 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.unimgr.impl;
9
10 import java.util.List;
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.md.sal.common.api.data.ReadFailedException;
16 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
17 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
18 import org.opendaylight.unimgr.api.IUnimgrConsoleProvider;
19 import org.opendaylight.unimgr.utils.EvcUtils;
20 import org.opendaylight.unimgr.utils.MdsalUtils;
21 import org.opendaylight.unimgr.utils.OvsdbUtils;
22 import org.opendaylight.unimgr.utils.UniUtils;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.Evc;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.EvcAugmentation;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.UniAugmentation;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniDest;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniSource;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.osgi.framework.BundleContext;
40 import org.osgi.framework.FrameworkUtil;
41 import org.osgi.framework.ServiceRegistration;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import com.google.common.base.Optional;
46 import com.google.common.util.concurrent.CheckedFuture;
47
48 public class UnimgrProvider implements BindingAwareProvider, AutoCloseable, IUnimgrConsoleProvider {
49
50     private static final Logger LOG = LoggerFactory.getLogger(UnimgrProvider.class);
51     private DataBroker dataBroker;
52     private EvcDataTreeChangeListener evcListener;
53     private OvsNodeDataTreeChangeListener ovsListener;
54     private UniDataTreeChangeListener uniListener;
55     private ServiceRegistration<IUnimgrConsoleProvider> unimgrConsoleRegistration;
56
57     public UnimgrProvider() {
58         LOG.info("Unimgr provider initialized");
59     }
60
61     @Override
62     public boolean addEvc(final EvcAugmentation evc) {
63         // TODO Auto-generated method stub
64         return false;
65     }
66
67     @Override
68     public boolean addUni(final UniAugmentation uniAug) {
69         if ((uniAug == null) || (uniAug.getIpAddress() == null) || (uniAug.getMacAddress() == null)) {
70             return false;
71         }
72         return UniUtils.createUniNode(dataBroker, uniAug);
73     }
74
75     @Override
76     public void close() throws Exception {
77         LOG.info("UnimgrProvider Closed");
78         unimgrConsoleRegistration.unregister();
79         uniListener.close();
80         evcListener.close();
81         ovsListener.close();
82     }
83
84     @Override
85     public Evc getEvc(final String uuid) {
86         // TODO Auto-generated method stub
87         return null;
88     }
89
90     @Override
91     public UniAugmentation getUni(final IpAddress ipAddress) {
92         return UniUtils.getUni(dataBroker, LogicalDatastoreType.OPERATIONAL, ipAddress);
93     }
94
95     protected void initDatastore(final LogicalDatastoreType type,
96                                  final TopologyId topoId) {
97         final InstanceIdentifier<Topology> path = InstanceIdentifier
98                                                 .create(NetworkTopology.class)
99                                                 .child(Topology.class,
100                                                         new TopologyKey(topoId));
101         initializeTopology(type);
102         final ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction();
103         final CheckedFuture<Optional<Topology>, ReadFailedException> unimgrTp = transaction.read(type,
104                                                                                            path);
105         try {
106             if (!unimgrTp.get().isPresent()) {
107                 final TopologyBuilder tpb = new TopologyBuilder();
108                 tpb.setTopologyId(topoId);
109                 transaction.put(type, path, tpb.build());
110                 transaction.submit().get();
111             } else {
112                 transaction.cancel();
113             }
114         } catch (final Exception e) {
115             LOG.error("Error initializing unimgr topology", e);
116         }
117     }
118
119     private void initializeTopology(final LogicalDatastoreType type) {
120         final ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction();
121         final InstanceIdentifier<NetworkTopology> path = InstanceIdentifier.create(NetworkTopology.class);
122         final CheckedFuture<Optional<NetworkTopology>, ReadFailedException> topology = transaction.read(type,path);
123         try {
124             if (!topology.get().isPresent()) {
125                 final NetworkTopologyBuilder ntb = new NetworkTopologyBuilder();
126                 transaction.put(type,path,ntb.build());
127                 transaction.submit().get();
128             } else {
129                 transaction.cancel();
130             }
131         } catch (final Exception e) {
132             LOG.error("Error initializing unimgr topology {}",e);
133         }
134     }
135
136     @Override
137     public List<UniAugmentation> listUnis(final LogicalDatastoreType dataStoreType) {
138         return UniUtils.getUnis(dataBroker, dataStoreType);
139     }
140
141     @Override
142     public void onSessionInitiated(final ProviderContext session) {
143         LOG.info("UnimgrProvider Session Initiated");
144
145         // Retrieve the data broker to create transactions
146         dataBroker =  session.getSALService(DataBroker.class);
147         // Register the unimgr OSGi CLI
148         final BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
149         unimgrConsoleRegistration = context.registerService(IUnimgrConsoleProvider.class,this, null);
150
151         // Register the data trees change listener
152         uniListener = new UniDataTreeChangeListener(dataBroker);
153         evcListener = new EvcDataTreeChangeListener(dataBroker);
154         ovsListener = new OvsNodeDataTreeChangeListener(dataBroker);
155
156         // Initialize operational and default config data in MD-SAL data store
157         initDatastore(LogicalDatastoreType.CONFIGURATION,
158                       UnimgrConstants.UNI_TOPOLOGY_ID);
159         initDatastore(LogicalDatastoreType.OPERATIONAL,
160                       UnimgrConstants.UNI_TOPOLOGY_ID);
161         initDatastore(LogicalDatastoreType.CONFIGURATION,
162                       UnimgrConstants.EVC_TOPOLOGY_ID);
163         initDatastore(LogicalDatastoreType.OPERATIONAL,
164                       UnimgrConstants.EVC_TOPOLOGY_ID);
165     }
166
167     @Override
168     public boolean removeEvc(final String uuid) {
169         // TODO Auto-generated method stub
170         return false;
171     }
172
173     @Override
174     public boolean removeUni(final IpAddress ipAddress) {
175         final InstanceIdentifier<Node> iidUni = UnimgrMapper.getUniIid(dataBroker, ipAddress, LogicalDatastoreType.CONFIGURATION);
176         if (iidUni == null) {
177             return false;
178         }
179         return MdsalUtils.deleteNode(dataBroker, iidUni, LogicalDatastoreType.CONFIGURATION);
180     }
181
182     @Override
183     public boolean updateEvc(final InstanceIdentifier<Link> evcKey, final EvcAugmentation evc, final UniSource uniSource,
184             final UniDest uniDest) {
185         final InstanceIdentifier<?> sourceUniIid = uniSource.getUni();
186         final InstanceIdentifier<?> destinationUniIid = uniDest.getUni();
187         return EvcUtils.updateEvcNode(LogicalDatastoreType.CONFIGURATION, evcKey, evc, sourceUniIid,
188                 destinationUniIid, dataBroker);
189     }
190
191     @Override
192     public boolean updateUni(final UniAugmentation uni) {
193         // Remove the old UNI with IpAdress and create a new one with updated informations
194         if (uni != null) {
195             LOG.trace("UNI updated {}.", uni.getIpAddress().getIpv4Address());
196             final InstanceIdentifier<?> uniIID = UnimgrMapper.getUniIid(dataBroker,
197                     uni.getIpAddress(), LogicalDatastoreType.OPERATIONAL);
198             Node ovsdbNode;
199             if (uni.getOvsdbNodeRef() != null) {
200                 final OvsdbNodeRef ovsdbNodeRef = uni.getOvsdbNodeRef();
201                 ovsdbNode= MdsalUtils.readNode(dataBroker,
202                         LogicalDatastoreType.OPERATIONAL, ovsdbNodeRef.getValue()).get();
203
204                 UniUtils.updateUniNode(LogicalDatastoreType.OPERATIONAL, uniIID, uni, ovsdbNode, dataBroker);
205                 LOG.trace("UNI updated {}.", uni.getIpAddress().getIpv4Address());
206             } else {
207                 final Optional<Node> optionalOvsdbNode = OvsdbUtils.findOvsdbNode(dataBroker, uni);
208                 ovsdbNode = optionalOvsdbNode.get();
209             }
210             MdsalUtils.deleteNode(dataBroker, uniIID, LogicalDatastoreType.OPERATIONAL);
211             return (UniUtils.updateUniNode(LogicalDatastoreType.CONFIGURATION, uniIID,
212                     uni, ovsdbNode, dataBroker) && UniUtils.updateUniNode(LogicalDatastoreType.OPERATIONAL, uniIID,
213                     uni, ovsdbNode, dataBroker));
214         }
215         return false;
216     }
217 }