Skip to content

Commit a27a88b

Browse files
committed
NIFI-14064: Descriptions are not shown for Python processors
Bug's been present since fb2a82c / PR #9288
1 parent df793ce commit a27a88b

File tree

4 files changed

+112
-0
lines changed

4 files changed

+112
-0
lines changed

nifi-extension-bundles/nifi-py4j-extension-bundle/nifi-py4j-integration-tests/src/test/java/org.apache.nifi.py4j/PythonControllerInteractionIT.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import java.nio.file.Files;
5252
import java.nio.file.Paths;
5353
import java.time.Duration;
54+
import java.util.Arrays;
5455
import java.util.Collections;
5556
import java.util.HashMap;
5657
import java.util.List;
@@ -160,6 +161,7 @@ public void testGetProcessorDetails() {
160161
.orElseThrow(() -> new RuntimeException("Could not find ConvertCsvToExcel"));
161162

162163
assertEquals("0.0.1-SNAPSHOT", convertCsvToExcel.getProcessorVersion());
164+
assertEquals(Arrays.asList("csv", "excel"), convertCsvToExcel.getTags());
163165
assertEquals(new File("target/python/extensions/ConvertCsvToExcel.py").getAbsolutePath(),
164166
new File(convertCsvToExcel.getSourceLocation()).getAbsolutePath());
165167
}

nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/manifest/StandardRuntimeManifestService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ private Extension createExtension(final PythonProcessorDetails pythonProcessorDe
191191
final Extension extension = new Extension();
192192
extension.setDescription(pythonProcessorDetails.getCapabilityDescription());
193193
extension.setName(pythonProcessorDetails.getProcessorType());
194+
extension.setTags(pythonProcessorDetails.getTags());
194195
extension.setInputRequirement(InputRequirement.INPUT_REQUIRED);
195196
extension.setSupportsBatching(true);
196197
extension.setType(ExtensionType.PROCESSOR);

nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/manifest/StandardRuntimeManifestServiceTest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,22 @@
2525
import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
2626
import org.apache.nifi.extension.manifest.parser.ExtensionManifestParser;
2727
import org.apache.nifi.extension.manifest.parser.jaxb.JAXBExtensionManifestParser;
28+
import org.apache.nifi.nar.ExtensionDefinition;
29+
import org.apache.nifi.nar.ExtensionDefinition.ExtensionRuntime;
2830
import org.apache.nifi.nar.ExtensionManager;
31+
import org.apache.nifi.nar.PythonBundle;
32+
import org.apache.nifi.processor.Processor;
33+
import org.apache.nifi.python.PythonProcessorDetails;
2934
import org.junit.jupiter.api.BeforeEach;
3035
import org.junit.jupiter.api.Test;
36+
import org.mockito.internal.util.collections.Sets;
3137

3238
import java.io.File;
3339
import java.util.Arrays;
3440
import java.util.HashSet;
3541
import java.util.List;
3642

43+
import static java.util.Collections.emptySet;
3744
import static org.junit.jupiter.api.Assertions.assertEquals;
3845
import static org.junit.jupiter.api.Assertions.assertNotNull;
3946
import static org.mockito.Mockito.mock;
@@ -43,6 +50,7 @@ public class StandardRuntimeManifestServiceTest {
4350

4451
private Bundle frameworkBundle;
4552
private Bundle testComponentsBundle;
53+
private Bundle testPythonComponentsBundle;
4654
private ExtensionManager extensionManager;
4755
private ExtensionManifestParser extensionManifestParser;
4856
private RuntimeManifestService runtimeManifestService;
@@ -69,6 +77,13 @@ public void setup() {
6977

7078
testComponentsBundle = new Bundle(testComponentsBundleDetails, this.getClass().getClassLoader());
7179

80+
final BundleDetails testPythonComponentsBundleDetails = new BundleDetails.Builder()
81+
.coordinate(PythonBundle.PYTHON_BUNDLE_COORDINATE)
82+
.workingDir(new File("src/test/resources/TestRuntimeManifest/nifi-test-python-components-nar"))
83+
.build();
84+
85+
testPythonComponentsBundle = new Bundle(testPythonComponentsBundleDetails, this.getClass().getClassLoader());
86+
7287
extensionManager = mock(ExtensionManager.class);
7388
extensionManifestParser = new JAXBExtensionManifestParser();
7489
runtimeManifestService = new TestableRuntimeManifestService(extensionManager, extensionManifestParser, frameworkBundle);
@@ -105,6 +120,49 @@ public void testGetRuntimeManifest() {
105120
assertEquals(1, controllerServiceDefinitions.size());
106121
}
107122

123+
@Test
124+
public void testGetPythonManifest() {
125+
final String CLASS_NAME = "ClassName";
126+
final List<String> EXPECTED_TAGS = Arrays.asList("tag1", "tag2");
127+
128+
when(extensionManager.getAllBundles()).thenReturn(emptySet());
129+
when(extensionManager.getExtensions(Processor.class)).thenReturn(Sets.newSet(
130+
new ExtensionDefinition.Builder()
131+
.implementationClassName(CLASS_NAME)
132+
.runtime(ExtensionRuntime.PYTHON)
133+
.bundle(testPythonComponentsBundle)
134+
.extensionType(Processor.class)
135+
.tags(EXPECTED_TAGS)
136+
.version(PythonBundle.VERSION)
137+
.build()
138+
));
139+
140+
final PythonProcessorDetails pythonProcessorDetails = mock(PythonProcessorDetails.class);
141+
when(pythonProcessorDetails.getTags()).thenReturn(EXPECTED_TAGS);
142+
143+
when(extensionManager.getPythonProcessorDetails(CLASS_NAME, PythonBundle.VERSION)).thenReturn(pythonProcessorDetails);
144+
145+
final List<org.apache.nifi.c2.protocol.component.api.Bundle> bundles = runtimeManifestService.getManifest().getBundles();
146+
assertNotNull(bundles);
147+
assertEquals(1, bundles.size());
148+
149+
final org.apache.nifi.c2.protocol.component.api.Bundle testPythonComponentsManifestBundle = bundles.getFirst();
150+
assertEquals(PythonBundle.GROUP_ID, testPythonComponentsManifestBundle.getGroup());
151+
assertEquals(PythonBundle.ARTIFACT_ID, testPythonComponentsManifestBundle.getArtifact());
152+
assertEquals(PythonBundle.VERSION, testPythonComponentsManifestBundle.getVersion());
153+
154+
final ComponentManifest testComponentsManifest = testPythonComponentsManifestBundle.getComponentManifest();
155+
assertNotNull(testComponentsManifest);
156+
157+
final List<ProcessorDefinition> processorDefinitions = testComponentsManifest.getProcessors();
158+
assertEquals(1, processorDefinitions.size());
159+
160+
assertEquals(new HashSet<>(EXPECTED_TAGS), processorDefinitions.getFirst().getTags());
161+
162+
final List<ControllerServiceDefinition> controllerServiceDefinitions = testComponentsManifest.getControllerServices();
163+
assertEquals(0, controllerServiceDefinitions.size());
164+
}
165+
108166
/**
109167
* Override getFrameworkBundle to provide a mocked Bundle.
110168
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
-->
15+
<extensionManifest>
16+
<systemApiVersion>1.8.0</systemApiVersion>
17+
<extensions>
18+
<extension>
19+
<name>TestProcessor1</name>
20+
<type>PROCESSOR</type>
21+
<description>Test processor 1.</description>
22+
<tags>
23+
<tag>test</tag>
24+
<tag>processor</tag>
25+
</tags>
26+
<triggerSerially>true</triggerSerially>
27+
<triggerWhenEmpty>true</triggerWhenEmpty>
28+
<triggerWhenAnyDestinationAvailable>true</triggerWhenAnyDestinationAvailable>
29+
<primaryNodeOnly>true</primaryNodeOnly>
30+
<supportsBatching>true</supportsBatching>
31+
<sideEffectFree>true</sideEffectFree>
32+
<defaultSettings>
33+
<yieldDuration>10 secs</yieldDuration>
34+
<penaltyDuration>20 secs</penaltyDuration>
35+
<bulletinLevel>DEBUG</bulletinLevel>
36+
</defaultSettings>
37+
<defaultSchedule>
38+
<strategy>CRON_DRIVEN</strategy>
39+
<period>* 1 * * *</period>
40+
<concurrentTasks>5</concurrentTasks>
41+
</defaultSchedule>
42+
</extension>
43+
<extension>
44+
<name>TestProcessor2</name>
45+
<type>PROCESSOR</type>
46+
<description/>
47+
<tags>
48+
</tags>
49+
</extension>
50+
</extensions>
51+
</extensionManifest>

0 commit comments

Comments
 (0)