2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.netconf.impl.osgi;
11 import com.google.common.collect.HashMultimap;
12 import com.google.common.collect.ImmutableSet;
13 import com.google.common.collect.ImmutableSet.Builder;
14 import com.google.common.collect.Maps;
15 import com.google.common.collect.Multimap;
16 import com.google.common.collect.Multimaps;
17 import com.google.common.collect.Sets;
18 import io.netty.util.internal.ConcurrentSet;
19 import java.util.HashSet;
20 import java.util.List;
23 import org.opendaylight.controller.config.util.capability.Capability;
24 import org.opendaylight.netconf.api.monitoring.CapabilityListener;
25 import org.opendaylight.netconf.mapping.api.NetconfOperation;
26 import org.opendaylight.netconf.mapping.api.NetconfOperationService;
27 import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
28 import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener;
29 import org.opendaylight.netconf.util.CloseableUtil;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
34 * NetconfOperationService aggregator. Makes a collection of operation services accessible as one.
36 public class AggregatedNetconfOperationServiceFactory
37 implements NetconfOperationServiceFactory, NetconfOperationServiceFactoryListener, AutoCloseable {
39 private static final Logger LOG = LoggerFactory.getLogger(AggregatedNetconfOperationServiceFactory.class);
41 private final Set<NetconfOperationServiceFactory> factories = new ConcurrentSet<>();
42 private final Multimap<NetconfOperationServiceFactory, AutoCloseable> registrations =
43 Multimaps.synchronizedMultimap(HashMultimap.create());
44 private final Set<CapabilityListener> listeners = new ConcurrentSet<>();
46 public AggregatedNetconfOperationServiceFactory() {
49 public AggregatedNetconfOperationServiceFactory(final List<NetconfOperationServiceFactory> mappers) {
50 mappers.forEach(this::onAddNetconfOperationServiceFactory);
54 public synchronized void onAddNetconfOperationServiceFactory(NetconfOperationServiceFactory service) {
55 factories.add(service);
57 for (final CapabilityListener listener : listeners) {
58 AutoCloseable reg = service.registerCapabilityListener(listener);
59 registrations.put(service, reg);
63 @SuppressWarnings("checkstyle:IllegalCatch")
65 public synchronized void onRemoveNetconfOperationServiceFactory(NetconfOperationServiceFactory service) {
66 factories.remove(service);
68 for (final AutoCloseable autoCloseable : registrations.get(service)) {
70 autoCloseable.close();
71 } catch (Exception e) {
72 LOG.warn("Unable to close listener registration", e);
76 registrations.removeAll(service);
80 public Set<Capability> getCapabilities() {
81 final HashSet<Capability> capabilities = Sets.newHashSet();
82 for (final NetconfOperationServiceFactory factory : factories) {
83 capabilities.addAll(factory.getCapabilities());
89 public synchronized AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
90 final Map<NetconfOperationServiceFactory, AutoCloseable> regs = Maps.newHashMap();
92 for (final NetconfOperationServiceFactory factory : factories) {
93 final AutoCloseable reg = factory.registerCapabilityListener(listener);
94 regs.put(factory, reg);
96 listeners.add(listener);
98 return new AutoCloseable() {
100 public void close() throws Exception {
101 synchronized (AggregatedNetconfOperationServiceFactory.this) {
102 listeners.remove(listener);
103 CloseableUtil.closeAll(regs.values());
104 for (final Map.Entry<NetconfOperationServiceFactory, AutoCloseable> reg : regs.entrySet()) {
105 registrations.remove(reg.getKey(), reg.getValue());
113 public synchronized NetconfOperationService createService(final String netconfSessionIdForReporting) {
114 return new AggregatedNetconfOperation(factories, netconfSessionIdForReporting);
118 public synchronized void close() throws Exception {
120 for (AutoCloseable reg : registrations.values()) {
123 registrations.clear();
127 private static final class AggregatedNetconfOperation implements NetconfOperationService {
129 private final Set<NetconfOperationService> services;
131 AggregatedNetconfOperation(final Set<NetconfOperationServiceFactory> factories,
132 final String netconfSessionIdForReporting) {
133 final Builder<NetconfOperationService> b = ImmutableSet.builder();
134 for (final NetconfOperationServiceFactory factory : factories) {
135 b.add(factory.createService(netconfSessionIdForReporting));
137 this.services = b.build();
141 public Set<NetconfOperation> getNetconfOperations() {
142 final HashSet<NetconfOperation> operations = Sets.newHashSet();
143 for (final NetconfOperationService service : services) {
144 operations.addAll(service.getNetconfOperations());
149 @SuppressWarnings("checkstyle:IllegalCatch")
151 public void close() {
153 CloseableUtil.closeAll(services);
154 } catch (final Exception e) {
155 throw new IllegalStateException("Unable to properly close all aggregated services", e);