Skip to content

Commit

Permalink
HC2VPP-412: add stats interfaceDump
Browse files Browse the repository at this point in the history
Change-Id: Ib5430d3818af230fc16fc736ed7cbb20840f35b9
Signed-off-by: Michal Cmarada <mcmarada@cisco.com>
  • Loading branch information
Michal Cmarada committed Jun 5, 2019
1 parent 0c8d4b6 commit 590fdfe
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 1 deletion.
3 changes: 3 additions & 0 deletions v3po/v3po2vpp/src/main/java/io/fd/hc2vpp/v3po/V3poModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import io.fd.hc2vpp.common.translate.util.NamingContext;
import io.fd.hc2vpp.stats.jvpp.JVppStatsProvider;
import io.fd.hc2vpp.v3po.factory.InterfacesReaderFactory;
import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceNamesDumpManager;
import io.fd.hc2vpp.v3po.interfacesstate.cache.InterfaceNamesDumpManagerProvider;
import io.fd.hc2vpp.v3po.factory.InterfacesWriterFactory;
import io.fd.hc2vpp.v3po.factory.L2HoneycombWriterFactory;
import io.fd.hc2vpp.v3po.factory.L2StateHoneycombReaderFactory;
Expand Down Expand Up @@ -71,6 +73,7 @@ protected void configure() {
.toInstance(new NamingContext("bridge-domain-", "bridge-domain-context"));

bind(InterfaceCacheDumpManager.class).toProvider(InterfaceCacheDumpManagerProvider.class).in(Singleton.class);
bind(InterfaceNamesDumpManager.class).toProvider(InterfaceNamesDumpManagerProvider.class).in(Singleton.class);

// Statistics
bind(InterfaceStatisticsManager.class).toProvider(InterfaceStatisticsManagerProvider.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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 io.fd.honeycomb.translate.ModificationCache;
import io.fd.honeycomb.translate.read.ReadFailedException;
import io.fd.jvpp.stats.dto.InterfaceName;
import java.util.List;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;

/**
* Manager for dump data of interface names from stats api. The main purpose of this manager is to cache common
* interface data between various classes that process this kind of data.
*/
public interface InterfaceNamesDumpManager {

/**
* Provides stream of all currently configured vpp interface names
*
* @param identifier id of currently processed data
* @param cache Modification cache of current transaction
* @return {@link List} of currently configured interface names
* @throws ReadFailedException if dumping of data was unsuccessful
*/
@Nonnull
List<InterfaceName> getInterfaceNames(@Nonnull final InstanceIdentifier<?> identifier,
@Nonnull final ModificationCache cache)
throws ReadFailedException;
}
Original file line number Diff line number Diff line change
@@ -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<InterfaceNamesDetailsReplyDump, Void> fullDumpManager;

public InterfaceNamesDumpManagerImpl(final FutureJVppStatsFacade jvppStats) {
this.jvppStats = jvppStats;
fullDumpManager = fullInterfaceDumpManager(this.jvppStats,
new StaticCacheKeyFactory(InterfaceNamesDumpManagerImpl.class.getName() + "_dump",
InterfaceNamesDetailsReplyDump.class));
}

private static DumpCacheManager<InterfaceNamesDetailsReplyDump, Void> fullInterfaceDumpManager(
final FutureJVppStatsFacade jvppStats,
final StaticCacheKeyFactory cacheKeyFactory) {
return new DumpCacheManager.DumpCacheManagerBuilder<InterfaceNamesDetailsReplyDump, Void>()
.withExecutor(fullInterfaceDumpExecutor(jvppStats))
.withCacheKeyFactory(cacheKeyFactory)
.acceptOnly(InterfaceNamesDetailsReplyDump.class)
.build();
}

private static EntityDumpExecutor<InterfaceNamesDetailsReplyDump, Void> fullInterfaceDumpExecutor(
final FutureJVppStatsFacade api) {
return (identifier, params) -> {
final InterfaceNamesDump request = new InterfaceNamesDump();

final CompletableFuture<InterfaceNamesDetailsReplyDump>
interfaceNamesDetailsReplyDumpCompletableFuture =
api.interfaceNamesDump(request).toCompletableFuture();
return INSTANCE.getReplyForRead(interfaceNamesDetailsReplyDumpCompletableFuture, identifier);
};
}

@Nonnull
@Override
public List<InterfaceName> 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<String, InterfaceName> 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<String, InterfaceName> freshIndex = Arrays.stream(dump.interfaceNamesDetails.interfaceNames)
.collect(toMap(detail -> detail.name, detail -> detail));
putMap(freshIndex, cache);
}

return getMap(cache);
}

private static Map<String, InterfaceName> getMap(final ModificationCache cache) {
return (Map<String, InterfaceName>) cache.get(BY_NAME_INDEX_KEY);
}

private static void putMap(final Map<String, InterfaceName> map, final ModificationCache cache) {
cache.put(BY_NAME_INDEX_KEY, map);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 com.google.inject.Inject;
import com.google.inject.Provider;
import io.fd.jvpp.stats.future.FutureJVppStatsFacade;

public class InterfaceNamesDumpManagerProvider implements Provider<InterfaceNamesDumpManager> {

@Inject
private FutureJVppStatsFacade jvppStats;


@Override
public InterfaceNamesDumpManager get() {
return new InterfaceNamesDumpManagerImpl(jvppStats);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import io.fd.honeycomb.translate.util.YangDAG;
import io.fd.honeycomb.translate.write.WriterFactory;
import io.fd.jvpp.core.future.FutureJVppCore;
import io.fd.jvpp.stats.future.FutureJVppStats;
import io.fd.jvpp.stats.future.FutureJVppStatsFacade;
import java.util.HashSet;
import java.util.Set;
Expand Down

0 comments on commit 590fdfe

Please sign in to comment.