Search in sources :

Example 41 with BundleCoordinate

use of org.apache.nifi.bundle.BundleCoordinate in project nifi by apache.

the class NarBundleUtil method fromNarDirectory.

/**
 * Creates a BundleDetails from the given NAR working directory.
 *
 * @param narDirectory the directory of an exploded NAR which contains a META-INF/MANIFEST.MF
 *
 * @return the BundleDetails constructed from the information in META-INF/MANIFEST.MF
 */
public static BundleDetails fromNarDirectory(final File narDirectory) throws IOException, IllegalStateException {
    if (narDirectory == null) {
        throw new IllegalArgumentException("NAR Directory cannot be null");
    }
    final File manifestFile = new File(narDirectory, "META-INF/MANIFEST.MF");
    try (final FileInputStream fis = new FileInputStream(manifestFile)) {
        final Manifest manifest = new Manifest(fis);
        final Attributes attributes = manifest.getMainAttributes();
        final BundleDetails.Builder builder = new BundleDetails.Builder();
        builder.workingDir(narDirectory);
        final String group = attributes.getValue(NarManifestEntry.NAR_GROUP.getManifestName());
        final String id = attributes.getValue(NarManifestEntry.NAR_ID.getManifestName());
        final String version = attributes.getValue(NarManifestEntry.NAR_VERSION.getManifestName());
        builder.coordinate(new BundleCoordinate(group, id, version));
        final String dependencyGroup = attributes.getValue(NarManifestEntry.NAR_DEPENDENCY_GROUP.getManifestName());
        final String dependencyId = attributes.getValue(NarManifestEntry.NAR_DEPENDENCY_ID.getManifestName());
        final String dependencyVersion = attributes.getValue(NarManifestEntry.NAR_DEPENDENCY_VERSION.getManifestName());
        if (!StringUtils.isBlank(dependencyId)) {
            builder.dependencyCoordinate(new BundleCoordinate(dependencyGroup, dependencyId, dependencyVersion));
        }
        builder.buildBranch(attributes.getValue(NarManifestEntry.BUILD_BRANCH.getManifestName()));
        builder.buildTag(attributes.getValue(NarManifestEntry.BUILD_TAG.getManifestName()));
        builder.buildRevision(attributes.getValue(NarManifestEntry.BUILD_REVISION.getManifestName()));
        builder.buildTimestamp(attributes.getValue(NarManifestEntry.BUILD_TIMESTAMP.getManifestName()));
        builder.buildJdk(attributes.getValue(NarManifestEntry.BUILD_JDK.getManifestName()));
        builder.builtBy(attributes.getValue(NarManifestEntry.BUILT_BY.getManifestName()));
        return builder.build();
    }
}
Also used : BundleDetails(org.apache.nifi.bundle.BundleDetails) Attributes(java.util.jar.Attributes) Manifest(java.util.jar.Manifest) File(java.io.File) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) FileInputStream(java.io.FileInputStream)

Example 42 with BundleCoordinate

use of org.apache.nifi.bundle.BundleCoordinate in project nifi by apache.

the class NarClassLoaders method load.

/**
 * Should be called at most once.
 */
private InitContext load(final ClassLoader rootClassloader, final File frameworkWorkingDir, final File extensionsWorkingDir) throws IOException, ClassNotFoundException {
    // find all nar files and create class loaders for them.
    final Map<String, Bundle> narDirectoryBundleLookup = new LinkedHashMap<>();
    final Map<String, ClassLoader> narCoordinateClassLoaderLookup = new HashMap<>();
    final Map<String, Set<BundleCoordinate>> narIdBundleLookup = new HashMap<>();
    // make sure the nar directory is there and accessible
    FileUtils.ensureDirectoryExistAndCanReadAndWrite(frameworkWorkingDir);
    FileUtils.ensureDirectoryExistAndCanReadAndWrite(extensionsWorkingDir);
    final List<File> narWorkingDirContents = new ArrayList<>();
    final File[] frameworkWorkingDirContents = frameworkWorkingDir.listFiles();
    if (frameworkWorkingDirContents != null) {
        narWorkingDirContents.addAll(Arrays.asList(frameworkWorkingDirContents));
    }
    final File[] extensionsWorkingDirContents = extensionsWorkingDir.listFiles();
    if (extensionsWorkingDirContents != null) {
        narWorkingDirContents.addAll(Arrays.asList(extensionsWorkingDirContents));
    }
    if (!narWorkingDirContents.isEmpty()) {
        final List<BundleDetails> narDetails = new ArrayList<>();
        final Map<String, String> narCoordinatesToWorkingDir = new HashMap<>();
        // load the nar details which includes and nar dependencies
        for (final File unpackedNar : narWorkingDirContents) {
            BundleDetails narDetail = null;
            try {
                narDetail = getNarDetails(unpackedNar);
            } catch (IllegalStateException e) {
                logger.warn("Unable to load NAR {} due to {}, skipping...", new Object[] { unpackedNar.getAbsolutePath(), e.getMessage() });
            }
            // prevent the application from starting when there are two NARs with same group, id, and version
            final String narCoordinate = narDetail.getCoordinate().getCoordinate();
            if (narCoordinatesToWorkingDir.containsKey(narCoordinate)) {
                final String existingNarWorkingDir = narCoordinatesToWorkingDir.get(narCoordinate);
                throw new IllegalStateException("Unable to load NAR with coordinates " + narCoordinate + " and working directory " + narDetail.getWorkingDirectory() + " because another NAR with the same coordinates already exists at " + existingNarWorkingDir);
            }
            narDetails.add(narDetail);
            narCoordinatesToWorkingDir.put(narCoordinate, narDetail.getWorkingDirectory().getCanonicalPath());
        }
        // attempt to locate the jetty nar
        ClassLoader jettyClassLoader = null;
        for (final Iterator<BundleDetails> narDetailsIter = narDetails.iterator(); narDetailsIter.hasNext(); ) {
            final BundleDetails narDetail = narDetailsIter.next();
            // look for the jetty nar
            if (JETTY_NAR_ID.equals(narDetail.getCoordinate().getId())) {
                // create the jetty classloader
                jettyClassLoader = createNarClassLoader(narDetail.getWorkingDirectory(), rootClassloader);
                // remove the jetty nar since its already loaded
                narDirectoryBundleLookup.put(narDetail.getWorkingDirectory().getCanonicalPath(), new Bundle(narDetail, jettyClassLoader));
                narCoordinateClassLoaderLookup.put(narDetail.getCoordinate().getCoordinate(), jettyClassLoader);
                narDetailsIter.remove();
            }
            // populate bundle lookup
            narIdBundleLookup.computeIfAbsent(narDetail.getCoordinate().getId(), id -> new HashSet<>()).add(narDetail.getCoordinate());
        }
        // ensure the jetty nar was found
        if (jettyClassLoader == null) {
            throw new IllegalStateException("Unable to locate Jetty bundle.");
        }
        int narCount;
        do {
            // record the number of nars to be loaded
            narCount = narDetails.size();
            // attempt to create each nar class loader
            for (final Iterator<BundleDetails> narDetailsIter = narDetails.iterator(); narDetailsIter.hasNext(); ) {
                final BundleDetails narDetail = narDetailsIter.next();
                final BundleCoordinate narDependencyCoordinate = narDetail.getDependencyCoordinate();
                // see if this class loader is eligible for loading
                ClassLoader narClassLoader = null;
                if (narDependencyCoordinate == null) {
                    narClassLoader = createNarClassLoader(narDetail.getWorkingDirectory(), jettyClassLoader);
                } else {
                    final String dependencyCoordinateStr = narDependencyCoordinate.getCoordinate();
                    // if the declared dependency has already been loaded
                    if (narCoordinateClassLoaderLookup.containsKey(dependencyCoordinateStr)) {
                        final ClassLoader narDependencyClassLoader = narCoordinateClassLoaderLookup.get(dependencyCoordinateStr);
                        narClassLoader = createNarClassLoader(narDetail.getWorkingDirectory(), narDependencyClassLoader);
                    } else {
                        // get all bundles that match the declared dependency id
                        final Set<BundleCoordinate> coordinates = narIdBundleLookup.get(narDependencyCoordinate.getId());
                        // ensure there are known bundles that match the declared dependency id
                        if (coordinates != null && !coordinates.contains(narDependencyCoordinate)) {
                            // ensure the declared dependency only has one possible bundle
                            if (coordinates.size() == 1) {
                                // get the bundle with the matching id
                                final BundleCoordinate coordinate = coordinates.stream().findFirst().get();
                                // if that bundle is loaded, use it
                                if (narCoordinateClassLoaderLookup.containsKey(coordinate.getCoordinate())) {
                                    logger.warn(String.format("While loading '%s' unable to locate exact NAR dependency '%s'. Only found one possible match '%s'. Continuing...", narDetail.getCoordinate().getCoordinate(), dependencyCoordinateStr, coordinate.getCoordinate()));
                                    final ClassLoader narDependencyClassLoader = narCoordinateClassLoaderLookup.get(coordinate.getCoordinate());
                                    narClassLoader = createNarClassLoader(narDetail.getWorkingDirectory(), narDependencyClassLoader);
                                }
                            }
                        }
                    }
                }
                // if we were able to create the nar class loader, store it and remove the details
                final ClassLoader bundleClassLoader = narClassLoader;
                if (bundleClassLoader != null) {
                    narDirectoryBundleLookup.put(narDetail.getWorkingDirectory().getCanonicalPath(), new Bundle(narDetail, bundleClassLoader));
                    narCoordinateClassLoaderLookup.put(narDetail.getCoordinate().getCoordinate(), narClassLoader);
                    narDetailsIter.remove();
                }
            }
        // attempt to load more if some were successfully loaded this iteration
        } while (narCount != narDetails.size());
        // see if any nars couldn't be loaded
        for (final BundleDetails narDetail : narDetails) {
            logger.warn(String.format("Unable to resolve required dependency '%s'. Skipping NAR '%s'", narDetail.getDependencyCoordinate().getId(), narDetail.getWorkingDirectory().getAbsolutePath()));
        }
    }
    // find the framework bundle, NarUnpacker already checked that there was a framework NAR and that there was only one
    final Bundle frameworkBundle = narDirectoryBundleLookup.values().stream().filter(b -> b.getBundleDetails().getCoordinate().getId().equals(FRAMEWORK_NAR_ID)).findFirst().orElse(null);
    return new InitContext(frameworkWorkingDir, extensionsWorkingDir, frameworkBundle, new LinkedHashMap<>(narDirectoryBundleLookup));
}
Also used : Bundle(org.apache.nifi.bundle.Bundle) Arrays(java.util.Arrays) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) IOException(java.io.IOException) HashMap(java.util.HashMap) BundleDetails(org.apache.nifi.bundle.BundleDetails) File(java.io.File) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) List(java.util.List) FileUtils(org.apache.nifi.util.FileUtils) Map(java.util.Map) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) LinkedHashMap(java.util.LinkedHashMap) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Bundle(org.apache.nifi.bundle.Bundle) BundleDetails(org.apache.nifi.bundle.BundleDetails) File(java.io.File)

Example 43 with BundleCoordinate

use of org.apache.nifi.bundle.BundleCoordinate in project nifi by apache.

the class ControllerServiceLoader method createControllerService.

private static ControllerServiceNode createControllerService(final ControllerServiceProvider provider, final Element controllerServiceElement, final StringEncryptor encryptor) {
    final ControllerServiceDTO dto = FlowFromDOMFactory.getControllerService(controllerServiceElement, encryptor);
    BundleCoordinate coordinate;
    try {
        coordinate = BundleUtils.getCompatibleBundle(dto.getType(), dto.getBundle());
    } catch (final IllegalStateException e) {
        final BundleDTO bundleDTO = dto.getBundle();
        if (bundleDTO == null) {
            coordinate = BundleCoordinate.UNKNOWN_COORDINATE;
        } else {
            coordinate = new BundleCoordinate(bundleDTO.getGroup(), bundleDTO.getArtifact(), bundleDTO.getVersion());
        }
    }
    final ControllerServiceNode node = provider.createControllerService(dto.getType(), dto.getId(), coordinate, Collections.emptySet(), false);
    node.setName(dto.getName());
    node.setComments(dto.getComments());
    node.setVersionedComponentId(dto.getVersionedComponentId());
    return node;
}
Also used : ControllerServiceDTO(org.apache.nifi.web.api.dto.ControllerServiceDTO) BundleDTO(org.apache.nifi.web.api.dto.BundleDTO) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate)

Example 44 with BundleCoordinate

use of org.apache.nifi.bundle.BundleCoordinate in project nifi by apache.

the class ControllerServiceAuditor method extractConfiguredPropertyValues.

/**
 * Extracts the values for the configured properties from the specified ControllerService.
 *
 * @param controllerService service
 * @param controllerServiceDTO dto
 * @return properties
 */
private Map<String, String> extractConfiguredPropertyValues(ControllerServiceNode controllerService, ControllerServiceDTO controllerServiceDTO) {
    Map<String, String> values = new HashMap<>();
    if (controllerServiceDTO.getName() != null) {
        values.put(NAME, controllerService.getName());
    }
    if (controllerServiceDTO.getAnnotationData() != null) {
        values.put(ANNOTATION_DATA, controllerService.getAnnotationData());
    }
    if (controllerServiceDTO.getBundle() != null) {
        final BundleCoordinate bundle = controllerService.getBundleCoordinate();
        values.put(EXTENSION_VERSION, formatExtensionVersion(controllerService.getComponentType(), bundle));
    }
    if (controllerServiceDTO.getProperties() != null) {
        // for each property specified, extract its configured value
        Map<String, String> properties = controllerServiceDTO.getProperties();
        Map<PropertyDescriptor, String> configuredProperties = controllerService.getProperties();
        for (String propertyName : properties.keySet()) {
            // build a descriptor for getting the configured value
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor.Builder().name(propertyName).build();
            String configuredPropertyValue = configuredProperties.get(propertyDescriptor);
            // if the configured value couldn't be found, use the default value from the actual descriptor
            if (configuredPropertyValue == null) {
                propertyDescriptor = locatePropertyDescriptor(configuredProperties.keySet(), propertyDescriptor);
                configuredPropertyValue = propertyDescriptor.getDefaultValue();
            }
            values.put(propertyName, configuredPropertyValue);
        }
    }
    if (controllerServiceDTO.getComments() != null) {
        values.put(COMMENTS, controllerService.getComments());
    }
    return values;
}
Also used : PropertyDescriptor(org.apache.nifi.components.PropertyDescriptor) HashMap(java.util.HashMap) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate)

Example 45 with BundleCoordinate

use of org.apache.nifi.bundle.BundleCoordinate in project nifi by apache.

the class ProcessorAuditor method extractConfiguredPropertyValues.

/**
 * Extracts the values for the configured properties from the specified Processor.
 */
private Map<String, String> extractConfiguredPropertyValues(ProcessorNode processor, ProcessorDTO processorDTO) {
    Map<String, String> values = new HashMap<>();
    if (processorDTO.getName() != null) {
        values.put(NAME, processor.getName());
    }
    if (processorDTO.getBundle() != null) {
        final BundleCoordinate bundle = processor.getBundleCoordinate();
        values.put(EXTENSION_VERSION, formatExtensionVersion(processor.getComponentType(), bundle));
    }
    if (processorDTO.getConfig() != null) {
        ProcessorConfigDTO newConfig = processorDTO.getConfig();
        if (newConfig.getConcurrentlySchedulableTaskCount() != null) {
            values.put(CONCURRENTLY_SCHEDULABLE_TASKS, String.valueOf(processor.getMaxConcurrentTasks()));
        }
        if (newConfig.getPenaltyDuration() != null) {
            values.put(PENALTY_DURATION, processor.getPenalizationPeriod());
        }
        if (newConfig.getYieldDuration() != null) {
            values.put(YIELD_DURATION, processor.getYieldPeriod());
        }
        if (newConfig.getBulletinLevel() != null) {
            values.put(BULLETIN_LEVEL, processor.getBulletinLevel().name());
        }
        if (newConfig.getAnnotationData() != null) {
            values.put(ANNOTATION_DATA, processor.getAnnotationData());
        }
        if (newConfig.getSchedulingPeriod() != null) {
            values.put(SCHEDULING_PERIOD, String.valueOf(processor.getSchedulingPeriod()));
        }
        if (newConfig.getAutoTerminatedRelationships() != null) {
            // get each of the auto terminated relationship names
            final Set<Relationship> autoTerminatedRelationships = processor.getAutoTerminatedRelationships();
            final List<String> autoTerminatedRelationshipNames = new ArrayList<>(autoTerminatedRelationships.size());
            for (final Relationship relationship : autoTerminatedRelationships) {
                autoTerminatedRelationshipNames.add(relationship.getName());
            }
            // sort them and include in the configuration
            Collections.sort(autoTerminatedRelationshipNames, Collator.getInstance(Locale.US));
            values.put(AUTO_TERMINATED_RELATIONSHIPS, StringUtils.join(autoTerminatedRelationshipNames, ", "));
        }
        if (newConfig.getProperties() != null) {
            // for each property specified, extract its configured value
            Map<String, String> properties = newConfig.getProperties();
            Map<PropertyDescriptor, String> configuredProperties = processor.getProperties();
            for (String propertyName : properties.keySet()) {
                // build a descriptor for getting the configured value
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor.Builder().name(propertyName).build();
                String configuredPropertyValue = configuredProperties.get(propertyDescriptor);
                // if the configured value couldn't be found, use the default value from the actual descriptor
                if (configuredPropertyValue == null) {
                    propertyDescriptor = locatePropertyDescriptor(configuredProperties.keySet(), propertyDescriptor);
                    configuredPropertyValue = propertyDescriptor.getDefaultValue();
                }
                values.put(propertyName, configuredPropertyValue);
            }
        }
        if (newConfig.getComments() != null) {
            values.put(COMMENTS, processor.getComments());
        }
        if (newConfig.getSchedulingStrategy() != null) {
            values.put(SCHEDULING_STRATEGY, processor.getSchedulingStrategy().name());
        }
        if (newConfig.getExecutionNode() != null) {
            values.put(EXECUTION_NODE, processor.getExecutionNode().name());
        }
    }
    return values;
}
Also used : ProcessorConfigDTO(org.apache.nifi.web.api.dto.ProcessorConfigDTO) PropertyDescriptor(org.apache.nifi.components.PropertyDescriptor) HashMap(java.util.HashMap) Relationship(org.apache.nifi.processor.Relationship) ArrayList(java.util.ArrayList) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate)

Aggregations

BundleCoordinate (org.apache.nifi.bundle.BundleCoordinate)65 Bundle (org.apache.nifi.bundle.Bundle)23 LinkedHashSet (java.util.LinkedHashSet)18 ArrayList (java.util.ArrayList)16 BundleDTO (org.apache.nifi.web.api.dto.BundleDTO)16 HashMap (java.util.HashMap)14 Test (org.junit.Test)14 URL (java.net.URL)13 HashSet (java.util.HashSet)13 File (java.io.File)12 PropertyDescriptor (org.apache.nifi.components.PropertyDescriptor)12 ControllerServiceNode (org.apache.nifi.controller.service.ControllerServiceNode)12 ConfigurableComponent (org.apache.nifi.components.ConfigurableComponent)10 List (java.util.List)8 Map (java.util.Map)8 Set (java.util.Set)8 Position (org.apache.nifi.connectable.Position)7 IOException (java.io.IOException)6 Collectors (java.util.stream.Collectors)6 Collections (java.util.Collections)5