From 5ec31f19f7a74a884e2bef8e5238fdd4cfa2c4c2 Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Tue, 14 Mar 2017 09:29:12 +0100 Subject: HC2VPP-7 - Split vpp state/Cli RPC to separate module Introduces VppManageModule containing - Vpp state attributes - CLI RPC support - Keep-alive Change-Id: I8907e57132cc9e57840aa3b9607fa131a77f767d Signed-off-by: Jan Srnicek --- .../main/java/io/fd/hc2vpp/v3po/V3poModule.java | 24 +-- .../fd/hc2vpp/v3po/cfgattrs/V3poConfiguration.java | 32 ---- .../v3po/factory/L2HoneycombWriterFactory.java | 81 +++++++++ .../factory/L2StateHoneycombReaderFactory.java | 67 ++++++++ .../v3po/factory/VppHoneycombWriterFactory.java | 82 ---------- .../factory/VppStateHoneycombReaderFactory.java | 94 ----------- .../l2/ArpTerminationTableEntryCustomizer.java | 115 +++++++++++++ .../fd/hc2vpp/v3po/l2/BridgeDomainCustomizer.java | 164 +++++++++++++++++++ .../io/fd/hc2vpp/v3po/l2/L2FibEntryCustomizer.java | 143 ++++++++++++++++ .../v3po/l2state/BridgeDomainCustomizer.java | 180 ++++++++++++++++++++ .../hc2vpp/v3po/l2state/L2FibEntryCustomizer.java | 165 +++++++++++++++++++ .../io/fd/hc2vpp/v3po/rpc/CliInbandService.java | 62 ------- .../vpp/ArpTerminationTableEntryCustomizer.java | 115 ------------- .../fd/hc2vpp/v3po/vpp/BridgeDomainCustomizer.java | 163 ------------------- .../fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java | 143 ---------------- .../v3po/vppstate/BridgeDomainCustomizer.java | 181 --------------------- .../hc2vpp/v3po/vppstate/L2FibEntryCustomizer.java | 165 ------------------- .../fd/hc2vpp/v3po/vppstate/VersionCustomizer.java | 82 ---------- 18 files changed, 919 insertions(+), 1139 deletions(-) delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/cfgattrs/V3poConfiguration.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/L2HoneycombWriterFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/L2StateHoneycombReaderFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppHoneycombWriterFactory.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppStateHoneycombReaderFactory.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/ArpTerminationTableEntryCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/BridgeDomainCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/L2FibEntryCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2state/BridgeDomainCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2state/L2FibEntryCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/rpc/CliInbandService.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizer.java (limited to 'v3po/v3po2vpp/src/main/java') diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java index 06d6d290f..1a0430049 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java @@ -20,22 +20,16 @@ import com.google.inject.AbstractModule; import com.google.inject.multibindings.Multibinder; import com.google.inject.name.Names; import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.v3po.cfgattrs.V3poConfiguration; import io.fd.hc2vpp.v3po.factory.InterfacesStateReaderFactory; import io.fd.hc2vpp.v3po.factory.InterfacesWriterFactory; +import io.fd.hc2vpp.v3po.factory.L2HoneycombWriterFactory; +import io.fd.hc2vpp.v3po.factory.L2StateHoneycombReaderFactory; import io.fd.hc2vpp.v3po.factory.SubinterfaceAugmentationWriterFactory; import io.fd.hc2vpp.v3po.factory.SubinterfaceStateAugmentationReaderFactory; -import io.fd.hc2vpp.v3po.factory.VppHoneycombWriterFactory; -import io.fd.hc2vpp.v3po.factory.VppStateHoneycombReaderFactory; import io.fd.hc2vpp.v3po.notification.InterfaceChangeNotificationProducer; -import io.fd.hc2vpp.v3po.rpc.CliInbandService; import io.fd.honeycomb.notification.ManagedNotificationProducer; -import io.fd.honeycomb.rpc.RpcService; import io.fd.honeycomb.translate.read.ReaderFactory; import io.fd.honeycomb.translate.write.WriterFactory; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import net.jmob.guice.conf.core.ConfigurationModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,8 +40,6 @@ public class V3poModule extends AbstractModule { @Override protected void configure() { LOG.debug("Installing V3PO module"); - install(ConfigurationModule.create()); - requestInjection(V3poConfiguration.class); // TODO HONEYCOMB-173 put into constants // Naming contexts @@ -58,10 +50,6 @@ public class V3poModule extends AbstractModule { .annotatedWith(Names.named("bridge-domain-context")) .toInstance(new NamingContext("bridge-domain-", "bridge-domain-context")); - // Executor needed for keepalives - bind(ScheduledExecutorService.class).toInstance(Executors.newScheduledThreadPool(1)); - - // Context utility for deleted interfaces bind(DisabledInterfacesManager.class).toInstance(new DisabledInterfacesManager()); @@ -69,7 +57,7 @@ public class V3poModule extends AbstractModule { final Multibinder readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); readerFactoryBinder.addBinding().to(InterfacesStateReaderFactory.class); readerFactoryBinder.addBinding().to(SubinterfaceStateAugmentationReaderFactory.class); - readerFactoryBinder.addBinding().to(VppStateHoneycombReaderFactory.class); + readerFactoryBinder.addBinding().to(L2StateHoneycombReaderFactory.class); // Expose disabled interfaces in operational data readerFactoryBinder.addBinding().to(DisabledInterfacesManager.ContextsReaderFactory.class); @@ -78,17 +66,13 @@ public class V3poModule extends AbstractModule { final Multibinder writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); writerFactoryBinder.addBinding().to(InterfacesWriterFactory.class); writerFactoryBinder.addBinding().to(SubinterfaceAugmentationWriterFactory.class); - writerFactoryBinder.addBinding().to(VppHoneycombWriterFactory.class); + writerFactoryBinder.addBinding().to(L2HoneycombWriterFactory.class); // Notifications final Multibinder notifiersBinder = Multibinder.newSetBinder(binder(), ManagedNotificationProducer.class); notifiersBinder.addBinding().to(InterfaceChangeNotificationProducer.class); - // RPCs - final Multibinder rpcsBinder = Multibinder.newSetBinder(binder(), RpcService.class); - rpcsBinder.addBinding().to(CliInbandService.class); - LOG.info("Module V3PO successfully configured"); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/cfgattrs/V3poConfiguration.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/cfgattrs/V3poConfiguration.java deleted file mode 100644 index f7b52accd..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/cfgattrs/V3poConfiguration.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.hc2vpp.v3po.cfgattrs; - -import net.jmob.guice.conf.core.BindConfig; -import net.jmob.guice.conf.core.InjectConfig; -import net.jmob.guice.conf.core.Syntax; - -@BindConfig(value = "v3po", syntax = Syntax.JSON) -public class V3poConfiguration { - - @InjectConfig("keepalive-delay") - private String keepaliveDelay; - - public int getKeepaliveDelay() { - return Integer.valueOf(this.keepaliveDelay); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/L2HoneycombWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/L2HoneycombWriterFactory.java new file mode 100644 index 000000000..80f72db78 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/L2HoneycombWriterFactory.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.v3po.factory; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.v3po.l2.ArpTerminationTableEntryCustomizer; +import io.fd.hc2vpp.v3po.l2.BridgeDomainCustomizer; +import io.fd.hc2vpp.v3po.l2.L2FibEntryCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.ArpTerminationTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + +public final class L2HoneycombWriterFactory implements WriterFactory { + + private final FutureJVppCore jvpp; + private final NamingContext bdContext; + private final NamingContext ifcContext; + + @Inject + public L2HoneycombWriterFactory(final FutureJVppCore vppJvppWriterDependency, + @Named("bridge-domain-context") final NamingContext bridgeDomainContextVppDependency, + @Named("interface-context") final NamingContext interfaceContextVppDependency) { + this.jvpp = vppJvppWriterDependency; + this.bdContext = bridgeDomainContextVppDependency; + this.ifcContext = interfaceContextVppDependency; + } + + @Override + public void init(final ModifiableWriterRegistryBuilder registry) { + // Vpp has no handlers + // BridgeDomains has no handlers + // BridgeDomain(handled before L2 of ifc and subifc) = + final InstanceIdentifier bdId = + InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class); + registry.addBefore(new GenericListWriter<>(bdId, new BridgeDomainCustomizer(jvpp, bdContext)), + Sets.newHashSet( + InterfacesWriterFactory.L2_ID, + SubinterfaceAugmentationWriterFactory.L2_ID)); + // L2FibTable has no handlers + // L2FibEntry(handled after BridgeDomain and L2 of ifc and subifc) = + final InstanceIdentifier l2FibEntryId = bdId.child(L2FibTable.class).child(L2FibEntry.class); + registry.addAfter( + new GenericListWriter<>(l2FibEntryId, new L2FibEntryCustomizer(jvpp, bdContext, ifcContext)), + Sets.newHashSet( + bdId, + InterfacesWriterFactory.L2_ID, + SubinterfaceAugmentationWriterFactory.L2_ID)); + // ArpTerminationTable has no handlers + // ArpTerminationTableEntry(handled after BridgeDomain) = + final InstanceIdentifier arpEntryId = + bdId.child(ArpTerminationTable.class).child(ArpTerminationTableEntry.class); + registry.addAfter( + new GenericListWriter<>(arpEntryId, new ArpTerminationTableEntryCustomizer(jvpp, bdContext)), + bdId); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/L2StateHoneycombReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/L2StateHoneycombReaderFactory.java new file mode 100644 index 000000000..eacc371fe --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/L2StateHoneycombReaderFactory.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.v3po.factory; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.v3po.l2state.BridgeDomainCustomizer; +import io.fd.hc2vpp.v3po.l2state.L2FibEntryCustomizer; +import io.fd.honeycomb.translate.impl.read.GenericInitListReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.BridgeDomainsState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.BridgeDomainsStateBuilder; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.state.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class L2StateHoneycombReaderFactory implements ReaderFactory { + + private final FutureJVppCore jVpp; + private final NamingContext ifcCtx; + private final NamingContext bdCtx; + + @Inject + public L2StateHoneycombReaderFactory(final FutureJVppCore jVpp, + @Named("interface-context") final NamingContext ifcCtx, + @Named("bridge-domain-context") final NamingContext bdCtx) { + this.jVpp = jVpp; + this.ifcCtx = ifcCtx; + this.bdCtx = bdCtx; + } + + @Override + public void init(final ModifiableReaderRegistryBuilder registry) { + // BridgeDomains(Structural) + final InstanceIdentifier bridgeDomainsId = InstanceIdentifier.create(BridgeDomainsState.class); + registry.addStructuralReader(bridgeDomainsId, BridgeDomainsStateBuilder.class); + // BridgeDomain + final InstanceIdentifier bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class); + registry.add(new GenericInitListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdCtx))); + // L2FibTable(Structural) + final InstanceIdentifier l2FibTableId = bridgeDomainId.child(L2FibTable.class); + registry.addStructuralReader(l2FibTableId, L2FibTableBuilder.class); + // L2FibEntry + registry.add(new GenericInitListReader<>(l2FibTableId.child(L2FibEntry.class), + new L2FibEntryCustomizer(jVpp, bdCtx, ifcCtx))); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppHoneycombWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppHoneycombWriterFactory.java deleted file mode 100644 index 0fb95938a..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppHoneycombWriterFactory.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.hc2vpp.v3po.factory; - -import com.google.common.collect.Sets; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.hc2vpp.v3po.vpp.ArpTerminationTableEntryCustomizer; -import io.fd.hc2vpp.v3po.vpp.BridgeDomainCustomizer; -import io.fd.hc2vpp.v3po.vpp.L2FibEntryCustomizer; -import io.fd.honeycomb.translate.impl.write.GenericListWriter; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Vpp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.ArpTerminationTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -public final class VppHoneycombWriterFactory implements WriterFactory { - - private final FutureJVppCore jvpp; - private final NamingContext bdContext; - private final NamingContext ifcContext; - - @Inject - public VppHoneycombWriterFactory(final FutureJVppCore vppJvppWriterDependency, - @Named("bridge-domain-context") final NamingContext bridgeDomainContextVppDependency, - @Named("interface-context") final NamingContext interfaceContextVppDependency) { - this.jvpp = vppJvppWriterDependency; - this.bdContext = bridgeDomainContextVppDependency; - this.ifcContext = interfaceContextVppDependency; - } - - @Override - public void init(final ModifiableWriterRegistryBuilder registry) { - // Vpp has no handlers - // BridgeDomains has no handlers - // BridgeDomain(handled before L2 of ifc and subifc) = - final InstanceIdentifier bdId = - InstanceIdentifier.create(Vpp.class).child(BridgeDomains.class).child(BridgeDomain.class); - registry.addBefore(new GenericListWriter<>(bdId, new BridgeDomainCustomizer(jvpp, bdContext)), - Sets.newHashSet( - InterfacesWriterFactory.L2_ID, - SubinterfaceAugmentationWriterFactory.L2_ID)); - // L2FibTable has no handlers - // L2FibEntry(handled after BridgeDomain and L2 of ifc and subifc) = - final InstanceIdentifier l2FibEntryId = bdId.child(L2FibTable.class).child(L2FibEntry.class); - registry.addAfter( - new GenericListWriter<>(l2FibEntryId, new L2FibEntryCustomizer(jvpp, bdContext, ifcContext)), - Sets.newHashSet( - bdId, - InterfacesWriterFactory.L2_ID, - SubinterfaceAugmentationWriterFactory.L2_ID)); - // ArpTerminationTable has no handlers - // ArpTerminationTableEntry(handled after BridgeDomain) = - final InstanceIdentifier arpEntryId = - bdId.child(ArpTerminationTable.class).child(ArpTerminationTableEntry.class); - registry.addAfter( - new GenericListWriter<>(arpEntryId, new ArpTerminationTableEntryCustomizer(jvpp, bdContext)), - bdId); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppStateHoneycombReaderFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppStateHoneycombReaderFactory.java deleted file mode 100644 index 6d019ea2a..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/factory/VppStateHoneycombReaderFactory.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.hc2vpp.v3po.factory; - -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.common.translate.util.ReadTimeoutException; -import io.fd.hc2vpp.common.translate.util.VppStatusListener; -import io.fd.hc2vpp.v3po.cfgattrs.V3poConfiguration; -import io.fd.hc2vpp.v3po.vppstate.BridgeDomainCustomizer; -import io.fd.hc2vpp.v3po.vppstate.L2FibEntryCustomizer; -import io.fd.hc2vpp.v3po.vppstate.VersionCustomizer; -import io.fd.honeycomb.translate.impl.read.GenericInitListReader; -import io.fd.honeycomb.translate.impl.read.GenericReader; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; -import io.fd.honeycomb.translate.util.read.KeepaliveReaderWrapper; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.ScheduledExecutorService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomainsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class VppStateHoneycombReaderFactory implements ReaderFactory { - - private final FutureJVppCore jVpp; - private final NamingContext ifcCtx; - private final NamingContext bdCtx; - private final ScheduledExecutorService keepaliveExecutor; - private final VppStatusListener vppStatusListener; - - @Inject - private V3poConfiguration v3poConfiguration; - - @Inject - public VppStateHoneycombReaderFactory(final FutureJVppCore jVpp, - @Named("interface-context") final NamingContext ifcCtx, - @Named("bridge-domain-context") final NamingContext bdCtx, - final ScheduledExecutorService keepaliveExecutorDependency, - final VppStatusListener vppStatusListener) { - this.jVpp = jVpp; - this.ifcCtx = ifcCtx; - this.bdCtx = bdCtx; - this.keepaliveExecutor = keepaliveExecutorDependency; - this.vppStatusListener = vppStatusListener; - } - - @Override - public void init(final ModifiableReaderRegistryBuilder registry) { - // VppState(Structural) - final InstanceIdentifier vppStateId = InstanceIdentifier.create(VppState.class); - registry.addStructuralReader(vppStateId, VppStateBuilder.class); - // Version - // Wrap with keepalive reader to detect connection issues - // Relying on VersionCustomizer to provide a "timing out read" - registry.add(new KeepaliveReaderWrapper<>( - new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp)), - keepaliveExecutor, ReadTimeoutException.class, v3poConfiguration.getKeepaliveDelay(), vppStatusListener)); - // BridgeDomains(Structural) - final InstanceIdentifier bridgeDomainsId = vppStateId.child(BridgeDomains.class); - registry.addStructuralReader(bridgeDomainsId, BridgeDomainsBuilder.class); - // BridgeDomain - final InstanceIdentifier bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class); - registry.add(new GenericInitListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdCtx))); - // L2FibTable(Structural) - final InstanceIdentifier l2FibTableId = bridgeDomainId.child(L2FibTable.class); - registry.addStructuralReader(l2FibTableId, L2FibTableBuilder.class); - // L2FibEntry - registry.add(new GenericInitListReader<>(l2FibTableId.child(L2FibEntry.class), - new L2FibEntryCustomizer(jVpp, bdCtx, ifcCtx))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/ArpTerminationTableEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/ArpTerminationTableEntryCustomizer.java new file mode 100644 index 000000000..614570dcc --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/ArpTerminationTableEntryCustomizer.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.v3po.l2; + +import com.google.common.base.Preconditions; +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.BdIpMacAddDel; +import io.fd.vpp.jvpp.core.dto.BdIpMacAddDelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntryKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.BridgeDomain; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer Customizer responsible for ARP termination table management.
Sends {@code bd_ip_mac_add_del} message to + * VPP.
Equivalent of invoking {@code vppctl set bridge-domain arp term} command. + */ +public class ArpTerminationTableEntryCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, ByteDataTranslator, + AddressTranslator, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(ArpTerminationTableEntryCustomizer.class); + + private final NamingContext bdContext; + + public ArpTerminationTableEntryCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final NamingContext bdContext) { + super(futureJvpp); + this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ArpTerminationTableEntry dataAfter, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Creating ARP termination table entry: {} {}", id, dataAfter); + bdIpMacAddDel(id, dataAfter, writeContext, true); + LOG.debug("L2 ARP termination table entry created successfully: {} {}", id, dataAfter); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ArpTerminationTableEntry dataBefore, + @Nonnull final ArpTerminationTableEntry dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException( + "ARP termination table entry update is not supported. It has to be deleted and then created."); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final ArpTerminationTableEntry dataBefore, + @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.debug("Deleting ARP termination table entry entry: {} {}", id, dataBefore); + bdIpMacAddDel(id, dataBefore, writeContext, false); + LOG.debug("ARP termination table entry deleted successfully: {} {}", id, dataBefore); + } + + private void bdIpMacAddDel(@Nonnull final InstanceIdentifier id, + @Nonnull final ArpTerminationTableEntry entry, + final WriteContext writeContext, boolean isAdd) throws WriteFailedException { + final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); + final int bdId = bdContext.getIndex(bdName, writeContext.getMappingContext()); + + final BdIpMacAddDel request = createRequest(entry, bdId, isAdd); + LOG.debug("Sending l2FibAddDel request: {}", request); + final CompletionStage replyCompletionStage = + getFutureJVpp().bdIpMacAddDel(request); + + getReplyForWrite(replyCompletionStage.toCompletableFuture(), id); + } + + private BdIpMacAddDel createRequest(final ArpTerminationTableEntry entry, final int bdId, boolean isAdd) { + final BdIpMacAddDel request = new BdIpMacAddDel(); + request.bdId = bdId; + request.isAdd = booleanToByte(isAdd); + request.macAddress = parseMac(entry.getPhysAddress().getValue()); + + final IpAddress ipAddress = entry.getIpAddress(); + + request.ipAddress = ipAddressToArray(ipAddress); + request.isIpv6 = booleanToByte(isIpv6(ipAddress)); + + return request; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/BridgeDomainCustomizer.java new file mode 100644 index 000000000..b316d28be --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/BridgeDomainCustomizer.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.v3po.l2; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.stream.Collectors.toList; + +import com.google.common.base.Preconditions; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.hc2vpp.common.translate.util.ReferenceCheck; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDel; +import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Collections; +import java.util.Optional; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.GuardedBy; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2BaseAttributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.BridgeDomainKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBased; + +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BridgeDomainCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer, + ReferenceCheck { + + private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); + + private static final byte ADD_OR_UPDATE_BD = (byte) 1; + private final NamingContext bdContext; + @GuardedBy("this") + private int bridgeDomainIndexCounter = 1; + + public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext bdContext) { + super(futureJVppCore); + this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); + } + + private BridgeDomainAddDelReply addOrUpdateBridgeDomain(@Nonnull final InstanceIdentifier id, + final int bdId, @Nonnull final BridgeDomain bd) + throws WriteFailedException { + final BridgeDomainAddDelReply reply; + final BridgeDomainAddDel request = new BridgeDomainAddDel(); + request.bdId = bdId; + request.flood = booleanToByte(bd.isFlood()); + request.forward = booleanToByte(bd.isForward()); + request.learn = booleanToByte(bd.isLearn()); + request.uuFlood = booleanToByte(bd.isUnknownUnicastFlood()); + request.arpTerm = booleanToByte(bd.isArpTermination()); + request.isAdd = ADD_OR_UPDATE_BD; + + reply = getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); + LOG.debug("Bridge domain {} (id={}) add/update successful", bd.getName(), bdId); + return reply; + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain dataBefore, + @Nonnull final WriteContext ctx) + throws WriteFailedException { + LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, dataBefore, ctx); + final String bdName = dataBefore.getName(); + + // Invoke 1. check index, 2. increase index 3. create ND 4. store mapping in a synchronized block to prevent + // race conditions in case of concurrent invocation + synchronized (this) { + int index; + if (bdContext.containsIndex(bdName, ctx.getMappingContext())) { + index = bdContext.getIndex(bdName, ctx.getMappingContext()); + } else { + // Critical section due to bridgeDomainIndexCounter read and write access + // TODO HONEYCOMB-199 move this "get next available index" into naming context or an adapter + // or a dedicated object + + // Use counter to assign bridge domain index, but still check naming context if it's not taken there + while (bdContext.containsName(bridgeDomainIndexCounter, ctx.getMappingContext())) { + bridgeDomainIndexCounter++; + } + index = bridgeDomainIndexCounter; + } + addOrUpdateBridgeDomain(id, index, dataBefore); + bdContext.addName(index, bdName, ctx.getMappingContext()); + } + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain dataBefore, + @Nonnull final WriteContext ctx) + throws WriteFailedException { + LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx); + final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); + + final com.google.common.base.Optional after = + ctx.readAfter(InstanceIdentifier.create(Interfaces.class)); + + if (after.isPresent()) { + checkReferenceExist(id, Optional.ofNullable(after.get().getInterface()) + .orElse(Collections.emptyList()) + .stream() + .map(iface -> Optional.ofNullable(iface.getAugmentation(VppInterfaceAugmentation.class)) + .map(VppInterfaceAugmentation::getL2) + .map(L2BaseAttributes::getInterconnection) + .orElse(null)) + .filter(interconnection -> interconnection instanceof BridgeBased) + .map(BridgeBased.class::cast) + .filter(bridgeBased -> bdName.equals(bridgeBased.getBridgeDomain())) + .collect(toList())); + } + + int bdId = bdContext.getIndex(bdName, ctx.getMappingContext()); + + final BridgeDomainAddDel request = new BridgeDomainAddDel(); + request.bdId = bdId; + + getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); + LOG.debug("Bridge domain {} (id={}) deleted successfully", bdName, bdId); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter, + @Nonnull final WriteContext ctx) + throws WriteFailedException { + LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter, + ctx); + + final String bdName = checkNotNull(dataAfter.getName()); + checkArgument(bdName.equals(dataBefore.getName()), + "BridgeDomain name changed. It should be deleted and then created."); + + addOrUpdateBridgeDomain(id, bdContext.getIndex(bdName, ctx.getMappingContext()), dataAfter); + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/L2FibEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/L2FibEntryCustomizer.java new file mode 100644 index 000000000..db2e0aef0 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2/L2FibEntryCustomizer.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.v3po.l2; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.primitives.Longs; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.L2FibAddDel; +import io.fd.vpp.jvpp.core.dto.L2FibAddDelReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.CompletionStage; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Writer Customizer responsible for L2 FIB create/delete operations.
Sends {@code l2_fib_add_del} message to + * VPP.
Equivalent of invoking {@code vppctl l2fib add/del} command. + */ +public class L2FibEntryCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer, ByteDataTranslator, MacTranslator, + JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class); + public static final int NO_INTERFACE_REF = -1; + + private final NamingContext bdContext; + private final NamingContext interfaceContext; + + public L2FibEntryCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext bdContext, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.bdContext = checkNotNull(bdContext, "bdContext should not be null"); + this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final L2FibEntry dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Creating L2 FIB entry: {} {}", id, dataAfter); + l2FibAddDel(id, dataAfter, writeContext, true); + LOG.debug("L2 FIB entry created successfully: {} {}", id, dataAfter); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final L2FibEntry dataBefore, @Nonnull final L2FibEntry dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException( + "L2 FIB entry update is not supported. It has to be deleted and then created."); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final L2FibEntry dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Deleting L2 FIB entry: {} {}", id, dataBefore); + l2FibAddDel(id, dataBefore, writeContext, false); + LOG.debug("L2 FIB entry deleted successfully: {} {}", id, dataBefore); + } + + private void l2FibAddDel(@Nonnull final InstanceIdentifier id, @Nonnull final L2FibEntry entry, + final WriteContext writeContext, boolean isAdd) throws WriteFailedException { + final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); + final MappingContext mappingContext = writeContext.getMappingContext(); + final int bdId = bdContext.getIndex(bdName, mappingContext); + + final L2FibAddDel l2FibRequest = createL2FibRequest(entry, bdId, getCheckedInterfaceIndex(entry, + mappingContext), isAdd); + LOG.debug("Sending l2FibAddDel request: {}", l2FibRequest); + final CompletionStage l2FibAddDelReplyCompletionStage = + getFutureJVpp().l2FibAddDel(l2FibRequest); + + getReplyForWrite(l2FibAddDelReplyCompletionStage.toCompletableFuture(), id); + } + + private int getCheckedInterfaceIndex(final L2FibEntry entry, final MappingContext mappingContext) { + if (L2FibFilter.class == entry.getAction()) { + // if filter, interface should not be defined + checkArgument(entry.getOutgoingInterface() == null, "Interface reference should not be defined for type %s", + L2FibFilter.class); + return NO_INTERFACE_REF; + } else { + // if type is not filter, interface reference is mandatory + return interfaceContext.getIndex( + checkNotNull(entry.getOutgoingInterface(), "Interface reference should be defined for type %s", + entry.getAction()), mappingContext); + } + } + + private L2FibAddDel createL2FibRequest(final L2FibEntry entry, final int bdId, final int swIfIndex, boolean isAdd) { + final L2FibAddDel request = new L2FibAddDel(); + request.mac = macToLong(entry.getPhysAddress().getValue()); + request.bdId = bdId; + request.swIfIndex = swIfIndex; + request.isAdd = booleanToByte(isAdd); + if (isAdd) { + request.staticMac = booleanToByte(entry.isStaticConfig()); + request.filterMac = booleanToByte(L2FibFilter.class == entry.getAction()); + } + return request; + } + + // mac address is string of the form: 11:22:33:44:55:66 + // but VPP expects long value in the format 11:22:33:44:55:66:XX:XX + private long macToLong(final String macAddress) { + final byte[] mac = parseMac(macAddress); + return Longs.fromBytes(mac[0], mac[1], mac[2], mac[3], + mac[4], mac[5], (byte) 0, (byte) 0); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2state/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2state/BridgeDomainCustomizer.java new file mode 100644 index 000000000..bf4222a77 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2state/BridgeDomainCustomizer.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.v3po.l2state; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.BridgeDomainDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.BridgeDomainsStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.state.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.state.BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.state.BridgeDomainKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class BridgeDomainCustomizer extends FutureJVppCustomizer + implements InitializingListReaderCustomizer, ByteDataTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); + private final NamingContext bdContext; + + public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore, + @Nonnull final NamingContext bdContext) { + super(futureJVppCore); + this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomainBuilder builder, @Nonnull final ReadContext context) + throws ReadFailedException { + LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: id={}, builderbuilder={}, context={}", + id, builder, context); + + final BridgeDomainKey key = id.firstKeyOf(id.getTargetType()); + LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: key={}", key); + + final int bdId = bdContext.getIndex(key.getName(), context.getMappingContext()); + LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: bdId={}", bdId); + + BridgeDomainDetailsReplyDump reply; + BridgeDomainDetails bridgeDomainDetails; + final BridgeDomainDump request = new BridgeDomainDump(); + request.bdId = bdContext.getIndex(key.getName(), context.getMappingContext()); + try { + reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get(); + bridgeDomainDetails = Iterables.getOnlyElement(reply.bridgeDomainDetails); + } catch (Exception e) { + LOG.debug("Unable to read bridge domain: {}", key.getName(), e); + return; + } + + logBridgeDomainDetails(bridgeDomainDetails); + + builder.setName(key.getName()); + builder.setArpTermination(byteToBoolean(bridgeDomainDetails.arpTerm)); + builder.setFlood(byteToBoolean(bridgeDomainDetails.flood)); + builder.setForward(byteToBoolean(bridgeDomainDetails.forward)); + builder.setLearn(byteToBoolean(bridgeDomainDetails.learn)); + builder.setUnknownUnicastFlood(byteToBoolean(bridgeDomainDetails.uuFlood)); + } + + private void logBridgeDomainDetails(final BridgeDomainDetails bridgeDomainDetails) { + LOG.debug("bridgeDomainDetails={}", bridgeDomainDetails); + if (bridgeDomainDetails != null) { + LOG.debug("bridgeDomainDetails.arpTerm={}", bridgeDomainDetails.arpTerm); + LOG.debug("bridgeDomainDetails.bdId={}", bridgeDomainDetails.bdId); + LOG.debug("bridgeDomainDetails.bviSwIfIndex={}", bridgeDomainDetails.bviSwIfIndex); + LOG.debug("bridgeDomainDetails.flood={}", bridgeDomainDetails.flood); + LOG.debug("bridgeDomainDetails.forward={}", bridgeDomainDetails.forward); + LOG.debug("bridgeDomainDetails.learn={}", bridgeDomainDetails.learn); + LOG.debug("bridgeDomainDetails.nSwIfs={}", bridgeDomainDetails.nSwIfs); + LOG.debug("bridgeDomainDetails.uuFlood={}", bridgeDomainDetails.uuFlood); + } + } + + @Nonnull + @Override + public BridgeDomainBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new BridgeDomainBuilder(); + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext context) throws ReadFailedException { + final BridgeDomainDump request = new BridgeDomainDump(); + request.bdId = -1; // dump call + + BridgeDomainDetailsReplyDump reply; + try { + reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get(); + } catch (Exception e) { + throw new ReadFailedException(id, e); + } + + if (reply == null || reply.bridgeDomainDetails == null) { + return Collections.emptyList(); + } + + final int bIdsLength = reply.bridgeDomainDetails.size(); + LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bIds.length={}", bIdsLength); + if (bIdsLength == 0) { + // No bridge domains + return Collections.emptyList(); + } + + final List allIds = new ArrayList<>(bIdsLength); + for (BridgeDomainDetails detail : reply.bridgeDomainDetails) { + logBridgeDomainDetails(detail); + + final String bName = bdContext.getName(detail.bdId, context.getMappingContext()); + LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bName={}", bName); + allIds.add(new BridgeDomainKey(bName)); + } + + return allIds; + } + + @Override + public void merge(@Nonnull final Builder builder, + @Nonnull final List readData) { + ((BridgeDomainsStateBuilder) builder).setBridgeDomain(readData); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.BridgeDomainBuilder() + .setName(readValue.getName()) + .setLearn(readValue.isLearn()) + .setUnknownUnicastFlood(readValue.isUnknownUnicastFlood()) + .setArpTermination(readValue.isArpTermination()) + .setFlood(readValue.isFlood()) + .setForward(readValue.isForward()) + .build()); + } + + static InstanceIdentifier getCfgId( + final InstanceIdentifier id) { + return InstanceIdentifier.create(BridgeDomains.class).child( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.BridgeDomain.class, + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.BridgeDomainKey( + id.firstKeyOf(BridgeDomain.class).getName())); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2state/L2FibEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2state/L2FibEntryCustomizer.java new file mode 100644 index 000000000..95188e5b1 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/l2state/L2FibEntryCustomizer.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.v3po.l2state; + +import com.google.common.base.Preconditions; +import com.google.common.primitives.Longs; +import io.fd.hc2vpp.v3po.interfacesstate.InterfaceDataTranslator; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.L2FibTableDump; +import io.fd.vpp.jvpp.core.dto.L2FibTableEntry; +import io.fd.vpp.jvpp.core.dto.L2FibTableEntryReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibForward; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.state.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domains.state.BridgeDomainKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class L2FibEntryCustomizer extends FutureJVppCustomizer + implements InitializingListReaderCustomizer, ByteDataTranslator, + InterfaceDataTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class); + + private static final Collector SINGLE_ITEM_COLLECTOR = + RWUtils.singleItemCollector(); + + private final NamingContext bdContext; + private final NamingContext interfaceContext; + + public L2FibEntryCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext bdContext, + @Nonnull final NamingContext interfaceContext) { + super(futureJVppCore); + this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); + this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final L2FibEntryBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + + final L2FibEntryKey key = id.firstKeyOf(id.getTargetType()); + final BridgeDomainKey bridgeDomainKey = id.firstKeyOf(BridgeDomain.class); + final int bdId = bdContext.getIndex(bridgeDomainKey.getName(), ctx.getMappingContext()); + LOG.debug("Reading L2 FIB entry: key={}. bridgeDomainKey={}, bdId={}", key, bridgeDomainKey, bdId); + + try { + // TODO HONEYCOMB-186 use cached l2FibTable + final L2FibTableEntry entry = dumpL2Fibs(id, bdId).stream().filter(e -> key.getPhysAddress() + .equals(new PhysAddress(vppPhysAddrToYang(Longs.toByteArray(e.mac), 2)))) + .collect(SINGLE_ITEM_COLLECTOR); + + builder.setAction(byteToBoolean(entry.filterMac) + ? L2FibFilter.class + : L2FibForward.class); + builder.setBridgedVirtualInterface(byteToBoolean(entry.bviMac)); + + if (entry.swIfIndex != -1) { + builder.setOutgoingInterface(interfaceContext.getName(entry.swIfIndex, ctx.getMappingContext())); + } + builder.setStaticConfig(byteToBoolean(entry.staticMac)); + builder.setPhysAddress(key.getPhysAddress()); + builder.setKey(key); + } catch (Exception e) { + throw new ReadFailedException(id, e); + } + } + + @Nonnull + private List dumpL2Fibs(final InstanceIdentifier id, final int bdId) + throws ReadFailedException { + final L2FibTableDump l2FibRequest = new L2FibTableDump(); + l2FibRequest.bdId = bdId; + + final CompletableFuture l2FibTableDumpCompletableFuture = + getFutureJVpp().l2FibTableDump(l2FibRequest).toCompletableFuture(); + + final L2FibTableEntryReplyDump dump = getReplyForRead(l2FibTableDumpCompletableFuture, id); + + if (null == dump || null == dump.l2FibTableEntry) { + return Collections.emptyList(); + } else { + return dump.l2FibTableEntry; + } + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext ctx) throws ReadFailedException { + final BridgeDomainKey bridgeDomainKey = id.firstKeyOf(BridgeDomain.class); + final int bdId = bdContext.getIndex(bridgeDomainKey.getName(), ctx.getMappingContext()); + + LOG.debug("Reading L2 FIB for bridge domain {} (bdId={})", bridgeDomainKey, bdId); + return dumpL2Fibs(id, bdId).stream() + .map(entry -> new L2FibEntryKey( + new PhysAddress(vppPhysAddrToYang(Longs.toByteArray(entry.mac), 2)))) + .collect(Collectors.toList()); + } + + @Override + public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { + ((L2FibTableBuilder) builder).setL2FibEntry(readData); + } + + @Nonnull + @Override + public L2FibEntryBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new L2FibEntryBuilder(); + } + + @Override + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final L2FibEntry readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(getCfgId(id), + // Convert operational object to config. VPP does not support setting BVI (see v3po.yang) + new L2FibEntryBuilder(readValue).setBridgedVirtualInterface(null).build()); + } + + static InstanceIdentifier getCfgId( + final @Nonnull InstanceIdentifier id) { + return BridgeDomainCustomizer.getCfgId(RWUtils.cutId(id, BridgeDomain.class)).child( + L2FibTable.class).child(L2FibEntry.class, new L2FibEntryKey(id.firstKeyOf(L2FibEntry.class))); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/rpc/CliInbandService.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/rpc/CliInbandService.java deleted file mode 100644 index 7128d06bc..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/rpc/CliInbandService.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.hc2vpp.v3po.rpc; - -import com.google.inject.Inject; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.honeycomb.rpc.RpcService; -import io.fd.vpp.jvpp.core.dto.CliInband; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.nio.charset.StandardCharsets; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.CliInbandInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.CliInbandOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.CliInbandOutputBuilder; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; - -public class CliInbandService implements RpcService, JvppReplyConsumer { - - private final FutureJVppCore jvpp; - private static final String localName = "cli-inband"; - private static final QName name = QName.create(CliInbandInput.QNAME, localName); - private static final SchemaPath schemaPath = SchemaPath.ROOT.createChild(name); - - @Inject - public CliInbandService(@Nonnull final FutureJVppCore jvpp) { - this.jvpp = jvpp; - } - - @Override - @Nonnull - public CompletionStage invoke(@Nonnull final CliInbandInput input) { - final CliInband request = new CliInband(); - request.cmd = input.getCmd().getBytes(StandardCharsets.UTF_8); - request.length = request.cmd.length; - return jvpp.cliInband(request) - .thenApply( - reply -> new CliInbandOutputBuilder().setReply(new String(reply.reply)).build() - ); - } - - @Nonnull - @Override - public SchemaPath getManagedNode() { - return schemaPath; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizer.java deleted file mode 100644 index 2b9f59209..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/ArpTerminationTableEntryCustomizer.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.hc2vpp.v3po.vpp; - -import com.google.common.base.Preconditions; -import io.fd.hc2vpp.common.translate.util.AddressTranslator; -import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.BdIpMacAddDel; -import io.fd.vpp.jvpp.core.dto.BdIpMacAddDelReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.bridge.domain.attributes.arp.termination.table.ArpTerminationTableEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer Customizer responsible for ARP termination table management.
Sends {@code bd_ip_mac_add_del} message to - * VPP.
Equivalent of invoking {@code vppctl set bridge-domain arp term} command. - */ -public class ArpTerminationTableEntryCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer, ByteDataTranslator, - AddressTranslator, JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(ArpTerminationTableEntryCustomizer.class); - - private final NamingContext bdContext; - - public ArpTerminationTableEntryCustomizer(@Nonnull final FutureJVppCore futureJvpp, - @Nonnull final NamingContext bdContext) { - super(futureJvpp); - this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ArpTerminationTableEntry dataAfter, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Creating ARP termination table entry: {} {}", id, dataAfter); - bdIpMacAddDel(id, dataAfter, writeContext, true); - LOG.debug("L2 ARP termination table entry created successfully: {} {}", id, dataAfter); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ArpTerminationTableEntry dataBefore, - @Nonnull final ArpTerminationTableEntry dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - throw new UnsupportedOperationException( - "ARP termination table entry update is not supported. It has to be deleted and then created."); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final ArpTerminationTableEntry dataBefore, - @Nonnull final WriteContext writeContext) - throws WriteFailedException { - LOG.debug("Deleting ARP termination table entry entry: {} {}", id, dataBefore); - bdIpMacAddDel(id, dataBefore, writeContext, false); - LOG.debug("ARP termination table entry deleted successfully: {} {}", id, dataBefore); - } - - private void bdIpMacAddDel(@Nonnull final InstanceIdentifier id, - @Nonnull final ArpTerminationTableEntry entry, - final WriteContext writeContext, boolean isAdd) throws WriteFailedException { - final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); - final int bdId = bdContext.getIndex(bdName, writeContext.getMappingContext()); - - final BdIpMacAddDel request = createRequest(entry, bdId, isAdd); - LOG.debug("Sending l2FibAddDel request: {}", request); - final CompletionStage replyCompletionStage = - getFutureJVpp().bdIpMacAddDel(request); - - getReplyForWrite(replyCompletionStage.toCompletableFuture(), id); - } - - private BdIpMacAddDel createRequest(final ArpTerminationTableEntry entry, final int bdId, boolean isAdd) { - final BdIpMacAddDel request = new BdIpMacAddDel(); - request.bdId = bdId; - request.isAdd = booleanToByte(isAdd); - request.macAddress = parseMac(entry.getPhysAddress().getValue()); - - final IpAddress ipAddress = entry.getIpAddress(); - - request.ipAddress = ipAddressToArray(ipAddress); - request.isIpv6 = booleanToByte(isIpv6(ipAddress)); - - return request; - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizer.java deleted file mode 100644 index 2962ec578..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/BridgeDomainCustomizer.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.hc2vpp.v3po.vpp; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static java.util.stream.Collectors.toList; - -import com.google.common.base.Preconditions; -import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.hc2vpp.common.translate.util.ReferenceCheck; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDel; -import io.fd.vpp.jvpp.core.dto.BridgeDomainAddDelReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Collections; -import java.util.Optional; -import javax.annotation.Nonnull; -import javax.annotation.concurrent.GuardedBy; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2BaseAttributes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.base.attributes.interconnection.BridgeBased; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class BridgeDomainCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer, ByteDataTranslator, JvppReplyConsumer, - ReferenceCheck { - - private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); - - private static final byte ADD_OR_UPDATE_BD = (byte) 1; - private final NamingContext bdContext; - @GuardedBy("this") - private int bridgeDomainIndexCounter = 1; - - public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext bdContext) { - super(futureJVppCore); - this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); - } - - private BridgeDomainAddDelReply addOrUpdateBridgeDomain(@Nonnull final InstanceIdentifier id, - final int bdId, @Nonnull final BridgeDomain bd) - throws WriteFailedException { - final BridgeDomainAddDelReply reply; - final BridgeDomainAddDel request = new BridgeDomainAddDel(); - request.bdId = bdId; - request.flood = booleanToByte(bd.isFlood()); - request.forward = booleanToByte(bd.isForward()); - request.learn = booleanToByte(bd.isLearn()); - request.uuFlood = booleanToByte(bd.isUnknownUnicastFlood()); - request.arpTerm = booleanToByte(bd.isArpTermination()); - request.isAdd = ADD_OR_UPDATE_BD; - - reply = getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); - LOG.debug("Bridge domain {} (id={}) add/update successful", bd.getName(), bdId); - return reply; - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain dataBefore, - @Nonnull final WriteContext ctx) - throws WriteFailedException { - LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, dataBefore, ctx); - final String bdName = dataBefore.getName(); - - // Invoke 1. check index, 2. increase index 3. create ND 4. store mapping in a synchronized block to prevent - // race conditions in case of concurrent invocation - synchronized (this) { - int index; - if (bdContext.containsIndex(bdName, ctx.getMappingContext())) { - index = bdContext.getIndex(bdName, ctx.getMappingContext()); - } else { - // Critical section due to bridgeDomainIndexCounter read and write access - // TODO HONEYCOMB-199 move this "get next available index" into naming context or an adapter - // or a dedicated object - - // Use counter to assign bridge domain index, but still check naming context if it's not taken there - while (bdContext.containsName(bridgeDomainIndexCounter, ctx.getMappingContext())) { - bridgeDomainIndexCounter++; - } - index = bridgeDomainIndexCounter; - } - addOrUpdateBridgeDomain(id, index, dataBefore); - bdContext.addName(index, bdName, ctx.getMappingContext()); - } - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain dataBefore, - @Nonnull final WriteContext ctx) - throws WriteFailedException { - LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx); - final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); - - final com.google.common.base.Optional after = - ctx.readAfter(InstanceIdentifier.create(Interfaces.class)); - - if (after.isPresent()) { - checkReferenceExist(id, Optional.ofNullable(after.get().getInterface()) - .orElse(Collections.emptyList()) - .stream() - .map(iface -> Optional.ofNullable(iface.getAugmentation(VppInterfaceAugmentation.class)) - .map(VppInterfaceAugmentation::getL2) - .map(L2BaseAttributes::getInterconnection) - .orElse(null)) - .filter(interconnection -> interconnection instanceof BridgeBased) - .map(BridgeBased.class::cast) - .filter(bridgeBased -> bdName.equals(bridgeBased.getBridgeDomain())) - .collect(toList())); - } - - int bdId = bdContext.getIndex(bdName, ctx.getMappingContext()); - - final BridgeDomainAddDel request = new BridgeDomainAddDel(); - request.bdId = bdId; - - getReplyForWrite(getFutureJVpp().bridgeDomainAddDel(request).toCompletableFuture(), id); - LOG.debug("Bridge domain {} (id={}) deleted successfully", bdName, bdId); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter, - @Nonnull final WriteContext ctx) - throws WriteFailedException { - LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter, - ctx); - - final String bdName = checkNotNull(dataAfter.getName()); - checkArgument(bdName.equals(dataBefore.getName()), - "BridgeDomain name changed. It should be deleted and then created."); - - addOrUpdateBridgeDomain(id, bdContext.getIndex(bdName, ctx.getMappingContext()), dataAfter); - } - -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java deleted file mode 100644 index 0eced8237..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vpp/L2FibEntryCustomizer.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.hc2vpp.v3po.vpp; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.primitives.Longs; -import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.MacTranslator; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.L2FibAddDel; -import io.fd.vpp.jvpp.core.dto.L2FibAddDelReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Writer Customizer responsible for L2 FIB create/delete operations.
Sends {@code l2_fib_add_del} message to - * VPP.
Equivalent of invoking {@code vppctl l2fib add/del} command. - */ -public class L2FibEntryCustomizer extends FutureJVppCustomizer - implements ListWriterCustomizer, ByteDataTranslator, MacTranslator, - JvppReplyConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class); - public static final int NO_INTERFACE_REF = -1; - - private final NamingContext bdContext; - private final NamingContext interfaceContext; - - public L2FibEntryCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext bdContext, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.bdContext = checkNotNull(bdContext, "bdContext should not be null"); - this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final L2FibEntry dataAfter, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - - LOG.debug("Creating L2 FIB entry: {} {}", id, dataAfter); - l2FibAddDel(id, dataAfter, writeContext, true); - LOG.debug("L2 FIB entry created successfully: {} {}", id, dataAfter); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final L2FibEntry dataBefore, @Nonnull final L2FibEntry dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - throw new UnsupportedOperationException( - "L2 FIB entry update is not supported. It has to be deleted and then created."); - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final L2FibEntry dataBefore, @Nonnull final WriteContext writeContext) - throws WriteFailedException { - - LOG.debug("Deleting L2 FIB entry: {} {}", id, dataBefore); - l2FibAddDel(id, dataBefore, writeContext, false); - LOG.debug("L2 FIB entry deleted successfully: {} {}", id, dataBefore); - } - - private void l2FibAddDel(@Nonnull final InstanceIdentifier id, @Nonnull final L2FibEntry entry, - final WriteContext writeContext, boolean isAdd) throws WriteFailedException { - final String bdName = id.firstKeyOf(BridgeDomain.class).getName(); - final MappingContext mappingContext = writeContext.getMappingContext(); - final int bdId = bdContext.getIndex(bdName, mappingContext); - - final L2FibAddDel l2FibRequest = createL2FibRequest(entry, bdId, getCheckedInterfaceIndex(entry, - mappingContext), isAdd); - LOG.debug("Sending l2FibAddDel request: {}", l2FibRequest); - final CompletionStage l2FibAddDelReplyCompletionStage = - getFutureJVpp().l2FibAddDel(l2FibRequest); - - getReplyForWrite(l2FibAddDelReplyCompletionStage.toCompletableFuture(), id); - } - - private int getCheckedInterfaceIndex(final L2FibEntry entry, final MappingContext mappingContext) { - if (L2FibFilter.class == entry.getAction()) { - // if filter, interface should not be defined - checkArgument(entry.getOutgoingInterface() == null, "Interface reference should not be defined for type %s", - L2FibFilter.class); - return NO_INTERFACE_REF; - } else { - // if type is not filter, interface reference is mandatory - return interfaceContext.getIndex( - checkNotNull(entry.getOutgoingInterface(), "Interface reference should be defined for type %s", - entry.getAction()), mappingContext); - } - } - - private L2FibAddDel createL2FibRequest(final L2FibEntry entry, final int bdId, final int swIfIndex, boolean isAdd) { - final L2FibAddDel request = new L2FibAddDel(); - request.mac = macToLong(entry.getPhysAddress().getValue()); - request.bdId = bdId; - request.swIfIndex = swIfIndex; - request.isAdd = booleanToByte(isAdd); - if (isAdd) { - request.staticMac = booleanToByte(entry.isStaticConfig()); - request.filterMac = booleanToByte(L2FibFilter.class == entry.getAction()); - } - return request; - } - - // mac address is string of the form: 11:22:33:44:55:66 - // but VPP expects long value in the format 11:22:33:44:55:66:XX:XX - private long macToLong(final String macAddress) { - final byte[] mac = parseMac(macAddress); - return Longs.fromBytes(mac[0], mac[1], mac[2], mac[3], - mac[4], mac[5], (byte) 0, (byte) 0); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizer.java deleted file mode 100644 index e6f3bbb49..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/BridgeDomainCustomizer.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.hc2vpp.v3po.vppstate; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Iterables; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.Initialized; -import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; -import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDetails; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump; -import io.fd.vpp.jvpp.core.dto.BridgeDomainDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.Vpp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.BridgeDomainsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class BridgeDomainCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer, ByteDataTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); - private final NamingContext bdContext; - - public BridgeDomainCustomizer(@Nonnull final FutureJVppCore futureJVppCore, - @Nonnull final NamingContext bdContext) { - super(futureJVppCore); - this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomainBuilder builder, @Nonnull final ReadContext context) - throws ReadFailedException { - LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: id={}, builderbuilder={}, context={}", - id, builder, context); - - final BridgeDomainKey key = id.firstKeyOf(id.getTargetType()); - LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: key={}", key); - - final int bdId = bdContext.getIndex(key.getName(), context.getMappingContext()); - LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: bdId={}", bdId); - - BridgeDomainDetailsReplyDump reply; - BridgeDomainDetails bridgeDomainDetails; - final BridgeDomainDump request = new BridgeDomainDump(); - request.bdId = bdContext.getIndex(key.getName(), context.getMappingContext()); - try { - reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get(); - bridgeDomainDetails = Iterables.getOnlyElement(reply.bridgeDomainDetails); - } catch (Exception e) { - LOG.debug("Unable to read bridge domain: {}", key.getName(), e); - return; - } - - logBridgeDomainDetails(bridgeDomainDetails); - - builder.setName(key.getName()); - builder.setArpTermination(byteToBoolean(bridgeDomainDetails.arpTerm)); - builder.setFlood(byteToBoolean(bridgeDomainDetails.flood)); - builder.setForward(byteToBoolean(bridgeDomainDetails.forward)); - builder.setLearn(byteToBoolean(bridgeDomainDetails.learn)); - builder.setUnknownUnicastFlood(byteToBoolean(bridgeDomainDetails.uuFlood)); - } - - private void logBridgeDomainDetails(final BridgeDomainDetails bridgeDomainDetails) { - LOG.debug("bridgeDomainDetails={}", bridgeDomainDetails); - if (bridgeDomainDetails != null) { - LOG.debug("bridgeDomainDetails.arpTerm={}", bridgeDomainDetails.arpTerm); - LOG.debug("bridgeDomainDetails.bdId={}", bridgeDomainDetails.bdId); - LOG.debug("bridgeDomainDetails.bviSwIfIndex={}", bridgeDomainDetails.bviSwIfIndex); - LOG.debug("bridgeDomainDetails.flood={}", bridgeDomainDetails.flood); - LOG.debug("bridgeDomainDetails.forward={}", bridgeDomainDetails.forward); - LOG.debug("bridgeDomainDetails.learn={}", bridgeDomainDetails.learn); - LOG.debug("bridgeDomainDetails.nSwIfs={}", bridgeDomainDetails.nSwIfs); - LOG.debug("bridgeDomainDetails.uuFlood={}", bridgeDomainDetails.uuFlood); - } - } - - @Nonnull - @Override - public BridgeDomainBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new BridgeDomainBuilder(); - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext context) throws ReadFailedException { - final BridgeDomainDump request = new BridgeDomainDump(); - request.bdId = -1; // dump call - - BridgeDomainDetailsReplyDump reply; - try { - reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get(); - } catch (Exception e) { - throw new ReadFailedException(id, e); - } - - if (reply == null || reply.bridgeDomainDetails == null) { - return Collections.emptyList(); - } - - final int bIdsLength = reply.bridgeDomainDetails.size(); - LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bIds.length={}", bIdsLength); - if (bIdsLength == 0) { - // No bridge domains - return Collections.emptyList(); - } - - final List allIds = new ArrayList<>(bIdsLength); - for (BridgeDomainDetails detail : reply.bridgeDomainDetails) { - logBridgeDomainDetails(detail); - - final String bName = bdContext.getName(detail.bdId, context.getMappingContext()); - LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bName={}", bName); - allIds.add(new BridgeDomainKey(bName)); - } - - return allIds; - } - - @Override - public void merge(@Nonnull final Builder builder, - @Nonnull final List readData) { - ((BridgeDomainsBuilder) builder).setBridgeDomain(readData); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainBuilder() - .setName(readValue.getName()) - .setLearn(readValue.isLearn()) - .setUnknownUnicastFlood(readValue.isUnknownUnicastFlood()) - .setArpTermination(readValue.isArpTermination()) - .setFlood(readValue.isFlood()) - .setForward(readValue.isForward()) - .build()); - } - - static InstanceIdentifier getCfgId( - final InstanceIdentifier id) { - return InstanceIdentifier.create(Vpp.class).child(BridgeDomains.class).child( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomain.class, - new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.bridge.domains.BridgeDomainKey( - id.firstKeyOf(BridgeDomain.class).getName())); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizer.java deleted file mode 100644 index 2605293c5..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/L2FibEntryCustomizer.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.hc2vpp.v3po.vppstate; - -import com.google.common.base.Preconditions; -import com.google.common.primitives.Longs; -import io.fd.hc2vpp.v3po.interfacesstate.InterfaceDataTranslator; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.Initialized; -import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; -import io.fd.honeycomb.translate.util.RWUtils; -import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.vpp.jvpp.core.dto.L2FibTableDump; -import io.fd.vpp.jvpp.core.dto.L2FibTableEntry; -import io.fd.vpp.jvpp.core.dto.L2FibTableEntryReplyDump; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibFilter; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.L2FibForward; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.L2FibTableBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.l2.fib.attributes.l2.fib.table.L2FibEntryKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class L2FibEntryCustomizer extends FutureJVppCustomizer - implements InitializingListReaderCustomizer, ByteDataTranslator, - InterfaceDataTranslator { - - private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class); - - private static final Collector SINGLE_ITEM_COLLECTOR = - RWUtils.singleItemCollector(); - - private final NamingContext bdContext; - private final NamingContext interfaceContext; - - public L2FibEntryCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext bdContext, - @Nonnull final NamingContext interfaceContext) { - super(futureJVppCore); - this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null"); - this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null"); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final L2FibEntryBuilder builder, @Nonnull final ReadContext ctx) - throws ReadFailedException { - - final L2FibEntryKey key = id.firstKeyOf(id.getTargetType()); - final BridgeDomainKey bridgeDomainKey = id.firstKeyOf(BridgeDomain.class); - final int bdId = bdContext.getIndex(bridgeDomainKey.getName(), ctx.getMappingContext()); - LOG.debug("Reading L2 FIB entry: key={}. bridgeDomainKey={}, bdId={}", key, bridgeDomainKey, bdId); - - try { - // TODO HONEYCOMB-186 use cached l2FibTable - final L2FibTableEntry entry = dumpL2Fibs(id, bdId).stream().filter(e -> key.getPhysAddress() - .equals(new PhysAddress(vppPhysAddrToYang(Longs.toByteArray(e.mac), 2)))) - .collect(SINGLE_ITEM_COLLECTOR); - - builder.setAction(byteToBoolean(entry.filterMac) - ? L2FibFilter.class - : L2FibForward.class); - builder.setBridgedVirtualInterface(byteToBoolean(entry.bviMac)); - - if (entry.swIfIndex != -1) { - builder.setOutgoingInterface(interfaceContext.getName(entry.swIfIndex, ctx.getMappingContext())); - } - builder.setStaticConfig(byteToBoolean(entry.staticMac)); - builder.setPhysAddress(key.getPhysAddress()); - builder.setKey(key); - } catch (Exception e) { - throw new ReadFailedException(id, e); - } - } - - @Nonnull - private List dumpL2Fibs(final InstanceIdentifier id, final int bdId) - throws ReadFailedException { - final L2FibTableDump l2FibRequest = new L2FibTableDump(); - l2FibRequest.bdId = bdId; - - final CompletableFuture l2FibTableDumpCompletableFuture = - getFutureJVpp().l2FibTableDump(l2FibRequest).toCompletableFuture(); - - final L2FibTableEntryReplyDump dump = getReplyForRead(l2FibTableDumpCompletableFuture, id); - - if (null == dump || null == dump.l2FibTableEntry) { - return Collections.emptyList(); - } else { - return dump.l2FibTableEntry; - } - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext ctx) throws ReadFailedException { - final BridgeDomainKey bridgeDomainKey = id.firstKeyOf(BridgeDomain.class); - final int bdId = bdContext.getIndex(bridgeDomainKey.getName(), ctx.getMappingContext()); - - LOG.debug("Reading L2 FIB for bridge domain {} (bdId={})", bridgeDomainKey, bdId); - return dumpL2Fibs(id, bdId).stream() - .map(entry -> new L2FibEntryKey( - new PhysAddress(vppPhysAddrToYang(Longs.toByteArray(entry.mac), 2)))) - .collect(Collectors.toList()); - } - - @Override - public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { - ((L2FibTableBuilder) builder).setL2FibEntry(readData); - } - - @Nonnull - @Override - public L2FibEntryBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new L2FibEntryBuilder(); - } - - @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final L2FibEntry readValue, - @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), - // Convert operational object to config. VPP does not support setting BVI (see v3po.yang) - new L2FibEntryBuilder(readValue).setBridgedVirtualInterface(null).build()); - } - - static InstanceIdentifier getCfgId( - final @Nonnull InstanceIdentifier id) { - return BridgeDomainCustomizer.getCfgId(RWUtils.cutId(id, BridgeDomain.class)).child( - L2FibTable.class).child(L2FibEntry.class, new L2FibEntryKey(id.firstKeyOf(L2FibEntry.class))); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizer.java deleted file mode 100644 index 3f69c98df..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/vppstate/VersionCustomizer.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.hc2vpp.v3po.vppstate; - -import com.google.common.primitives.UnsignedInts; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; -import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.vpp.jvpp.core.dto.ShowVersion; -import io.fd.vpp.jvpp.core.dto.ShowVersionReply; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import io.fd.vpp.jvpp.dto.ControlPing; -import io.fd.vpp.jvpp.dto.ControlPingReply; -import io.fd.vpp.jvpp.dto.JVppReply; -import java.util.concurrent.CompletionStage; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev161214.vpp.state.VersionBuilder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class VersionCustomizer - extends FutureJVppCustomizer - implements ReaderCustomizer, ByteDataTranslator, JvppReplyConsumer { - - public VersionCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { - super(futureJVppCore); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Version readValue) { - ((VppStateBuilder) parentBuilder).setVersion(readValue); - } - - @Nonnull - @Override - public VersionBuilder getBuilder(@Nonnull InstanceIdentifier id) { - return new VersionBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final VersionBuilder builder, - @Nonnull final ReadContext context) throws ReadFailedException { - - // Execute with timeout - final CompletionStage showVersionFuture = getFutureJVpp().showVersion(new ShowVersion()); - final ShowVersionReply reply = getReplyForRead(showVersionFuture.toCompletableFuture(), id); - - builder.setBranch(toString(reply.version)); - builder.setName(toString(reply.program)); - builder.setBuildDate(toString(reply.buildDate)); - builder.setBuildDirectory(toString(reply.buildDirectory)); - builder.setPid(getPid(id)); - } - - private Long getPid(@Nonnull final InstanceIdentifier id) throws ReadFailedException { - final CompletionStage> request = getFutureJVpp().send(new ControlPing()); - final ControlPingReply reply = (ControlPingReply)getReplyForRead(request.toCompletableFuture(), id); - return UnsignedInts.toLong(reply.vpePid); - } - - -} -- cgit 1.2.3-korg