You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by mm...@apache.org on 2018/04/06 19:34:50 UTC

[incubator-pulsar] branch master updated: Enable FQFN specification for the Pulsar Functions CLI (#1504)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9d23892  Enable FQFN specification for the Pulsar Functions CLI (#1504)
9d23892 is described below

commit 9d23892568e4158c04417bab027dae7fc8b6eebc
Author: Luc Perkins <lu...@gmail.com>
AuthorDate: Fri Apr 6 12:34:47 2018 -0700

    Enable FQFN specification for the Pulsar Functions CLI (#1504)
    
    * Add FQFN flag plus corresponding test
    
    * add fqfn field to function config protobuf definition
    
    * add section in PF overview on FQFNs
    
    * add missing --jar flag to test
    
    * remove unnecessary imports
    
    * add missing license header
    
    * add final missing import
    
    * remove incomplete line
    
    * make FQFN name check more stringent
---
 .../apache/pulsar/admin/cli/CmdFunctionsTest.java  | 25 ++++++++++++
 .../org/apache/pulsar/admin/cli/CmdFunctions.java  | 45 ++++++++++++++++------
 .../proto/src/main/proto/Function.proto            |  3 ++
 site/_includes/fqfn.html                           | 23 +++++++++++
 site/_sass/_docs.scss                              |  6 +--
 site/docs/latest/functions/overview.md             |  8 ++++
 6 files changed, 96 insertions(+), 14 deletions(-)

diff --git a/pulsar-client-tools-test/src/test/java/org/apache/pulsar/admin/cli/CmdFunctionsTest.java b/pulsar-client-tools-test/src/test/java/org/apache/pulsar/admin/cli/CmdFunctionsTest.java
index 7bcb109..5f745d1 100644
--- a/pulsar-client-tools-test/src/test/java/org/apache/pulsar/admin/cli/CmdFunctionsTest.java
+++ b/pulsar-client-tools-test/src/test/java/org/apache/pulsar/admin/cli/CmdFunctionsTest.java
@@ -233,6 +233,31 @@ public class CmdFunctionsTest {
     }
 
     @Test
+    public void testCreateUsingFullyQualifiedFunctionName() throws Exception {
+        String inputTopicName = TEST_NAME + "-input-topic";
+        String outputTopicName = TEST_NAME + "-output-topic";
+        String tenant = "sample";
+        String namespace = "ns1";
+        String functionName = "func";
+        String fqfn = String.format("%s/%s/%s", tenant, namespace, functionName);
+
+        cmd.run(new String[] {
+                "create",
+                "--inputs", inputTopicName,
+                "--output", outputTopicName,
+                "--fqfn", fqfn,
+                "--jar", "SomeJar.jar",
+                "--className", DummyFunction.class.getName(),
+        });
+
+        CreateFunction creater = cmd.getCreater();
+        assertEquals(tenant, creater.getFunctionConfig().getTenant());
+        assertEquals(namespace, creater.getFunctionConfig().getNamespace());
+        assertEquals(functionName, creater.getFunctionConfig().getName());
+        verify(functions, times(1)).createFunction(any(FunctionConfig.class), anyString());
+    }
+
+    @Test
     public void testCreateWithoutFunctionName() throws Exception {
         String inputTopicName = TEST_NAME + "-input-topic";
         String outputTopicName = TEST_NAME + "-output-topic";
diff --git a/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdFunctions.java b/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdFunctions.java
index e3951ab..adf7283 100644
--- a/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdFunctions.java
+++ b/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdFunctions.java
@@ -103,6 +103,9 @@ public class CmdFunctions extends CmdBase {
      */
     @Getter
     abstract class NamespaceCommand extends BaseCommand {
+        @Parameter(names = "--fqfn", description = "The Fully Qualified Function Name (FQFN) for the function", required = false)
+        protected String fqfn;
+
         @Parameter(names = "--tenant", description = "The function's tenant", required = true)
         protected String tenant;
 
@@ -124,6 +127,8 @@ public class CmdFunctions extends CmdBase {
      */
     @Getter
     abstract class FunctionConfigCommand extends BaseCommand {
+        @Parameter(names = "--fqfn", description = "The Fully Qualified Function Name (FQFN) for the function")
+        protected String fqfn;
         @Parameter(names = "--tenant", description = "The function's tenant")
         protected String tenant;
         @Parameter(names = "--namespace", description = "The function's namespace")
@@ -168,13 +173,29 @@ public class CmdFunctions extends CmdBase {
 
         @Override
         void processArguments() throws Exception {
-
             FunctionConfig.Builder functionConfigBuilder;
+
+            // Initialize config builder either from a supplied YAML config file or from scratch
             if (null != fnConfigFile) {
                 functionConfigBuilder = loadConfig(new File(fnConfigFile));
             } else {
                 functionConfigBuilder = FunctionConfig.newBuilder();
             }
+
+            if (null != fqfn) {
+                parseFullyQualifiedFunctionName(fqfn, functionConfigBuilder);
+            } else {
+                if (null != tenant) {
+                    functionConfigBuilder.setTenant(tenant);
+                }
+                if (null != namespace) {
+                    functionConfigBuilder.setNamespace(namespace);
+                }
+                if (null != functionName) {
+                    functionConfigBuilder.setName(functionName);
+                }
+            }
+
             if (null != inputs) {
                 String[] topicNames = inputs.split(",");
                 for (int i = 0; i < topicNames.length; ++i) {
@@ -192,15 +213,6 @@ public class CmdFunctions extends CmdBase {
             if (null != logTopic) {
                 functionConfigBuilder.setLogTopic(logTopic);
             }
-            if (null != tenant) {
-                functionConfigBuilder.setTenant(tenant);
-            }
-            if (null != namespace) {
-                functionConfigBuilder.setNamespace(namespace);
-            }
-            if (null != functionName) {
-                functionConfigBuilder.setName(functionName);
-            }
             if (null != className) {
                 functionConfigBuilder.setClassName(className);
             }
@@ -373,6 +385,17 @@ public class CmdFunctions extends CmdBase {
             }
         }
 
+        private void parseFullyQualifiedFunctionName(String fqfn, FunctionConfig.Builder functionConfigBuilder) {
+            String[] args = fqfn.split("/");
+            if (args.length != 3) {
+                throw new RuntimeException("Fully qualified function names must be of the form tenant/namespace/name");
+            } else {
+                functionConfigBuilder.setTenant(args[0]);
+                functionConfigBuilder.setNamespace(args[1]);
+                functionConfigBuilder.setName(args[2]);
+            }
+        }
+
         private void doPythonSubmitChecks(FunctionConfig.Builder functionConfigBuilder) {
             if (functionConfigBuilder.getProcessingGuarantees() == FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE) {
                 throw new RuntimeException("Effectively-once processing guarantees not yet supported in Python");
@@ -702,7 +725,7 @@ public class CmdFunctions extends CmdBase {
     TriggerFunction getTriggerer() {
         return triggerer;
     }
-    
+
     private static FunctionConfig.Builder loadConfig(File file) throws IOException {
         String json = FunctionConfigUtils.convertYamlToJson(file);
         FunctionConfig.Builder functionConfigBuilder = FunctionConfig.newBuilder();
diff --git a/pulsar-functions/proto/src/main/proto/Function.proto b/pulsar-functions/proto/src/main/proto/Function.proto
index 4b74dc7..542d847 100644
--- a/pulsar-functions/proto/src/main/proto/Function.proto
+++ b/pulsar-functions/proto/src/main/proto/Function.proto
@@ -53,6 +53,9 @@ message FunctionConfig {
     bool autoAck = 13;
     repeated string inputs = 14;
     int32 parallelism = 15;
+    // Fully qualified function name
+    // (alternative to specifying tenant/namespace/name)
+    string fqfn = 16;
 }
 
 message PackageLocationMetaData {
diff --git a/site/_includes/fqfn.html b/site/_includes/fqfn.html
new file mode 100644
index 0000000..4ab61b6
--- /dev/null
+++ b/site/_includes/fqfn.html
@@ -0,0 +1,23 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<section class="fqfn">
+  <span class="tenant">{{ include.tenant }}</span>/<span class="namespace">{{ include.namespace }}</span>/<span class="name">{{ include.name }}</span>
+</section>
\ No newline at end of file
diff --git a/site/_sass/_docs.scss b/site/_sass/_docs.scss
index a66bd16..8d55b5c 100644
--- a/site/_sass/_docs.scss
+++ b/site/_sass/_docs.scss
@@ -109,7 +109,7 @@
         }
       }
 
-      .topic {
+      .topic, .fqfn {
         color: $sx-light-gray;
         background-color: $black;
         font-size: $code-font-size;
@@ -117,8 +117,8 @@
         padding: 10px 0 10px 20px;
         border-radius: 0;
 
-        .property { color: $sx-olive; }
-        .cluster { color: $sx-red; }
+        .property, .tenant { color: $sx-olive; }
+        .cluster, .name { color: $sx-red; }
         .namespace { color: $sx-7; }
         .t { color: $sx-magenta; }
 
diff --git a/site/docs/latest/functions/overview.md b/site/docs/latest/functions/overview.md
index 9629856..ffee467 100644
--- a/site/docs/latest/functions/overview.md
+++ b/site/docs/latest/functions/overview.md
@@ -146,6 +146,14 @@ $ bin/pulsar-functions localrun \
   --className org.apache.pulsar.functions.api.examples.ExclamationFunction
 ```
 
+## Fully Qualified Function Name (FQFN) {#fqfn}
+
+Each Pulsar Function has a **Fully Qualified Function Name** (FQFN) that consists of three elements: the function's {% popover tenant %}, {% popover namespace %}, and function name. FQFN's look like this:
+
+{% include fqfn.html tenant="tenant" namespace="namespace" name="name" %}
+
+FQFNs enable you to, for example, create multiple functions with the same name provided that they're in different namespaces.
+
 ## Configuration
 
 Pulsar Functions can be configured in two ways:

-- 
To stop receiving notification emails like this one, please contact
mmerli@apache.org.