1 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406;
3 import io.fd.honeycomb.v3po.translate.impl.read.GenericListReader;
4 import io.fd.honeycomb.v3po.translate.impl.read.GenericReader;
5 import io.fd.honeycomb.v3po.translate.read.ReaderFactory;
6 import io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
7 import io.fd.honeycomb.v3po.translate.util.read.KeepaliveReaderWrapper;
8 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
9 import io.fd.honeycomb.v3po.translate.v3po.util.ReadTimeoutException;
10 import io.fd.honeycomb.v3po.translate.v3po.vppstate.BridgeDomainCustomizer;
11 import io.fd.honeycomb.v3po.translate.v3po.vppstate.L2FibEntryCustomizer;
12 import io.fd.honeycomb.v3po.translate.v3po.vppstate.VersionCustomizer;
13 import java.lang.management.ManagementFactory;
14 import javax.management.Attribute;
15 import javax.management.InstanceNotFoundException;
16 import javax.management.ObjectName;
17 import org.opendaylight.controller.config.api.ConflictingVersionException;
18 import org.opendaylight.controller.config.api.ValidationException;
19 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
20 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
21 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
22 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.jvpp.cfg.rev160406.VppJvppImplModule;
23 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.jvpp.cfg.rev160406.VppJvppImplModuleFactory;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.L2FibTable;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.L2FibTableBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntry;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.openvpp.jvpp.future.FutureJVpp;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 public class VppStateHoneycombReaderModule extends
39 org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractVppStateHoneycombReaderModule {
41 private static final Logger LOG = LoggerFactory.getLogger(VppStateHoneycombReaderModule.class);
43 public VppStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
44 org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
45 super(identifier, dependencyResolver);
48 public VppStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
49 org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
50 org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.VppStateHoneycombReaderModule oldModule,
51 java.lang.AutoCloseable oldInstance) {
52 super(identifier, dependencyResolver, oldModule, oldInstance);
56 public void customValidation() {
57 // add custom validation form module attributes here.
61 public java.lang.AutoCloseable createInstance() {
62 return new VppStateHoneycombReaderFactory(getVppJvppDependency(),
63 getInterfaceContextVppStateDependency(),
64 getBridgeDomainContextVppStateDependency(),
65 getKeepaliveExecutorDependency());
68 private static long reinitializationCounter;
69 private static final long reinitializationLimit = 10;
72 * In case we detect connection issues with VPP, reinitialize JVpp.
74 private static void reinitializeJVpp(final long currentAttempt) {
75 // FIXME https://jira.fd.io/browse/HONEYCOMB-78 This code correctly re-initializes all the components
76 // starting with jvpp, but jvpp reconnect fails. Test in a JVpp test and then from C
77 LOG.info("Reinitializing JVpp, attempt: {}", currentAttempt);
79 final long nextAttempt = currentAttempt + 1;
80 if (nextAttempt - reinitializationCounter > reinitializationLimit) {
81 LOG.error("Too many JVpp reinitialization attempts. Unable to reinitialize JVpp in {} attempts. Giving up",
82 reinitializationLimit);
83 throw new IllegalStateException("Too many JVpp reinitialization attempts. Unable to reinitialize JVpp in "
84 + reinitializationLimit + " attempts. Giving up");
87 final ConfigRegistryJMXClient cfgRegistryClient =
88 ConfigRegistryJMXClient.createWithoutNotifications(ManagementFactory.getPlatformMBeanServer());
90 final ObjectName objectName = cfgRegistryClient.beginConfig();
91 final ConfigTransactionJMXClient txClient = cfgRegistryClient.getConfigTransactionClient(objectName);
93 final ObjectName jvppOn;
95 final String attributeName = VppJvppImplModule.descriptionJmxAttribute.getAttributeName();
96 final String factoryName = VppJvppImplModuleFactory.NAME;
97 jvppOn = txClient.lookupConfigBean(factoryName, "vpp-jvpp");
99 // Change configuration attribute of JVpp to trigger full reinitialization here using config subsystem
100 // TODO improve this when switching from karaf in planned minimal distribution
101 txClient.setAttribute(jvppOn, attributeName, new Attribute(attributeName,
102 Long.toString(nextAttempt)));
104 txClient.validateConfig();
105 cfgRegistryClient.commitConfig(txClient.getObjectName());
106 LOG.info("JVpp reinitialized successfully");
107 } catch (InstanceNotFoundException | ValidationException e) {
108 LOG.error("Unable to reinitialize JVpp. Honeycomb will not work properly from now on.", e);
109 throw new IllegalStateException("Unable to find jvpp instance in config subsystem. Unable to reinitialize JVpp", e);
110 } catch (ConflictingVersionException e) {
111 LOG.debug("Conflict changes occurred, retrying", e);
112 // Just retry until there's no conflicting change in progress
113 reinitializeJVpp(nextAttempt);
116 reinitializationCounter = nextAttempt;
120 private static final class VppStateHoneycombReaderFactory implements ReaderFactory, AutoCloseable {
122 private final FutureJVpp jVpp;
123 private final NamingContext ifcCtx;
124 private final NamingContext bdCtx;
125 private final ScheduledThreadPool keepaliveExecutor;
127 public VppStateHoneycombReaderFactory(final FutureJVpp jVpp,
128 final NamingContext ifcCtx,
129 final NamingContext bdCtx,
130 final ScheduledThreadPool keepaliveExecutorDependency) {
132 this.ifcCtx = ifcCtx;
134 this.keepaliveExecutor = keepaliveExecutorDependency;
138 public void close() throws Exception {
139 // TODO unregister not available
143 public void init(final ModifiableReaderRegistryBuilder registry) {
144 // VppState(Structural)
145 final InstanceIdentifier<VppState> vppStateId = InstanceIdentifier.create(VppState.class);
146 registry.addStructuralReader(vppStateId, VppStateBuilder.class);
148 // Wrap with keepalive reader to detect connection issues
149 // TODO keepalive reader wrapper relies on VersionReaderCustomizer (to perform timeout on reads)
150 // Once readers+customizers are asynchronous, pull the timeout to keepalive executor so that keepalive wrapper
152 registry.add(new KeepaliveReaderWrapper<>(
153 new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp)),
154 keepaliveExecutor.getExecutor(), ReadTimeoutException.class, 30,
155 () -> reinitializeJVpp(reinitializationCounter)));
156 // BridgeDomains(Structural)
157 final InstanceIdentifier<BridgeDomains> bridgeDomainsId = vppStateId.child(BridgeDomains.class);
158 registry.addStructuralReader(bridgeDomainsId, BridgeDomainsBuilder.class);
160 final InstanceIdentifier<BridgeDomain> bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class);
161 registry.add(new GenericListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdCtx)));
162 // L2FibTable(Structural)
163 final InstanceIdentifier<L2FibTable> l2FibTableId = bridgeDomainId.child(L2FibTable.class);
164 registry.addStructuralReader(l2FibTableId, L2FibTableBuilder.class);
166 registry.add(new GenericListReader<>(l2FibTableId.child(L2FibEntry.class),
167 new L2FibEntryCustomizer(jVpp, bdCtx, ifcCtx)));