public static Class<?>[] getFunctionTypes(FunctionConfig functionConfig, ClassLoader classLoader) { Object userClass = createInstance(functionConfig.getClassName(), classLoader); boolean isWindowConfigPresent = functionConfig.getWindowConfig() != null; return getFunctionTypes(userClass, isWindowConfigPresent); }
private void inferMissingArguments(FunctionConfig functionConfig) { if (StringUtils.isEmpty(functionConfig.getName())) { inferMissingFunctionName(functionConfig); } if (StringUtils.isEmpty(functionConfig.getTenant())) { inferMissingTenant(functionConfig); } if (StringUtils.isEmpty(functionConfig.getNamespace())) { inferMissingNamespace(functionConfig); } if (functionConfig.getParallelism() == 0) { functionConfig.setParallelism(1); } if (functionConfig.getJar() != null) { functionConfig.setRuntime(FunctionConfig.Runtime.JAVA); } else if (functionConfig.getPy() != null) { functionConfig.setRuntime(FunctionConfig.Runtime.PYTHON); } WindowConfig windowConfig = functionConfig.getWindowConfig(); if (windowConfig != null) { WindowUtils.inferDefaultConfigs(windowConfig); functionConfig.setAutoAck(false); } }
private static void doPythonChecks(FunctionConfig functionConfig, String name) { if (functionConfig.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE) { throw new RuntimeException("Effectively-once processing guarantees not yet supported in Python"); } if (functionConfig.getWindowConfig() != null) { throw new IllegalArgumentException("There is currently no support windowing in python"); } if (functionConfig.getMaxMessageRetries() >= 0) { throw new IllegalArgumentException("Message retries not yet supported in python"); } }
private void inferMissingFunctionName(FunctionConfig functionConfig) { if (isNull(functionConfig.getClassName())) { throw new ParameterException("You must specify a class name for the function"); } String[] domains = functionConfig.getClassName().split("\\."); if (domains.length == 0) { functionConfig.setName(functionConfig.getClassName()); } else { functionConfig.setName(domains[domains.length - 1]); } }
functionConfig = CmdUtils.loadConfig(fnConfigFile, FunctionConfig.class); } else { functionConfig = new FunctionConfig(); } else { if (null != tenant) { functionConfig.setTenant(tenant); functionConfig.setNamespace(namespace); functionConfig.setName(functionName); functionConfig.setInputs(inputTopics); functionConfig.setCustomSerdeInputs(customSerdeInputMap); functionConfig.setCustomSchemaInputs(customschemaInputMap); functionConfig.setTopicsPattern(topicsPattern); functionConfig.setOutput(output); functionConfig.setLogTopic(logTopic); functionConfig.setClassName(className); functionConfig.setOutputSerdeClassName(outputSerdeClassName); functionConfig.setOutputSchemaType(schemaType);
if (functionConfig.getRuntime() == FunctionConfig.Runtime.JAVA) { if (classLoader != null) { typeArgs = Utils.getFunctionTypes(functionConfig, classLoader); if (functionConfig.getInputs() != null) { functionConfig.getInputs().forEach((topicName -> { sourceSpecBuilder.putInputSpecs(topicName, Function.ConsumerSpec.newBuilder() if (functionConfig.getTopicsPattern() != null && !functionConfig.getTopicsPattern().isEmpty()) { sourceSpecBuilder.putInputSpecs(functionConfig.getTopicsPattern(), Function.ConsumerSpec.newBuilder() .setIsRegexPattern(true) .build()); if (functionConfig.getCustomSerdeInputs() != null) { functionConfig.getCustomSerdeInputs().forEach((topicName, serdeClassName) -> { sourceSpecBuilder.putInputSpecs(topicName, Function.ConsumerSpec.newBuilder() if (functionConfig.getCustomSchemaInputs() != null) { functionConfig.getCustomSchemaInputs().forEach((topicName, schemaType) -> { sourceSpecBuilder.putInputSpecs(topicName, Function.ConsumerSpec.newBuilder() if (functionConfig.getInputSpecs() != null) { functionConfig.getInputSpecs().forEach((topicName, consumerConf) -> { Function.ConsumerSpec.Builder bldr = Function.ConsumerSpec.newBuilder() .setIsRegexPattern(consumerConf.isRegexPattern());
private static void doCommonChecks(FunctionConfig functionConfig) { Collection<String> allInputTopics = collectAllInputTopics(functionConfig); if (allInputTopics.isEmpty()) { throw new RuntimeException("No input topic(s) specified for the function"); } // Ensure that topics aren't being used as both input and output verifyNoTopicClash(allInputTopics, functionConfig.getOutput()); WindowConfig windowConfig = functionConfig.getWindowConfig(); if (windowConfig != null) { // set auto ack to false since windowing framework is responsible // for acking and not the function framework if (functionConfig.isAutoAck() == true) { throw new IllegalArgumentException("Cannot enable auto ack when using windowing functionality"); } functionConfig.setAutoAck(false); } if (functionConfig.getTimeoutMs() != null && functionConfig.getProcessingGuarantees() != null && functionConfig.getProcessingGuarantees() != FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE) { throw new IllegalArgumentException("Message timeout can only be specified with processing guarantee is " + FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE.name()); } if (functionConfig.getMaxMessageRetries() >= 0 && functionConfig.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE) { throw new IllegalArgumentException("MaxMessageRetries and Effectively once don't gel well"); } if (functionConfig.getMaxMessageRetries() < 0 && !StringUtils.isEmpty(functionConfig.getDeadLetterTopic())) { throw new IllegalArgumentException("Dead Letter Topic specified, however max retries is set to infinity"); } }
protected void validateFunctionConfigs(FunctionConfig functionConfig) { if (isNotBlank(functionConfig.getJar()) && isNotBlank(functionConfig.getPy())) { throw new ParameterException("Either a Java jar or a Python file needs to" + " be specified for the function. Cannot specify both."); if (isBlank(functionConfig.getJar()) && isBlank(functionConfig.getPy())) { throw new ParameterException("Either a Java jar or a Python file needs to" + " be specified for the function. Please specify one."); boolean isJarPathUrl = isNotBlank(functionConfig.getJar()) && Utils.isFunctionPackageUrlSupported(functionConfig.getJar()); String jarFilePath = null; if (isJarPathUrl) { if (functionConfig.getJar().startsWith(Utils.HTTP)) { tempPkgFile = downloadFromHttpUrl(functionConfig.getJar(), functionConfig.getName()); jarFilePath = tempPkgFile.getAbsolutePath(); } catch (Exception e) { throw new ParameterException("Failed to download jar from " + functionConfig.getJar() + ", due to =" + e.getMessage()); if (functionConfig.getRuntime() == FunctionConfig.Runtime.JAVA) { .validateField("className", functionConfig.getClassName(), classLoader); ConfigValidation.validateConfig(functionConfig, functionConfig.getRuntime().name(), classLoader); } catch (Exception e) { throw new IllegalArgumentException(e.getMessage());
@Override public void validateField(String name, Object o, ClassLoader classLoader) { FunctionConfig functionConfig = (FunctionConfig) o; doCommonChecks(functionConfig); if (functionConfig.getRuntime() == FunctionConfig.Runtime.JAVA) { if (classLoader != null) { doJavaChecks(functionConfig, name, classLoader); } } else { doPythonChecks(functionConfig, name); } } }
@Override void runCmd() throws Exception { // merge deprecated args with new args mergeArgs(); CmdFunctions.startLocalRun(FunctionConfigUtils.convert(functionConfig, classLoader), functionConfig.getParallelism(), instanceIdOffset, brokerServiceUrl, stateStorageServiceUrl, AuthenticationConfig.builder().clientAuthenticationPlugin(clientAuthPlugin) .clientAuthenticationParameters(clientAuthParams).useTls(useTls) .tlsAllowInsecureConnection(tlsAllowInsecureConnection) .tlsHostnameVerificationEnable(tlsHostNameVerificationEnabled) .tlsTrustCertsFilePath(tlsTrustCertFilePath).build(), userCodeFile, admin); } }