fcde347881b41df99f32e5e94e23b5a548cc8fe0
[controller.git] / opendaylight / config / config-manager / src / main / java / org / opendaylight / controller / config / manager / impl / osgi / mapping / RefreshingSCPModuleInfoRegistry.java
1 /*
2  * Copyright (c) 2013 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.manager.impl.osgi.mapping;
10
11 import java.util.Dictionary;
12 import java.util.Hashtable;
13 import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy;
14 import org.opendaylight.mdsal.binding.generator.api.ModuleInfoRegistry;
15 import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
16 import org.opendaylight.yangtools.concepts.ObjectRegistration;
17 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
18 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
19 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
20 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
21 import org.osgi.framework.BundleContext;
22 import org.osgi.framework.ServiceRegistration;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 /**
27  * Update SchemaContext service in Service Registry each time new YangModuleInfo is added or removed.
28  */
29 public class RefreshingSCPModuleInfoRegistry implements ModuleInfoRegistry, AutoCloseable {
30     private static final Logger LOG = LoggerFactory.getLogger(RefreshingSCPModuleInfoRegistry.class);
31
32     private final ModuleInfoRegistry moduleInfoRegistry;
33     private final SchemaContextProvider schemaContextProvider;
34     private final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
35     private final BindingContextProvider bindingContextProvider;
36     private final ClassLoadingStrategy classLoadingStrat;
37
38     private volatile ServiceRegistration<SchemaContextProvider> osgiReg;
39
40     public RefreshingSCPModuleInfoRegistry(final ModuleInfoRegistry moduleInfoRegistry,
41         final SchemaContextProvider schemaContextProvider, final ClassLoadingStrategy classLoadingStrat,
42         final SchemaSourceProvider<YangTextSchemaSource> sourceProvider, final BindingContextProvider bindingContextProvider,
43         final BundleContext bundleContext) {
44
45         this.moduleInfoRegistry = moduleInfoRegistry;
46         this.schemaContextProvider = schemaContextProvider;
47         this.classLoadingStrat = classLoadingStrat;
48         this.sourceProvider = sourceProvider;
49         this.bindingContextProvider = bindingContextProvider;
50         this.osgiReg = bundleContext
51             .registerService(SchemaContextProvider.class, schemaContextProvider, new Hashtable<String, String>());
52     }
53
54     public synchronized void updateService() {
55         if (this.osgiReg != null) {
56             try {
57                 this.bindingContextProvider.update(this.classLoadingStrat, this.schemaContextProvider);
58
59                 final Dictionary<String, Object> props = new Hashtable<>();
60                 props.put(BindingRuntimeContext.class.getName(), this.bindingContextProvider.getBindingContext());
61                 props.put(SchemaSourceProvider.class.getName(), this.sourceProvider);
62                 // send modifiedService event
63                 this.osgiReg.setProperties(props);
64             } catch (final RuntimeException e) {
65                 // The ModuleInfoBackedContext throws a RuntimeException if it can't create the schema context.
66                 LOG.warn("Error updating the BindingContextProvider", e);
67             }
68         }
69     }
70
71     @Override
72     public ObjectRegistration<YangModuleInfo> registerModuleInfo(final YangModuleInfo yangModuleInfo) {
73         final ObjectRegistration<YangModuleInfo> yangModuleInfoObjectRegistration = this.moduleInfoRegistry.registerModuleInfo(yangModuleInfo);
74         return new ObjectRegistrationWrapper(yangModuleInfoObjectRegistration);
75     }
76
77     @Override
78     public synchronized void close() throws Exception {
79         if (this.osgiReg != null) {
80             this.osgiReg.unregister();
81         }
82
83         this.osgiReg = null;
84     }
85
86     private class ObjectRegistrationWrapper implements ObjectRegistration<YangModuleInfo> {
87         private final ObjectRegistration<YangModuleInfo> inner;
88
89         private ObjectRegistrationWrapper(final ObjectRegistration<YangModuleInfo> inner) {
90             this.inner = inner;
91         }
92
93         @Override
94         public YangModuleInfo getInstance() {
95             return this.inner.getInstance();
96         }
97
98         @Override
99         public void close() throws Exception {
100             this.inner.close();
101             // send modify event when a bundle disappears
102             updateService();
103         }
104
105         @Override
106         public String toString() {
107             return this.inner.toString();
108         }
109     }
110 }