2 * Copyright (c) 2016 Cisco and/or its affiliates.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package io.fd.honeycomb.v3po.translate.v3po.vpp;
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
22 import com.google.common.base.Preconditions;
23 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
24 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
25 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
26 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
27 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
28 import io.fd.honeycomb.v3po.translate.write.WriteContext;
29 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
30 import java.util.List;
31 import javax.annotation.Nonnull;
32 import javax.annotation.Nullable;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey;
36 import org.opendaylight.yangtools.yang.binding.DataObject;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.openvpp.jvpp.dto.BridgeDomainAddDel;
39 import org.openvpp.jvpp.dto.BridgeDomainAddDelReply;
40 import org.openvpp.jvpp.future.FutureJVpp;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 public class BridgeDomainCustomizer
45 extends FutureJVppCustomizer
46 implements ListWriterCustomizer<BridgeDomain, BridgeDomainKey> {
48 private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class);
50 private static final byte ADD_OR_UPDATE_BD = (byte) 1;
51 private final NamingContext bdContext;
53 public BridgeDomainCustomizer(@Nonnull final FutureJVpp futureJvpp, @Nonnull final NamingContext bdContext) {
55 this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null");
60 public List<BridgeDomain> extract(@Nonnull final InstanceIdentifier<BridgeDomain> currentId,
61 @Nonnull final DataObject parentData) {
62 return ((BridgeDomains) parentData).getBridgeDomain();
65 private BridgeDomainAddDelReply addOrUpdateBridgeDomain(final int bdId, @Nonnull final BridgeDomain bd)
66 throws VppApiInvocationException {
67 final BridgeDomainAddDel request = new BridgeDomainAddDel();
69 request.flood = booleanToByte(bd.isFlood());
70 request.forward = booleanToByte(bd.isForward());
71 request.learn = booleanToByte(bd.isLearn());
72 request.uuFlood = booleanToByte(bd.isUnknownUnicastFlood());
73 request.arpTerm = booleanToByte(bd.isArpTermination());
74 request.isAdd = ADD_OR_UPDATE_BD;
76 final BridgeDomainAddDelReply reply =
77 V3poUtils.getReply(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture());
78 if (reply.retval < 0) {
79 LOG.warn("Bridge domain {} (id={}) add/update failed", bd.getName(), bdId);
80 throw new VppApiInvocationException("bridgeDomainAddDel", reply.context, reply.retval);
82 LOG.debug("Bridge domain {} (id={}) add/update successful", bd.getName(), bdId);
89 public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
90 @Nonnull final BridgeDomain dataBefore,
91 @Nonnull final WriteContext ctx) throws WriteFailedException.CreateFailedException {
92 LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, dataBefore, ctx);
93 final String bdName = dataBefore.getName();
96 // FIXME we need the bd index to be returned by VPP or we should have a counter field (maybe in context similar to artificial name)
97 // Here we assign the next available ID from bdContext's perspective
99 while(bdContext.containsName(index, ctx.getMappingContext())) {
102 addOrUpdateBridgeDomain(index, dataBefore);
103 bdContext.addName(index, bdName, ctx.getMappingContext());
104 } catch (VppApiInvocationException e) {
105 LOG.warn("Failed to create bridge domain", e);
106 throw new WriteFailedException.CreateFailedException(id, dataBefore, e);
110 private byte booleanToByte(@Nullable final Boolean aBoolean) {
111 return aBoolean != null && aBoolean
117 public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
118 @Nonnull final BridgeDomain dataBefore,
119 @Nonnull final WriteContext ctx) throws WriteFailedException.DeleteFailedException {
120 LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx);
122 final String bdName = id.firstKeyOf(BridgeDomain.class).getName();
123 int bdId = bdContext.getIndex(bdName, ctx.getMappingContext());
124 final BridgeDomainAddDel request = new BridgeDomainAddDel();
127 final BridgeDomainAddDelReply reply =
128 V3poUtils.getReply(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture());
129 if (reply.retval < 0) {
130 LOG.warn("Bridge domain {} (id={}) delete failed", bdName, bdId);
131 throw new WriteFailedException.DeleteFailedException(id,
132 new VppApiInvocationException("bridgeDomainAddDel", reply.context, reply.retval));
134 LOG.debug("Bridge domain {} (id={}) deleted successfully", bdName, bdId);
139 public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
140 @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter,
141 @Nonnull final WriteContext ctx) throws WriteFailedException.UpdateFailedException {
142 LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter,
145 // FIXME can be removed after updating mdsal-binding-dom-codec to 0.8.2-Beryllium-SR2
146 // and restoring equality check in AbstractCompositeWriter
147 if (dataBefore.equals(dataAfter)) {
148 LOG.debug("dataBefore equals dataAfter, update will not be performed");
152 final String bdName = checkNotNull(dataAfter.getName());
153 checkArgument(bdName.equals(dataBefore.getName()),
154 "BridgeDomain name changed. It should be deleted and then created.");
157 addOrUpdateBridgeDomain(bdContext.getIndex(bdName, ctx.getMappingContext()), dataAfter);
158 } catch (VppApiInvocationException e) {
159 LOG.warn("Failed to create bridge domain", e);
160 throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);