From fd56a7403e572d9cf31b0e8623ada3ae4cf7e3cc Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Thu, 3 Nov 2016 08:25:47 +0100 Subject: HONEYCOMB-285 - Cache scope for sub-interface addresses Same as for interface addresses, these addresses must have caching scope of their parent sub-interface Change-Id: I31a8d123e02a99e592181c198f69a34b0be910e5 Signed-off-by: Jan Srnicek --- .../ip/SubInterfaceIpv4AddressCustomizer.java | 4 + .../ip/SubInterfaceIpv4AddressCustomizerTest.java | 127 +++++++++++++++++++-- 2 files changed, 122 insertions(+), 9 deletions(-) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java index a445c3f55..e18de5581 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizer.java @@ -19,12 +19,14 @@ package io.fd.honeycomb.translate.v3po.interfacesstate.ip; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; 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.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; import io.fd.honeycomb.translate.v3po.interfacesstate.SubInterfaceCustomizer; import io.fd.honeycomb.translate.v3po.interfacesstate.ip.dump.params.AddressDumpParams; import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer; @@ -66,6 +68,8 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder() .withExecutor(createExecutor(futureJVppCore)) + //same as with ipv4 addresses for interfaces, these must have cache scope of their parent sub-interface + .withCacheKeyFactory(new IdentifierCacheKeyFactory(ImmutableSet.of(SubInterface.class))) .build(); } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java index a3e80e9d7..9a9346a5a 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/SubInterfaceIpv4AddressCustomizerTest.java @@ -18,18 +18,31 @@ package io.fd.honeycomb.translate.v3po.interfacesstate.ip; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.google.common.collect.ImmutableSet; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.util.read.cache.CacheKeyFactory; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; +import io.fd.honeycomb.translate.vpp.util.Ipv4Translator; import io.fd.honeycomb.translate.vpp.util.NamingContext; import io.fd.honeycomb.vpp.test.read.ListReaderCustomizerTest; +import io.fd.vpp.jvpp.core.dto.IpAddressDetails; +import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; +import java.util.Arrays; import java.util.List; +import org.junit.Assert; import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; @@ -43,24 +56,29 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.AddressKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLengthBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.dto.IpAddressDetails; -import io.fd.vpp.jvpp.core.dto.IpAddressDetailsReplyDump; -public class SubInterfaceIpv4AddressCustomizerTest extends ListReaderCustomizerTest { +public class SubInterfaceIpv4AddressCustomizerTest extends ListReaderCustomizerTest + implements Ipv4Translator { private static final String IFC_CTX_NAME = "ifc-test-instance"; private static final String IF_NAME = "local0"; private static final int IF_INDEX = 1; private static final String SUB_IF_NAME = "local0.1"; + private static final String SUB_IF_2_NAME = "local0.2"; private static final long SUB_IF_ID = 1; private static final int SUB_IF_INDEX = 11; + private static final int SUB_IF_2_INDEX = 12; private static final InstanceIdentifier IP4_IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(SubinterfaceStateAugmentation.class) - .child(SubInterfaces.class).child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)) - .child(Ipv4.class); + InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(SubinterfaceStateAugmentation.class) + .child(SubInterfaces.class).child(SubInterface.class, new SubInterfaceKey(SUB_IF_ID)) + .child(Ipv4.class); + private InstanceIdentifier
ifaceOneAddressOneIdentifier; + private InstanceIdentifier
ifaceTwoAddressOneIdentifier; + private CacheKeyFactory cacheKeyFactory; private static final Ipv4AddressNoZone IP1 = new Ipv4AddressNoZone("10.1.1.1"); private static final Ipv4AddressNoZone IP2 = new Ipv4AddressNoZone("10.1.1.2"); private static final short PREFIX_LENGTH = 16; @@ -74,8 +92,28 @@ public class SubInterfaceIpv4AddressCustomizerTest extends ListReaderCustomizerT @Override protected void setUp() throws Exception { interfaceContext = new NamingContext("generatedIfaceName", IFC_CTX_NAME); + + ifaceOneAddressOneIdentifier = InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(SubinterfaceStateAugmentation.class) + .child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(1L)) + .child(Ipv4.class) + .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); + ifaceTwoAddressOneIdentifier = InstanceIdentifier.create(InterfacesState.class) + .child(Interface.class, new InterfaceKey(IF_NAME)) + .augmentation(SubinterfaceStateAugmentation.class) + .child(SubInterfaces.class) + .child(SubInterface.class, new SubInterfaceKey(2L)) + .child(Ipv4.class) + .child(Address.class, new AddressKey(new Ipv4AddressNoZone("192.168.2.1"))); + + // to simulate complex key + cacheKeyFactory = new IdentifierCacheKeyFactory(ImmutableSet.of(SubInterface.class)); + defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_CTX_NAME); defineMapping(mappingContext, SUB_IF_NAME, SUB_IF_INDEX, IFC_CTX_NAME); + defineMapping(mappingContext, SUB_IF_2_NAME, SUB_IF_2_INDEX, IFC_CTX_NAME); } @Override @@ -120,16 +158,87 @@ public class SubInterfaceIpv4AddressCustomizerTest extends ListReaderCustomizerT getCustomizer().getAllIds(getId(), ctx); } + @Test + public void testCacheScope() { + + } + + @Test + public void testCachingScopeSpecificRequest() throws ReadFailedException { + fillCacheForTwoIfaces(); + final AddressBuilder ifaceOneAddressBuilder = new AddressBuilder(); + final AddressBuilder ifaceTwoAddressBuilder = new AddressBuilder(); + + getCustomizer().readCurrentAttributes(ifaceOneAddressOneIdentifier, ifaceOneAddressBuilder, ctx); + getCustomizer().readCurrentAttributes(ifaceTwoAddressOneIdentifier, ifaceTwoAddressBuilder, ctx); + + // addresses have caching scope of parent interface, so returned address should have respective prefix lengths + assertEquals("192.168.2.1", ifaceOneAddressBuilder.getIp().getValue()); + assertTrue(ifaceOneAddressBuilder.getSubnet() instanceof PrefixLength); + assertEquals(22, PrefixLength.class.cast(ifaceOneAddressBuilder.getSubnet()).getPrefixLength().intValue()); + + assertEquals("192.168.2.1", ifaceTwoAddressBuilder.getIp().getValue()); + assertTrue(ifaceTwoAddressBuilder.getSubnet() instanceof PrefixLength); + assertEquals(23, PrefixLength.class.cast(ifaceTwoAddressBuilder.getSubnet()).getPrefixLength().intValue()); + } + + @Test + public void testCachingScopeGetAll() throws ReadFailedException { + fillCacheForFirstIfaceSecondEmpty(); + + final List keysForIfaceOne = getCustomizer().getAllIds(ifaceOneAddressOneIdentifier, ctx); + Assert.assertThat(keysForIfaceOne, hasSize(1)); + final AddressKey keyIfaceOne = keysForIfaceOne.get(0); + assertEquals("192.168.2.1", keyIfaceOne.getIp().getValue()); + + final List keysForIfaceTwo = getCustomizer().getAllIds(ifaceTwoAddressOneIdentifier, ctx); + Assert.assertThat(keysForIfaceTwo, is(empty())); + } + + private void fillCacheForTwoIfaces() { + IpAddressDetails detailIfaceOneAddressOne = new IpAddressDetails(); + IpAddressDetails detailIfaceTwoAddressOne = new IpAddressDetails(); + IpAddressDetailsReplyDump replyIfaceOne = new IpAddressDetailsReplyDump(); + IpAddressDetailsReplyDump replyIfaceTwo = new IpAddressDetailsReplyDump(); + + replyIfaceOne.ipAddressDetails = Arrays.asList(detailIfaceOneAddressOne); + replyIfaceTwo.ipAddressDetails = Arrays.asList(detailIfaceTwoAddressOne); + + detailIfaceOneAddressOne.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detailIfaceOneAddressOne.prefixLength = 22; + + detailIfaceTwoAddressOne.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detailIfaceTwoAddressOne.prefixLength = 23; + + cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); + cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), replyIfaceTwo); + } + + private void fillCacheForFirstIfaceSecondEmpty() { + IpAddressDetails detailIfaceOneAddressOne = new IpAddressDetails(); + IpAddressDetailsReplyDump replyIfaceOne = new IpAddressDetailsReplyDump(); + replyIfaceOne.ipAddressDetails = Arrays.asList(detailIfaceOneAddressOne); + + detailIfaceOneAddressOne.ip = reverseBytes( + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1")))); + detailIfaceOneAddressOne.prefixLength = 22; + + cache.put(cacheKeyFactory.createKey(ifaceOneAddressOneIdentifier), replyIfaceOne); + cache.put(cacheKeyFactory.createKey(ifaceTwoAddressOneIdentifier), new IpAddressDetailsReplyDump()); + } + private IpAddressDetailsReplyDump dump() { final IpAddressDetailsReplyDump reply = new IpAddressDetailsReplyDump(); final IpAddressDetails details1 = new IpAddressDetails(); - details1.ip = new byte[] {1, 1, 1, 10}; + details1.ip = new byte[]{1, 1, 1, 10}; details1.prefixLength = (byte) PREFIX_LENGTH; reply.ipAddressDetails.add(details1); final IpAddressDetails details2 = new IpAddressDetails(); - details2.ip = new byte[] {2, 1, 1, 10}; + details2.ip = new byte[]{2, 1, 1, 10}; details2.prefixLength = (byte) PREFIX_LENGTH; reply.ipAddressDetails.add(details2); -- cgit 1.2.3-korg