/* * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.mdsal.binding.dom.adapter; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ClassToInstanceMap; import com.google.common.collect.ImmutableClassToInstanceMap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier; import org.opendaylight.mdsal.dom.api.DOMRpcImplementation; import org.opendaylight.mdsal.dom.api.DOMRpcProviderService; import org.opendaylight.yangtools.concepts.ObjectRegistration; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.Rpc; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; @VisibleForTesting public class BindingDOMRpcProviderServiceAdapter extends AbstractBindingAdapter implements RpcProviderService { private static final ImmutableSet GLOBAL = ImmutableSet.of(YangInstanceIdentifier.empty()); public BindingDOMRpcProviderServiceAdapter(final AdapterContext adapterContext, final DOMRpcProviderService domRpcRegistry) { super(adapterContext, domRpcRegistry); } @Override @Deprecated public ObjectRegistration registerRpcImplementation(final Class type, final I implementation) { return register(currentSerializer(), type, implementation, GLOBAL); } @Override @Deprecated public ObjectRegistration registerRpcImplementation(final Class type, final I implementation, final Set> paths) { final var serializer = currentSerializer(); return register(serializer, type, implementation, toYangInstanceIdentifiers(serializer, paths)); } @Override public Registration registerRpcImplementation(final Rpc implementation) { return register(currentSerializer(), implementation, GLOBAL); } @Override public Registration registerRpcImplementation(final Rpc implementation, final Set> paths) { final var serializer = currentSerializer(); return register(serializer, implementation, toYangInstanceIdentifiers(serializer, paths)); } @Override public Registration registerRpcImplementations(final ClassToInstanceMap> implementations) { return register(currentSerializer(), implementations, GLOBAL); } @Override public Registration registerRpcImplementations(final ClassToInstanceMap> implementations, final Set> paths) { final var serializer = currentSerializer(); return register(serializer, implementations, toYangInstanceIdentifiers(serializer, paths)); } private > Registration register(final CurrentAdapterSerializer serializer, final T implementation, final Collection rpcContextPaths) { @SuppressWarnings("unchecked") final var type = (Class) implementation.implementedInterface(); return register(serializer, ImmutableClassToInstanceMap.of(type, implementation), rpcContextPaths); } private Registration register(final CurrentAdapterSerializer serializer, final ClassToInstanceMap> implementations, final Collection rpcContextPaths) { final var context = serializer.getRuntimeContext(); final var builder = ImmutableMap.builderWithExpectedSize( implementations.size()); for (var entry : implementations.entrySet()) { final var type = entry.getKey(); final var def = context.getRpcDefinition(type); if (def == null) { throw new IllegalArgumentException("Cannot resolve YANG definition of " + type); } final var name = def.statement().argument(); final var impl = new BindingDOMRpcImplementationAdapter(adapterContext(), entry.getValue(), name); for (var id : createDomRpcIdentifiers(Set.of(name), rpcContextPaths)) { builder.put(id, impl); } } return getDelegate().registerRpcImplementations(builder.build()); } @Deprecated private ObjectRegistration register( final CurrentAdapterSerializer serializer, final Class type, final T implementation, final Collection rpcContextPaths) { final var rpcs = serializer.getRpcMethodToQName(type).inverse(); return new BindingRpcAdapterRegistration<>(implementation, getDelegate().registerRpcImplementation( new LegacyDOMRpcImplementationAdapter(adapterContext(), type, rpcs, implementation), createDomRpcIdentifiers(rpcs.keySet(), rpcContextPaths))); } private static Set createDomRpcIdentifiers(final Set rpcs, final Collection paths) { final Set ret = new HashSet<>(); for (final YangInstanceIdentifier path : paths) { for (final QName rpc : rpcs) { ret.add(DOMRpcIdentifier.create(rpc, path)); } } return ret; } private static Collection toYangInstanceIdentifiers( final CurrentAdapterSerializer serializer, final Set> identifiers) { final var ret = new ArrayList(identifiers.size()); for (final InstanceIdentifier binding : identifiers) { ret.add(serializer.toCachedYangInstanceIdentifier(binding)); } return ret; } }