use of org.apache.nifi.util.NiFiProperties in project nifi-minifi by apache.
the class NarUnpackerTest method testUnpackNarsFromNonExistantDir.
@Test
public void testUnpackNarsFromNonExistantDir() {
final File nonExistantDir = new File("./target/this/dir/should/not/exist/");
nonExistantDir.delete();
nonExistantDir.deleteOnExit();
final Map<String, String> others = new HashMap<>();
others.put("nifi.nar.library.directory.alt", nonExistantDir.toString());
NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties", others);
final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties);
assertTrue(extensionMapping.getAllExtensionNames().contains("org.apache.nifi.processors.dummy.one"));
assertEquals(1, extensionMapping.getAllExtensionNames().size());
final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory();
File[] extensionFiles = extensionsWorkingDir.listFiles();
assertEquals(1, extensionFiles.length);
assertEquals("dummy-one.nar-unpacked", extensionFiles[0].getName());
}
use of org.apache.nifi.util.NiFiProperties in project nifi-minifi by apache.
the class NarThreadContextClassLoader method createInstance.
/**
* Constructs an instance of the given type using either default no args
* constructor or a constructor which takes a NiFiProperties object
* (preferred).
*
* @param <T> the type to create an instance for
* @param implementationClassName the implementation class name
* @param typeDefinition the type definition
* @param nifiProperties the NiFiProperties instance
* @return constructed instance
* @throws InstantiationException if there is an error instantiating the class
* @throws IllegalAccessException if there is an error accessing the type
* @throws ClassNotFoundException if the class cannot be found
*/
public static <T> T createInstance(final String implementationClassName, final Class<T> typeDefinition, final NiFiProperties nifiProperties) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
final ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(NarThreadContextClassLoader.getInstance());
try {
final List<Bundle> bundles = ExtensionManager.getBundles(implementationClassName);
if (bundles.size() == 0) {
throw new IllegalStateException(String.format("The specified implementation class '%s' is not known to this nifi.", implementationClassName));
}
if (bundles.size() > 1) {
throw new IllegalStateException(String.format("More than one bundle was found for the specified implementation class '%s', only one is allowed.", implementationClassName));
}
final Bundle bundle = bundles.get(0);
final ClassLoader detectedClassLoaderForType = bundle.getClassLoader();
final Class<?> rawClass = Class.forName(implementationClassName, true, detectedClassLoaderForType);
Thread.currentThread().setContextClassLoader(detectedClassLoaderForType);
final Class<?> desiredClass = rawClass.asSubclass(typeDefinition);
if (nifiProperties == null) {
return typeDefinition.cast(desiredClass.newInstance());
}
Constructor<?> constructor = null;
try {
constructor = desiredClass.getConstructor(NiFiProperties.class);
} catch (NoSuchMethodException nsme) {
try {
constructor = desiredClass.getConstructor();
} catch (NoSuchMethodException nsme2) {
throw new IllegalStateException("Failed to find constructor which takes NiFiProperties as argument as well as the default constructor on " + desiredClass.getName(), nsme2);
}
}
try {
if (constructor.getParameterTypes().length == 0) {
return typeDefinition.cast(constructor.newInstance());
} else {
return typeDefinition.cast(constructor.newInstance(nifiProperties));
}
} catch (InvocationTargetException ite) {
throw new IllegalStateException("Failed to instantiate a component due to (see target exception)", ite);
}
} finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
}
use of org.apache.nifi.util.NiFiProperties in project nifi-minifi by apache.
the class FlowEnricherTest method enrichFlowWithBundleInformationTest.
@Test
public void enrichFlowWithBundleInformationTest() throws Exception {
/* Setup Mocks */
// Create a copy of the document to use with our mock
final FlowParser parser = new FlowParser();
final Document flowDocument = parser.parse(TEST_FLOW_XML_FILE);
final FlowParser mockFlowParser = Mockito.mock(FlowParser.class);
Mockito.when(mockFlowParser.parse(any())).thenReturn(flowDocument);
final MiNiFi minifi = Mockito.mock(MiNiFi.class);
final NiFiProperties mockProperties = Mockito.mock(NiFiProperties.class);
Mockito.when(mockProperties.getFlowConfigurationFile()).thenReturn(new File(TEST_FLOW_XML_PATH));
final String defaultGroup = "org.apache.nifi";
final String aVersion = "1.0.0";
final String anotherVersion = "2.0.0";
final String minifiGroup = "org.apache.nifi.minifi";
final String minifiStandardNarId = "minifi-standard-nar";
final String minifiVersion = "0.0.2";
// Standard Services API Bundles
final String standardSvcsId = "nifi-standard-services-api-nar";
final List<Bundle> standardSvcsBundles = new ArrayList<>();
standardSvcsBundles.add(generateBundle(defaultGroup, standardSvcsId, aVersion));
standardSvcsBundles.add(generateBundle(defaultGroup, standardSvcsId, anotherVersion));
// SSL Context Service Bundles - depends on nifi-standard-services-api
final String sslContextSvcId = "nifi-ssl-context-service-nar";
final List<Bundle> sslBundles = new ArrayList<>();
sslBundles.add(generateBundle(defaultGroup, sslContextSvcId, aVersion, standardSvcsBundles.get(0).getBundleDetails().getCoordinate()));
sslBundles.add(generateBundle(defaultGroup, sslContextSvcId, anotherVersion, standardSvcsBundles.get(1).getBundleDetails().getCoordinate()));
// MiNiFi Standard NAR Bundle
List<Bundle> minifiStdBundles = new ArrayList<>();
minifiStdBundles.add(generateBundle(minifiGroup, minifiStandardNarId, minifiVersion, standardSvcsBundles.get(0).getBundleDetails().getCoordinate()));
// Kafka depends on SSL
List<Bundle> kafkaBundles = new ArrayList<>();
final String kafkaId = "nifi-kafka-0-10-nar";
kafkaBundles.add(generateBundle(defaultGroup, kafkaId, anotherVersion, standardSvcsBundles.get(1).getBundleDetails().getCoordinate()));
/* If we are evaluating potential problem children components, provide a tailored bundle.
* Otherwise, these can be sourced from the standard NAR.
*/
Mockito.when(minifi.getBundles(anyString())).thenAnswer((Answer<List<Bundle>>) invocationOnMock -> {
final String requestedClass = (String) invocationOnMock.getArguments()[0];
switch(requestedClass) {
case KAFKA_PROCESSOR_CLASS:
return kafkaBundles;
case SSL_CONTROLLER_SERVICE_CLASS:
return sslBundles;
default:
return minifiStdBundles;
}
});
/* Perform Test */
final FlowEnricher flowEnricher = new FlowEnricher(minifi, mockFlowParser, mockProperties);
flowEnricher.enrichFlowWithBundleInformation();
final ArgumentCaptor<String> bundleLookupCaptor = ArgumentCaptor.forClass(String.class);
// Inspect the document to ensure all components were enriched
Mockito.verify(minifi, atLeastOnce()).getBundles(bundleLookupCaptor.capture());
final List<String> allValues = bundleLookupCaptor.getAllValues();
// Verify each class performed a bundle look up
EXTENSION_CLASSES.stream().forEach(procClass -> Assert.assertTrue(allValues.contains(procClass)));
// Verify bundles are correctly applied in our flow document
// We have three processors, one controller service, and no reporting tasks
final NodeList processorNodes = flowDocument.getElementsByTagName(FlowEnricher.PROCESSOR_TAG_NAME);
Assert.assertEquals("Incorrect number of processors", 3, processorNodes.getLength());
final NodeList controllerServiceNodes = flowDocument.getElementsByTagName(FlowEnricher.CONTROLLER_SERVICE_TAG_NAME);
Assert.assertEquals("Incorrect number of controller services", 1, controllerServiceNodes.getLength());
final NodeList reportingTaskNodes = flowDocument.getElementsByTagName(FlowEnricher.REPORTING_TASK_TAG_NAME);
Assert.assertEquals("Incorrect number of reporting tasks", 0, reportingTaskNodes.getLength());
for (int i = 0; i < processorNodes.getLength(); i++) {
final Element componentElement = (Element) processorNodes.item(i);
Assert.assertEquals(1, componentElement.getElementsByTagName(FlowEnricher.EnrichingElementAdapter.BUNDLE_ELEMENT_NAME).getLength());
final FlowEnricher.EnrichingElementAdapter elementAdapter = new FlowEnricher.EnrichingElementAdapter(componentElement);
// Only our Kafka processor has a bundle outside of the standard bundle
if (elementAdapter.getComponentClass().equalsIgnoreCase(KAFKA_PROCESSOR_CLASS)) {
verifyBundleProperties(elementAdapter, defaultGroup, kafkaId, anotherVersion);
} else {
verifyBundleProperties(elementAdapter, minifiGroup, minifiStandardNarId, minifiVersion);
}
}
for (int i = 0; i < controllerServiceNodes.getLength(); i++) {
final Element componentElement = (Element) controllerServiceNodes.item(i);
Assert.assertEquals(1, componentElement.getElementsByTagName(FlowEnricher.EnrichingElementAdapter.BUNDLE_ELEMENT_NAME).getLength());
final FlowEnricher.EnrichingElementAdapter elementAdapter = new FlowEnricher.EnrichingElementAdapter(componentElement);
// Only our Kafka processor has a bundle outside of the standard bundle
if (elementAdapter.getComponentClass().equalsIgnoreCase(SSL_CONTROLLER_SERVICE_CLASS)) {
verifyBundleProperties(elementAdapter, defaultGroup, sslContextSvcId, anotherVersion);
} else {
Assert.fail("A controller service that was not an SSL Controller service was found.");
}
}
// Verify the updated flow was persisted
Mockito.verify(mockFlowParser, atLeastOnce()).writeFlow(any(), any());
}
Aggregations