Search in sources :

Example 1 with DefaultEndpointPluginContext

use of co.cask.cdap.internal.app.runtime.DefaultEndpointPluginContext in project cdap by caskdata.

the class PluginService method getPluginEndpoint.

private PluginEndpoint getPluginEndpoint(NamespaceId namespace, ArtifactDetail artifactDetail, String pluginType, String pluginName, ArtifactDescriptor parentArtifactDescriptor, Set<ArtifactRange> parentArtifactRanges, String methodName) throws NotFoundException, IOException, ClassNotFoundException {
    Id.Artifact artifactId = Id.Artifact.from(Id.Namespace.fromEntityId(namespace), artifactDetail.getDescriptor().getArtifactId());
    Set<PluginClass> pluginClasses = artifactDetail.getMeta().getClasses().getPlugins();
    PluginClass pluginClass = null;
    for (PluginClass plugin : pluginClasses) {
        if (plugin.getName().equals(pluginName) && plugin.getType().equals(pluginType)) {
            // plugin type and name matched, next check for endpoint method presence
            if (plugin.getEndpoints() == null || !plugin.getEndpoints().contains(methodName)) {
                throw new NotFoundException(String.format("Plugin with type: %s name: %s found, " + "but Endpoint %s was not found", pluginType, pluginName, methodName));
            }
            pluginClass = plugin;
        }
    }
    if (pluginClass == null) {
        throw new NotFoundException(String.format("No Plugin with type : %s, name: %s was found", pluginType, pluginName));
    }
    // initialize parent classloader and plugin instantiator
    Instantiators instantiators = this.instantiators.getUnchecked(parentArtifactDescriptor);
    PluginInstantiator pluginInstantiator = instantiators.getPluginInstantiator(artifactDetail, artifactId.toArtifactId());
    // we pass the parent artifact to endpoint plugin context,
    // as plugin method will use this context to load other plugins.
    DefaultEndpointPluginContext defaultEndpointPluginContext = new DefaultEndpointPluginContext(namespace, authArtifactRepository, pluginInstantiator, parentArtifactRanges);
    return getPluginEndpoint(pluginInstantiator, artifactId, pluginClass, methodName, defaultEndpointPluginContext);
}
Also used : DefaultEndpointPluginContext(co.cask.cdap.internal.app.runtime.DefaultEndpointPluginContext) ArtifactNotFoundException(co.cask.cdap.common.ArtifactNotFoundException) NotFoundException(co.cask.cdap.common.NotFoundException) ArtifactId(co.cask.cdap.api.artifact.ArtifactId) Id(co.cask.cdap.common.id.Id) NamespaceId(co.cask.cdap.proto.id.NamespaceId) PluginClass(co.cask.cdap.api.plugin.PluginClass)

Example 2 with DefaultEndpointPluginContext

use of co.cask.cdap.internal.app.runtime.DefaultEndpointPluginContext in project cdap by caskdata.

the class PluginService method getPluginEndpoint.

/**
 * load and instantiate the plugin and return {@link PluginEndpoint}
 * which can be used to invoke plugin method with request object.
 *
 * @param pluginInstantiator to instantiate plugin instances.
 * @param artifact artifact of the plugin
 * @param pluginClass class having the plugin method to invoke
 * @param endpointName name of the endpoint to invoke
 * @param endpointPluginContext endpoint plugin context that can optionally be passed to the method
 * @throws IOException if there was an exception getting the classloader
 * @throws ClassNotFoundException if plugin class cannot be loaded
 * @throws NotFoundException Not Found exception thrown if no matching plugin found.
 */
private PluginEndpoint getPluginEndpoint(final PluginInstantiator pluginInstantiator, Id.Artifact artifact, PluginClass pluginClass, String endpointName, final DefaultEndpointPluginContext endpointPluginContext) throws IOException, ClassNotFoundException, NotFoundException {
    Plugin plugin = new Plugin(new ArrayList<ArtifactId>(), artifact.toArtifactId(), pluginClass, PluginProperties.builder().build());
    ClassLoader pluginClassLoader = pluginInstantiator.getPluginClassLoader(plugin);
    Class pluginClassLoaded = pluginClassLoader.loadClass(pluginClass.getClassName());
    final Object pluginInstance = pluginInstantiator.newInstanceWithoutConfig(plugin);
    Method[] methods = pluginClassLoaded.getMethods();
    for (final Method method : methods) {
        Path pathAnnotation = method.getAnnotation(Path.class);
        // method should have path annotation else continue
        if (pathAnnotation == null || !pathAnnotation.value().equals(endpointName)) {
            continue;
        }
        return new PluginEndpoint() {

            @Override
            public java.lang.reflect.Type getMethodParameterType() throws IllegalArgumentException {
                if (method.getParameterTypes().length == 0) {
                    // should not happen, checks should have happened during deploy artifact.
                    throw new IllegalArgumentException("No Method parameter type found");
                }
                return method.getGenericParameterTypes()[0];
            }

            @Override
            public java.lang.reflect.Type getResultType() {
                return method.getGenericReturnType();
            }

            @Override
            public Object invoke(Object request) throws IOException, ClassNotFoundException, InvocationTargetException, IllegalAccessException, IllegalArgumentException {
                if (method.getParameterTypes().length == 2 && EndpointPluginContext.class.isAssignableFrom(method.getParameterTypes()[1])) {
                    return method.invoke(pluginInstance, request, endpointPluginContext);
                } else if (method.getParameterTypes().length == 1) {
                    return method.invoke(pluginInstance, request);
                } else {
                    throw new IllegalArgumentException(String.format("Only method with 1 parameter and optional EndpointPluginContext as 2nd parameter is " + "allowed in Plugin endpoint method, Found %s parameters", method.getParameterTypes().length));
                }
            }
        };
    }
    ;
    // cannot find the endpoint in plugin method. should not happen as this is checked earlier.
    throw new NotFoundException("Could not find the plugin method with the requested method endpoint {}", endpointName);
}
Also used : Path(javax.ws.rs.Path) ArtifactId(co.cask.cdap.api.artifact.ArtifactId) EndpointPluginContext(co.cask.cdap.api.plugin.EndpointPluginContext) DefaultEndpointPluginContext(co.cask.cdap.internal.app.runtime.DefaultEndpointPluginContext) ArtifactNotFoundException(co.cask.cdap.common.ArtifactNotFoundException) NotFoundException(co.cask.cdap.common.NotFoundException) Method(java.lang.reflect.Method) CloseableClassLoader(co.cask.cdap.api.artifact.CloseableClassLoader) PluginClass(co.cask.cdap.api.plugin.PluginClass) Plugin(co.cask.cdap.api.plugin.Plugin)

Aggregations

ArtifactId (co.cask.cdap.api.artifact.ArtifactId)2 PluginClass (co.cask.cdap.api.plugin.PluginClass)2 ArtifactNotFoundException (co.cask.cdap.common.ArtifactNotFoundException)2 NotFoundException (co.cask.cdap.common.NotFoundException)2 DefaultEndpointPluginContext (co.cask.cdap.internal.app.runtime.DefaultEndpointPluginContext)2 CloseableClassLoader (co.cask.cdap.api.artifact.CloseableClassLoader)1 EndpointPluginContext (co.cask.cdap.api.plugin.EndpointPluginContext)1 Plugin (co.cask.cdap.api.plugin.Plugin)1 Id (co.cask.cdap.common.id.Id)1 NamespaceId (co.cask.cdap.proto.id.NamespaceId)1 Method (java.lang.reflect.Method)1 Path (javax.ws.rs.Path)1