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 PortAware 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)) {
\r
110 for (String computeOwner : COMPUTE_OWNER) {
\r
111 if (deviceOwner.contains(computeOwner)) {
\r
121 void processUpdated(Port original, Port delta) {
\r
122 if (isValidVhostUser(original)) {
\r
123 ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
\r
124 Optional<BaseEndpointByPort> optBebp = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
\r
125 createBaseEpByPortIid(original.getUuid()), rTx);
\r
127 if (!optBebp.isPresent()) {
\r
130 processDeleted(optBebp.get());
\r
132 processCreated(delta);
\r
135 void processDeleted(BaseEndpointByPort bebp) {
\r
136 VppEndpointKey vppEpKey = new VppEndpointKey(bebp.getAddress(), bebp.getAddressType(), bebp.getContextId(),
\r
137 bebp.getContextType());
\r
138 InstanceIdentifier<VppEndpoint> vppEpIid = createVppEndpointIid(vppEpKey);
\r
139 ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();
\r
140 Optional<VppEndpoint> readVppEp = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, vppEpIid, rTx);
\r
142 if (readVppEp.isPresent()) {
\r
143 writeVppEndpoint(vppEpIid, null);
\r
144 LOG.debug("Deleted vpp-endpoint {}", vppEpKey);
\r
148 private void writeVppEndpoint(InstanceIdentifier<VppEndpoint> vppEpIid, VppEndpoint vppEp) {
\r
149 WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();
\r
150 if (vppEp != null) {
\r
151 wTx.put(LogicalDatastoreType.CONFIGURATION, vppEpIid, vppEp, true);
\r
153 wTx.delete(LogicalDatastoreType.CONFIGURATION, vppEpIid);
\r
156 wTx.submit().checkedGet();
\r
157 } catch (TransactionCommitFailedException e) {
\r
158 LOG.error("Transaction chain commit failed. {}", e);
\r
159 transactionChain.close();
\r
160 transactionChain = dataBroker.createTransactionChain(this);
\r
165 VppEndpoint buildVhostUserEndpoint(Port port, BaseEndpointByPort bebp) {
\r
166 PortBindingExtension portBinding = port.getAugmentation(PortBindingExtension.class);
\r
167 String socket = socketInfo.getSocketPath() + socketInfo.getSocketPrefix() + bebp.getPortId().getValue();
\r
168 return new VppEndpointBuilder().setDescription("neutron port")
\r
169 .setContextId(bebp.getContextId())
\r
170 .setContextType(bebp.getContextType())
\r
171 .setAddress(bebp.getAddress())
\r
172 .setInterfaceTypeChoice(new VhostUserCaseBuilder().setSocket(socket).build())
\r
173 .setAddressType(bebp.getAddressType())
\r
174 .setVppInterfaceName(bebp.getPortId().getValue())
\r
175 .setVppNodePath(createNodeIid(new NodeId(portBinding.getHostId())))
\r
179 private InstanceIdentifier<Node> createNodeIid(NodeId nodeId) {
\r
180 return InstanceIdentifier.builder(NetworkTopology.class)
\r
181 .child(Topology.class, new TopologyKey(new TopologyId(NETCONF_TOPOLOGY_ID)))
\r
182 .child(Node.class, new NodeKey(nodeId))
\r
186 private InstanceIdentifier<VppEndpoint> createVppEndpointIid(VppEndpointKey vppEpKey) {
\r
187 return InstanceIdentifier.builder(Config.class).child(VppEndpoint.class, vppEpKey).build();
\r
190 private InstanceIdentifier<BaseEndpointByPort> createBaseEpByPortIid(Uuid uuid) {
\r
191 return createBaseEpByPortIid(new UniqueId(uuid.getValue()));
\r
194 private InstanceIdentifier<BaseEndpointByPort> createBaseEpByPortIid(UniqueId uuid) {
\r
195 return InstanceIdentifier.builder(Mappings.class)
\r
196 .child(GbpByNeutronMappings.class)
\r
197 .child(BaseEndpointsByPorts.class)
\r
198 .child(BaseEndpointByPort.class, new BaseEndpointByPortKey(uuid))
\r
202 InstanceIdentifier<Port> createWildcartedPortIid() {
\r
203 return portsIid().child(Port.class).build();
\r
206 private InstanceIdentifier<Port> createPortIid(UniqueId uuid) {
\r
207 return portsIid().child(Port.class, new PortKey(new Uuid(uuid.getValue()))).build();
\r
210 private InstanceIdentifierBuilder<Ports> portsIid() {
\r
211 return InstanceIdentifier.builder(Neutron.class).child(Ports.class);
\r
215 public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction,
\r
217 LOG.error("Transaction chain failed. {}", cause.getMessage());
\r
218 transactionChain.close();
\r
219 transactionChain = dataBroker.createTransactionChain(this);
\r
223 public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
\r
224 LOG.trace("Transaction chain was successfull. {}", chain);
\r