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

lhotari pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/pulsar.git

commit e9ba10bd3849af30ab433a33f0a4835a04614cdb
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]>
    (cherry picked from commit 235a7a8a4ca3cb6914f965ae2407030dbd1fa128)
---
 .../functions/worker/rest/api/ComponentImpl.java   |  4 +--
 .../api/v3/AbstractFunctionApiResourceTest.java    | 39 ++++++++++++++++++++++
 2 files changed, 41 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 4058ebb667c..f3bebd78de6 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
@@ -1776,7 +1776,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)");
             }
@@ -1785,7 +1785,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 d7c5b877f63..16cf98b9847 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
@@ -1028,6 +1028,45 @@ 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 = FunctionMetaData.newBuilder()
+                .setFunctionDetails(createDefaultFunctionDetails())
+                
.setPackageLocation(org.apache.pulsar.functions.proto.Function.PackageLocationMetaData.newBuilder()
+                        .setPackagePath(filePackageUrl)
+                        .build())
+                .build();
+
+        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