8001169771e6a77a3dc9e2544cab9c91e9fc5cdb
[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.yangtools.concepts.ObjectRegistration;
14 import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
15 import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry;
16 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
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         osgiReg = bundleContext
51             .registerService(SchemaContextProvider.class, schemaContextProvider, new Hashtable<String, String>());
52     }
53
54     public void updateService() {
55         if(osgiReg != null) {
56             try {
57                 bindingContextProvider.update(classLoadingStrat, schemaContextProvider);
58
59                 final Dictionary<String, Object> props = new Hashtable<>();
60                 props.put(BindingRuntimeContext.class.getName(), bindingContextProvider.getBindingContext());
61                 props.put(SchemaSourceProvider.class.getName(), sourceProvider);
62                 osgiReg.setProperties(props); // send modifiedService event
63             } catch (RuntimeException e) {
64                 // The ModuleInfoBackedContext throws a RuntimeException if it can't create the schema context.
65                 LOG.warn("Error updating the BindingContextProvider", e);
66             }
67         }
68     }
69
70     @Override
71     public ObjectRegistration<YangModuleInfo> registerModuleInfo(final YangModuleInfo yangModuleInfo) {
72         ObjectRegistration<YangModuleInfo> yangModuleInfoObjectRegistration = moduleInfoRegistry.registerModuleInfo(yangModuleInfo);
73         ObjectRegistrationWrapper wrapper = new ObjectRegistrationWrapper(yangModuleInfoObjectRegistration);
74         return wrapper;
75     }
76
77     @Override
78     public void close() throws Exception {
79         if(osgiReg != null) {
80             osgiReg.unregister();
81         }
82
83         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 inner.getInstance();
96         }
97
98         @Override
99         public void close() throws Exception {
100             inner.close();
101             updateService();// send modify event when a bundle disappears
102         }
103
104         @Override
105         public String toString() {
106             return inner.toString();
107         }
108     }
109 }