2 * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.vpnservice.interfacemgr;
10 import com.google.common.util.concurrent.FutureCallback;
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
19 import org.opendaylight.vpnservice.AbstractDataChangeListener;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
22 import org.opendaylight.yangtools.concepts.ListenerRegistration;
23 import org.opendaylight.yangtools.yang.binding.DataObject;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
25 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
26 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import com.google.common.base.Optional;
36 public class InterfaceManager extends AbstractDataChangeListener<Interface> implements AutoCloseable{
37 private static final Logger LOG = LoggerFactory.getLogger(InterfaceManager.class);
38 private ListenerRegistration<DataChangeListener> listenerRegistration;
39 private final DataBroker broker;
41 private static final FutureCallback<Void> DEFAULT_CALLBACK =
42 new FutureCallback<Void>() {
43 public void onSuccess(Void result) {
44 LOG.debug("Success in Datastore write operation");
47 public void onFailure(Throwable error) {
48 LOG.error("Error in Datastore write operation", error);
52 public InterfaceManager(final DataBroker db) {
53 super(Interface.class);
59 public void close() throws Exception {
60 if (listenerRegistration != null) {
62 listenerRegistration.close();
63 } catch (final Exception e) {
64 LOG.error("Error when cleaning up DataChangeListener.", e);
66 listenerRegistration = null;
68 LOG.info("Interface Manager Closed");
71 private void registerListener(final DataBroker db) {
73 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
74 getWildCardPath(), InterfaceManager.this, DataChangeScope.SUBTREE);
75 } catch (final Exception e) {
76 LOG.error("InterfaceManager DataChange listener registration fail!", e);
77 throw new IllegalStateException("InterfaceManager registration Listener failed.", e);
82 protected void add(final InstanceIdentifier<Interface> identifier,
83 final Interface imgrInterface) {
84 LOG.trace("key: " + identifier + ", value=" + imgrInterface );
85 addInterface(identifier, imgrInterface);
88 private InstanceIdentifier<Interface> buildId(final InstanceIdentifier<Interface> identifier) {
89 //TODO Make this generic and move to AbstractDataChangeListener or Utils.
90 final InterfaceKey key = identifier.firstKeyOf(Interface.class, InterfaceKey.class);
91 String interfaceName = key.getName();
92 InstanceIdentifierBuilder<Interface> idBuilder =
93 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
94 InstanceIdentifier<Interface> id = idBuilder.build();
98 private void addInterface(final InstanceIdentifier<Interface> identifier,
99 final Interface imgrInterface) {
100 InstanceIdentifier<Interface> id = buildId(identifier);
101 Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
102 if(port.isPresent()) {
103 Interface interf = port.get();
104 NodeConnector nodeConn = getNodeConnectorFromInterface(interf);
105 updateInterfaceState(identifier, imgrInterface, interf);
107 * 1. Get interface-id from id manager
108 * 2. Update interface-state with following:
109 * admin-status = set to enable value
110 * oper-status = Down [?]
111 * if-index = interface-id
114 * 1. Get operational data from node-connector-id?
120 private void updateInterfaceState(InstanceIdentifier<Interface> identifier, Interface imgrInterface,
122 // TODO Update InterfaceState
126 private NodeConnector getNodeConnectorFromInterface(Interface interf) {
127 NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId();
128 NodeId nodeId = new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
129 InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
130 .child(Node.class, new NodeKey(nodeId))
131 .child(NodeConnector.class, new NodeConnectorKey(ncId)).build();
133 Optional<NodeConnector> nc = read(LogicalDatastoreType.OPERATIONAL, ncIdentifier);
135 NodeConnector nodeConn = nc.get();
136 LOG.trace("nodeConnector: {}",nodeConn);
142 private void delInterface(final InstanceIdentifier<Interface> identifier,
143 final Interface del) {
144 InstanceIdentifier<Interface> id = buildId(identifier);
145 Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
146 if(port.isPresent()) {
147 Interface interf = port.get();
148 // TODO: Update operational data
152 private void updateInterface(final InstanceIdentifier<Interface> identifier,
153 final Interface original, final Interface udpate) {
154 InstanceIdentifier<Interface> id = buildId(identifier);
155 Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
156 if(port.isPresent()) {
157 Interface interf = port.get();
158 //TODO: Update operational data
162 private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
163 InstanceIdentifier<T> path) {
165 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
167 Optional<T> result = Optional.absent();
169 result = tx.read(datastoreType, path).get();
170 } catch (Exception e) {
171 throw new RuntimeException(e);
177 private InstanceIdentifier<Interface> getWildCardPath() {
178 return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
182 protected void remove(InstanceIdentifier<Interface> identifier, Interface del) {
183 LOG.trace("key: " + identifier + ", value=" + del );
184 delInterface(identifier, del);
188 protected void update(InstanceIdentifier<Interface> identifier, Interface original, Interface update) {
189 LOG.trace("key: " + identifier + ", original=" + original + ", update=" + update );
190 updateInterface(identifier, original, update);