Search in sources :

Example 61 with BundleCoordinate

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

the class StandardReportingTaskDAO method verifyUpdate.

private void verifyUpdate(final ReportingTaskNode reportingTask, final ReportingTaskDTO reportingTaskDTO) {
    // ensure the state, if specified, is valid
    if (isNotNull(reportingTaskDTO.getState())) {
        try {
            final ScheduledState purposedScheduledState = ScheduledState.valueOf(reportingTaskDTO.getState());
            // only attempt an action if it is changing
            if (!purposedScheduledState.equals(reportingTask.getScheduledState())) {
                // perform the appropriate action
                switch(purposedScheduledState) {
                    case RUNNING:
                        reportingTask.verifyCanStart();
                        break;
                    case STOPPED:
                        switch(reportingTask.getScheduledState()) {
                            case RUNNING:
                                reportingTask.verifyCanStop();
                                break;
                            case DISABLED:
                                reportingTask.verifyCanEnable();
                                break;
                        }
                        break;
                    case DISABLED:
                        reportingTask.verifyCanDisable();
                        break;
                }
            }
        } catch (IllegalArgumentException iae) {
            throw new IllegalArgumentException(String.format("The specified reporting task state (%s) is not valid. Valid options are 'RUNNING', 'STOPPED', and 'DISABLED'.", reportingTaskDTO.getState()));
        }
    }
    boolean modificationRequest = false;
    if (isAnyNotNull(reportingTaskDTO.getName(), reportingTaskDTO.getSchedulingStrategy(), reportingTaskDTO.getSchedulingPeriod(), reportingTaskDTO.getAnnotationData(), reportingTaskDTO.getProperties(), reportingTaskDTO.getBundle())) {
        modificationRequest = true;
        // validate the request
        final List<String> requestValidation = validateProposedConfiguration(reportingTask, reportingTaskDTO);
        // ensure there was no validation errors
        if (!requestValidation.isEmpty()) {
            throw new ValidationException(requestValidation);
        }
    }
    final BundleDTO bundleDTO = reportingTaskDTO.getBundle();
    if (bundleDTO != null) {
        // ensures all nodes in a cluster have the bundle, throws exception if bundle not found for the given type
        final BundleCoordinate bundleCoordinate = BundleUtils.getBundle(reportingTask.getCanonicalClassName(), bundleDTO);
        // ensure we are only changing to a bundle with the same group and id, but different version
        reportingTask.verifyCanUpdateBundle(bundleCoordinate);
    }
    if (modificationRequest) {
        reportingTask.verifyCanUpdate();
    }
}
Also used : ValidationException(org.apache.nifi.controller.exception.ValidationException) ScheduledState(org.apache.nifi.controller.ScheduledState) BundleDTO(org.apache.nifi.web.api.dto.BundleDTO) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate)

Example 62 with BundleCoordinate

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

the class StandardReportingTaskDAO method updateBundle.

private void updateBundle(ReportingTaskNode reportingTask, ReportingTaskDTO reportingTaskDTO) {
    final BundleDTO bundleDTO = reportingTaskDTO.getBundle();
    if (bundleDTO != null) {
        final BundleCoordinate incomingCoordinate = BundleUtils.getBundle(reportingTask.getCanonicalClassName(), bundleDTO);
        final BundleCoordinate existingCoordinate = reportingTask.getBundleCoordinate();
        if (!existingCoordinate.getCoordinate().equals(incomingCoordinate.getCoordinate())) {
            try {
                // we need to use the property descriptors from the temp component here in case we are changing from a ghost component to a real component
                final ConfigurableComponent tempComponent = ExtensionManager.getTempComponent(reportingTask.getCanonicalClassName(), incomingCoordinate);
                final Set<URL> additionalUrls = reportingTask.getAdditionalClasspathResources(tempComponent.getPropertyDescriptors());
                reloadComponent.reload(reportingTask, reportingTask.getCanonicalClassName(), incomingCoordinate, additionalUrls);
            } catch (ReportingTaskInstantiationException e) {
                throw new NiFiCoreException(String.format("Unable to update reporting task %s from %s to %s due to: %s", reportingTaskDTO.getId(), reportingTask.getBundleCoordinate().getCoordinate(), incomingCoordinate.getCoordinate(), e.getMessage()), e);
            }
        }
    }
}
Also used : NiFiCoreException(org.apache.nifi.web.NiFiCoreException) ReportingTaskInstantiationException(org.apache.nifi.controller.reporting.ReportingTaskInstantiationException) ConfigurableComponent(org.apache.nifi.components.ConfigurableComponent) BundleDTO(org.apache.nifi.web.api.dto.BundleDTO) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) URL(java.net.URL)

Example 63 with BundleCoordinate

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

the class FlowEnricher method enrichComponent.

private void enrichComponent(EnrichingElementAdapter componentToEnrich, Map<String, Bundle> componentToEnrichVersionToBundles) throws FlowEnrichmentException {
    if (componentToEnrich.getBundleElement() != null) {
        return;
    }
    BundleCoordinate enrichingBundleCoordinate = null;
    if (!componentToEnrichVersionToBundles.isEmpty()) {
        // If there is only one supporting bundle, choose it, otherwise carry out additional analysis
        if (componentToEnrichVersionToBundles.size() == 1) {
            BundleDetails enrichingBundleDetails = componentToEnrichVersionToBundles.entrySet().iterator().next().getValue().getBundleDetails();
            enrichingBundleCoordinate = enrichingBundleDetails.getCoordinate();
            // Adjust the bundle to reflect the values we learned from the Extension Manager
            componentToEnrich.setBundleInformation(enrichingBundleCoordinate);
            componentToEnrich.setDependsUponBundleCoordinate(enrichingBundleDetails.getDependencyCoordinate());
        } else {
            // multiple options
            final Set<String> componentToEnrichBundleVersions = componentToEnrichVersionToBundles.values().stream().map(bundle -> bundle.getBundleDetails().getCoordinate().getVersion()).collect(Collectors.toSet());
            // Select the last version of those available for the enriching bundle
            final String bundleVersion = componentToEnrichBundleVersions.stream().sorted().reduce((version, otherVersion) -> otherVersion).get();
            final BundleCoordinate enrichingCoordinate = componentToEnrichVersionToBundles.get(bundleVersion).getBundleDetails().getCoordinate();
            componentToEnrich.setBundleInformation(enrichingCoordinate);
            logger.warn("Multiple enriching bundle options were available for component {}.  The automatically selected enriching bundle was {}", new Object[] { componentToEnrich.getComponentClass(), enrichingCoordinate });
        }
    } else {
        logger.warn("Could not find any eligible bundles for {}.  Automatic start of the flow cannot be guaranteed.", componentToEnrich.getComponentClass());
    }
}
Also used : Bundle(org.apache.nifi.bundle.Bundle) Arrays(java.util.Arrays) Logger(org.slf4j.Logger) NodeList(org.w3c.dom.NodeList) TransformerException(javax.xml.transform.TransformerException) 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) Collectors(java.util.stream.Collectors) List(java.util.List) Element(org.w3c.dom.Element) NiFiProperties(org.apache.nifi.util.NiFiProperties) Document(org.w3c.dom.Document) Node(org.w3c.dom.Node) Map(java.util.Map) Path(java.nio.file.Path) BundleDetails(org.apache.nifi.bundle.BundleDetails) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate)

Example 64 with BundleCoordinate

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

the class NarClassLoaders method load.

/**
 * Should be called at most once.
 */
private InitContext load(final File frameworkWorkingDir, final File extensionsWorkingDir) throws IOException, ClassNotFoundException {
    // get the system classloader
    final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    // get the current context class loader
    ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
    // 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());
        }
        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(), currentContextClassLoader);
                } 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 : Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Bundle(org.apache.nifi.bundle.Bundle) ArrayList(java.util.ArrayList) BundleCoordinate(org.apache.nifi.bundle.BundleCoordinate) LinkedHashMap(java.util.LinkedHashMap) BundleDetails(org.apache.nifi.bundle.BundleDetails) File(java.io.File)

Example 65 with BundleCoordinate

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

the class FlowEnricherTest method generateBundle.

private static Bundle generateBundle(String group, String id, String version, BundleCoordinate dependencyCoordinate) {
    final File workingDirectory = new File("src/test/resources");
    final BundleCoordinate bundleCoordinate = new BundleCoordinate(group, id, version);
    final String buildTag = "HEAD";
    final String buildRevision = "1";
    final String buildBranch = "DEV";
    final String buildTimestamp = "2017-01-01 00:00:00";
    final String buildJdk = "JDK8";
    final String builtBy = "somebody";
    Builder bundleBuilder = new Builder().workingDir(workingDirectory).coordinate(bundleCoordinate).buildTag(buildTag).buildRevision(buildRevision).buildBranch(buildBranch).buildTimestamp(buildTimestamp).buildJdk(buildJdk).builtBy(builtBy);
    if (dependencyCoordinate != null) {
        bundleBuilder.dependencyCoordinate(dependencyCoordinate);
    }
    return new Bundle(bundleBuilder.build(), mockClassLoader);
}
Also used : Bundle(org.apache.nifi.bundle.Bundle) Builder(org.apache.nifi.bundle.BundleDetails.Builder) Matchers.anyString(org.mockito.Matchers.anyString) File(java.io.File) 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