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