c6248df41bc133f7754f9c78f0ec2bb15fa69bcb
[controller.git] / opendaylight / netconf / config-netconf-connector / src / main / java / org / opendaylight / controller / netconf / confignetconfconnector / osgi / NetconfOperationServiceImpl.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.netconf.confignetconfconnector.osgi;
10
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15
16 import org.opendaylight.controller.config.api.LookupRegistry;
17 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
18 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
19 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
20 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
21 import org.opendaylight.controller.netconf.mapping.api.Capability;
22 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
23 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
24 import org.opendaylight.yangtools.yang.model.api.Module;
25
26 import com.google.common.annotations.VisibleForTesting;
27 import com.google.common.base.Optional;
28 import com.google.common.base.Preconditions;
29 import com.google.common.collect.Sets;
30
31 /**
32  * Manages life cycle of {@link YangStoreSnapshot}.
33  */
34 public class NetconfOperationServiceImpl implements NetconfOperationService {
35
36     private final YangStoreSnapshot yangStoreSnapshot;
37     private final NetconfOperationProvider operationProvider;
38     private final Set<Capability> capabilities;
39     private final TransactionProvider transactionProvider;
40
41     public NetconfOperationServiceImpl(YangStoreService yangStoreService, ConfigRegistryJMXClient jmxClient,
42             String netconfSessionIdForReporting) throws YangStoreException {
43
44         yangStoreSnapshot = yangStoreService.getYangStoreSnapshot();
45         checkConsistencyBetweenYangStoreAndConfig(jmxClient, yangStoreSnapshot);
46
47         transactionProvider = new TransactionProvider(jmxClient, netconfSessionIdForReporting);
48         operationProvider = new NetconfOperationProvider(yangStoreSnapshot, jmxClient, transactionProvider,
49                 netconfSessionIdForReporting);
50         capabilities = setupCapabilities(yangStoreSnapshot);
51     }
52
53
54     @VisibleForTesting
55     static void checkConsistencyBetweenYangStoreAndConfig(LookupRegistry jmxClient, YangStoreSnapshot yangStoreSnapshot) {
56         Set<String> missingModulesFromConfig = Sets.newHashSet();
57
58         Set<String> modulesSeenByConfig = jmxClient.getAvailableModuleFactoryQNames();
59         Map<String, Map<String, ModuleMXBeanEntry>> moduleMXBeanEntryMap = yangStoreSnapshot.getModuleMXBeanEntryMap();
60
61         for (Map<String, ModuleMXBeanEntry> moduleNameToMBE : moduleMXBeanEntryMap.values()) {
62             for (ModuleMXBeanEntry moduleMXBeanEntry : moduleNameToMBE.values()) {
63                 String moduleSeenByYangStore = moduleMXBeanEntry.getYangModuleQName().toString();
64                 if(modulesSeenByConfig.contains(moduleSeenByYangStore) == false)
65                     missingModulesFromConfig.add(moduleSeenByYangStore);
66             }
67         }
68
69         Preconditions
70                 .checkState(
71                         missingModulesFromConfig.isEmpty(),
72                         "There are inconsistencies between configuration subsystem and yangstore in terms of discovered yang modules, yang modules missing from config subsystem but present in yangstore: %s, %sAll modules present in config: %s",
73                         missingModulesFromConfig, System.lineSeparator(), modulesSeenByConfig);
74
75     }
76
77     @Override
78     public void close() {
79         yangStoreSnapshot.close();
80         transactionProvider.close();
81     }
82
83     @Override
84     public Set<Capability> getCapabilities() {
85         return capabilities;
86     }
87
88     @Override
89     public Set<NetconfOperation> getNetconfOperations() {
90         return operationProvider.getOperations();
91     }
92
93     private static Set<Capability> setupCapabilities(YangStoreSnapshot yangStoreSnapshot) {
94         Set<Capability> capabilities = new HashSet<>();
95         // [RFC6241] 8.3.  Candidate Configuration Capability
96         capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
97         // [RFC6241] 8.5.  Rollback-on-Error Capability
98         capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
99
100         Set<Module> modules = yangStoreSnapshot.getModules();
101         for (Module module : modules) {
102             capabilities.add(new YangStoreCapability(module, yangStoreSnapshot.getModuleSource(module)));
103         }
104
105         return capabilities;
106     }
107
108     private static class BasicCapability implements Capability {
109
110         private final String capability;
111
112         private BasicCapability(String capability) {
113             this.capability = capability;
114         }
115
116         @Override
117         public String getCapabilityUri() {
118             return capability;
119         }
120
121         @Override
122         public Optional<String> getModuleNamespace() {
123             return Optional.absent();
124         }
125
126         @Override
127         public Optional<String> getModuleName() {
128             return Optional.absent();
129         }
130
131         @Override
132         public Optional<String> getRevision() {
133             return Optional.absent();
134         }
135
136         @Override
137         public Optional<String> getCapabilitySchema() {
138             return Optional.absent();
139         }
140
141         @Override
142         public Optional<List<String>> getLocation() {
143             return Optional.absent();
144         }
145
146         @Override
147         public String toString() {
148             return capability;
149         }
150     }
151
152     private static class YangStoreCapability extends BasicCapability {
153
154         private final String content;
155         private final String revision;
156         private final String moduleName;
157         private final String moduleNamespace;
158
159         public YangStoreCapability(Module module, String moduleContent) {
160             super(toCapabilityURI(module));
161             this.content = moduleContent;
162             this.moduleName = module.getName();
163             this.moduleNamespace = module.getNamespace().toString();
164             this.revision = Util.writeDate(module.getRevision());
165         }
166
167         @Override
168         public Optional<String> getCapabilitySchema() {
169             return Optional.of(content);
170         }
171
172         private static String toCapabilityURI(Module module) {
173             return String.valueOf(module.getNamespace()) + "?module="
174                     + module.getName() + "&revision=" + Util.writeDate(module.getRevision());
175         }
176
177         @Override
178         public Optional<String> getModuleName() {
179             return Optional.of(moduleName);
180         }
181
182         @Override
183         public Optional<String> getModuleNamespace() {
184             return Optional.of(moduleNamespace);
185         }
186
187         @Override
188         public Optional<String> getRevision() {
189             return Optional.of(revision);
190         }
191     }
192 }