private static boolean registerModule( Path pythonModuleRoot, String pythonModuleName, final String pythonClassName) { String pythonModuleRelPath = pythonModuleName.replace('.', '/'); Path pythonModuleFile = pythonModuleRoot.resolve(pythonModuleRelPath + ".py"); if (!Files.exists(pythonModuleFile)) { LOG.severe(String.format("Missing Python module '%s'", pythonModuleFile.toUri())); return false; } Path pythonInfoXmlFile = pythonModuleRoot.resolve(pythonModuleRelPath + "-info.xml"); if (!Files.exists(pythonInfoXmlFile)) { LOG.warning( String.format( "Missing operator metadata file '%s'. Using defaults.", pythonInfoXmlFile.toUri())); } DefaultOperatorDescriptor operatorDescriptor = createOperatorDescriptor(pythonInfoXmlFile, pythonModuleName); File pythonModuleRootFile = FileUtils.toFile(pythonModuleRoot); PyOperatorSpi operatorSpi = new PyOperatorSpi(operatorDescriptor) { @Override public Operator createOperator() throws OperatorException { PyOperator pyOperator = (PyOperator) super.createOperator(); pyOperator.setParameterDefaultValues(); pyOperator.setPythonModulePath(pythonModuleRootFile.getPath()); pyOperator.setPythonModuleName(pythonModuleName); pyOperator.setPythonClassName(pythonClassName); return pyOperator; } }; String operatorName = operatorDescriptor.getAlias() != null ? operatorDescriptor.getAlias() : operatorDescriptor.getName(); GPF.getDefaultInstance().getOperatorSpiRegistry().addOperatorSpi(operatorName, operatorSpi); LOG.info( String.format( "Python operator '%s' registered (Python module: '%s', class: '%s', root: '%s')", operatorName, pythonModuleName, pythonClassName, pythonModuleRootFile)); return true; }
private static DefaultOperatorDescriptor createOperatorDescriptor( Path pythonInfoXmlFile, String pythonModuleName) { DefaultOperatorDescriptor operatorDescriptor; if (Files.exists(pythonInfoXmlFile)) { try { try (BufferedReader reader = Files.newBufferedReader(pythonInfoXmlFile)) { operatorDescriptor = DefaultOperatorDescriptor.fromXml( reader, pythonInfoXmlFile.toUri().toString(), PyOperatorSpi.class.getClassLoader()); } } catch (IOException e) { LOG.severe(String.format("Failed to read from '%s'", pythonInfoXmlFile)); operatorDescriptor = null; } } else { operatorDescriptor = new DefaultOperatorDescriptor(pythonModuleName, PyOperator.class); } return operatorDescriptor; }