ac5526861246537cf2ae7081e38b64cb136252de
[honeycomb.git] / v3po / v3po2vpp / src / main / java / io / fd / honeycomb / translate / v3po / interfaces / InterconnectionWriteUtils.java
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.translate.v3po.interfaces;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static java.util.Objects.requireNonNull;
21
22 import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer;
23 import io.fd.honeycomb.translate.vpp.util.NamingContext;
24 import io.fd.honeycomb.translate.write.WriteContext;
25 import io.fd.honeycomb.translate.write.WriteFailedException;
26 import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Bridge;
27 import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2BridgeReply;
28 import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2Xconnect;
29 import io.fd.vpp.jvpp.core.dto.SwInterfaceSetL2XconnectReply;
30 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
31 import java.util.concurrent.CompletionStage;
32 import javax.annotation.Nonnull;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.XconnectBased;
36 import org.opendaylight.yangtools.yang.binding.DataObject;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 /**
42  * Utility class providing Interconnection CUD support.
43  */
44 final class InterconnectionWriteUtils implements JvppReplyConsumer {
45
46     private static final Logger LOG = LoggerFactory.getLogger(InterconnectionWriteUtils.class);
47
48     private final FutureJVppCore futureJVppCore;
49     private final NamingContext interfaceContext;
50     private final NamingContext bridgeDomainContext;
51
52     InterconnectionWriteUtils(@Nonnull final FutureJVppCore futureJVppCore,
53                               @Nonnull final NamingContext interfaceContext,
54                               @Nonnull final NamingContext bridgeDomainContext) {
55         this.futureJVppCore = requireNonNull(futureJVppCore, "futureJVppCore should not be null");
56         this.interfaceContext = requireNonNull(interfaceContext, "interfaceContext should not be null");
57         this.bridgeDomainContext = requireNonNull(bridgeDomainContext, "bridgeDomainContext should not be null");
58     }
59
60     void setInterconnection(final InstanceIdentifier<? extends DataObject> id, final int swIfIndex,
61                             final String ifcName, final Interconnection ic, final WriteContext writeContext)
62             throws WriteFailedException {
63
64         if (ic == null) { // TODO in case of update we should delete interconnection
65             LOG.trace("Interconnection is not set. Skipping");
66         } else if (ic instanceof XconnectBased) {
67             setXconnectBasedL2(id, swIfIndex, ifcName, (XconnectBased) ic, writeContext, (byte) 1 /*enable*/);
68         } else if (ic instanceof BridgeBased) {
69             setBridgeBasedL2(id, swIfIndex, ifcName, (BridgeBased) ic, writeContext, (byte) 1 /*enable*/);
70         } else {
71             // Choices&cases are not data objects, so they cannot have a dedicated Reader/Writer
72             // This choice is already from augment, so its not possible to augment augmented choice
73             LOG.error("Unable to handle Interconnection of type {}", ic.getClass());
74             throw new WriteFailedException(id, "Unable to handle Interconnection of type " + ic.getClass());
75         }
76     }
77
78     void deleteInterconnection(final InstanceIdentifier<? extends DataObject> id, final int swIfIndex,
79                                final String ifcName, final Interconnection ic, final WriteContext writeContext)
80             throws WriteFailedException {
81
82         if (ic == null) { // TODO in case of update we should delete interconnection
83             LOG.trace("Interconnection is not set. Skipping");
84         } else if (ic instanceof XconnectBased) {
85             setXconnectBasedL2(id, swIfIndex, ifcName, (XconnectBased) ic, writeContext, (byte) 0 /*disable*/);
86         } else if (ic instanceof BridgeBased) {
87             setBridgeBasedL2(id, swIfIndex, ifcName, (BridgeBased) ic, writeContext, (byte) 0 /*disable*/);
88         } else {
89             LOG.error("Unable to delete Interconnection of type {}", ic.getClass());
90             throw new WriteFailedException(id, "Unable to delete Interconnection of type " + ic.getClass());
91         }
92     }
93
94     private void setBridgeBasedL2(final InstanceIdentifier<? extends DataObject> id, final int swIfIndex,
95                                   final String ifcName, final BridgeBased bb,
96                                   final WriteContext writeContext, final byte enabled) throws WriteFailedException {
97         LOG.debug("Setting bridge based interconnection(bridge-domain={}) for interface: {}", bb.getBridgeDomain(),
98                 ifcName);
99
100         String bdName = bb.getBridgeDomain();
101
102         int bdId = bridgeDomainContext.getIndex(bdName, writeContext.getMappingContext());
103         checkArgument(bdId > 0, "Unable to set Interconnection for Interface: %s, bridge domain: %s does not exist",
104                 ifcName, bdName);
105
106         byte bvi = bb.isBridgedVirtualInterface()
107                 ? (byte) 1
108                 : (byte) 0;
109         byte shg = 0;
110         if (bb.getSplitHorizonGroup() != null) {
111             shg = bb.getSplitHorizonGroup().byteValue();
112         }
113
114         final CompletionStage<SwInterfaceSetL2BridgeReply> swInterfaceSetL2BridgeReplyCompletionStage = futureJVppCore
115                 .swInterfaceSetL2Bridge(getL2BridgeRequest(swIfIndex, bdId, shg, bvi, enabled));
116         getReplyForWrite(swInterfaceSetL2BridgeReplyCompletionStage.toCompletableFuture(), id);
117
118         LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifcName, bb);
119     }
120
121     private SwInterfaceSetL2Bridge getL2BridgeRequest(final int swIfIndex, final int bdId, final byte shg,
122                                                       final byte bvi, final byte enabled) {
123         final SwInterfaceSetL2Bridge swInterfaceSetL2Bridge = new SwInterfaceSetL2Bridge();
124         swInterfaceSetL2Bridge.rxSwIfIndex = swIfIndex;
125         swInterfaceSetL2Bridge.bdId = bdId;
126         swInterfaceSetL2Bridge.shg = shg;
127         swInterfaceSetL2Bridge.bvi = bvi;
128         swInterfaceSetL2Bridge.enable = enabled;
129         return swInterfaceSetL2Bridge;
130     }
131
132     private void setXconnectBasedL2(final InstanceIdentifier<? extends DataObject> id, final int swIfIndex,
133                                     final String ifcName, final XconnectBased ic,
134                                     final WriteContext writeContext, final byte enabled) throws WriteFailedException {
135         String outSwIfName = ic.getXconnectOutgoingInterface();
136         LOG.debug("Setting xconnect based interconnection(outgoing ifc={}) for interface: {}", outSwIfName, ifcName);
137
138         int outSwIfIndex = interfaceContext.getIndex(outSwIfName, writeContext.getMappingContext());
139         checkArgument(outSwIfIndex > 0,
140                 "Unable to set Interconnection for Interface: %s, outgoing interface: %s does not exist",
141                 ifcName, outSwIfIndex);
142
143         final CompletionStage<SwInterfaceSetL2XconnectReply> swInterfaceSetL2XconnectReplyCompletionStage =
144                 futureJVppCore
145                         .swInterfaceSetL2Xconnect(getL2XConnectRequest(swIfIndex, outSwIfIndex, enabled));
146         getReplyForWrite(swInterfaceSetL2XconnectReplyCompletionStage.toCompletableFuture(), id);
147         LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifcName, ic);
148     }
149
150     private SwInterfaceSetL2Xconnect getL2XConnectRequest(final int rxIfc, final int txIfc,
151                                                           final byte enabled) {
152
153         final SwInterfaceSetL2Xconnect swInterfaceSetL2Xconnect = new SwInterfaceSetL2Xconnect();
154         swInterfaceSetL2Xconnect.enable = enabled;
155         swInterfaceSetL2Xconnect.rxSwIfIndex = rxIfc;
156         swInterfaceSetL2Xconnect.txSwIfIndex = txIfc;
157         return swInterfaceSetL2Xconnect;
158     }
159 }