[ 
https://issues.apache.org/jira/browse/NIFI-5859?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16715536#comment-16715536
 ] 

ASF GitHub Bot commented on NIFI-5859:
--------------------------------------

Github user bbende commented on a diff in the pull request:

    https://github.com/apache/nifi-maven/pull/7#discussion_r240374218
  
    --- Diff: 
src/main/java/org/apache/nifi/extension/definition/extraction/ExtensionDefinitionFactory.java
 ---
    @@ -0,0 +1,247 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +package org.apache.nifi.extension.definition.extraction;
    +
    +import org.apache.maven.artifact.Artifact;
    +import org.apache.maven.plugin.MojoExecutionException;
    +import org.apache.nifi.extension.definition.ExtensionDefinition;
    +import org.apache.nifi.extension.definition.ExtensionType;
    +import org.apache.nifi.extension.definition.Restriction;
    +import org.apache.nifi.extension.definition.Restrictions;
    +import org.apache.nifi.extension.definition.ServiceAPIDefinition;
    +
    +import java.io.BufferedReader;
    +import java.io.IOException;
    +import java.io.InputStream;
    +import java.io.InputStreamReader;
    +import java.io.Reader;
    +import java.lang.annotation.Annotation;
    +import java.lang.reflect.InvocationTargetException;
    +import java.lang.reflect.Method;
    +import java.net.URL;
    +import java.util.Collections;
    +import java.util.Enumeration;
    +import java.util.HashMap;
    +import java.util.HashSet;
    +import java.util.Map;
    +import java.util.Set;
    +import java.util.stream.Collectors;
    +import java.util.stream.Stream;
    +
    +public class ExtensionDefinitionFactory {
    +    private static final String SERVICES_DIRECTORY = "META-INF/services/";
    +
    +    private static final Map<ExtensionType, String> INTERFACE_NAMES = new 
HashMap<>();
    +    static {
    +        INTERFACE_NAMES.put(ExtensionType.PROCESSOR, 
"org.apache.nifi.processor.Processor");
    +        INTERFACE_NAMES.put(ExtensionType.CONTROLLER_SERVICE, 
"org.apache.nifi.controller.ControllerService");
    +        INTERFACE_NAMES.put(ExtensionType.REPORTING_TASK, 
"org.apache.nifi.reporting.ReportingTask");
    +    }
    +
    +    private final ClassLoader extensionClassLoader;
    +
    +    public ExtensionDefinitionFactory(final ClassLoader classLoader) {
    +        this.extensionClassLoader = classLoader;
    +    }
    +
    +    public Set<ExtensionDefinition> discoverExtensions(final ExtensionType 
extensionType) throws IOException {
    +        final String interfaceName = INTERFACE_NAMES.get(extensionType);
    +        final Set<String> classNames = discoverClassNames(interfaceName);
    +
    +        if (classNames.isEmpty()) {
    +            return Collections.emptySet();
    +        }
    +
    +        final Set<ExtensionDefinition> definitions = new HashSet<>();
    +        for (final String className : classNames) {
    +            try {
    +                definitions.add(createExtensionDefinition(extensionType, 
className));
    +            } catch (final Exception e) {
    +                throw new IOException("Failed to create Extension 
Definition for " + extensionType + " " + className, e);
    +            }
    +        }
    +
    +        return definitions;
    +    }
    +
    +    private ExtensionDefinition createExtensionDefinition(final 
ExtensionType extensionType, final String className) throws 
ClassNotFoundException,
    +                IllegalAccessException, NoSuchMethodException, 
InvocationTargetException {
    +
    +        final Class<?> extensionClass = Class.forName(className, false, 
extensionClassLoader);
    +
    +        final String capabilityDescription = 
getCapabilityDescription(extensionClass);
    +        final Set<String> tags = getTags(extensionClass);
    +        final Restrictions restrictions = getRestrictions(extensionClass);
    +        final Set<ServiceAPIDefinition> serviceApis = 
getProvidedServiceAPIs(extensionType, extensionClass);
    +
    +        return new StandardExtensionDefinition(extensionType, className, 
capabilityDescription, tags, restrictions, serviceApis);
    +    }
    +
    +    private Set<ServiceAPIDefinition> getProvidedServiceAPIs(final 
ExtensionType extensionType, final Class<?> extensionClass) throws 
ClassNotFoundException {
    +        if (extensionType != ExtensionType.CONTROLLER_SERVICE) {
    +            return Collections.emptySet();
    +        }
    +
    +        final Set<ServiceAPIDefinition> serviceApis = new HashSet<>();
    +        final Class<?> controllerServiceClass = 
Class.forName("org.apache.nifi.controller.ControllerService", false, 
extensionClassLoader);
    +
    +        for (final Class<?> implementedInterface : 
extensionClass.getInterfaces()) {
    +            if 
(controllerServiceClass.isAssignableFrom(implementedInterface)) {
    +                final ClassLoader interfaceClassLoader = 
implementedInterface.getClassLoader();
    +                if (interfaceClassLoader instanceof ExtensionClassLoader) {
    +                    final Artifact interfaceNarArtifact = 
((ExtensionClassLoader) interfaceClassLoader).getNarArtifact();
    +
    +                    final ServiceAPIDefinition serviceDefinition = new 
StandardServiceAPIDefinition(implementedInterface.getName(),
    +                        interfaceNarArtifact.getGroupId(), 
interfaceNarArtifact.getArtifactId(), interfaceNarArtifact.getVersion());
    +
    +                    serviceApis.add(serviceDefinition);
    +                }
    +            }
    +        }
    +
    +        return serviceApis;
    +    }
    +
    +    private Restrictions getRestrictions(final Class<?> extensionClass) 
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, 
InvocationTargetException {
    --- End diff --
    
    I'm not sure if it's worth removing since you already implemented these, 
but from tracing through the code, I think if we removed the XML/Property 
writers that are not being used, then we also don't need the tags, 
restrictions, and capability description in here and in the ExtensionDefinition 
interface, since the code in nifi-api would be obtaining all of that, right?
    
    Can then also remove the Restrictions and Restriction interfaces and their 
implementations.


> Update NAR maven plugin to include information about Extensions
> ---------------------------------------------------------------
>
>                 Key: NIFI-5859
>                 URL: https://issues.apache.org/jira/browse/NIFI-5859
>             Project: Apache NiFi
>          Issue Type: New Feature
>          Components: Tools and Build
>            Reporter: Mark Payne
>            Assignee: Mark Payne
>            Priority: Major
>
> In order to have the NiFi Registry host any extensions, the registry will 
> need a way to know what extensions exist in a given NAR. Currently, that 
> information is not available directly.
> The NAR maven plugin should be updated to provide a list of extensions and 
> for each one, provide at least the following minimal information:
>  * Extension Type
>  * Extension Name
>  * Capability Description
>  * Whether or not the component is Restricted, "sub-restrictions" it has, and 
> explanations of both
>  * Any Tags that the component has
>  * If the component is a Controller Service, any Controller Service API's 
> that it provides
> Additionally, it would be ideal to provide all documentation for the 
> component within the NAR. It is best, though, not to write the documentation 
> in HTML as is done now but rather in XML or some sort of form that provides 
> the information in a structured way without any styling. This would allow the 
> documentation to be rendered consistently, even if the styling changes from 1 
> version to the next.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to