Search in sources :

Example 11 with BundleDetails

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

the class FlowResource method getAboutInfo.

/**
 * Retrieves details about this NiFi to put in the About dialog.
 *
 * @return An aboutEntity.
 */
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("about")
@ApiOperation(value = "Retrieves details about this NiFi to put in the About dialog", response = AboutEntity.class, authorizations = { @Authorization(value = "Read - /flow") })
@ApiResponses(value = { @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), @ApiResponse(code = 401, message = "Client could not be authenticated."), @ApiResponse(code = 403, message = "Client is not authorized to make this request."), @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") })
public Response getAboutInfo() {
    authorizeFlow();
    // create the about dto
    final AboutDTO aboutDTO = new AboutDTO();
    aboutDTO.setTitle("NiFi");
    aboutDTO.setUri(generateResourceUri());
    aboutDTO.setTimezone(new Date());
    // get the content viewer url
    final NiFiProperties properties = getProperties();
    aboutDTO.setContentViewerUrl(properties.getProperty(NiFiProperties.CONTENT_VIEWER_URL));
    final Bundle frameworkBundle = NarClassLoaders.getInstance().getFrameworkBundle();
    if (frameworkBundle != null) {
        final BundleDetails frameworkDetails = frameworkBundle.getBundleDetails();
        // set the version
        aboutDTO.setVersion(frameworkDetails.getCoordinate().getVersion());
        // Get build info
        aboutDTO.setBuildTag(frameworkDetails.getBuildTag());
        aboutDTO.setBuildRevision(frameworkDetails.getBuildRevision());
        aboutDTO.setBuildBranch(frameworkDetails.getBuildBranch());
        aboutDTO.setBuildTimestamp(frameworkDetails.getBuildTimestampDate());
    }
    // create the response entity
    final AboutEntity entity = new AboutEntity();
    entity.setAbout(aboutDTO);
    // generate the response
    return generateOkResponse(entity).build();
}
Also used : NiFiProperties(org.apache.nifi.util.NiFiProperties) BundleDetails(org.apache.nifi.bundle.BundleDetails) Bundle(org.apache.nifi.bundle.Bundle) AboutEntity(org.apache.nifi.web.api.entity.AboutEntity) AboutDTO(org.apache.nifi.web.api.dto.AboutDTO) Date(java.util.Date) Path(javax.ws.rs.Path) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 12 with BundleDetails

use of org.apache.nifi.bundle.BundleDetails 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 13 with BundleDetails

use of org.apache.nifi.bundle.BundleDetails 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)

Aggregations

BundleDetails (org.apache.nifi.bundle.BundleDetails)13 File (java.io.File)10 Bundle (org.apache.nifi.bundle.Bundle)8 BundleCoordinate (org.apache.nifi.bundle.BundleCoordinate)5 HashMap (java.util.HashMap)4 Set (java.util.Set)3 Test (org.junit.Test)3 FileInputStream (java.io.FileInputStream)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 Arrays (java.util.Arrays)2 LinkedHashMap (java.util.LinkedHashMap)2 LinkedHashSet (java.util.LinkedHashSet)2 List (java.util.List)2 Map (java.util.Map)2 Attributes (java.util.jar.Attributes)2 Manifest (java.util.jar.Manifest)2 NiFiProperties (org.apache.nifi.util.NiFiProperties)2 Logger (org.slf4j.Logger)2 LoggerFactory (org.slf4j.LoggerFactory)2