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();
}
}
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));
}
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;
}
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;
}
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;
}
Aggregations