5be949b133ec808776cf91ae651a4fc2c203f0f0
[hc2vpp.git] /
1 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406;
2
3 import io.fd.honeycomb.translate.impl.read.GenericListReader;
4 import io.fd.honeycomb.translate.impl.read.GenericReader;
5 import io.fd.honeycomb.translate.read.ReaderFactory;
6 import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder;
7 import io.fd.honeycomb.translate.util.read.KeepaliveReaderWrapper;
8 import io.fd.honeycomb.translate.v3po.util.NamingContext;
9 import io.fd.honeycomb.translate.v3po.util.ReadTimeoutException;
10 import io.fd.honeycomb.translate.v3po.vppstate.BridgeDomainCustomizer;
11 import io.fd.honeycomb.translate.v3po.vppstate.L2FibEntryCustomizer;
12 import io.fd.honeycomb.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;
37
38 public class VppStateHoneycombReaderModule extends
39     org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractVppStateHoneycombReaderModule {
40
41     private static final Logger LOG = LoggerFactory.getLogger(VppStateHoneycombReaderModule.class);
42
43     public VppStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
44                                          org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
45         super(identifier, dependencyResolver);
46     }
47
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);
53     }
54
55     @Override
56     public void customValidation() {
57         // add custom validation form module attributes here.
58     }
59
60     @Override
61     public java.lang.AutoCloseable createInstance() {
62         return new VppStateHoneycombReaderFactory(getVppJvppDependency(),
63                 getInterfaceContextVppStateDependency(),
64                 getBridgeDomainContextVppStateDependency(),
65                 getKeepaliveExecutorDependency());
66     }
67
68     private static long reinitializationCounter;
69     private static final long reinitializationLimit = 10;
70
71     /**
72      * In case we detect connection issues with VPP, reinitialize JVpp.
73      */
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);
78
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");
85         }
86
87         final ConfigRegistryJMXClient cfgRegistryClient =
88             ConfigRegistryJMXClient.createWithoutNotifications(ManagementFactory.getPlatformMBeanServer());
89
90         final ObjectName objectName = cfgRegistryClient.beginConfig();
91         final ConfigTransactionJMXClient txClient = cfgRegistryClient.getConfigTransactionClient(objectName);
92
93         final ObjectName jvppOn;
94         try {
95             final String attributeName = VppJvppImplModule.descriptionJmxAttribute.getAttributeName();
96             final String factoryName = VppJvppImplModuleFactory.NAME;
97             jvppOn = txClient.lookupConfigBean(factoryName, "vpp-jvpp");
98
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)));
103
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);
114         }
115
116         reinitializationCounter = nextAttempt;
117     }
118
119
120     private static final class VppStateHoneycombReaderFactory implements ReaderFactory, AutoCloseable {
121
122         private final FutureJVpp jVpp;
123         private final NamingContext ifcCtx;
124         private final NamingContext bdCtx;
125         private final ScheduledThreadPool keepaliveExecutor;
126
127         public VppStateHoneycombReaderFactory(final FutureJVpp jVpp,
128                                               final NamingContext ifcCtx,
129                                               final NamingContext bdCtx,
130                                               final ScheduledThreadPool keepaliveExecutorDependency) {
131             this.jVpp = jVpp;
132             this.ifcCtx = ifcCtx;
133             this.bdCtx = bdCtx;
134             this.keepaliveExecutor = keepaliveExecutorDependency;
135         }
136
137         @Override
138         public void init(final ModifiableReaderRegistryBuilder registry) {
139             // VppState(Structural)
140             final InstanceIdentifier<VppState> vppStateId = InstanceIdentifier.create(VppState.class);
141             registry.addStructuralReader(vppStateId, VppStateBuilder.class);
142             //  Version
143             // Wrap with keepalive reader to detect connection issues
144             // TODO keepalive reader wrapper relies on VersionReaderCustomizer (to perform timeout on reads)
145             // Once readers+customizers are asynchronous, pull the timeout to keepalive executor so that keepalive wrapper
146             // is truly generic
147             registry.add(new KeepaliveReaderWrapper<>(
148                     new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp)),
149                     keepaliveExecutor.getExecutor(), ReadTimeoutException.class, 30,
150                     () -> reinitializeJVpp(reinitializationCounter)));
151             //  BridgeDomains(Structural)
152             final InstanceIdentifier<BridgeDomains> bridgeDomainsId = vppStateId.child(BridgeDomains.class);
153             registry.addStructuralReader(bridgeDomainsId, BridgeDomainsBuilder.class);
154             //   BridgeDomain
155             final InstanceIdentifier<BridgeDomain> bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class);
156             registry.add(new GenericListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdCtx)));
157             //    L2FibTable(Structural)
158             final InstanceIdentifier<L2FibTable> l2FibTableId = bridgeDomainId.child(L2FibTable.class);
159             registry.addStructuralReader(l2FibTableId, L2FibTableBuilder.class);
160             //     L2FibEntry
161             registry.add(new GenericListReader<>(l2FibTableId.child(L2FibEntry.class),
162                     new L2FibEntryCustomizer(jVpp, bdCtx, ifcCtx)));
163         }
164     }
165 }