Merge "BUG 2676 : Use notification-dispatcher for DataChangeListener actors"
[controller.git] / opendaylight / netconf / config-netconf-connector / src / main / java / org / opendaylight / controller / netconf / confignetconfconnector / osgi / NetconfOperationServiceFactoryImpl.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.base.Optional;
12 import java.lang.management.ManagementFactory;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.HashSet;
16 import java.util.Set;
17 import javax.management.MBeanServer;
18 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
19 import org.opendaylight.controller.netconf.api.Capability;
20 import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
21 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
22 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
23 import org.opendaylight.yangtools.yang.model.api.Module;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 public class NetconfOperationServiceFactoryImpl implements NetconfOperationServiceFactory {
28
29     public static final int ATTEMPT_TIMEOUT_MS = 1000;
30     private static final int SILENT_ATTEMPTS = 30;
31
32     private final YangStoreService yangStoreService;
33     private final ConfigRegistryJMXClient jmxClient;
34
35     private static final Logger LOG = LoggerFactory.getLogger(NetconfOperationServiceFactoryImpl.class);
36
37     public NetconfOperationServiceFactoryImpl(YangStoreService yangStoreService) {
38         this(yangStoreService, ManagementFactory.getPlatformMBeanServer());
39     }
40
41     public NetconfOperationServiceFactoryImpl(YangStoreService yangStoreService, MBeanServer mBeanServer) {
42         this.yangStoreService = yangStoreService;
43
44         ConfigRegistryJMXClient configRegistryJMXClient;
45         int i = 0;
46         // Config registry might not be present yet, but will be eventually
47         while(true) {
48
49             try {
50                 configRegistryJMXClient = new ConfigRegistryJMXClient(mBeanServer);
51                 break;
52             } catch (IllegalStateException e) {
53                 ++i;
54                 if (i > SILENT_ATTEMPTS) {
55                     LOG.info("JMX client not created after {} attempts, still trying", i, e);
56                 } else {
57                     LOG.debug("JMX client could not be created, reattempting, try {}", i, e);
58                 }
59                 try {
60                     Thread.sleep(ATTEMPT_TIMEOUT_MS);
61                 } catch (InterruptedException e1) {
62                     Thread.currentThread().interrupt();
63                     throw new IllegalStateException("Interrupted while reattempting connection", e1);
64                 }
65             }
66         }
67
68         jmxClient = configRegistryJMXClient;
69         if (i > SILENT_ATTEMPTS) {
70             LOG.info("Created JMX client after {} attempts", i);
71         } else {
72             LOG.debug("Created JMX client after {} attempts", i);
73         }
74     }
75
76     @Override
77     public NetconfOperationServiceImpl createService(String netconfSessionIdForReporting) {
78         return new NetconfOperationServiceImpl(yangStoreService, jmxClient, netconfSessionIdForReporting);
79     }
80
81
82     @Override
83     public Set<Capability> getCapabilities() {
84         return setupCapabilities(yangStoreService);
85     }
86
87     @Override
88     public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
89         return yangStoreService.registerCapabilityListener(listener);
90     }
91
92     public static Set<Capability> setupCapabilities(final YangStoreContext 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(final 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 Collection<String> getLocation() {
144             return Collections.emptyList();
145         }
146
147         @Override
148         public String toString() {
149             return capability;
150         }
151     }
152
153     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(final Module module, final 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(final 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 }