1 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406;
3 import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader;
4 import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
5 import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
6 import io.fd.honeycomb.v3po.translate.read.ChildReader;
7 import io.fd.honeycomb.v3po.translate.util.KeepaliveReaderWrapper;
8 import io.fd.honeycomb.v3po.translate.util.RWUtils;
9 import io.fd.honeycomb.v3po.translate.util.read.CloseableReader;
10 import io.fd.honeycomb.v3po.translate.util.read.ReflexiveChildReaderCustomizer;
11 import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer;
12 import io.fd.honeycomb.v3po.translate.v3po.util.ReadTimeoutException;
13 import io.fd.honeycomb.v3po.translate.v3po.vppstate.BridgeDomainCustomizer;
14 import io.fd.honeycomb.v3po.translate.v3po.vppstate.L2FibEntryCustomizer;
15 import io.fd.honeycomb.v3po.translate.v3po.vppstate.VersionCustomizer;
16 import java.lang.management.ManagementFactory;
17 import java.util.ArrayList;
18 import java.util.List;
19 import javax.management.Attribute;
20 import javax.management.InstanceNotFoundException;
21 import javax.management.ObjectName;
22 import org.opendaylight.controller.config.api.ConflictingVersionException;
23 import org.opendaylight.controller.config.api.ValidationException;
24 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
25 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
26 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.jvpp.cfg.rev160406.VppJvppImplModule;
27 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.jvpp.cfg.rev160406.VppJvppImplModuleFactory;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.L2FibTable;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.L2FibTableBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntry;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntryKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey;
41 import org.opendaylight.yangtools.yang.binding.ChildOf;
42 import org.openvpp.jvpp.future.FutureJVpp;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 public class VppStateHoneycombReaderModule extends
47 org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractVppStateHoneycombReaderModule {
49 private static final Logger LOG = LoggerFactory.getLogger(VppStateHoneycombReaderModule.class);
51 public VppStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
52 org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
53 super(identifier, dependencyResolver);
56 public VppStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
57 org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
58 org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.VppStateHoneycombReaderModule oldModule,
59 java.lang.AutoCloseable oldInstance) {
60 super(identifier, dependencyResolver, oldModule, oldInstance);
64 public void customValidation() {
65 // add custom validation form module attributes here.
69 public java.lang.AutoCloseable createInstance() {
70 final FutureJVpp vppApi = getVppJvppDependency();
72 ChildReader<Version> versionReader = new CompositeChildReader<>(Version.class, new VersionCustomizer(vppApi));
73 // Wrap with keepalive reader to detect connection issues
74 // TODO keepalive reader wrapper relies on VersionReaderCustomizer (to perform timeout on reads)
75 // Once readers+customizers are asynchronous, pull the timeout to keepalive executor so that keepalive wrapper
77 versionReader = new KeepaliveReaderWrapper<>(versionReader, getKeepaliveExecutorDependency().getExecutor(),
78 ReadTimeoutException.class, 30, () -> reinitializeJVpp(reinitializationCounter));
80 final CompositeListReader<L2FibEntry, L2FibEntryKey, L2FibEntryBuilder> l2FibEntryReader =
81 new CompositeListReader<>(L2FibEntry.class,
82 new L2FibEntryCustomizer(vppApi,
83 getBridgeDomainContextVppStateDependency(), getInterfaceContextVppStateDependency()));
85 final ChildReader<L2FibTable> l2FibTableReader = new CompositeChildReader<>(
87 RWUtils.singletonChildReaderList(l2FibEntryReader),
88 new ReflexiveChildReaderCustomizer<>(L2FibTableBuilder.class));
90 final CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
91 new CompositeListReader<>(BridgeDomain.class,
92 RWUtils.singletonChildReaderList((ChildReader) l2FibTableReader),
93 new BridgeDomainCustomizer(vppApi,
94 getBridgeDomainContextVppStateDependency()));
96 final ChildReader<BridgeDomains> bridgeDomainsReader = new CompositeChildReader<>(
98 RWUtils.singletonChildReaderList(bridgeDomainReader),
99 new ReflexiveChildReaderCustomizer<>(BridgeDomainsBuilder.class));
101 final List<ChildReader<? extends ChildOf<VppState>>> childVppReaders = new ArrayList<>();
102 childVppReaders.add(versionReader);
103 childVppReaders.add(bridgeDomainsReader);
105 return new CloseableReader<>(new CompositeRootReader<>(
108 RWUtils.emptyAugReaderList(),
109 new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class)));
112 private static long reinitializationCounter;
113 private static final long reinitializationLimit = 10;
116 * In case we detect connection issues with VPP, reinitialize JVpp
118 private void reinitializeJVpp(final long currentAttempt) {
119 // FIXME https://jira.fd.io/browse/HONEYCOMB-78 This code correctly re-initializes all the components
120 // starting with jvpp, but jvpp reconnect fails. Test in a JVpp test and then from C
121 LOG.info("Reinitializing JVpp, attempt: {}", currentAttempt);
123 final long nextAttempt = currentAttempt + 1;
124 if (nextAttempt - reinitializationCounter > reinitializationLimit) {
125 LOG.error("Too many JVpp reinitialization attempts. Unable to reinitialize JVpp in {} attempts. Giving up",
126 reinitializationLimit);
127 throw new IllegalStateException("Too many JVpp reinitialization attempts. Unable to reinitialize JVpp in "
128 + reinitializationLimit + " attempts. Giving up");
131 final ConfigRegistryJMXClient cfgRegistryClient =
132 ConfigRegistryJMXClient.createWithoutNotifications(ManagementFactory.getPlatformMBeanServer());
134 final ObjectName objectName = cfgRegistryClient.beginConfig();
135 final ConfigTransactionJMXClient txClient = cfgRegistryClient.getConfigTransactionClient(objectName);
137 final ObjectName jvppOn;
139 final String attributeName = VppJvppImplModule.descriptionJmxAttribute.getAttributeName();
140 final String factoryName = VppJvppImplModuleFactory.NAME;
141 jvppOn = txClient.lookupConfigBean(factoryName, "vpp-jvpp");
143 // Change configuration attribute of JVpp to trigger full reinitialization here using config subsystem
144 // TODO improve this when switching from karaf in planned minimal distribution
145 txClient.setAttribute(jvppOn, attributeName, new Attribute(attributeName,
146 Long.toString(nextAttempt)));
148 txClient.validateConfig();
149 cfgRegistryClient.commitConfig(txClient.getObjectName());
150 LOG.info("JVpp reinitialized successfully");
151 } catch (InstanceNotFoundException | ValidationException e) {
152 LOG.error("Unable to reinitialize JVpp. Honeycomb will not work properly from now on.", e);
153 throw new IllegalStateException("Unable to find jvpp instance in config subsystem. " +
154 "Unable to reinitialize JVpp", e);
155 } catch (ConflictingVersionException e) {
156 LOG.debug("Conflict changes occurred, retrying", e);
157 // Just retry until there's no conflicting change in progress
158 reinitializeJVpp(nextAttempt);
161 reinitializationCounter = nextAttempt;