/* * Copyright (c) 2013 Cisco Systems, Inc. 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.openflowplugin.applications.topology.manager; import com.google.common.base.Optional; import java.util.concurrent.ExecutionException; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadTransaction; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.controller.sal.binding.api.NotificationProviderService; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.NotificationListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class FlowCapableTopologyProvider implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(FlowCapableTopologyProvider.class); static final String TOPOLOGY_ID = "flow:1"; private final DataBroker dataBroker; private final NotificationProviderService notificationService; private final OperationProcessor processor; private ListenerRegistration<NotificationListener> listenerRegistration; public FlowCapableTopologyProvider(DataBroker dataBroker, NotificationProviderService notificationService, OperationProcessor processor) { this.dataBroker = dataBroker; this.notificationService = notificationService; this.processor = processor; } /** * Gets called on start of a bundle. */ public void start() { final TopologyKey key = new TopologyKey(new TopologyId(TOPOLOGY_ID)); final InstanceIdentifier<Topology> path = InstanceIdentifier .create(NetworkTopology.class) .child(Topology.class, key); final FlowCapableTopologyExporter listener = new FlowCapableTopologyExporter(processor, path); this.listenerRegistration = notificationService.registerNotificationListener(listener); if(!isFlowTopologyExist(dataBroker, path)){ final ReadWriteTransaction tx = dataBroker.newReadWriteTransaction(); tx.put(LogicalDatastoreType.OPERATIONAL, path, new TopologyBuilder().setKey(key).build(), true); try { tx.submit().get(); } catch (InterruptedException | ExecutionException e) { LOG.warn("Initial topology export failed, continuing anyway", e); } } LOG.info("FlowCapableTopologyProvider started"); } @Override public void close() { LOG.info("FlowCapableTopologyProvider stopped."); if (this.listenerRegistration != null) { try { this.listenerRegistration.close(); } catch (Exception e) { LOG.warn("Failed to close listener registration: {}", e.getMessage()); LOG.debug("Failed to close listener registration.. ", e); } listenerRegistration = null; } } private boolean isFlowTopologyExist(final DataBroker dataBroker, final InstanceIdentifier<Topology> path) { final ReadTransaction tx = dataBroker.newReadOnlyTransaction(); try { Optional<Topology> ofTopology = tx.read(LogicalDatastoreType.OPERATIONAL, path).checkedGet(); LOG.debug("OpenFlow topology exist in the operational data store at {}",path); if(ofTopology.isPresent()){ return true; } } catch (ReadFailedException e) { LOG.warn("OpenFlow topology read operation failed!", e); } return false; } }