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
8 package org.opendaylight.netconf.impl.osgi;
10 import com.google.common.collect.HashMultimap;
11 import com.google.common.collect.ImmutableSet;
12 import com.google.common.collect.ImmutableSet.Builder;
13 import com.google.common.collect.Multimap;
14 import com.google.common.collect.Multimaps;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.List;
20 import java.util.concurrent.ConcurrentHashMap;
21 import org.opendaylight.netconf.api.capability.Capability;
22 import org.opendaylight.netconf.api.monitoring.CapabilityListener;
23 import org.opendaylight.netconf.mapping.api.NetconfOperation;
24 import org.opendaylight.netconf.mapping.api.NetconfOperationService;
25 import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
26 import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener;
27 import org.opendaylight.netconf.util.CloseableUtil;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * NetconfOperationService aggregator. Makes a collection of operation services accessible as one.
34 public final class AggregatedNetconfOperationServiceFactory
35 implements NetconfOperationServiceFactory, NetconfOperationServiceFactoryListener, AutoCloseable {
37 private static final Logger LOG = LoggerFactory.getLogger(AggregatedNetconfOperationServiceFactory.class);
39 private final Set<NetconfOperationServiceFactory> factories = ConcurrentHashMap.newKeySet();
40 private final Multimap<NetconfOperationServiceFactory, AutoCloseable> registrations =
41 Multimaps.synchronizedMultimap(HashMultimap.create());
42 private final Set<CapabilityListener> listeners = ConcurrentHashMap.newKeySet();
44 public AggregatedNetconfOperationServiceFactory() {
47 public AggregatedNetconfOperationServiceFactory(final List<NetconfOperationServiceFactory> mappers) {
48 mappers.forEach(this::onAddNetconfOperationServiceFactory);
52 public synchronized void onAddNetconfOperationServiceFactory(final NetconfOperationServiceFactory service) {
53 factories.add(service);
55 for (final CapabilityListener listener : listeners) {
56 AutoCloseable reg = service.registerCapabilityListener(listener);
57 registrations.put(service, reg);
61 @SuppressWarnings("checkstyle:IllegalCatch")
63 public synchronized void onRemoveNetconfOperationServiceFactory(final NetconfOperationServiceFactory service) {
64 factories.remove(service);
66 for (final AutoCloseable autoCloseable : registrations.get(service)) {
68 autoCloseable.close();
69 } catch (Exception e) {
70 LOG.warn("Unable to close listener registration", e);
74 registrations.removeAll(service);
78 public Set<Capability> getCapabilities() {
79 final Set<Capability> capabilities = new HashSet<>();
80 for (final NetconfOperationServiceFactory factory : factories) {
81 capabilities.addAll(factory.getCapabilities());
87 public synchronized AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
88 final Map<NetconfOperationServiceFactory, AutoCloseable> regs = new HashMap<>();
90 for (final NetconfOperationServiceFactory factory : factories) {
91 final AutoCloseable reg = factory.registerCapabilityListener(listener);
92 regs.put(factory, reg);
94 listeners.add(listener);
97 synchronized (AggregatedNetconfOperationServiceFactory.this) {
98 listeners.remove(listener);
99 CloseableUtil.closeAll(regs.values());
100 for (final Map.Entry<NetconfOperationServiceFactory, AutoCloseable> reg : regs.entrySet()) {
101 registrations.remove(reg.getKey(), reg.getValue());
108 public synchronized NetconfOperationService createService(final String netconfSessionIdForReporting) {
109 return new AggregatedNetconfOperation(factories, netconfSessionIdForReporting);
113 public synchronized void close() throws Exception {
115 for (AutoCloseable reg : registrations.values()) {
118 registrations.clear();
122 private static final class AggregatedNetconfOperation implements NetconfOperationService {
124 private final Set<NetconfOperationService> services;
126 AggregatedNetconfOperation(final Set<NetconfOperationServiceFactory> factories,
127 final String netconfSessionIdForReporting) {
128 final Builder<NetconfOperationService> b = ImmutableSet.builder();
129 for (final NetconfOperationServiceFactory factory : factories) {
130 b.add(factory.createService(netconfSessionIdForReporting));
132 services = b.build();
136 public Set<NetconfOperation> getNetconfOperations() {
137 final Set<NetconfOperation> operations = new HashSet<>();
138 for (final NetconfOperationService service : services) {
139 operations.addAll(service.getNetconfOperations());
144 @SuppressWarnings("checkstyle:IllegalCatch")
146 public void close() {
148 CloseableUtil.closeAll(services);
149 } catch (final Exception e) {
150 throw new IllegalStateException("Unable to properly close all aggregated services", e);