X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openflowplugin%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fopenflow%2Fmd%2Fcore%2Fsal%2FSalRegistrationManager.java;h=25e29aba26632fdf1c2e0c752f9616de86afd392;hb=0ac72c313aa4eef9c63a5949fe255d558f4e6f88;hp=63e2224500196f2105c7c47f4a42ce2d1945a192;hpb=90c0c5386c58444df43a077b9e93d79d3218a535;p=openflowplugin.git diff --git a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/SalRegistrationManager.java b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/SalRegistrationManager.java index 63e2224500..25e29aba26 100644 --- a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/SalRegistrationManager.java +++ b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/SalRegistrationManager.java @@ -1,18 +1,33 @@ +/** + * 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.openflow.md.core.sal; +import com.google.common.base.Preconditions; import java.math.BigInteger; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.sal.binding.api.NotificationProviderService; -import org.opendaylight.openflowplugin.openflow.md.ModelDrivenSwitch; -import org.opendaylight.openflowplugin.openflow.md.SwitchInventory; -import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.openflowplugin.api.openflow.md.ModelDrivenSwitch; +import org.opendaylight.openflowplugin.api.openflow.md.core.NotificationQueueWrapper; +import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext; +import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionListener; +import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionManager; +import org.opendaylight.openflowplugin.api.openflow.md.core.session.SwitchSessionKeyOF; import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil; -import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext; -import org.opendaylight.openflowplugin.openflow.md.core.session.SessionListener; -import org.opendaylight.openflowplugin.openflow.md.core.session.SessionManager; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdatedBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved; @@ -23,20 +38,33 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; +import org.opendaylight.yangtools.concepts.CompositeObjectRegistration; +import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class SalRegistrationManager implements SessionListener, SwitchInventory { +/** + * session and inventory listener implementation + */ +public class SalRegistrationManager implements SessionListener, AutoCloseable { - private final static Logger LOG = LoggerFactory.getLogger(SalRegistrationManager.class); + private static final Logger LOG = LoggerFactory.getLogger(SalRegistrationManager.class); - Map, ModelDrivenSwitch> salSwitches = new ConcurrentHashMap<>(); + private NotificationProviderService publishService; - private ProviderContext providerContext; + private DataBroker dataService; - private NotificationProviderService publishService; + private RpcProviderRegistry rpcProviderRegistry; + + private SwitchFeaturesUtil swFeaturesUtil; + + private ListenerRegistration sessionListenerRegistration; + + public SalRegistrationManager() { + swFeaturesUtil = SwitchFeaturesUtil.getInstance(); + } public NotificationProviderService getPublishService() { return publishService; @@ -46,34 +74,40 @@ public class SalRegistrationManager implements SessionListener, SwitchInventory this.publishService = publishService; } - public ProviderContext getProviderContext() { - return providerContext; + public void setDataService(DataBroker dataService) { + this.dataService = dataService; } - public void onSessionInitiated(ProviderContext session) { - this.providerContext = session; - this.publishService = session.getSALService(NotificationProviderService.class); - - // We register as listener for Session Manager - getSessionManager().registerSessionListener(this); - LOG.info("SalRegistrationManager initialized"); + public void setRpcProviderRegistry(RpcProviderRegistry rpcProviderRegistry) { + this.rpcProviderRegistry = rpcProviderRegistry; + } + public void init() { + LOG.debug("init.."); + sessionListenerRegistration = getSessionManager().registerSessionListener(this); + getSessionManager().setNotificationProviderService(publishService); + getSessionManager().setDataBroker(dataService); + LOG.debug("SalRegistrationManager initialized"); } @Override - public void onSessionAdded(SwitchConnectionDistinguisher sessionKey, SessionContext context) { + public void onSessionAdded(SwitchSessionKeyOF sessionKey, SessionContext context) { GetFeaturesOutput features = context.getFeatures(); BigInteger datapathId = features.getDatapathId(); InstanceIdentifier identifier = identifierFromDatapathId(datapathId); NodeRef nodeRef = new NodeRef(identifier); NodeId nodeId = nodeIdFromDatapathId(datapathId); ModelDrivenSwitchImpl ofSwitch = new ModelDrivenSwitchImpl(nodeId, identifier, context); - salSwitches.put(identifier, ofSwitch); - ofSwitch.register(providerContext); + CompositeObjectRegistration registration = + ofSwitch.register(rpcProviderRegistry); + context.setProviderRegistration(registration); - LOG.info("ModelDrivenSwitch for {} registered to MD-SAL.", datapathId.toString()); + LOG.debug("ModelDrivenSwitch for {} registered to MD-SAL.", datapathId); - publishService.publish(nodeAdded(ofSwitch, features,nodeRef)); + NotificationQueueWrapper wrappedNotification = new NotificationQueueWrapper( + nodeAdded(ofSwitch, features, nodeRef), + context.getFeatures().getVersion()); + context.getNotificationEnqueuer().enqueueNotification(wrappedNotification); } @Override @@ -84,33 +118,71 @@ public class SalRegistrationManager implements SessionListener, SwitchInventory NodeRef nodeRef = new NodeRef(identifier); NodeRemoved nodeRemoved = nodeRemoved(nodeRef); - LOG.info("ModelDrivenSwitch for {} unregistred from MD-SAL.", datapathId.toString()); - publishService.publish(nodeRemoved); + CompositeObjectRegistration registration = context.getProviderRegistration(); + if (null != registration) { + registration.close(); + context.setProviderRegistration(null); + } + LOG.debug("ModelDrivenSwitch for {} unregistered from MD-SAL.", datapathId); + + NotificationQueueWrapper wrappedNotification = new NotificationQueueWrapper( + nodeRemoved, context.getFeatures().getVersion()); + context.getNotificationEnqueuer().enqueueNotification(wrappedNotification); } private NodeUpdated nodeAdded(ModelDrivenSwitch sw, GetFeaturesOutput features, NodeRef nodeRef) { NodeUpdatedBuilder builder = new NodeUpdatedBuilder(); builder.setId(sw.getNodeId()); builder.setNodeRef(nodeRef); + + FlowCapableNodeUpdatedBuilder builder2 = new FlowCapableNodeUpdatedBuilder(); + try { + builder2.setIpAddress(getIpAddressOf(sw)); + } catch (Exception e) { + LOG.warn("IP address of the node {} cannot be obtained.", sw.getNodeId(), e); + } + builder2.setSwitchFeatures(swFeaturesUtil.buildSwitchFeatures(features)); + builder.addAugmentation(FlowCapableNodeUpdated.class, builder2.build()); + return builder.build(); } + private static IpAddress getIpAddressOf(ModelDrivenSwitch sw) { + SessionContext sessionContext = sw.getSessionContext(); + Preconditions.checkNotNull(sessionContext.getPrimaryConductor(), + "primary conductor must not be NULL -> " + sw.getNodeId()); + Preconditions.checkNotNull(sessionContext.getPrimaryConductor().getConnectionAdapter(), + "connection adapter of primary conductor must not be NULL -> " + sw.getNodeId()); + InetSocketAddress remoteAddress = sessionContext.getPrimaryConductor().getConnectionAdapter() + .getRemoteAddress(); + if (remoteAddress == null) { + LOG.warn("IP address of the node {} cannot be obtained. No connection with switch.", sw.getNodeId()); + return null; + } + return resolveIpAddress(remoteAddress.getAddress()); + } + + private static IpAddress resolveIpAddress(InetAddress address) { + String hostAddress = address.getHostAddress(); + if (address instanceof Inet4Address) { + return new IpAddress(new Ipv4Address(hostAddress)); + } + if (address instanceof Inet6Address) { + return new IpAddress(new Ipv6Address(hostAddress)); + } + throw new IllegalArgumentException("Unsupported IP address type!"); + } + private NodeRemoved nodeRemoved(NodeRef nodeRef) { NodeRemovedBuilder builder = new NodeRemovedBuilder(); builder.setNodeRef(nodeRef); return builder.build(); } - @Override - public ModelDrivenSwitch getSwitch(NodeRef node) { - return salSwitches.get(node.getValue()); - } - public static InstanceIdentifier identifierFromDatapathId(BigInteger datapathId) { - InstanceIdentifierBuilder builder = InstanceIdentifier.builder().node(Nodes.class); - NodeKey nodeKey = nodeKeyFromDatapathId(datapathId); - return builder.node(Node.class, nodeKey).toInstance(); + InstanceIdentifierBuilder builder = InstanceIdentifier.builder(Nodes.class).child(Node.class, nodeKey); + return builder.build(); } public static NodeKey nodeKeyFromDatapathId(BigInteger datapathId) { @@ -119,11 +191,22 @@ public class SalRegistrationManager implements SessionListener, SwitchInventory public static NodeId nodeIdFromDatapathId(BigInteger datapathId) { // FIXME: Convert to textual representation of datapathID - String current = datapathId.toString(); + String current = String.valueOf(datapathId); return new NodeId("openflow:" + current); } public SessionManager getSessionManager() { return OFSessionUtil.getSessionManager(); } + + @Override + public void close() { + LOG.debug("close"); + dataService = null; + rpcProviderRegistry = null; + publishService = null; + if (sessionListenerRegistration != null) { + sessionListenerRegistration.close(); + } + } }