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.WriteTransaction;
\r
15 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
\r
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
\r
17 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
\r
18 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
\r
19 import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.SocketInfo;
\r
20 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
\r
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings;
\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.GbpByNeutronMappings;
\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.BaseEndpointsByPorts;
\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;
\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPortKey;
\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;
\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCaseBuilder;
\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
\r
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
\r
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
\r
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
\r
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
\r
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
\r
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
\r
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
\r
45 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
\r
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
\r
47 import org.slf4j.Logger;
\r
48 import org.slf4j.LoggerFactory;
\r
50 import com.google.common.annotations.VisibleForTesting;
\r
51 import com.google.common.base.Optional;
\r
53 public class PortHandler implements TransactionChainListener {
\r
55 private static final Logger LOG = LoggerFactory.getLogger(MappingProvider.class);
\r
57 private static final String[] COMPUTE_OWNER = {"compute"};
\r
58 private static final String VHOST_USER = "vhostuser";
\r
59 private static final String NETCONF_TOPOLOGY_ID = "topology-netconf";
\r
61 private BindingTransactionChain transactionChain;
\r
62 PortAware portByBaseEpListener;
\r
63 DataBroker dataBroker;
\r
64 SocketInfo socketInfo;
\r
66 PortHandler(DataBroker dataBroker, SocketInfo socketInfo) {
\r
67 this.dataBroker = dataBroker;
\r
68 this.socketInfo = socketInfo;
\r
69 transactionChain = this.dataBroker.createTransactionChain(this);
\r
72 void processCreated(Port port) {
\r
73 ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();
\r
74 Optional<BaseEndpointByPort> optBaseEpByPort = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
\r
75 createBaseEpByPortIid(port.getUuid()), rTx);
\r
77 if (!optBaseEpByPort.isPresent()) {
\r
80 processCreatedData(port, optBaseEpByPort.get());
\r
83 void processCreated(BaseEndpointByPort bebp) {
\r
84 ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();
\r
85 Optional<Port> optPort = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
\r
86 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 = transactionChain.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 synchronized 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
159 VppEndpoint buildVhostUserEndpoint(Port port, BaseEndpointByPort bebp) {
\r
160 PortBindingExtension portBinding = port.getAugmentation(PortBindingExtension.class);
\r
161 String socket = socketInfo.getSocketPath() + socketInfo.getSocketPrefix() + bebp.getPortId().getValue();
\r
162 return new VppEndpointBuilder().setDescription("neutron port")
\r
163 .setContextId(bebp.getContextId())
\r
164 .setContextType(bebp.getContextType())
\r
165 .setAddress(bebp.getAddress())
\r
166 .setInterfaceTypeChoice(new VhostUserCaseBuilder().setSocket(socket).build())
\r
167 .setAddressType(bebp.getAddressType())
\r
168 .setVppInterfaceName(bebp.getPortId().getValue())
\r
169 .setVppNodePath(createNodeIid(new NodeId(portBinding.getHostId())))
\r
173 private InstanceIdentifier<Node> createNodeIid(NodeId nodeId) {
\r
174 return InstanceIdentifier.builder(NetworkTopology.class)
\r
175 .child(Topology.class, new TopologyKey(new TopologyId(NETCONF_TOPOLOGY_ID)))
\r
176 .child(Node.class, new NodeKey(nodeId))
\r
180 private InstanceIdentifier<VppEndpoint> createVppEndpointIid(VppEndpointKey vppEpKey) {
\r
181 return InstanceIdentifier.builder(Config.class).child(VppEndpoint.class, vppEpKey).build();
\r
184 private InstanceIdentifier<BaseEndpointByPort> createBaseEpByPortIid(Uuid uuid) {
\r
185 return createBaseEpByPortIid(new UniqueId(uuid.getValue()));
\r
188 private InstanceIdentifier<BaseEndpointByPort> createBaseEpByPortIid(UniqueId uuid) {
\r
189 return InstanceIdentifier.builder(Mappings.class)
\r
190 .child(GbpByNeutronMappings.class)
\r
191 .child(BaseEndpointsByPorts.class)
\r
192 .child(BaseEndpointByPort.class, new BaseEndpointByPortKey(uuid))
\r
196 InstanceIdentifier<Port> createWildcartedPortIid() {
\r
197 return portsIid().child(Port.class).build();
\r
200 private InstanceIdentifier<Port> createPortIid(UniqueId uuid) {
\r
201 return portsIid().child(Port.class, new PortKey(new Uuid(uuid.getValue()))).build();
\r
204 private InstanceIdentifierBuilder<Ports> portsIid() {
\r
205 return InstanceIdentifier.builder(Neutron.class).child(Ports.class);
\r
209 public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction,
\r
211 LOG.error("Transaction chain failed. {} \nTransaction which caused the chain to fail {}", cause.getMessage(),
\r
212 transaction, cause);
\r
213 transactionChain.close();
\r
214 transactionChain = dataBroker.createTransactionChain(this);
\r
218 public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
\r
219 LOG.trace("Transaction chain was successfull. {}", chain);
\r