+++ /dev/null
-/*
- * Copyright (c) 2017 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.controller.blueprint.ext;
-
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableSet;
-import java.util.Objects;
-import org.opendaylight.mdsal.binding.api.RpcProviderService;
-import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
-import org.opendaylight.mdsal.dom.api.DOMRpcProviderService;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.util.concurrent.FluentFutures;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.osgi.framework.Bundle;
-import org.osgi.service.blueprint.container.ComponentDefinitionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Blueprint bean corresponding to the "action-provider" element that registers the promise to instantiate action
- * instances with RpcProviderRegistry.
- *
- * <p>
- * This bean has two distinct facets:
- * - if a reference bean is provided, it registers it with {@link RpcProviderService}
- * - if a reference bean is not provided, it registers the corresponding no-op implementation with
- * {@link DOMRpcProviderService} for all action (Routed RPC) elements in the provided interface
- */
-public class ActionProviderBean {
- static final String ACTION_PROVIDER = "action-provider";
-
- private static final Logger LOG = LoggerFactory.getLogger(ActionProviderBean.class);
-
- private DOMRpcProviderService domRpcProvider = null;
- private RpcProviderService bindingRpcProvider = null;
- private DOMSchemaService schemaService = null;
- private RpcService implementation = null;
- private String interfaceName = null;
- private Registration reg;
- private Bundle bundle = null;
-
- public void setBundle(final Bundle bundle) {
- this.bundle = bundle;
- }
-
- public void setInterfaceName(final String interfaceName) {
- this.interfaceName = interfaceName;
- }
-
- public void setImplementation(final RpcService implementation) {
- this.implementation = implementation;
- }
-
- public void setDomRpcProvider(final DOMRpcProviderService rpcProviderService) {
- domRpcProvider = rpcProviderService;
- }
-
- public void setBindingRpcProvider(final RpcProviderService rpcProvider) {
- bindingRpcProvider = rpcProvider;
- }
-
- public void setSchemaService(final DOMSchemaService schemaService) {
- this.schemaService = schemaService;
- }
-
- public void init() {
- // First resolve the interface class
- final Class<RpcService> interfaceClass = getRpcClass();
-
- LOG.debug("{}: resolved interface {} to {}", ACTION_PROVIDER, interfaceName, interfaceClass);
-
- if (implementation != null) {
- registerImplementation(interfaceClass);
- } else {
- registerFallback(interfaceClass);
- }
- }
-
- @SuppressWarnings("checkstyle:IllegalCatch")
- public void destroy() {
- if (reg != null) {
- try {
- reg.close();
- } catch (final Exception e) {
- LOG.warn("{}: error while unregistering", ACTION_PROVIDER, e);
- } finally {
- reg = null;
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private Class<RpcService> getRpcClass() {
- final Class<?> iface;
-
- try {
- iface = bundle.loadClass(interfaceName);
- } catch (final ClassNotFoundException e) {
- throw new ComponentDefinitionException(String.format(
- "The specified \"interface\" for %s \"%s\" does not refer to an available class", interfaceName,
- ACTION_PROVIDER), e);
- }
- if (!RpcService.class.isAssignableFrom(iface)) {
- throw new ComponentDefinitionException(String.format(
- "The specified \"interface\" %s for \"%s\" is not an RpcService", interfaceName, ACTION_PROVIDER));
- }
-
- return (Class<RpcService>) iface;
- }
-
- private void registerFallback(final Class<RpcService> interfaceClass) {
- final var paths = RpcUtil.decomposeRpcService(interfaceClass, schemaService.getGlobalContext(),
- Objects::nonNull);
- if (paths.isEmpty()) {
- LOG.warn("{}: interface {} has no actions defined", ACTION_PROVIDER, interfaceClass);
- return;
- }
-
- final var rpcs = ImmutableSet.copyOf(Collections2.transform(paths, DOMRpcIdentifier::create));
- reg = domRpcProvider.registerRpcImplementation(
- (rpc, input) -> FluentFutures.immediateFailedFluentFuture(new DOMRpcImplementationNotAvailableException(
- "Action %s has no instance matching %s", rpc, input)), rpcs);
- LOG.debug("Registered provider for {}", interfaceName);
- }
-
- private void registerImplementation(final Class<RpcService> interfaceClass) {
- if (!interfaceClass.isInstance(implementation)) {
- throw new ComponentDefinitionException(String.format(
- "The specified \"interface\" %s for \"%s\" is not implemented by RpcService \"ref\" %s",
- interfaceName, ACTION_PROVIDER, implementation.getClass()));
- }
-
- reg = bindingRpcProvider.registerRpcImplementation(interfaceClass, implementation);
- LOG.debug("Registered implementation {} for {}", implementation, interfaceName);
- }
-}