2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
\r
4 * This program and the accompanying materials are made available under the
\r
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
\r
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
\r
9 package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;
\r
11 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
\r
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
\r
13 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
\r
14 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
\r
15 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
\r
16 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
\r
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
\r
18 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
\r
19 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
\r
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
\r
21 import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.SocketInfo;
\r
22 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
\r
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings;
\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.GbpByNeutronMappings;
\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.BaseEndpointsByPorts;
\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;
\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPortKey;
\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;
\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCaseBuilder;
\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
\r
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
\r
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
\r
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
\r
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
\r
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
\r
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
\r
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
\r
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
\r
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
\r
49 import org.slf4j.Logger;
\r
50 import org.slf4j.LoggerFactory;
\r
52 import com.google.common.annotations.VisibleForTesting;
\r
53 import com.google.common.base.Optional;
\r
55 public class PortHandler implements TransactionChainListener {
\r
57 private static final Logger LOG = LoggerFactory.getLogger(MappingProvider.class);
\r
59 private static final String COMPUTE_OWNER = "compute";
\r
60 private static final String VHOST_USER = "vhostuser";
\r
61 private static final String NETCONF_TOPOLOGY_ID = "topology-netconf";
\r
63 private BindingTransactionChain transactionChain;
\r
64 BaseEndpointByPortListener portByBaseEpListener;
\r
65 DataBroker dataBroker;
\r
66 SocketInfo socketInfo;
\r
68 PortHandler(DataBroker dataBroker, SocketInfo socketInfo) {
\r
69 this.dataBroker = dataBroker;
\r
70 this.socketInfo = socketInfo;
\r
71 transactionChain = this.dataBroker.createTransactionChain(this);
\r
74 void processCreated(Port port) {
\r
75 ReadTransaction rTx = dataBroker.newReadOnlyTransaction();
\r
76 Optional<BaseEndpointByPort> optBaseEpByPort = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
\r
77 createBaseEpByPortIid(port.getUuid()), rTx);
\r
78 if (!optBaseEpByPort.isPresent()) {
\r
81 processCreatedData(port, optBaseEpByPort.get());
\r
84 void processCreated(BaseEndpointByPort bebp) {
\r
85 ReadTransaction rTx = dataBroker.newReadOnlyTransaction();
\r
86 Optional<Port> optPort = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
\r
87 createPortIid(bebp.getPortId()), rTx);
\r
88 if (!optPort.isPresent()) {
\r
91 processCreatedData(optPort.get(), bebp);
\r
95 void processCreatedData(Port port, BaseEndpointByPort bebp) {
\r
96 if (isValidVhostUser(port)) {
\r
97 VppEndpoint vppEp = buildVhostUserEndpoint(port, bebp);
\r
98 writeVppEndpoint(createVppEndpointIid(vppEp.getKey()), vppEp);
\r
99 LOG.debug("Created vpp-endpoint {}", vppEp);
\r
103 private boolean isValidVhostUser(Port port) {
\r
104 PortBindingExtension portBindingExt = port.getAugmentation(PortBindingExtension.class);
\r
105 if (portBindingExt != null) {
\r
106 String vifType = portBindingExt.getVifType();
\r
107 String deviceOwner = port.getDeviceOwner();
\r
108 if (vifType != null && deviceOwner != null) {
\r
109 if (vifType.contains(VHOST_USER) && deviceOwner.contains(COMPUTE_OWNER)) {
\r
117 void processUpdated(Port original, Port delta) {
\r
118 if (isValidVhostUser(original)) {
\r
119 ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
\r
120 Optional<BaseEndpointByPort> optBebp = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
\r
121 createBaseEpByPortIid(original.getUuid()), rTx);
\r
123 if (!optBebp.isPresent()) {
\r
126 processDeleted(optBebp.get());
\r
128 processCreated(delta);
\r
131 void processDeleted(BaseEndpointByPort bebp) {
\r
132 VppEndpointKey vppEpKey = new VppEndpointKey(bebp.getAddress(), bebp.getAddressType(), bebp.getContextId(),
\r
133 bebp.getContextType());
\r
134 InstanceIdentifier<VppEndpoint> vppEpIid = createVppEndpointIid(vppEpKey);
\r
135 ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();
\r
136 Optional<VppEndpoint> readVppEp = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, vppEpIid, rTx);
\r
138 if (readVppEp.isPresent()) {
\r
139 writeVppEndpoint(vppEpIid, null);
\r
140 LOG.debug("Deleted vpp-endpoint {}", vppEpKey);
\r
144 private void writeVppEndpoint(InstanceIdentifier<VppEndpoint> vppEpIid, VppEndpoint vppEp) {
\r
145 WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();
\r
146 if (vppEp != null) {
\r
147 wTx.put(LogicalDatastoreType.CONFIGURATION, vppEpIid, vppEp, true);
\r
149 wTx.delete(LogicalDatastoreType.CONFIGURATION, vppEpIid);
\r
152 wTx.submit().checkedGet();
\r
153 } catch (TransactionCommitFailedException e) {
\r
154 LOG.error("Transaction chain commit failed. {}", e);
\r
155 transactionChain.close();
\r
156 transactionChain = dataBroker.createTransactionChain(this);
\r
161 VppEndpoint buildVhostUserEndpoint(Port port, BaseEndpointByPort bebp) {
\r
162 PortBindingExtension portBinding = port.getAugmentation(PortBindingExtension.class);
\r
163 String socket = socketInfo.getSocketPath() + socketInfo.getSocketPrefix() + bebp.getPortId().getValue();
\r
164 return new VppEndpointBuilder().setDescription("neutron port")
\r
165 .setContextId(bebp.getContextId())
\r
166 .setContextType(bebp.getContextType())
\r
167 .setAddress(bebp.getAddress())
\r
168 .setInterfaceTypeChoice(new VhostUserCaseBuilder().setSocket(socket).build())
\r
169 .setAddressType(bebp.getAddressType())
\r
170 .setVppInterfaceName(bebp.getPortId().getValue())
\r
171 .setVppNodePath(createNodeIid(new NodeId(portBinding.getHostId())))
\r
175 private InstanceIdentifier<Node> createNodeIid(NodeId nodeId) {
\r
176 return InstanceIdentifier.builder(NetworkTopology.class)
\r
177 .child(Topology.class, new TopologyKey(new TopologyId(NETCONF_TOPOLOGY_ID)))
\r
178 .child(Node.class, new NodeKey(nodeId))
\r
182 private InstanceIdentifier<VppEndpoint> createVppEndpointIid(VppEndpointKey vppEpKey) {
\r
183 return InstanceIdentifier.builder(Config.class).child(VppEndpoint.class, vppEpKey).build();
\r
186 private InstanceIdentifier<BaseEndpointByPort> createBaseEpByPortIid(Uuid uuid) {
\r
187 return createBaseEpByPortIid(new UniqueId(uuid.getValue()));
\r
190 private InstanceIdentifier<BaseEndpointByPort> createBaseEpByPortIid(UniqueId uuid) {
\r
191 return InstanceIdentifier.builder(Mappings.class)
\r
192 .child(GbpByNeutronMappings.class)
\r
193 .child(BaseEndpointsByPorts.class)
\r
194 .child(BaseEndpointByPort.class, new BaseEndpointByPortKey(uuid))
\r
198 InstanceIdentifier<Port> createWildcartedPortIid() {
\r
199 return portsIid().child(Port.class).build();
\r
202 private InstanceIdentifier<Port> createPortIid(UniqueId uuid) {
\r
203 return portsIid().child(Port.class, new PortKey(new Uuid(uuid.getValue()))).build();
\r
206 private InstanceIdentifierBuilder<Ports> portsIid() {
\r
207 return InstanceIdentifier.builder(Neutron.class).child(Ports.class);
\r
211 public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction,
\r
213 LOG.error("Transaction chain failed. {}", cause.getMessage());
\r
214 transactionChain.close();
\r
215 transactionChain = dataBroker.createTransactionChain(this);
\r
219 public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
\r
220 LOG.trace("Transaction chain was successfull. {}", chain);
\r