From 590fdfed2ae071f731e8795ac7ac80c65d43feb1 Mon Sep 17 00:00:00 2001 From: Michal Cmarada Date: Tue, 4 Jun 2019 14:22:41 +0200 Subject: HC2VPP-412: add stats interfaceDump Change-Id: Ib5430d3818af230fc16fc736ed7cbb20840f35b9 Signed-off-by: Michal Cmarada --- .../cache/InterfaceNamesDumpManagerImpl.java | 119 +++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceNamesDumpManagerImpl.java (limited to 'v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceNamesDumpManagerImpl.java') diff --git a/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceNamesDumpManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceNamesDumpManagerImpl.java new file mode 100644 index 000000000..b0210b6b1 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/interfacesstate/cache/InterfaceNamesDumpManagerImpl.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2019 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.interfacesstate.cache; + +import static io.fd.hc2vpp.common.translate.util.JvppReplyConsumer.INSTANCE; +import static java.util.stream.Collectors.toMap; + +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.honeycomb.translate.util.read.cache.StaticCacheKeyFactory; +import io.fd.jvpp.stats.dto.InterfaceName; +import io.fd.jvpp.stats.dto.InterfaceNamesDetailsReplyDump; +import io.fd.jvpp.stats.dto.InterfaceNamesDump; +import io.fd.jvpp.stats.future.FutureJVppStatsFacade; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class InterfaceNamesDumpManagerImpl implements InterfaceNamesDumpManager { + // byNameIndex must be cached, not held as reference here, to have it destroyed with cache after transaction + static final String BY_NAME_INDEX_KEY = InterfaceNamesDumpManagerImpl.class.getName() + "_byNameIndex"; + private static final Logger LOG = LoggerFactory.getLogger(InterfaceNamesDumpManagerImpl.class); + private final FutureJVppStatsFacade jvppStats; + + private final DumpCacheManager fullDumpManager; + + public InterfaceNamesDumpManagerImpl(final FutureJVppStatsFacade jvppStats) { + this.jvppStats = jvppStats; + fullDumpManager = fullInterfaceDumpManager(this.jvppStats, + new StaticCacheKeyFactory(InterfaceNamesDumpManagerImpl.class.getName() + "_dump", + InterfaceNamesDetailsReplyDump.class)); + } + + private static DumpCacheManager fullInterfaceDumpManager( + final FutureJVppStatsFacade jvppStats, + final StaticCacheKeyFactory cacheKeyFactory) { + return new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(fullInterfaceDumpExecutor(jvppStats)) + .withCacheKeyFactory(cacheKeyFactory) + .acceptOnly(InterfaceNamesDetailsReplyDump.class) + .build(); + } + + private static EntityDumpExecutor fullInterfaceDumpExecutor( + final FutureJVppStatsFacade api) { + return (identifier, params) -> { + final InterfaceNamesDump request = new InterfaceNamesDump(); + + final CompletableFuture + interfaceNamesDetailsReplyDumpCompletableFuture = + api.interfaceNamesDump(request).toCompletableFuture(); + return INSTANCE.getReplyForRead(interfaceNamesDetailsReplyDumpCompletableFuture, identifier); + }; + } + + @Nonnull + @Override + public List getInterfaceNames(@Nonnull final InstanceIdentifier identifier, + @Nonnull final ModificationCache cache) + throws ReadFailedException { + LOG.debug("Reading all interface names[{}]", identifier); + return new ArrayList<>(initMapAndGet(identifier, cache).values()); + } + + private Map initMapAndGet(final InstanceIdentifier identifier, + final ModificationCache cache) + throws ReadFailedException { + + if (!cache.containsKey(BY_NAME_INDEX_KEY)) { + LOG.debug("Performing dump[{}]", identifier); + final InterfaceNamesDetailsReplyDump dump = + fullDumpManager.getDump(identifier, cache).orElse(new InterfaceNamesDetailsReplyDump()); + + // naming context initialization must be done here, as it is uses getName in next step, therefore it would + // create artificial mapping for every interface, because this happens before interface dump is processed + Arrays.stream(dump.interfaceNamesDetails.interfaceNames).forEach((elt) -> { + // Store interface name from VPP in context if not yet present + LOG.trace("Interface with VPP name: {} and index: {} found in VPP", elt.name, elt.swIfIndex); + }); + + final Map freshIndex = Arrays.stream(dump.interfaceNamesDetails.interfaceNames) + .collect(toMap(detail -> detail.name, detail -> detail)); + putMap(freshIndex, cache); + } + + return getMap(cache); + } + + private static Map getMap(final ModificationCache cache) { + return (Map) cache.get(BY_NAME_INDEX_KEY); + } + + private static void putMap(final Map map, final ModificationCache cache) { + cache.put(BY_NAME_INDEX_KEY, map); + } +} -- cgit 1.2.3-korg