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.Multimap;
13 import com.google.common.collect.Multimaps;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.List;
19 import java.util.concurrent.ConcurrentHashMap;
20 import org.opendaylight.netconf.api.capability.Capability;
21 import org.opendaylight.netconf.api.monitoring.CapabilityListener;
22 import org.opendaylight.netconf.mapping.api.NetconfOperation;
23 import org.opendaylight.netconf.mapping.api.NetconfOperationService;
24 import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
25 import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener;
26 import org.opendaylight.yangtools.concepts.AbstractRegistration;
27 import org.opendaylight.yangtools.concepts.Registration;
30 * NetconfOperationService aggregator. Makes a collection of operation services accessible as one.
32 // Non-final for OSGi DS
33 // FIXME: split into abstract class for the multiple uses we have, which really is about which construct is being
35 public class AggregatedNetconfOperationServiceFactory
36 implements NetconfOperationServiceFactory, NetconfOperationServiceFactoryListener, AutoCloseable {
37 private final Set<NetconfOperationServiceFactory> factories = ConcurrentHashMap.newKeySet();
38 private final Multimap<NetconfOperationServiceFactory, Registration> registrations =
39 Multimaps.synchronizedMultimap(HashMultimap.create());
40 private final Set<CapabilityListener> listeners = ConcurrentHashMap.newKeySet();
42 public AggregatedNetconfOperationServiceFactory() {
45 public AggregatedNetconfOperationServiceFactory(final List<NetconfOperationServiceFactory> mappers) {
46 mappers.forEach(this::onAddNetconfOperationServiceFactory);
50 public final synchronized void onAddNetconfOperationServiceFactory(final NetconfOperationServiceFactory service) {
51 factories.add(service);
53 for (final CapabilityListener listener : listeners) {
54 registrations.put(service, service.registerCapabilityListener(listener));
59 public final synchronized void onRemoveNetconfOperationServiceFactory(
60 final NetconfOperationServiceFactory service) {
61 factories.remove(service);
62 registrations.removeAll(service).forEach(Registration::close);
66 public final Set<Capability> getCapabilities() {
67 final Set<Capability> capabilities = new HashSet<>();
68 for (final NetconfOperationServiceFactory factory : factories) {
69 capabilities.addAll(factory.getCapabilities());
75 public final synchronized Registration registerCapabilityListener(final CapabilityListener listener) {
76 final Map<NetconfOperationServiceFactory, Registration> regs = new HashMap<>();
78 for (final NetconfOperationServiceFactory factory : factories) {
79 regs.put(factory, factory.registerCapabilityListener(listener));
81 listeners.add(listener);
83 return new AbstractRegistration() {
86 protected void removeRegistration() {
87 synchronized (AggregatedNetconfOperationServiceFactory.this) {
88 listeners.remove(listener);
89 regs.values().forEach(Registration::close);
90 for (var reg : regs.entrySet()) {
91 registrations.remove(reg.getKey(), reg.getValue());
99 public final synchronized NetconfOperationService createService(final String netconfSessionIdForReporting) {
100 return new AggregatedNetconfOperation(factories, netconfSessionIdForReporting);
104 public synchronized void close() {
106 registrations.values().forEach(Registration::close);
107 registrations.clear();
111 private static final class AggregatedNetconfOperation implements NetconfOperationService {
112 private final ImmutableSet<NetconfOperationService> services;
114 AggregatedNetconfOperation(final Set<NetconfOperationServiceFactory> factories,
115 final String netconfSessionIdForReporting) {
116 services = factories.stream()
117 .map(factory -> factory.createService(netconfSessionIdForReporting))
118 .collect(ImmutableSet.toImmutableSet());
122 public Set<NetconfOperation> getNetconfOperations() {
123 return services.stream()
124 .flatMap(service -> service.getNetconfOperations().stream())
125 .collect(ImmutableSet.toImmutableSet());
129 public void close() {
130 services.forEach(NetconfOperationService::close);