-/*\r
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-package org.opendaylight.vpnservice;\r
-\r
-import java.util.List;\r
-import java.util.ArrayList;\r
-\r
-import com.google.common.base.Optional;\r
-import com.google.common.util.concurrent.Futures;\r
-import com.google.common.util.concurrent.FutureCallback;\r
-\r
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
-import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
-import org.opendaylight.yangtools.yang.binding.DataObject;\r
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;\r
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.AdjacencyList;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;\r
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;\r
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;\r
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.AdjacenciesBuilder;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable {\r
- private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class);\r
- private ListenerRegistration<DataChangeListener> listenerRegistration;\r
- private final DataBroker broker;\r
-\r
- private static final FutureCallback<Void> DEFAULT_CALLBACK =\r
- new FutureCallback<Void>() {\r
- public void onSuccess(Void result) {\r
- LOG.info("Success in Datastore write operation");\r
- }\r
-\r
- public void onFailure(Throwable error) {\r
- LOG.error("Error in Datastore write operation", error);\r
- };\r
- };\r
-\r
- /**\r
- * Responsible for listening to data change related to VPN Interface\r
- * Bind VPN Service on the interface and informs the BGP service\r
- * \r
- * @param db - dataBroker service reference\r
- */\r
- public VpnInterfaceManager(final DataBroker db) {\r
- super(VpnInterface.class);\r
- broker = db;\r
- registerListener(db);\r
- }\r
-\r
- @Override\r
- public void close() throws Exception {\r
- if (listenerRegistration != null) {\r
- try {\r
- listenerRegistration.close();\r
- } catch (final Exception e) {\r
- LOG.error("Error when cleaning up DataChangeListener.", e);\r
- }\r
- listenerRegistration = null;\r
- }\r
- LOG.info("VPN Interface Manager Closed");\r
- }\r
-\r
- private void registerListener(final DataBroker db) {\r
- try {\r
- listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,\r
- getWildCardPath(), VpnInterfaceManager.this, DataChangeScope.SUBTREE);\r
- } catch (final Exception e) {\r
- LOG.error("VPN Service DataChange listener registration fail!", e);\r
- throw new IllegalStateException("VPN Service registration Listener failed.", e);\r
- }\r
- }\r
-\r
- @Override\r
- protected void add(final InstanceIdentifier<VpnInterface> identifier,\r
- final VpnInterface vpnInterface) {\r
- LOG.info("key: " + identifier + ", value=" + vpnInterface );\r
- addInterface(identifier, vpnInterface);\r
- }\r
-\r
- private void addInterface(final InstanceIdentifier<VpnInterface> identifier,\r
- final VpnInterface vpnInterface) {\r
- final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);\r
- String interfaceName = key.getName();\r
- InstanceIdentifierBuilder<Interface> idBuilder = \r
- InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));\r
- InstanceIdentifier<Interface> id = idBuilder.build();\r
- Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);\r
- if (port.isPresent()) {\r
- Interface interf = port.get();\r
- bindServiceOnInterface(interf);\r
- updateNextHops(identifier, vpnInterface);\r
- }\r
- }\r
-\r
- private void updateNextHops(final InstanceIdentifier<VpnInterface> identifier, VpnInterface intf) {\r
- //Read NextHops\r
- InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);\r
- Optional<Adjacencies> adjacencies = read(LogicalDatastoreType.CONFIGURATION, path);\r
- String intfName = intf.getName();\r
-\r
- if (adjacencies.isPresent()) {\r
- List<Adjacency> nextHops = adjacencies.get().getAdjacency();\r
- List<Adjacency> value = new ArrayList<>();\r
-\r
- if (!nextHops.isEmpty()) {\r
- LOG.info("NextHops are " + nextHops);\r
- for (Adjacency nextHop : nextHops) {\r
- //TODO: Generate label for the prefix and store it in the next hop model\r
- long label = 200;\r
-\r
- //TODO: Update BGP\r
- updatePrefixToBGP(nextHop);\r
- value.add(new AdjacencyBuilder(nextHop).setLabel(label).build());\r
- }\r
- }\r
- Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(value);\r
- VpnInterface opInterface = VpnUtil.getVpnInterface(intfName, intf.getVpnInstanceName(), aug);\r
- InstanceIdentifier<VpnInterface> interfaceId = VpnUtil.getVpnInterfaceIdentifier(intfName);\r
- asyncWrite(LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface, DEFAULT_CALLBACK);\r
- }\r
- }\r
-\r
- private void bindServiceOnInterface(Interface intf) {\r
- //TODO: Create Ingress flow on the interface to bind the VPN service\r
- }\r
-\r
- private void updatePrefixToBGP(Adjacency nextHop) {\r
- //TODO: Update the Prefix to BGP\r
- }\r
-\r
- private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,\r
- InstanceIdentifier<T> path) {\r
-\r
- ReadOnlyTransaction tx = broker.newReadOnlyTransaction();\r
-\r
- Optional<T> result = Optional.absent();\r
- try {\r
- result = tx.read(datastoreType, path).get();\r
- } catch (Exception e) {\r
- throw new RuntimeException(e);\r
- }\r
-\r
- return result;\r
- }\r
-\r
- private InstanceIdentifier<VpnInterface> getWildCardPath() {\r
- return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class);\r
- }\r
-\r
- @Override\r
- protected void remove( InstanceIdentifier<VpnInterface> identifier, VpnInterface del) {\r
- // TODO Auto-generated method stub\r
-\r
- }\r
-\r
- @Override\r
- protected void update(InstanceIdentifier<VpnInterface> identifier, \r
- VpnInterface original, VpnInterface update) {\r
- // TODO Auto-generated method stub\r
-\r
- }\r
-\r
- private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,\r
- InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {\r
- WriteTransaction tx = broker.newWriteOnlyTransaction();\r
- tx.put(datastoreType, path, data, true);\r
- Futures.addCallback(tx.submit(), callback);\r
- }\r
-}\r
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.FutureCallback;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.AdjacencyList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.AdjacenciesBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable {
+ private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class);
+ private ListenerRegistration<DataChangeListener> listenerRegistration;
+ private final DataBroker broker;
+
+ private static final FutureCallback<Void> DEFAULT_CALLBACK =
+ new FutureCallback<Void>() {
+ public void onSuccess(Void result) {
+ LOG.info("Success in Datastore write operation");
+ }
+
+ public void onFailure(Throwable error) {
+ LOG.error("Error in Datastore write operation", error);
+ };
+ };
+
+ /**
+ * Responsible for listening to data change related to VPN Interface
+ * Bind VPN Service on the interface and informs the BGP service
+ *
+ * @param db - dataBroker service reference
+ */
+ public VpnInterfaceManager(final DataBroker db) {
+ super(VpnInterface.class);
+ broker = db;
+ registerListener(db);
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (final Exception e) {
+ LOG.error("Error when cleaning up DataChangeListener.", e);
+ }
+ listenerRegistration = null;
+ }
+ LOG.info("VPN Interface Manager Closed");
+ }
+
+ private void registerListener(final DataBroker db) {
+ try {
+ listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+ getWildCardPath(), VpnInterfaceManager.this, DataChangeScope.SUBTREE);
+ } catch (final Exception e) {
+ LOG.error("VPN Service DataChange listener registration fail!", e);
+ throw new IllegalStateException("VPN Service registration Listener failed.", e);
+ }
+ }
+
+ @Override
+ protected void add(final InstanceIdentifier<VpnInterface> identifier,
+ final VpnInterface vpnInterface) {
+ LOG.info("key: " + identifier + ", value=" + vpnInterface );
+ addInterface(identifier, vpnInterface);
+ }
+
+ private void addInterface(final InstanceIdentifier<VpnInterface> identifier,
+ final VpnInterface vpnInterface) {
+ final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
+ String interfaceName = key.getName();
+ InstanceIdentifierBuilder<Interface> idBuilder =
+ InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
+ InstanceIdentifier<Interface> id = idBuilder.build();
+ Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
+ if (port.isPresent()) {
+ Interface interf = port.get();
+ bindServiceOnInterface(interf);
+ updateNextHops(identifier, vpnInterface);
+ }
+ }
+
+ private void updateNextHops(final InstanceIdentifier<VpnInterface> identifier, VpnInterface intf) {
+ //Read NextHops
+ InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
+ Optional<Adjacencies> adjacencies = read(LogicalDatastoreType.CONFIGURATION, path);
+ String intfName = intf.getName();
+
+ if (adjacencies.isPresent()) {
+ List<Adjacency> nextHops = adjacencies.get().getAdjacency();
+ List<Adjacency> value = new ArrayList<>();
+
+ if (!nextHops.isEmpty()) {
+ LOG.info("NextHops are " + nextHops);
+ for (Adjacency nextHop : nextHops) {
+ //TODO: Generate label for the prefix and store it in the next hop model
+ long label = 200;
+
+ //TODO: Update BGP
+ updatePrefixToBGP(nextHop);
+ value.add(new AdjacencyBuilder(nextHop).setLabel(label).build());
+ }
+ }
+ Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(value);
+ VpnInterface opInterface = VpnUtil.getVpnInterface(intfName, intf.getVpnInstanceName(), aug);
+ InstanceIdentifier<VpnInterface> interfaceId = VpnUtil.getVpnInterfaceIdentifier(intfName);
+ asyncWrite(LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface, DEFAULT_CALLBACK);
+ }
+ }
+
+ private void bindServiceOnInterface(Interface intf) {
+ //TODO: Create Ingress flow on the interface to bind the VPN service
+ }
+
+ private void updatePrefixToBGP(Adjacency nextHop) {
+ //TODO: Update the Prefix to BGP
+ }
+
+ private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path) {
+
+ ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+ Optional<T> result = Optional.absent();
+ try {
+ result = tx.read(datastoreType, path).get();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return result;
+ }
+
+ private InstanceIdentifier<VpnInterface> getWildCardPath() {
+ return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class);
+ }
+
+ @Override
+ protected void remove( InstanceIdentifier<VpnInterface> identifier, VpnInterface del) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<VpnInterface> identifier,
+ VpnInterface original, VpnInterface update) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.put(datastoreType, path, data, true);
+ Futures.addCallback(tx.submit(), callback);
+ }
+}