Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIFI-13770 Remove Placeholder Prefix from Python Component Types #9283

Merged
merged 1 commit into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public interface PythonProcessorBridge {
void replaceController(PythonController controller);

/**
* @return the name of the Processor implementation. This will not contain a 'python.' prefix.
* @return the name of the Processor implementation.
*/
String getProcessorType();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ public ProcessorNode buildProcessor() {

final String componentType;
if (PythonBundle.isPythonCoordinate(bundleCoordinate)) {
componentType = type.substring("python.".length());
componentType = type;
} else if (creationSuccessful) {
componentType = loggableComponent.getComponent().getClass().getSimpleName();
} else {
Expand Down Expand Up @@ -896,9 +896,7 @@ private LoggableComponent<Processor> createLoggablePythonProcessor() {
classloaderIsolationKey);
Thread.currentThread().setContextClassLoader(detectedClassLoader);

// TODO: This is a hack because there's a bug in the UI that causes it to not load extensions that don't have a `.` in the type.
final String processorType = type.startsWith("python.") ? type.substring("python.".length()) : type;
final Processor processor = pythonBridge.createProcessor(identifier, processorType, bundleCoordinate.getVersion(), true, true);
final Processor processor = pythonBridge.createProcessor(identifier, type, bundleCoordinate.getVersion(), true, true);

final ComponentLog componentLog = new SimpleProcessLogger(identifier, processor, new StandardLoggingContext(null));
final TerminationAwareLogger terminationAwareLogger = new TerminationAwareLogger(componentLog);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ private <T extends ComponentNode> boolean isComponentFromType(final T componentN

if (PythonBundle.isPythonCoordinate(componentCoordinate)) {
final String componentType = componentNode.getComponentType();
final String pythonComponentType = "python." + componentType;
return pythonComponentType.equals(extensionDefinitionClassName) && componentCoordinate.equals(extensionDefinitionCoordinate);
return componentType.equals(extensionDefinitionClassName) && componentCoordinate.equals(extensionDefinitionCoordinate);
} else if (componentNode.isExtensionMissing()) {
return componentClassName.equals(extensionDefinitionClassName)
&& componentCoordinate.getGroup().equals(extensionDefinitionCoordinate.getGroup())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public class ComponentNodeDefinitionPredicateTest {
private static final BundleCoordinate STANDARD_BUNDLE_COORDINATE_V2 = new BundleCoordinate("org.apache.nifi", "my-processors-nar", "2.0.0");

private static final String PYTHON_PROCESSOR_TYPE = "PythonProcessor";
private static final String FULL_PYTHON_PROCESSOR_TYPE = "python." + PYTHON_PROCESSOR_TYPE;
private static final String OTHER_PYTHON_PROCESSOR_TYPE = "OtherPythonProcessor";
private static final BundleCoordinate PYTHON_BUNDLE_COORDINATE = new BundleCoordinate(PythonBundle.GROUP_ID, PythonBundle.ARTIFACT_ID, "0.0.1");

Expand All @@ -66,7 +65,7 @@ public void setup() {
when(pythonBundle.getBundleDetails()).thenReturn(pythonBundleDetails);

pythonProcessorDefinition = mock(ExtensionDefinition.class);
when(pythonProcessorDefinition.getImplementationClassName()).thenReturn(FULL_PYTHON_PROCESSOR_TYPE);
when(pythonProcessorDefinition.getImplementationClassName()).thenReturn(PYTHON_PROCESSOR_TYPE);
when(pythonProcessorDefinition.getBundle()).thenReturn(pythonBundle);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@
public class StandardExtensionDiscoveringManager implements ExtensionDiscoveringManager {

private static final Logger logger = LoggerFactory.getLogger(StandardExtensionDiscoveringManager.class);
private static final String PYTHON_TYPE_PREFIX = "python.";

// Maps a service definition (interface) to those classes that implement the interface
private final Map<Class<?>, Set<ExtensionDefinition>> definitionMap = new HashMap<>();
Expand Down Expand Up @@ -234,8 +233,7 @@ private void loadPythonExtensions(final Bundle pythonBundle, final long startTim
final BundleDetails bundleDetails = createBundleDetailsWithOverriddenVersion(pythonBundle.getBundleDetails(), details.getProcessorVersion());
final Bundle bundle = new Bundle(bundleDetails, pythonBundle.getClassLoader());

// TODO: This is a workaround because the UI has a bug that causes it not to work properly if the type doesn't have a '.' in it
final String className = PYTHON_TYPE_PREFIX + details.getProcessorType();
final String className = details.getProcessorType();
final ExtensionDefinition extensionDefinition = new ExtensionDefinition.Builder()
.implementationClassName(className)
.runtime(ExtensionRuntime.PYTHON)
Expand Down Expand Up @@ -274,8 +272,7 @@ private void loadPythonExtensions(final Bundle pythonBundle, final long startTim

@Override
public synchronized PythonProcessorDetails getPythonProcessorDetails(final String processorType, final String version) {
final String canonicalProcessorType = stripPythonTypePrefix(processorType);
final List<PythonProcessorDetails> detailsList = this.pythonProcessorDetails.get(canonicalProcessorType);
final List<PythonProcessorDetails> detailsList = this.pythonProcessorDetails.get(processorType);
if (detailsList == null) {
return null;
}
Expand Down Expand Up @@ -785,19 +782,18 @@ private void removeExtensionDefinition(final ExtensionDefinition extensionDefini
final String tempComponentKey = getClassBundleKey(removeExtensionClassName, extensionDefinitionCoordinate);
final ConfigurableComponent removedTempComponent = tempComponentLookup.remove(tempComponentKey);

if (removeExtensionClassName.startsWith(PYTHON_TYPE_PREFIX)) {
final String strippedClassName = stripPythonTypePrefix(removeExtensionClassName);
logger.debug("Removing Python processor type {} - {}", strippedClassName, extensionDefinition.getVersion());
if (PythonBundle.isPythonCoordinate(extensionDefinitionCoordinate)) {
logger.debug("Removing Python processor type {} - {}", removeExtensionClassName, extensionDefinition.getVersion());

final List<PythonProcessorDetails> processorDetailsList = Optional.ofNullable(pythonProcessorDetails.get(strippedClassName)).orElse(Collections.emptyList());
processorDetailsList.removeIf(processorDetails -> processorDetails.getProcessorType().equals(strippedClassName)
final List<PythonProcessorDetails> processorDetailsList = Optional.ofNullable(pythonProcessorDetails.get(removeExtensionClassName)).orElse(Collections.emptyList());
processorDetailsList.removeIf(processorDetails -> processorDetails.getProcessorType().equals(removeExtensionClassName)
&& processorDetails.getProcessorVersion().equals(extensionDefinition.getVersion()));

if (removedTempComponent != null) {
final String pythonTempComponentId = getPythonTempComponentId(strippedClassName);
pythonBridge.onProcessorRemoved(pythonTempComponentId, strippedClassName, extensionDefinition.getVersion());
final String pythonTempComponentId = getPythonTempComponentId(removeExtensionClassName);
pythonBridge.onProcessorRemoved(pythonTempComponentId, removeExtensionClassName, extensionDefinition.getVersion());
}
pythonBridge.removeProcessorType(strippedClassName, extensionDefinition.getVersion());
pythonBridge.removeProcessorType(removeExtensionClassName, extensionDefinition.getVersion());
}
}

Expand Down Expand Up @@ -861,11 +857,8 @@ public synchronized ConfigurableComponent getTempComponent(final String classTyp
try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(bundleClassLoader)) {
final ConfigurableComponent tempComponent;
if (PythonBundle.isPythonCoordinate(bundle.getBundleDetails().getCoordinate())) {
// TODO: This is a workaround due to bug in UI. Fix bug in UI.
final String type = stripPythonTypePrefix(classType);

final String procId = getPythonTempComponentId(type);
tempComponent = pythonBridge.createProcessor(procId, type, bundleCoordinate.getVersion(), false, false);
final String procId = getPythonTempComponentId(classType);
tempComponent = pythonBridge.createProcessor(procId, classType, bundleCoordinate.getVersion(), false, false);
} else {
final Class<?> componentClass = Class.forName(classType, true, bundleClassLoader);
tempComponent = (ConfigurableComponent) componentClass.getDeclaredConstructor().newInstance();
Expand All @@ -890,17 +883,6 @@ private static String getPythonTempComponentId(final String type) {
return "temp-component-" + type;
}

private static String stripPythonTypePrefix(final String value) {
if (value == null) {
return null;
}
if (value.startsWith(PYTHON_TYPE_PREFIX)) {
return value.substring(PYTHON_TYPE_PREFIX.length());
}

return value;
}

private static String getClassBundleKey(final String classType, final BundleCoordinate bundleCoordinate) {
return classType + "_" + bundleCoordinate.getCoordinate();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export class Prioritizers implements ControlValueAccessor {
}

getPrioritizerLabel(entity: DocumentedType): string {
return this.nifiCommon.substringAfterLast(entity.type, '.');
return this.nifiCommon.getComponentTypeLabel(entity.type);
}

hasDescription(entity: DocumentedType): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export class CreateRegistryClient extends CloseOnEscapeDialog {
}

formatType(option: DocumentedType): string {
return this.nifiCommon.substringAfterLast(option.type, '.');
return this.nifiCommon.getComponentTypeLabel(option.type);
}

createRegistryClientClicked() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class ChangeComponentVersionDialog extends CloseOnEscapeDialog {
}

getName(selected: DocumentedType | null): string {
return this.nifiCommon.substringAfterLast(selected?.type || '', '.');
return this.nifiCommon.getComponentTypeLabel(selected?.type || '');
}

protected readonly TextTip = TextTip;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class ExtensionCreation extends CloseOnEscapeDialog {

formatType(documentedType: DocumentedType): string {
if (documentedType) {
return this.nifiCommon.substringAfterLast(documentedType.type, '.');
return this.nifiCommon.getComponentTypeLabel(documentedType.type);
}
return '';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export class NiFiCommon {
public static readonly BYTES_IN_GIGABYTE: number = 1073741824;
public static readonly BYTES_IN_TERABYTE: number = 1099511627776;

public static readonly PACKAGE_SEPARATOR: string = '.';

private policyTypeListing: SelectOption[] = [
{
text: 'view the user interface',
Expand Down Expand Up @@ -173,6 +175,22 @@ export class NiFiCommon {
return result;
}

/**
* Get the label for a Component Type using the simple name from a qualified class
*
* @argument {string} componentType Qualified class name or simple name
*/
public getComponentTypeLabel(componentType: string): string {
let label = componentType;

const separatorIndex = componentType.indexOf(NiFiCommon.PACKAGE_SEPARATOR);
if (separatorIndex >= 0) {
label = this.substringAfterLast(componentType, NiFiCommon.PACKAGE_SEPARATOR);
}

return label;
}

/**
* Determines whether the specified string is blank (or null or undefined).
*
Expand Down Expand Up @@ -268,7 +286,7 @@ export class NiFiCommon {
* @param dataContext component datum
*/
public formatClassName(dataContext: any): string {
return this.substringAfterLast(dataContext.type, '.');
return this.getComponentTypeLabel(dataContext.type);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public void stopProcessor(final ProcessorEntity currentEntity) throws NiFiClient
}

public ProcessorEntity createPythonProcessor(final String typeName) throws NiFiClientException, IOException {
return createProcessor( "python." + typeName, NiFiSystemIT.NIFI_GROUP_ID, NiFiSystemIT.TEST_PYTHON_EXTENSIONS_ARTIFACT_ID, "0.0.1-SNAPSHOT");
return createProcessor(typeName, NiFiSystemIT.NIFI_GROUP_ID, NiFiSystemIT.TEST_PYTHON_EXTENSIONS_ARTIFACT_ID, "0.0.1-SNAPSHOT");
}

public ProcessorEntity createProcessor(final String simpleTypeName) throws NiFiClientException, IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class NarUploadPythonIT extends NiFiSystemIT {
private static final Logger logger = LoggerFactory.getLogger(NarUploadPythonIT.class);

private static final String PYTHON_TEXT_EXTENSIONS_NAR_ID = "nifi-python-test-extensions-nar";
private static final String PYTHON_WRITE_BECH_32_CHARSET = "python.WriteBech32Charset";
private static final String PYTHON_WRITE_BECH_32_CHARSET = "WriteBech32Charset";
private static final String EXPECTED_FLOW_FILE_CONTENT = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";

@Override
Expand Down