This is an automated email from the ASF dual-hosted git repository.

nodece pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 235a7a8a4ca [fix][fn] Fix functions update issue where artifact is 
provided as a http url (#25840)
235a7a8a4ca is described below

commit 235a7a8a4ca3cb6914f965ae2407030dbd1fa128
Author: sbourkeostk <[email protected]>
AuthorDate: Thu May 21 10:25:36 2026 +0100

    [fix][fn] Fix functions update issue where artifact is provided as a http 
url (#25840)
    
    Co-authored-by: Stephen Bourke <[email protected]>
    Co-authored-by: Lari Hotari <[email protected]>
    Co-authored-by: Zixuan Liu <[email protected]>
---
 .../functions/worker/rest/api/ComponentImpl.java   |  4 +--
 .../api/v3/AbstractFunctionApiResourceTest.java    | 36 ++++++++++++++++++++++
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git 
a/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/ComponentImpl.java
 
b/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/ComponentImpl.java
index 28fe2c5ea8f..f74ccf4a26b 100644
--- 
a/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/ComponentImpl.java
+++ 
b/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/ComponentImpl.java
@@ -1926,7 +1926,7 @@ public abstract class ComponentImpl implements 
Component<PulsarWorkerService> {
         if (isNotBlank(functionPkgUrl)) {
             componentPackageFile = getPackageFile(componentType, 
functionPkgUrl);
         } else if (existingPackagePath.startsWith(Utils.FILE) || 
existingPackagePath.startsWith(Utils.HTTP)) {
-            if 
(!worker().getPackageUrlValidator().isValidPackageUrl(componentType, 
functionPkgUrl)) {
+            if 
(!worker().getPackageUrlValidator().isValidPackageUrl(componentType, 
existingPackagePath)) {
                 throw new IllegalArgumentException("Function Package url is 
not valid."
                         + "supported url (http/https/file)");
             }
@@ -1935,7 +1935,7 @@ public abstract class ComponentImpl implements 
Component<PulsarWorkerService> {
             } catch (Exception e) {
                 throw new IllegalArgumentException(String.format("Encountered 
error \"%s\" "
                                 + "when getting %s package from %s", 
e.getMessage(),
-                        ComponentTypeUtils.toString(componentType), 
functionPkgUrl));
+                        ComponentTypeUtils.toString(componentType), 
existingPackagePath));
             }
         } else if (Utils.hasPackageTypePrefix(existingPackagePath)) {
             componentPackageFile = getPackageFile(componentType, 
existingPackagePath);
diff --git 
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/AbstractFunctionApiResourceTest.java
 
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/AbstractFunctionApiResourceTest.java
index f5b11c4567a..453e39e4132 100644
--- 
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/AbstractFunctionApiResourceTest.java
+++ 
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/AbstractFunctionApiResourceTest.java
@@ -1020,6 +1020,42 @@ public abstract class AbstractFunctionApiResourceTest 
extends AbstractFunctionsR
 
     }
 
+    @Test
+    public void testUpdateFunctionWithExistingFileUrl() throws IOException {
+
+        String fileLocation = 
FutureUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+        String filePackageUrl = "file://" + fileLocation;
+
+        FunctionConfig functionConfig = new FunctionConfig();
+        functionConfig.setOutput(OUTPUT_TOPIC);
+        functionConfig.setOutputSerdeClassName(OUTPUT_SERDE_CLASS_NAME);
+        functionConfig.setTenant(TENANT);
+        functionConfig.setNamespace(NAMESPACE);
+        functionConfig.setName(FUNCTION);
+        functionConfig.setClassName(CLASS_NAME);
+        // increment parallelism to avoid 'Update contains no change' exception
+        functionConfig.setParallelism(PARALLELISM + 1);
+        functionConfig.setRuntime(FunctionConfig.Runtime.JAVA);
+        functionConfig.setCustomSerdeInputs(TOPICS_TO_SER_DE_CLASS_NAME);
+
+        FunctionMetaData existingMetaData = new FunctionMetaData();
+        
existingMetaData.setFunctionDetails().copyFrom(createDefaultFunctionDetails());
+        existingMetaData.setPackageLocation().setPackagePath(filePackageUrl);
+
+        when(mockedManager.containsFunction(eq(TENANT), eq(NAMESPACE), 
eq(FUNCTION))).thenReturn(true);
+        when(mockedManager.getFunctionMetaData(any(), any(), 
any())).thenReturn(existingMetaData);
+
+        updateFunction(
+                TENANT,
+                NAMESPACE,
+                FUNCTION,
+                null,
+                null,
+                null,
+                functionConfig,
+                null, null);
+    }
+
     @Test(expectedExceptions = RestException.class, 
expectedExceptionsMessageRegExp = "function failed to register")
     public void testUpdateFunctionFailure() throws Exception {
         try {

Reply via email to