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.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.translate.spi.write.ListWriterCustomizer;
24 import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator;
25 import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer;
26 import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer;
27 import io.fd.honeycomb.translate.vpp.util.NamingContext;
28 import io.fd.honeycomb.translate.write.WriteContext;
29 import io.fd.honeycomb.translate.write.WriteFailedException;
30 import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDel;
31 import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDelReply;
32 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
33 import javax.annotation.Nonnull;
34 import javax.annotation.concurrent.GuardedBy;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public class BridgeDomainCustomizer
42 extends FutureJVppCustomizer
43 implements ListWriterCustomizer<BridgeDomain, BridgeDomainKey>, ByteDataTranslator, JvppReplyConsumer {
45 private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class);
47 private static final byte ADD_OR_UPDATE_BD = (byte) 1;
48 private final NamingContext bdContext;
50 private int bridgeDomainIndexCounter = 1;
52 public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
53 @Nonnull final NamingContext bdContext) {
54 super(futureJVppCore);
55 this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null");
58 private BridgeDomainAddDelReply addOrUpdateBridgeDomain(@Nonnull final InstanceIdentifier<BridgeDomain> id,
59 final int bdId, @Nonnull final BridgeDomain bd)
60 throws WriteFailedException {
61 final BridgeDomainAddDelReply reply;
62 final BridgeDomainAddDel request = new BridgeDomainAddDel();
64 request.flood = booleanToByte(bd.isFlood());
65 request.forward = booleanToByte(bd.isForward());
66 request.learn = booleanToByte(bd.isLearn());
67 request.uuFlood = booleanToByte(bd.isUnknownUnicastFlood());
68 request.arpTerm = booleanToByte(bd.isArpTermination());
69 request.isAdd = ADD_OR_UPDATE_BD;
71 reply = getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id);
72 LOG.debug("Bridge domain {} (id={}) add/update successful", bd.getName(), bdId);
77 public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
78 @Nonnull final BridgeDomain dataBefore,
79 @Nonnull final WriteContext ctx)
80 throws WriteFailedException {
81 LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, dataBefore, ctx);
82 final String bdName = dataBefore.getName();
84 // Invoke 1. check index, 2. increase index 3. create ND 4. store mapping in a synchronized block to prevent
85 // race conditions in case of concurrent invocation
88 if (bdContext.containsIndex(bdName, ctx.getMappingContext())) {
89 index = bdContext.getIndex(bdName, ctx.getMappingContext());
91 // Critical section due to bridgeDomainIndexCounter read and write access
92 // TODO HONEYCOMB-199 move this "get next available index" into naming context or an adapter
93 // or a dedicated object
95 // Use counter to assign bridge domain index, but still check naming context if it's not taken there
96 while (bdContext.containsName(bridgeDomainIndexCounter, ctx.getMappingContext())) {
97 bridgeDomainIndexCounter++;
99 index = bridgeDomainIndexCounter;
101 addOrUpdateBridgeDomain(id, index, dataBefore);
102 bdContext.addName(index, bdName, ctx.getMappingContext());
107 public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
108 @Nonnull final BridgeDomain dataBefore,
109 @Nonnull final WriteContext ctx)
110 throws WriteFailedException {
111 LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx);
112 final String bdName = id.firstKeyOf(BridgeDomain.class).getName();
113 int bdId = bdContext.getIndex(bdName, ctx.getMappingContext());
115 final BridgeDomainAddDel request = new BridgeDomainAddDel();
118 getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id);
119 LOG.debug("Bridge domain {} (id={}) deleted successfully", bdName, bdId);
123 public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
124 @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter,
125 @Nonnull final WriteContext ctx)
126 throws WriteFailedException {
127 LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter,
130 final String bdName = checkNotNull(dataAfter.getName());
131 checkArgument(bdName.equals(dataBefore.getName()),
132 "BridgeDomain name changed. It should be deleted and then created.");
134 addOrUpdateBridgeDomain(id, bdContext.getIndex(bdName, ctx.getMappingContext()), dataAfter);