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.