Remove yang-test
[controller.git] / opendaylight / config / config-manager-facade-xml / src / main / java / org / opendaylight / controller / config / facade / xml / osgi / YangStoreActivator.java
1 /*
2  * Copyright (c) 2015, 2017 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.config.facade.xml.osgi;
10
11 import com.google.common.base.Preconditions;
12 import java.lang.management.ManagementFactory;
13 import java.util.Hashtable;
14 import java.util.concurrent.atomic.AtomicBoolean;
15 import javax.management.MBeanServer;
16 import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
17 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
18 import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
19 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
20 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
21 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
22 import org.osgi.framework.BundleActivator;
23 import org.osgi.framework.BundleContext;
24 import org.osgi.framework.ServiceReference;
25 import org.osgi.framework.ServiceRegistration;
26 import org.osgi.util.tracker.ServiceTracker;
27 import org.osgi.util.tracker.ServiceTrackerCustomizer;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * Start yang store service and the XML config manager facade.
33  */
34 public class YangStoreActivator implements BundleActivator {
35
36     private static final Logger LOG = LoggerFactory.getLogger(YangStoreActivator.class);
37
38     private final MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer();
39
40     private ServiceRegistration<YangStoreService> yangStoreServiceServiceRegistration;
41     private ConfigRegistryLookupThread configRegistryLookup = null;
42     private BundleContext context;
43     private ServiceRegistration<ConfigSubsystemFacadeFactory> osgiRegistrayion;
44
45     @Override
46     @SuppressWarnings("checkstyle:hiddenField")
47     public void start(final BundleContext context) throws Exception {
48         LOG.debug("ConfigPersister starting");
49         this.context = context;
50
51         final ServiceTrackerCustomizer<SchemaContextProvider, YangStoreService> schemaServiceTrackerCustomizer =
52                 new ServiceTrackerCustomizer<SchemaContextProvider, YangStoreService>() {
53
54             private final AtomicBoolean alreadyStarted = new AtomicBoolean(false);
55
56             @Override
57             public YangStoreService addingService(final ServiceReference<SchemaContextProvider> reference) {
58                 LOG.debug("Got addingService(SchemaContextProvider) event");
59                 if (reference.getProperty(SchemaSourceProvider.class.getName()) == null
60                         && reference.getProperty(BindingRuntimeContext.class.getName()) == null) {
61                     LOG.debug("SchemaContextProvider not from config-manager. Ignoring");
62                     return null;
63                 }
64
65                 // Yang store service should not be registered multiple times
66                 if (!this.alreadyStarted.compareAndSet(false, true)) {
67                     LOG.warn("Starting yang store service multiple times. Received new service {}", reference);
68                     throw new RuntimeException("Starting yang store service multiple times");
69                 }
70                 final SchemaContextProvider schemaContextProvider = reference.getBundle().getBundleContext()
71                         .getService(reference);
72                 final Object sourceProvider = Preconditions.checkNotNull(
73                         reference.getProperty(SchemaSourceProvider.class.getName()), "Source provider not found");
74                 Preconditions.checkArgument(sourceProvider instanceof SchemaSourceProvider);
75
76                 // TODO avoid cast
77                 final YangStoreService yangStoreService = new YangStoreService(schemaContextProvider,
78                         (SchemaSourceProvider<YangTextSchemaSource>) sourceProvider);
79
80                 final BindingRuntimeContext runtimeContext = (BindingRuntimeContext) reference
81                         .getProperty(BindingRuntimeContext.class.getName());
82                 LOG.debug("BindingRuntimeContext retrieved as {}", runtimeContext);
83                 if (runtimeContext != null) {
84                     yangStoreService.refresh(runtimeContext);
85                 }
86
87                 YangStoreActivator.this.yangStoreServiceServiceRegistration = context
88                         .registerService(YangStoreService.class, yangStoreService, new Hashtable<>());
89                 YangStoreActivator.this.configRegistryLookup = new ConfigRegistryLookupThread(yangStoreService);
90                 YangStoreActivator.this.configRegistryLookup.start();
91                 return yangStoreService;
92             }
93
94             @Override
95             public void modifiedService(final ServiceReference<SchemaContextProvider> reference,
96                     final YangStoreService service) {
97                 if (service == null) {
98                     return;
99                 }
100
101                 LOG.debug("Got modifiedService(SchemaContextProvider) event");
102                 final BindingRuntimeContext runtimeContext = (BindingRuntimeContext) reference
103                         .getProperty(BindingRuntimeContext.class.getName());
104                 LOG.debug("BindingRuntimeContext retrieved as {}", runtimeContext);
105                 service.refresh(runtimeContext);
106             }
107
108             @Override
109             public void removedService(final ServiceReference<SchemaContextProvider> reference,
110                     final YangStoreService service) {
111                 if (service == null) {
112                     return;
113                 }
114
115                 LOG.debug("Got removedService(SchemaContextProvider) event");
116                 this.alreadyStarted.set(false);
117                 YangStoreActivator.this.configRegistryLookup.interrupt();
118                 YangStoreActivator.this.yangStoreServiceServiceRegistration.unregister();
119                 YangStoreActivator.this.yangStoreServiceServiceRegistration = null;
120             }
121         };
122
123         final ServiceTracker<SchemaContextProvider, YangStoreService> schemaContextProviderServiceTracker =
124                 new ServiceTracker<>(context, SchemaContextProvider.class, schemaServiceTrackerCustomizer);
125         schemaContextProviderServiceTracker.open();
126     }
127
128     @Override
129     @SuppressWarnings("checkstyle:hiddenField")
130     public void stop(final BundleContext context) throws Exception {
131         if (this.configRegistryLookup != null) {
132             this.configRegistryLookup.interrupt();
133         }
134         if (this.osgiRegistrayion != null) {
135             this.osgiRegistrayion.unregister();
136         }
137         if (this.yangStoreServiceServiceRegistration != null) {
138             this.yangStoreServiceServiceRegistration.unregister();
139             this.yangStoreServiceServiceRegistration = null;
140         }
141     }
142
143     /**
144      * Find ConfigRegistry from config manager in JMX.
145      */
146     private class ConfigRegistryLookupThread extends Thread {
147         public static final int ATTEMPT_TIMEOUT_MS = 1000;
148         private static final int SILENT_ATTEMPTS = 30;
149
150         private final YangStoreService yangStoreService;
151
152         ConfigRegistryLookupThread(final YangStoreService yangStoreService) {
153             super("config-registry-lookup");
154             this.yangStoreService = yangStoreService;
155         }
156
157         @Override
158         public void run() {
159
160             ConfigRegistryJMXClient configRegistryJMXClient;
161             ConfigRegistryJMXClient configRegistryJMXClientNoNotifications;
162             int index = 0;
163             // Config registry might not be present yet, but will be eventually
164             while (true) {
165
166                 try {
167                     configRegistryJMXClient = new ConfigRegistryJMXClient(YangStoreActivator.this.configMBeanServer);
168                     configRegistryJMXClientNoNotifications = ConfigRegistryJMXClient
169                             .createWithoutNotifications(YangStoreActivator.this.configMBeanServer);
170                     break;
171                 } catch (final IllegalStateException e) {
172                     ++index;
173                     if (index > SILENT_ATTEMPTS) {
174                         LOG.info("JMX client not created after {} attempts, still trying", index, e);
175                     } else {
176                         LOG.debug("JMX client could not be created, reattempting, try {}", index, e);
177                     }
178                     try {
179                         Thread.sleep(ATTEMPT_TIMEOUT_MS);
180                     } catch (final InterruptedException e1) {
181                         Thread.currentThread().interrupt();
182                         throw new IllegalStateException("Interrupted while reattempting connection", e1);
183                     }
184                 }
185             }
186
187             final ConfigRegistryJMXClient jmxClient = configRegistryJMXClient;
188             final ConfigRegistryJMXClient jmxClientNoNotifications = configRegistryJMXClientNoNotifications;
189             if (index > SILENT_ATTEMPTS) {
190                 LOG.info("Created JMX client after {} attempts", index);
191             } else {
192                 LOG.debug("Created JMX client after {} attempts", index);
193             }
194
195             final ConfigSubsystemFacadeFactory configSubsystemFacade = new ConfigSubsystemFacadeFactory(jmxClient,
196                     jmxClientNoNotifications, this.yangStoreService);
197             YangStoreActivator.this.osgiRegistrayion = YangStoreActivator.this.context
198                     .registerService(ConfigSubsystemFacadeFactory.class, configSubsystemFacade, new Hashtable<>());
199         }
200     }
201 }