This is an automated email from the ASF dual-hosted git repository.
penghui 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 55293017c1a [refactor][function][PIP-166] Function add MANUAL delivery
semantics (#16279)
55293017c1a is described below
commit 55293017c1a21f10aef9637c9697c7d9fb871fa8
Author: Baodi Shi <[email protected]>
AuthorDate: Mon Aug 1 09:30:36 2022 +0800
[refactor][function][PIP-166] Function add MANUAL delivery semantics
(#16279)
---
.../pulsar/common/functions/FunctionConfig.java | 5 +-
.../pulsar/common/functions/WindowConfig.java | 12 +
.../org/apache/pulsar/common/io/SinkConfig.java | 2 +
pulsar-function-go/conf/conf.go | 1 +
pulsar-function-go/pb/Function.pb.go | 593 +++++++++++----------
pulsar-function-go/pb/generate.sh | 2 +
pulsar-function-go/pf/instance.go | 17 +-
pulsar-function-go/pf/instanceConf.go | 32 +-
pulsar-function-go/pf/instanceConf_test.go | 17 +
pulsar-function-go/pf/instance_test.go | 8 +-
pulsar-function-go/pf/stats.go | 16 +-
.../pulsar/functions/instance/ContextImpl.java | 3 +-
.../functions/instance/JavaInstanceRunnable.java | 18 +-
.../apache/pulsar/functions/sink/PulsarSink.java | 16 +
.../functions/source/PulsarFunctionRecord.java | 113 ++++
.../windowing/WindowFunctionExecutor.java | 18 +-
.../pulsar/functions/windowing/WindowManager.java | 8 +-
.../instance/src/main/python/Function_pb2.py | 123 +++--
.../instance/src/main/python/python_instance.py | 3 +-
.../src/main/python/python_instance_main.py | 12 +
.../pulsar/functions/instance/ContextImplTest.java | 13 +-
.../instance/JavaInstanceRunnableTest.java | 69 ++-
.../pulsar/functions/sink/PulsarSinkTest.java | 46 +-
.../functions/source/PulsarFunctionRecordTest.java | 62 +++
.../windowing/WindowFunctionExecutorTest.java | 44 ++
.../proto/src/main/proto/Function.proto | 4 +-
.../functions/utils/FunctionConfigUtils.java | 36 +-
.../pulsar/functions/utils/SinkConfigUtils.java | 3 +-
.../pulsar/functions/utils/SourceConfigUtils.java | 2 +-
.../functions/utils/FunctionConfigUtilsTest.java | 17 +
.../functions/utils/SinkConfigUtilsTest.java | 14 +
.../rest/api/v2/FunctionApiV2ResourceTest.java | 1 +
.../rest/api/v3/FunctionApiV3ResourceTest.java | 1 +
site2/docs/functions-cli.md | 4 +-
site2/docs/functions-concepts.md | 13 +-
35 files changed, 932 insertions(+), 416 deletions(-)
diff --git
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/FunctionConfig.java
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/FunctionConfig.java
index 527c954110d..dd8a46b7d8b 100644
---
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/FunctionConfig.java
+++
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/FunctionConfig.java
@@ -41,7 +41,8 @@ public class FunctionConfig {
public enum ProcessingGuarantees {
ATLEAST_ONCE,
ATMOST_ONCE,
- EFFECTIVELY_ONCE
+ EFFECTIVELY_ONCE,
+ MANUAL
}
/**
@@ -102,6 +103,8 @@ public class FunctionConfig {
// SecretProviderConfigurator.getSecretObjectType() method.
private Map<String, Object> secrets;
private Runtime runtime;
+ // Deprecated since, see https://github.com/apache/pulsar/issues/15560
+ @Deprecated
private Boolean autoAck;
private Integer maxMessageRetries;
private String deadLetterTopic;
diff --git
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/WindowConfig.java
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/WindowConfig.java
index 1fb2ef7ca3e..1f507137917 100644
---
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/WindowConfig.java
+++
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/functions/WindowConfig.java
@@ -47,4 +47,16 @@ public class WindowConfig {
private String timestampExtractorClassName;
private String actualWindowFunctionClassName;
+
+ private ProcessingGuarantees processingGuarantees;
+
+ /**
+ * This is a semantic option that windows can provide,
+ * forcing the semantics of the {@link
FunctionConfig.ProcessingGuarantees} to be equal to MANUAL,
+ * and then letting the windows function handle the semantic timing by
itself.
+ */
+ public enum ProcessingGuarantees {
+ ATLEAST_ONCE,
+ ATMOST_ONCE
+ }
}
diff --git
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/io/SinkConfig.java
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/io/SinkConfig.java
index 5bd9227ca1b..f1844e6090c 100644
---
a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/io/SinkConfig.java
+++
b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/common/io/SinkConfig.java
@@ -74,6 +74,8 @@ public class SinkConfig {
private Boolean retainOrdering;
private Boolean retainKeyOrdering;
private Resources resources;
+ // Deprecated since, see https://github.com/apache/pulsar/issues/15560
+ @Deprecated
private Boolean autoAck;
private Long timeoutMs;
private Long negativeAckRedeliveryDelayMs;
diff --git a/pulsar-function-go/conf/conf.go b/pulsar-function-go/conf/conf.go
index dfbf54289f2..c2ff443fcc4 100644
--- a/pulsar-function-go/conf/conf.go
+++ b/pulsar-function-go/conf/conf.go
@@ -49,6 +49,7 @@ type Conf struct {
ProcessingGuarantees int32 `json:"processingGuarantees"
yaml:"processingGuarantees"`
SecretsMap string `json:"secretsMap" yaml:"secretsMap"`
Runtime int32 `json:"runtime" yaml:"runtime"`
+ //Deprecated
AutoACK bool `json:"autoAck" yaml:"autoAck"`
Parallelism int32 `json:"parallelism" yaml:"parallelism"`
//source config
diff --git a/pulsar-function-go/pb/Function.pb.go
b/pulsar-function-go/pb/Function.pb.go
index d137995dd94..bee1af7cd0c 100644
--- a/pulsar-function-go/pb/Function.pb.go
+++ b/pulsar-function-go/pb/Function.pb.go
@@ -20,7 +20,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
-// protoc v3.17.3
+// protoc v3.19.4
// source: Function.proto
package api
@@ -50,6 +50,7 @@ const (
ProcessingGuarantees_ATLEAST_ONCE ProcessingGuarantees = 0 //
[default value]
ProcessingGuarantees_ATMOST_ONCE ProcessingGuarantees = 1
ProcessingGuarantees_EFFECTIVELY_ONCE ProcessingGuarantees = 2
+ ProcessingGuarantees_MANUAL ProcessingGuarantees = 3
)
// Enum value maps for ProcessingGuarantees.
@@ -58,11 +59,13 @@ var (
0: "ATLEAST_ONCE",
1: "ATMOST_ONCE",
2: "EFFECTIVELY_ONCE",
+ 3: "MANUAL",
}
ProcessingGuarantees_value = map[string]int32{
"ATLEAST_ONCE": 0,
"ATMOST_ONCE": 1,
"EFFECTIVELY_ONCE": 2,
+ "MANUAL": 3,
}
)
@@ -510,15 +513,17 @@ type FunctionDetails struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- Tenant string
`protobuf:"bytes,1,opt,name=tenant,proto3" json:"tenant,omitempty"`
- Namespace string
`protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"`
- Name string
`protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
- ClassName string
`protobuf:"bytes,4,opt,name=className,proto3" json:"className,omitempty"`
- LogTopic string
`protobuf:"bytes,5,opt,name=logTopic,proto3" json:"logTopic,omitempty"`
- ProcessingGuarantees ProcessingGuarantees
`protobuf:"varint,6,opt,name=processingGuarantees,proto3,enum=proto.ProcessingGuarantees"
json:"processingGuarantees,omitempty"`
- UserConfig string
`protobuf:"bytes,7,opt,name=userConfig,proto3" json:"userConfig,omitempty"`
- SecretsMap string
`protobuf:"bytes,16,opt,name=secretsMap,proto3" json:"secretsMap,omitempty"`
- Runtime FunctionDetails_Runtime
`protobuf:"varint,8,opt,name=runtime,proto3,enum=proto.FunctionDetails_Runtime"
json:"runtime,omitempty"`
+ Tenant string
`protobuf:"bytes,1,opt,name=tenant,proto3" json:"tenant,omitempty"`
+ Namespace string
`protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"`
+ Name string
`protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
+ ClassName string
`protobuf:"bytes,4,opt,name=className,proto3" json:"className,omitempty"`
+ LogTopic string
`protobuf:"bytes,5,opt,name=logTopic,proto3" json:"logTopic,omitempty"`
+ ProcessingGuarantees ProcessingGuarantees
`protobuf:"varint,6,opt,name=processingGuarantees,proto3,enum=proto.ProcessingGuarantees"
json:"processingGuarantees,omitempty"`
+ UserConfig string
`protobuf:"bytes,7,opt,name=userConfig,proto3" json:"userConfig,omitempty"`
+ SecretsMap string
`protobuf:"bytes,16,opt,name=secretsMap,proto3" json:"secretsMap,omitempty"`
+ Runtime FunctionDetails_Runtime
`protobuf:"varint,8,opt,name=runtime,proto3,enum=proto.FunctionDetails_Runtime"
json:"runtime,omitempty"`
+ // Deprecated since, see https://github.com/apache/pulsar/issues/15560
+ //
AutoAck bool
`protobuf:"varint,9,opt,name=autoAck,proto3" json:"autoAck,omitempty"`
Parallelism int32
`protobuf:"varint,10,opt,name=parallelism,proto3" json:"parallelism,omitempty"`
Source *SourceSpec
`protobuf:"bytes,11,opt,name=source,proto3" json:"source,omitempty"`
@@ -632,6 +637,7 @@ func (x *FunctionDetails) GetRuntime()
FunctionDetails_Runtime {
return FunctionDetails_JAVA
}
+// Deprecated: Do not use.
func (x *FunctionDetails) GetAutoAck() bool {
if x != nil {
return x.AutoAck
@@ -1660,7 +1666,7 @@ var file_Function_proto_rawDesc = []byte{
0x61, 0x67, 0x65, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x28,
0x0a, 0x0f, 0x64, 0x65,
0x61, 0x64, 0x4c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x54, 0x6f, 0x70, 0x69,
0x63, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x61, 0x64, 0x4c, 0x65, 0x74,
0x74, 0x65, 0x72, 0x54,
- 0x6f, 0x70, 0x69, 0x63, 0x22, 0xc5, 0x08, 0x0a, 0x0f, 0x46, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f,
+ 0x6f, 0x70, 0x69, 0x63, 0x22, 0xc9, 0x08, 0x0a, 0x0f, 0x46, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f,
0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06,
0x74, 0x65, 0x6e, 0x61,
0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x65,
0x6e, 0x61, 0x6e, 0x74,
0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x18, 0x02, 0x20,
@@ -1682,294 +1688,295 @@ var file_Function_proto_rawDesc = []byte{
0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x1e,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x44,
0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69,
0x6d, 0x65, 0x52, 0x07,
- 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61,
0x75, 0x74, 0x6f, 0x41,
- 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x61, 0x75,
0x74, 0x6f, 0x41, 0x63,
- 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65,
0x6c, 0x69, 0x73, 0x6d,
- 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x61,
0x6c, 0x6c, 0x65, 0x6c,
- 0x69, 0x73, 0x6d, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x18, 0x0b, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x53, 0x6f, 0x75, 0x72,
- 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x12, 0x23,
- 0x0a, 0x04, 0x73, 0x69, 0x6e, 0x6b, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0f, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6e, 0x6b, 0x53, 0x70, 0x65,
0x63, 0x52, 0x04, 0x73,
- 0x69, 0x6e, 0x6b, 0x12, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x73,
- 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x52,
- 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72,
- 0x63, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x63, 0x6b, 0x61,
0x67, 0x65, 0x55, 0x72,
- 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x63,
0x6b, 0x61, 0x67, 0x65,
- 0x55, 0x72, 0x6c, 0x12, 0x37, 0x0a, 0x0c, 0x72, 0x65, 0x74, 0x72, 0x79,
0x44, 0x65, 0x74, 0x61,
- 0x69, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x44, 0x65, 0x74, 0x61, 0x69,
0x6c, 0x73, 0x52, 0x0c,
- 0x72, 0x65, 0x74, 0x72, 0x79, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73,
0x12, 0x22, 0x0a, 0x0c,
- 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73,
0x18, 0x11, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x46,
0x6c, 0x61, 0x67, 0x73,
- 0x12, 0x4a, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
0x74, 0x54, 0x79, 0x70,
- 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e,
- 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61,
0x69, 0x6c, 0x73, 0x2e,
- 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
0x65, 0x52, 0x0d, 0x63,
- 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65,
0x12, 0x32, 0x0a, 0x14,
+ 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x07, 0x61,
0x75, 0x74, 0x6f, 0x41,
+ 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01,
0x52, 0x07, 0x61, 0x75,
+ 0x74, 0x6f, 0x41, 0x63, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72,
0x61, 0x6c, 0x6c, 0x65,
+ 0x6c, 0x69, 0x73, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b,
0x70, 0x61, 0x72, 0x61,
+ 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, 0x6d, 0x12, 0x29, 0x0a, 0x06, 0x73,
0x6f, 0x75, 0x72, 0x63,
+ 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e,
+ 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x06,
0x73, 0x6f, 0x75, 0x72,
+ 0x63, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x73, 0x69, 0x6e, 0x6b, 0x18, 0x0c,
0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6e,
0x6b, 0x53, 0x70, 0x65,
+ 0x63, 0x52, 0x04, 0x73, 0x69, 0x6e, 0x6b, 0x12, 0x2e, 0x0a, 0x09, 0x72,
0x65, 0x73, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10,
0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
0x52, 0x09, 0x72, 0x65,
+ 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x70,
0x61, 0x63, 0x6b, 0x61,
+ 0x67, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0a, 0x70, 0x61, 0x63,
+ 0x6b, 0x61, 0x67, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x37, 0x0a, 0x0c, 0x72,
0x65, 0x74, 0x72, 0x79,
+ 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x13, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x44,
0x65, 0x74, 0x61, 0x69,
+ 0x6c, 0x73, 0x52, 0x0c, 0x72, 0x65, 0x74, 0x72, 0x79, 0x44, 0x65, 0x74,
0x61, 0x69, 0x6c, 0x73,
+ 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x46,
0x6c, 0x61, 0x67, 0x73,
+ 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x74,
0x69, 0x6d, 0x65, 0x46,
+ 0x6c, 0x61, 0x67, 0x73, 0x12, 0x4a, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70,
0x6f, 0x6e, 0x65, 0x6e,
+ 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x24, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x44, 0x65, 0x74, 0x61,
+ 0x69, 0x6c, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e,
0x74, 0x54, 0x79, 0x70,
+ 0x65, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74,
0x54, 0x79, 0x70, 0x65,
+ 0x12, 0x32, 0x0a, 0x14, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75,
0x6e, 0x74, 0x69, 0x6d,
+ 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x13, 0x20, 0x01,
0x28, 0x09, 0x52, 0x14,
0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d,
0x65, 0x4f, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14,
0x63, 0x75, 0x73, 0x74,
- 0x6f, 0x6d, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x73,
- 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x18,
0x14, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x12, 0x26,
0x0a, 0x0e, 0x72, 0x65,
- 0x74, 0x61, 0x69, 0x6e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67,
0x18, 0x15, 0x20, 0x01,
- 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x4f, 0x72,
0x64, 0x65, 0x72, 0x69,
- 0x6e, 0x67, 0x12, 0x2c, 0x0a, 0x11, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e,
0x4b, 0x65, 0x79, 0x4f,
- 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x16, 0x20, 0x01, 0x28,
0x08, 0x52, 0x11, 0x72,
- 0x65, 0x74, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x4f, 0x72, 0x64, 0x65,
0x72, 0x69, 0x6e, 0x67,
- 0x12, 0x4f, 0x0a, 0x14, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x69, 0x6f, 0x6e,
- 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x17, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x1b,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x14, 0x73, 0x75, 0x62,
- 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73,
0x69, 0x74, 0x69, 0x6f,
- 0x6e, 0x22, 0x27, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
0x12, 0x08, 0x0a, 0x04,
- 0x4a, 0x41, 0x56, 0x41, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x59,
0x54, 0x48, 0x4f, 0x4e,
- 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x4f, 0x10, 0x03, 0x22, 0x40,
0x0a, 0x0d, 0x43, 0x6f,
- 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12,
0x0b, 0x0a, 0x07, 0x55,
- 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08,
0x46, 0x55, 0x4e, 0x43,
- 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x4f,
0x55, 0x52, 0x43, 0x45,
- 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x49, 0x4e, 0x4b, 0x10, 0x03,
0x22, 0x95, 0x05, 0x0a,
- 0x0c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x53, 0x70, 0x65,
0x63, 0x12, 0x1e, 0x0a,
- 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70,
0x65, 0x12, 0x26, 0x0a,
- 0x0e, 0x73, 0x65, 0x72, 0x64, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e,
0x61, 0x6d, 0x65, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x64, 0x65,
0x43, 0x6c, 0x61, 0x73,
- 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x73, 0x52,
0x65, 0x67, 0x65, 0x78,
- 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28,
0x08, 0x52, 0x0e, 0x69,
- 0x73, 0x52, 0x65, 0x67, 0x65, 0x78, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72,
0x6e, 0x12, 0x53, 0x0a,
- 0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x51, 0x75, 0x65,
0x75, 0x65, 0x53, 0x69,
- 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f,
- 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x53, 0x70, 0x65,
0x63, 0x2e, 0x52, 0x65,
- 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x51, 0x75, 0x65, 0x75, 0x65, 0x53,
0x69, 0x7a, 0x65, 0x52,
- 0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x51, 0x75, 0x65,
0x75, 0x65, 0x53, 0x69,
- 0x7a, 0x65, 0x12, 0x55, 0x0a, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61,
0x50, 0x72, 0x6f, 0x70,
- 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x29, 0x2e, 0x70,
+ 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c,
0x74, 0x69, 0x6e, 0x18,
+ 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74,
0x69, 0x6e, 0x12, 0x26,
+ 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x4f, 0x72, 0x64, 0x65,
0x72, 0x69, 0x6e, 0x67,
+ 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x74, 0x61,
0x69, 0x6e, 0x4f, 0x72,
+ 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x2c, 0x0a, 0x11, 0x72, 0x65,
0x74, 0x61, 0x69, 0x6e,
+ 0x4b, 0x65, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18,
0x16, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x11, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6e, 0x4b, 0x65, 0x79,
0x4f, 0x72, 0x64, 0x65,
+ 0x72, 0x69, 0x6e, 0x67, 0x12, 0x4f, 0x0a, 0x14, 0x73, 0x75, 0x62, 0x73,
0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x18, 0x17, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53,
0x75, 0x62, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x52,
+ 0x14, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x50, 0x6f, 0x73,
+ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x27, 0x0a, 0x07, 0x52, 0x75, 0x6e,
0x74, 0x69, 0x6d, 0x65,
+ 0x12, 0x08, 0x0a, 0x04, 0x4a, 0x41, 0x56, 0x41, 0x10, 0x00, 0x12, 0x0a,
0x0a, 0x06, 0x50, 0x59,
+ 0x54, 0x48, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x47, 0x4f,
0x10, 0x03, 0x22, 0x40,
+ 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54,
0x79, 0x70, 0x65, 0x12,
+ 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00,
0x12, 0x0c, 0x0a, 0x08,
+ 0x46, 0x55, 0x4e, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x0a,
0x0a, 0x06, 0x53, 0x4f,
+ 0x55, 0x52, 0x43, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x49,
0x4e, 0x4b, 0x10, 0x03,
+ 0x22, 0x95, 0x05, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
0x72, 0x53, 0x70, 0x65,
+ 0x63, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54,
0x79, 0x70, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d,
0x61, 0x54, 0x79, 0x70,
+ 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x64, 0x65, 0x43, 0x6c,
0x61, 0x73, 0x73, 0x4e,
+ 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73,
0x65, 0x72, 0x64, 0x65,
+ 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a,
0x0e, 0x69, 0x73, 0x52,
+ 0x65, 0x67, 0x65, 0x78, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18,
0x03, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x0e, 0x69, 0x73, 0x52, 0x65, 0x67, 0x65, 0x78, 0x50, 0x61,
0x74, 0x74, 0x65, 0x72,
+ 0x6e, 0x12, 0x53, 0x0a, 0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
0x72, 0x51, 0x75, 0x65,
+ 0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x25, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
0x72, 0x53, 0x70, 0x65,
- 0x63, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70,
0x65, 0x72, 0x74, 0x69,
- 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x73, 0x63, 0x68,
0x65, 0x6d, 0x61, 0x50,
- 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x5b, 0x0a,
0x12, 0x63, 0x6f, 0x6e,
- 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,
0x69, 0x65, 0x73, 0x18,
- 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x43, 0x6f,
- 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x43,
0x6f, 0x6e, 0x73, 0x75,
- 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
0x73, 0x45, 0x6e, 0x74,
- 0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72,
0x50, 0x72, 0x6f, 0x70,
- 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x63, 0x72,
0x79, 0x70, 0x74, 0x6f,
- 0x53, 0x70, 0x65, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65,
0x63, 0x52, 0x0a, 0x63,
- 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x12, 0x22, 0x0a,
0x0c, 0x70, 0x6f, 0x6f,
- 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x08, 0x20,
0x01, 0x28, 0x08, 0x52,
- 0x0c, 0x70, 0x6f, 0x6f, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x73, 0x1a, 0x29, 0x0a,
- 0x11, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x51, 0x75, 0x65,
0x75, 0x65, 0x53, 0x69,
- 0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28,
- 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x43, 0x0a, 0x15,
0x53, 0x63, 0x68, 0x65,
- 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73,
0x45, 0x6e, 0x74, 0x72,
- 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03,
- 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
0x01, 0x1a, 0x45, 0x0a,
- 0x17, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f,
0x70, 0x65, 0x72, 0x74,
- 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
0x6b, 0x65, 0x79, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
0x0a, 0x05, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65,
- 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9f, 0x02, 0x0a, 0x0c, 0x50, 0x72, 0x6f,
0x64, 0x75, 0x63, 0x65,
- 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2e, 0x0a, 0x12, 0x6d, 0x61, 0x78,
0x50, 0x65, 0x6e, 0x64,
- 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18,
0x01, 0x20, 0x01, 0x28,
- 0x05, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e,
0x67, 0x4d, 0x65, 0x73,
- 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x4e, 0x0a, 0x22, 0x6d, 0x61, 0x78,
0x50, 0x65, 0x6e, 0x64,
- 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x41,
0x63, 0x72, 0x6f, 0x73,
- 0x73, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
0x02, 0x20, 0x01, 0x28,
- 0x05, 0x52, 0x22, 0x6d, 0x61, 0x78, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e,
0x67, 0x4d, 0x65, 0x73,
- 0x73, 0x61, 0x67, 0x65, 0x73, 0x41, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x50,
0x61, 0x72, 0x74, 0x69,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x0a, 0x17, 0x75, 0x73, 0x65,
0x54, 0x68, 0x72, 0x65,
- 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x64, 0x75,
0x63, 0x65, 0x72, 0x73,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x75, 0x73, 0x65, 0x54,
0x68, 0x72, 0x65, 0x61,
- 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63,
0x65, 0x72, 0x73, 0x12,
- 0x31, 0x0a, 0x0a, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65,
0x63, 0x18, 0x04, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x43, 0x72, 0x79, 0x70,
- 0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0a, 0x63, 0x72, 0x79, 0x70,
0x74, 0x6f, 0x53, 0x70,
- 0x65, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x62, 0x61, 0x74, 0x63, 0x68, 0x42,
0x75, 0x69, 0x6c, 0x64,
- 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61,
0x74, 0x63, 0x68, 0x42,
- 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x22, 0xc1, 0x03, 0x0a, 0x0a, 0x43,
0x72, 0x79, 0x70, 0x74,
- 0x6f, 0x53, 0x70, 0x65, 0x63, 0x12, 0x3a, 0x0a, 0x18, 0x63, 0x72, 0x79,
0x70, 0x74, 0x6f, 0x4b,
- 0x65, 0x79, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73,
0x73, 0x4e, 0x61, 0x6d,
- 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x63, 0x72, 0x79,
0x70, 0x74, 0x6f, 0x4b,
- 0x65, 0x79, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73,
0x73, 0x4e, 0x61, 0x6d,
- 0x65, 0x12, 0x34, 0x0a, 0x15, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x4b,
0x65, 0x79, 0x52, 0x65,
- 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09,
- 0x52, 0x15, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x52,
0x65, 0x61, 0x64, 0x65,
- 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x19, 0x70,
0x72, 0x6f, 0x64, 0x75,
- 0x63, 0x65, 0x72, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x4b, 0x65, 0x79,
- 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19,
0x70, 0x72, 0x6f, 0x64,
- 0x75, 0x63, 0x65, 0x72, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x4b, 0x65,
- 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x61, 0x0a, 0x1b, 0x70, 0x72, 0x6f,
0x64, 0x75, 0x63, 0x65,
- 0x72, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x75,
0x72, 0x65, 0x41, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f,
0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65,
0x63, 0x2e, 0x46, 0x61,
- 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x1b, 0x70, 0x72, 0x6f,
+ 0x63, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x51, 0x75,
0x65, 0x75, 0x65, 0x53,
+ 0x69, 0x7a, 0x65, 0x52, 0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
0x72, 0x51, 0x75, 0x65,
+ 0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x55, 0x0a, 0x10, 0x73, 0x63,
0x68, 0x65, 0x6d, 0x61,
+ 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05,
0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e,
0x73, 0x75, 0x6d, 0x65,
+ 0x72, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61,
0x50, 0x72, 0x6f, 0x70,
+ 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
0x10, 0x73, 0x63, 0x68,
+ 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
0x73, 0x12, 0x5b, 0x0a,
+ 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f,
0x70, 0x65, 0x72, 0x74,
+ 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x53, 0x70,
0x65, 0x63, 0x2e, 0x43,
+ 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65,
0x72, 0x74, 0x69, 0x65,
+ 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73,
0x75, 0x6d, 0x65, 0x72,
+ 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x31,
0x0a, 0x0a, 0x63, 0x72,
+ 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x18, 0x07, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x11,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x79, 0x70, 0x74,
0x6f, 0x53, 0x70, 0x65,
+ 0x63, 0x52, 0x0a, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65,
0x63, 0x12, 0x22, 0x0a,
+ 0x0c, 0x70, 0x6f, 0x6f, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x73, 0x18, 0x08, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x0c, 0x70, 0x6f, 0x6f, 0x6c, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65,
+ 0x73, 0x1a, 0x29, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
0x72, 0x51, 0x75, 0x65,
+ 0x75, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x1a, 0x43, 0x0a, 0x15,
+ 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,
0x74, 0x69, 0x65, 0x73,
+ 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x3a, 0x02, 0x38,
+ 0x01, 0x1a, 0x45, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
0x72, 0x50, 0x72, 0x6f,
+ 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x12, 0x10, 0x0a, 0x03,
+ 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
0x65, 0x79, 0x12, 0x14,
+ 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x05, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9f, 0x02, 0x0a,
0x0c, 0x50, 0x72, 0x6f,
+ 0x64, 0x75, 0x63, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2e, 0x0a,
0x12, 0x6d, 0x61, 0x78,
+ 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x50, 0x65,
0x6e, 0x64, 0x69, 0x6e,
+ 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x4e, 0x0a,
0x22, 0x6d, 0x61, 0x78,
+ 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x41,
+ 0x63, 0x72, 0x6f, 0x73, 0x73, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x22, 0x6d, 0x61, 0x78, 0x50, 0x65,
0x6e, 0x64, 0x69, 0x6e,
+ 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x41, 0x63, 0x72,
0x6f, 0x73, 0x73, 0x50,
+ 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x0a,
0x17, 0x75, 0x73, 0x65,
+ 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50,
0x72, 0x6f, 0x64, 0x75,
+ 0x63, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17,
0x75, 0x73, 0x65, 0x54,
+ 0x68, 0x72, 0x65, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x72,
0x6f, 0x64, 0x75, 0x63,
+ 0x65, 0x72, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x63, 0x72, 0x79, 0x70, 0x74,
0x6f, 0x53, 0x70, 0x65,
+ 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e,
+ 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0a,
0x63, 0x72, 0x79, 0x70,
+ 0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x12, 0x22, 0x0a, 0x0c, 0x62, 0x61,
0x74, 0x63, 0x68, 0x42,
+ 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0c, 0x62, 0x61,
+ 0x74, 0x63, 0x68, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x22, 0xc1,
0x03, 0x0a, 0x0a, 0x43,
+ 0x72, 0x79, 0x70, 0x74, 0x6f, 0x53, 0x70, 0x65, 0x63, 0x12, 0x3a, 0x0a,
0x18, 0x63, 0x72, 0x79,
+ 0x70, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72,
0x43, 0x6c, 0x61, 0x73,
+ 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x18, 0x63, 0x72, 0x79,
+ 0x70, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72,
0x43, 0x6c, 0x61, 0x73,
+ 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x15, 0x63, 0x72, 0x79,
0x70, 0x74, 0x6f, 0x4b,
+ 0x65, 0x79, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f,
0x4b, 0x65, 0x79, 0x52,
+ 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x3c, 0x0a, 0x19, 0x70,
+ 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x45, 0x6e, 0x63, 0x72, 0x79,
0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x4b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x03,
0x28, 0x09, 0x52, 0x19,
+ 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x45, 0x6e, 0x63, 0x72,
0x79, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x61, 0x0a,
0x1b, 0x70, 0x72, 0x6f,
0x64, 0x75, 0x63, 0x65, 0x72, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x46,
0x61, 0x69, 0x6c, 0x75,
- 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x61, 0x0a, 0x1b,
0x63, 0x6f, 0x6e, 0x73,
- 0x75, 0x6d, 0x65, 0x72, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x46, 0x61,
0x69, 0x6c, 0x75, 0x72,
- 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28,
0x0e, 0x32, 0x1f, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f,
0x53, 0x70, 0x65, 0x63,
- 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x52, 0x1b,
+ 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x1f,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72, 0x79, 0x70, 0x74,
0x6f, 0x53, 0x70, 0x65,
+ 0x63, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x52,
+ 0x1b, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x43, 0x72, 0x79,
0x70, 0x74, 0x6f, 0x46,
+ 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x61, 0x0a, 0x1b,
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x43, 0x72, 0x79, 0x70,
0x74, 0x6f, 0x46, 0x61,
- 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22,
0x3d, 0x0a, 0x0d, 0x46,
- 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x08, 0x0a, 0x04,
- 0x46, 0x41, 0x49, 0x4c, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x49,
0x53, 0x43, 0x41, 0x52,
- 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x4e, 0x53, 0x55,
0x4d, 0x45, 0x10, 0x02,
- 0x12, 0x08, 0x0a, 0x04, 0x53, 0x45, 0x4e, 0x44, 0x10, 0x0a, 0x22, 0xd1,
0x06, 0x0a, 0x0a, 0x53,
- 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1c, 0x0a,
0x09, 0x63, 0x6c, 0x61,
- 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x09, 0x63, 0x6c,
- 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63,
0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f,
0x6e, 0x66, 0x69, 0x67,
- 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x79, 0x70, 0x65, 0x43, 0x6c, 0x61,
0x73, 0x73, 0x4e, 0x61,
- 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x79,
0x70, 0x65, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x73,
0x75, 0x62, 0x73, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18,
0x03, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x75,
0x62, 0x73, 0x63, 0x72,
- 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x10,
0x73, 0x75, 0x62, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65,
0x12, 0x69, 0x0a, 0x16,
- 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x44,
0x65, 0x43, 0x6c, 0x61,
- 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x2d, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53,
0x70, 0x65, 0x63, 0x2e,
- 0x54, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x44,
0x65, 0x43, 0x6c, 0x61,
- 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42,
0x02, 0x18, 0x01, 0x52,
- 0x16, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f, 0x53, 0x65, 0x72,
0x44, 0x65, 0x43, 0x6c,
- 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x69,
0x6e, 0x70, 0x75, 0x74,
- 0x53, 0x70, 0x65, 0x63, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x21, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70,
0x65, 0x63, 0x2e, 0x49,
- 0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 0x73, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x52, 0x0a,
- 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 0x73, 0x12, 0x1c,
0x0a, 0x09, 0x74, 0x69,
- 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,
0x04, 0x52, 0x09, 0x74,
- 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x28, 0x0a, 0x0d,
0x74, 0x6f, 0x70, 0x69,
- 0x63, 0x73, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x07, 0x20,
0x01, 0x28, 0x09, 0x42,
- 0x02, 0x18, 0x01, 0x52, 0x0d, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x50,
0x61, 0x74, 0x74, 0x65,
- 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69,
0x6e, 0x18, 0x08, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e,
0x12, 0x2a, 0x0a, 0x10,
- 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x4e, 0x61, 0x6d, 0x65,
- 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x75, 0x62, 0x73,
0x63, 0x72, 0x69, 0x70,
- 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x13,
0x63, 0x6c, 0x65, 0x61,
- 0x6e, 0x75, 0x70, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x18,
- 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x63, 0x6c, 0x65, 0x61, 0x6e,
0x75, 0x70, 0x53, 0x75,
- 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4f,
0x0a, 0x14, 0x73, 0x75,
- 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f,
0x73, 0x69, 0x74, 0x69,
- 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f,
- 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x50, 0x6f, 0x73,
- 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x73, 0x75, 0x62, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x42, 0x0a, 0x1c, 0x6e,
- 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x41, 0x63, 0x6b, 0x52, 0x65,
0x64, 0x65, 0x6c, 0x69,
- 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x18,
0x0d, 0x20, 0x01, 0x28,
- 0x04, 0x52, 0x1c, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x41,
0x63, 0x6b, 0x52, 0x65,
- 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x61,
0x79, 0x4d, 0x73, 0x1a,
- 0x49, 0x0a, 0x1b, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f, 0x53,
0x65, 0x72, 0x44, 0x65,
- 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x12, 0x10,
+ 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18,
0x05, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x72,
0x79, 0x70, 0x74, 0x6f,
+ 0x53, 0x70, 0x65, 0x63, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65,
0x41, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x52, 0x1b, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72,
0x43, 0x72, 0x79, 0x70,
+ 0x74, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x22,
+ 0x3d, 0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x41, 0x63,
0x74, 0x69, 0x6f, 0x6e,
+ 0x12, 0x08, 0x0a, 0x04, 0x46, 0x41, 0x49, 0x4c, 0x10, 0x00, 0x12, 0x0b,
0x0a, 0x07, 0x44, 0x49,
+ 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43,
0x4f, 0x4e, 0x53, 0x55,
+ 0x4d, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x45, 0x4e, 0x44,
0x10, 0x0a, 0x22, 0xd1,
+ 0x06, 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65,
0x63, 0x12, 0x1c, 0x0a,
+ 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12,
0x18, 0x0a, 0x07, 0x63,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x07, 0x63, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x79, 0x70,
0x65, 0x43, 0x6c, 0x61,
+ 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0d, 0x74, 0x79,
+ 0x70, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12,
0x43, 0x0a, 0x10, 0x73,
+ 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54,
0x79, 0x70, 0x65, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x53, 0x75,
+ 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79,
0x70, 0x65, 0x52, 0x10,
+ 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x54, 0x79, 0x70, 0x65,
+ 0x12, 0x69, 0x0a, 0x16, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f,
0x53, 0x65, 0x72, 0x44,
+ 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04,
0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x53,
+ 0x70, 0x65, 0x63, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54, 0x6f,
0x53, 0x65, 0x72, 0x44,
+ 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x42,
+ 0x02, 0x18, 0x01, 0x52, 0x16, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x54,
0x6f, 0x53, 0x65, 0x72,
+ 0x44, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12,
0x41, 0x0a, 0x0a, 0x69,
+ 0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 0x73, 0x18, 0x0a, 0x20,
0x03, 0x28, 0x0b, 0x32,
+ 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x53, 0x70,
+ 0x65, 0x63, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63,
0x73, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65,
0x63, 0x73, 0x12, 0x1c,
+ 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18,
0x06, 0x20, 0x01, 0x28,
+ 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73,
0x12, 0x28, 0x0a, 0x0d,
+ 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72,
0x6e, 0x18, 0x07, 0x20,
+ 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x74, 0x6f, 0x70,
0x69, 0x63, 0x73, 0x50,
+ 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75,
0x69, 0x6c, 0x74, 0x69,
+ 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69,
0x6c, 0x74, 0x69, 0x6e,
+ 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x69, 0x6f, 0x6e,
+ 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10,
0x73, 0x75, 0x62, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65,
0x12, 0x30, 0x0a, 0x13,
+ 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x53, 0x75, 0x62, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x63,
0x6c, 0x65, 0x61, 0x6e,
+ 0x75, 0x70, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x12, 0x4f,
+ 0x0a, 0x14, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x50, 0x6f,
+ 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x1b, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
0x70, 0x74, 0x69, 0x6f,
+ 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x73,
0x75, 0x62, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x12,
+ 0x42, 0x0a, 0x1c, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x41,
0x63, 0x6b, 0x52, 0x65,
+ 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x6c, 0x61,
0x79, 0x4d, 0x73, 0x18,
+ 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1c, 0x6e, 0x65, 0x67, 0x61, 0x74,
0x69, 0x76, 0x65, 0x41,
+ 0x63, 0x6b, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79,
0x44, 0x65, 0x6c, 0x61,
+ 0x79, 0x4d, 0x73, 0x1a, 0x49, 0x0a, 0x1b, 0x54, 0x6f, 0x70, 0x69, 0x63,
0x73, 0x54, 0x6f, 0x53,
+ 0x65, 0x72, 0x44, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d,
0x65, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52,
+ 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
0x38, 0x01, 0x1a, 0x52,
+ 0x0a, 0x0f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 0x73,
0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03,
+ 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43,
0x6f, 0x6e, 0x73, 0x75,
+ 0x6d, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x3a, 0x02,
+ 0x38, 0x01, 0x22, 0x95, 0x05, 0x0a, 0x08, 0x53, 0x69, 0x6e, 0x6b, 0x53,
0x70, 0x65, 0x63, 0x12,
+ 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65,
0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d,
0x65, 0x12, 0x18, 0x0a,
+ 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07,
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74,
0x79, 0x70, 0x65, 0x43,
+ 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0d,
+ 0x74, 0x79, 0x70, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d,
0x65, 0x12, 0x14, 0x0a,
+ 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x05, 0x74, 0x6f,
+ 0x70, 0x69, 0x63, 0x12, 0x37, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75,
0x63, 0x65, 0x72, 0x53,
+ 0x70, 0x65, 0x63, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x53, 0x70,
0x65, 0x63, 0x52, 0x0c,
+ 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63,
0x12, 0x26, 0x0a, 0x0e,
+ 0x73, 0x65, 0x72, 0x44, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61,
0x6d, 0x65, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x44, 0x65, 0x43,
0x6c, 0x61, 0x73, 0x73,
+ 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c,
0x74, 0x69, 0x6e, 0x18,
+ 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74,
0x69, 0x6e, 0x12, 0x1e,
+ 0x0a, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65,
0x18, 0x07, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79,
0x70, 0x65, 0x12, 0x42,
+ 0x0a, 0x1c, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x4d,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,
0x74, 0x79, 0x18, 0x08,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72,
0x64, 0x53, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x72,
0x6f, 0x70, 0x65, 0x72,
+ 0x74, 0x79, 0x12, 0x51, 0x0a, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61,
0x50, 0x72, 0x6f, 0x70,
+ 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x25, 0x2e, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6e, 0x6b, 0x53, 0x70, 0x65,
0x63, 0x2e, 0x53, 0x63,
+ 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,
0x65, 0x73, 0x45, 0x6e,
+ 0x74, 0x72, 0x79, 0x52, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50,
0x72, 0x6f, 0x70, 0x65,
+ 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x12, 0x63, 0x6f, 0x6e,
0x73, 0x75, 0x6d, 0x65,
+ 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18,
0x0a, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69,
0x6e, 0x6b, 0x53, 0x70,
+ 0x65, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50,
0x72, 0x6f, 0x70, 0x65,
+ 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12,
0x63, 0x6f, 0x6e, 0x73,
+ 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,
0x65, 0x73, 0x1a, 0x43,
+ 0x0a, 0x15, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70,
0x65, 0x72, 0x74, 0x69,
+ 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
0x65, 0x79, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a,
0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x3a,
+ 0x02, 0x38, 0x01, 0x1a, 0x45, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x73, 0x75,
0x6d, 0x65, 0x72, 0x50,
+ 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x12, 0x10,
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x03, 0x6b, 0x65, 0x79,
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52,
- 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x52,
0x0a, 0x0f, 0x49, 0x6e,
- 0x70, 0x75, 0x74, 0x53, 0x70, 0x65, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x12, 0x10, 0x0a,
- 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x6b, 0x65, 0x79, 0x12,
- 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x13,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75,
0x6d, 0x65, 0x72, 0x53,
- 0x70, 0x65, 0x63, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
0x38, 0x01, 0x22, 0x95,
- 0x05, 0x0a, 0x08, 0x53, 0x69, 0x6e, 0x6b, 0x53, 0x70, 0x65, 0x63, 0x12,
0x1c, 0x0a, 0x09, 0x63,
- 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x09,
- 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a,
0x07, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
0x63, 0x6f, 0x6e, 0x66,
- 0x69, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x79, 0x70, 0x65, 0x43,
0x6c, 0x61, 0x73, 0x73,
- 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
0x74, 0x79, 0x70, 0x65,
- 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a,
0x05, 0x74, 0x6f, 0x70,
- 0x69, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f,
0x70, 0x69, 0x63, 0x12,
- 0x37, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x53,
0x70, 0x65, 0x63, 0x18,
- 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x50, 0x72,
- 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0c,
0x70, 0x72, 0x6f, 0x64,
- 0x75, 0x63, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x26, 0x0a, 0x0e,
0x73, 0x65, 0x72, 0x44,
- 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09,
- 0x52, 0x0e, 0x73, 0x65, 0x72, 0x44, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73,
0x4e, 0x61, 0x6d, 0x65,
- 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x18,
0x06, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x12, 0x1e,
0x0a, 0x0a, 0x73, 0x63,
- 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0a,
- 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x42,
0x0a, 0x1c, 0x66, 0x6f,
- 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d,
0x65, 0x73, 0x73, 0x61,
- 0x67, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x18, 0x08,
0x20, 0x01, 0x28, 0x08,
- 0x52, 0x1c, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x53, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x4d,
- 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,
0x74, 0x79, 0x12, 0x51,
- 0x0a, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70,
0x65, 0x72, 0x74, 0x69,
- 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f,
- 0x2e, 0x53, 0x69, 0x6e, 0x6b, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x53, 0x63,
0x68, 0x65, 0x6d, 0x61,
- 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x52,
- 0x10, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65,
0x72, 0x74, 0x69, 0x65,
- 0x73, 0x12, 0x57, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
0x72, 0x50, 0x72, 0x6f,
- 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x27, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6e, 0x6b, 0x53, 0x70,
0x65, 0x63, 0x2e, 0x43,
- 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65,
0x72, 0x74, 0x69, 0x65,
- 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73,
0x75, 0x6d, 0x65, 0x72,
- 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x43,
0x0a, 0x15, 0x53, 0x63,
- 0x68, 0x65, 0x6d, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,
0x65, 0x73, 0x45, 0x6e,
- 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09,
- 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
0x02, 0x38, 0x01, 0x1a,
- 0x45, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50,
0x72, 0x6f, 0x70, 0x65,
- 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
0x0a, 0x03, 0x6b, 0x65,
- 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
0x12, 0x14, 0x0a, 0x05,
- 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x67, 0x0a, 0x17, 0x50, 0x61,
0x63, 0x6b, 0x61, 0x67,
- 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74,
0x61, 0x44, 0x61, 0x74,
- 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
0x50, 0x61, 0x74, 0x68,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x63, 0x6b,
0x61, 0x67, 0x65, 0x50,
- 0x61, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x69,
0x6e, 0x61, 0x6c, 0x46,
- 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x10, 0x6f,
- 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x4e,
0x61, 0x6d, 0x65, 0x22,
- 0xd5, 0x03, 0x0a, 0x10, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x4d, 0x65, 0x74, 0x61,
- 0x44, 0x61, 0x74, 0x61, 0x12, 0x40, 0x0a, 0x0f, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e,
- 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x16, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x44, 0x65,
- 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0f, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x44,
- 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x48, 0x0a, 0x0f, 0x70, 0x61,
0x63, 0x6b, 0x61, 0x67,
- 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32,
- 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, 0x63, 0x6b,
0x61, 0x67, 0x65, 0x4c,
- 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44,
0x61, 0x74, 0x61, 0x52,
- 0x0f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61,
0x74, 0x69, 0x6f, 0x6e,
- 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
0x03, 0x20, 0x01, 0x28,
- 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e,
0x0a, 0x0a, 0x63, 0x72,
- 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01,
0x28, 0x04, 0x52, 0x0a,
- 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x53,
0x0a, 0x0e, 0x69, 0x6e,
- 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73,
0x18, 0x05, 0x20, 0x03,
- 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46,
0x75, 0x6e, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x2e,
0x49, 0x6e, 0x73, 0x74,
- 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x52,
- 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61,
0x74, 0x65, 0x73, 0x12,
- 0x4d, 0x0a, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41,
0x75, 0x74, 0x68, 0x53,
- 0x70, 0x65, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e,
0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75,
0x74, 0x68, 0x65, 0x6e,
- 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63,
0x52, 0x10, 0x66, 0x75,
- 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x53, 0x70,
0x65, 0x63, 0x1a, 0x57,
- 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74,
0x61, 0x74, 0x65, 0x73,
- 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
0x18, 0x01, 0x20, 0x01,
- 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x46,
- 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65,
0x52, 0x05, 0x76, 0x61,
- 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4c, 0x0a, 0x1a, 0x46,
0x75, 0x6e, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63,
0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74,
0x61, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a,
0x08, 0x70, 0x72, 0x6f,
- 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x70, 0x72, 0x6f,
- 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x6f, 0x0a, 0x08, 0x49, 0x6e, 0x73,
0x74, 0x61, 0x6e, 0x63,
- 0x65, 0x12, 0x43, 0x0a, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x4d, 0x65, 0x74,
- 0x61, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x17, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x4d, 0x65, 0x74, 0x61,
- 0x44, 0x61, 0x74, 0x61, 0x52, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x4d, 0x65,
- 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e,
0x73, 0x74, 0x61, 0x6e,
- 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a,
0x69, 0x6e, 0x73, 0x74,
- 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x55, 0x0a, 0x0a, 0x41, 0x73,
0x73, 0x69, 0x67, 0x6e,
- 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74,
0x61, 0x6e, 0x63, 0x65,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x49,
- 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73,
0x74, 0x61, 0x6e, 0x63,
- 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49,
0x64, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49,
0x64, 0x2a, 0x4f, 0x0a,
- 0x14, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x47,
0x75, 0x61, 0x72, 0x61,
- 0x6e, 0x74, 0x65, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x54, 0x4c,
0x45, 0x41, 0x53, 0x54,
- 0x5f, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x41,
0x54, 0x4d, 0x4f, 0x53,
- 0x54, 0x5f, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10,
0x45, 0x46, 0x46, 0x45,
- 0x43, 0x54, 0x49, 0x56, 0x45, 0x4c, 0x59, 0x5f, 0x4f, 0x4e, 0x43, 0x45,
0x10, 0x02, 0x2a, 0x3c,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x67,
0x0a, 0x17, 0x50, 0x61,
+ 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x4d, 0x65, 0x74,
+ 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x63,
0x6b, 0x61, 0x67, 0x65,
+ 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
0x70, 0x61, 0x63, 0x6b,
+ 0x61, 0x67, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2a, 0x0a, 0x10, 0x6f,
0x72, 0x69, 0x67, 0x69,
+ 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x46,
0x69, 0x6c, 0x65, 0x4e,
+ 0x61, 0x6d, 0x65, 0x22, 0xd5, 0x03, 0x0a, 0x10, 0x46, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e,
+ 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x40, 0x0a, 0x0f,
0x66, 0x75, 0x6e, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18,
0x01, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75,
0x6e, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x0f, 0x66,
0x75, 0x6e, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x48,
0x0a, 0x0f, 0x70, 0x61,
+ 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x50, 0x61, 0x63, 0x6b,
+ 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d,
0x65, 0x74, 0x61, 0x44,
+ 0x61, 0x74, 0x61, 0x52, 0x0f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
0x4c, 0x6f, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x12, 0x1e,
+ 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65,
0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69,
0x6d, 0x65, 0x12, 0x53,
+ 0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74,
0x61, 0x74, 0x65, 0x73,
+ 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2e, 0x46,
+ 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44,
0x61, 0x74, 0x61, 0x2e,
+ 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74,
0x65, 0x73, 0x45, 0x6e,
+ 0x74, 0x72, 0x79, 0x52, 0x0e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
0x65, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x41,
+ 0x75, 0x74, 0x68, 0x53, 0x70, 0x65, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x21, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x41, 0x75,
+ 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x53, 0x70, 0x65, 0x63,
+ 0x52, 0x10, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75,
0x74, 0x68, 0x53, 0x70,
+ 0x65, 0x63, 0x1a, 0x57, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e,
0x63, 0x65, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
0x03, 0x6b, 0x65, 0x79,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x2a, 0x0a, 0x05, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14,
0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53,
0x74, 0x61, 0x74, 0x65,
+ 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22,
0x4c, 0x0a, 0x1a, 0x46,
+ 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x65,
0x6e, 0x74, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a,
0x04, 0x64, 0x61, 0x74,
+ 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74,
0x61, 0x12, 0x1a, 0x0a,
+ 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52,
+ 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x6f, 0x0a,
0x08, 0x49, 0x6e, 0x73,
+ 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x10, 0x66, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32,
+ 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e,
+ 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x52, 0x10, 0x66, 0x75,
0x6e, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1e,
0x0a, 0x0a, 0x69, 0x6e,
+ 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x05, 0x52, 0x0a,
+ 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x55,
0x0a, 0x0a, 0x41, 0x73,
+ 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x08,
0x69, 0x6e, 0x73, 0x74,
+ 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,
0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52,
0x08, 0x69, 0x6e, 0x73,
+ 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72,
0x6b, 0x65, 0x72, 0x49,
+ 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72,
0x6b, 0x65, 0x72, 0x49,
+ 0x64, 0x2a, 0x5b, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
0x69, 0x6e, 0x67, 0x47,
+ 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x73, 0x12, 0x10, 0x0a,
0x0c, 0x41, 0x54, 0x4c,
+ 0x45, 0x41, 0x53, 0x54, 0x5f, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x00, 0x12,
0x0f, 0x0a, 0x0b, 0x41,
+ 0x54, 0x4d, 0x4f, 0x53, 0x54, 0x5f, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x01,
0x12, 0x14, 0x0a, 0x10,
+ 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x49, 0x56, 0x45, 0x4c, 0x59, 0x5f,
0x4f, 0x4e, 0x43, 0x45,
+ 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x41, 0x4e, 0x55, 0x41, 0x4c,
0x10, 0x03, 0x2a, 0x3c,
0x0a, 0x10, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x54, 0x79,
0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x52, 0x45, 0x44,
0x10, 0x00, 0x12, 0x0c,
0x0a, 0x08, 0x46, 0x41, 0x49, 0x4c, 0x4f, 0x56, 0x45, 0x52, 0x10, 0x01,
0x12, 0x0e, 0x0a, 0x0a,
diff --git a/pulsar-function-go/pb/generate.sh
b/pulsar-function-go/pb/generate.sh
index 5e302e8f7ac..a9e115c46e8 100755
--- a/pulsar-function-go/pb/generate.sh
+++ b/pulsar-function-go/pb/generate.sh
@@ -27,6 +27,8 @@
#
# Requirements:
# * protoc and protoc-gen-go are installed. See:
https://github.com/golang/protobuf
+# * protoc : v3.17.3
+# * protoc-gen-go: v1.25.0
# * The Pulsar project is checked out somewhere on the file system
# in order to source the .proto files
echo "generate pulsar go function protobuf code..."
diff --git a/pulsar-function-go/pf/instance.go
b/pulsar-function-go/pf/instance.go
index 8402e9da625..5e05c070e65 100644
--- a/pulsar-function-go/pf/instance.go
+++ b/pulsar-function-go/pf/instance.go
@@ -40,7 +40,7 @@ type goInstance struct {
producer pulsar.Producer
consumers map[string]pulsar.Consumer
client pulsar.Client
- lastHealthCheckTs int64
+ lastHealthCheckTS int64
properties map[string]string
stats StatWithLabelValues
}
@@ -75,7 +75,7 @@ func newGoInstance() *goInstance {
return producer
}
- goInstance.lastHealthCheckTs = now.UnixNano()
+ goInstance.lastHealthCheckTS = now.UnixNano()
goInstance.properties = make(map[string]string)
goInstance.stats =
NewStatWithLabelValues(goInstance.getMetricsLabels()...)
return goInstance
@@ -85,7 +85,7 @@ func (gi *goInstance) processSpawnerHealthCheckTimer(tkr
*time.Ticker) {
log.Info("Starting processSpawnerHealthCheckTimer")
now := time.Now()
maxIdleTime := gi.context.GetMaxIdleTime()
- timeSinceLastCheck := now.UnixNano() - gi.lastHealthCheckTs
+ timeSinceLastCheck := now.UnixNano() - gi.lastHealthCheckTS
if (timeSinceLastCheck) > (maxIdleTime) {
log.Error("Haven't received health check from spawner in a
while. Stopping instance...")
gi.close()
@@ -112,7 +112,7 @@ func (gi *goInstance) startFunction(function function)
error {
// start process spawner health check timer
now := time.Now()
- gi.lastHealthCheckTs = now.UnixNano()
+ gi.lastHealthCheckTS = now.UnixNano()
gi.startScheduler()
@@ -349,7 +349,6 @@ func (gi *goInstance) handlerMsg(input pulsar.Message)
(output []byte, err error
func (gi *goInstance) processResult(msgInput pulsar.Message, output []byte) {
atLeastOnce := gi.context.instanceConf.funcDetails.ProcessingGuarantees
== pb.ProcessingGuarantees_ATLEAST_ONCE
- atMostOnce := gi.context.instanceConf.funcDetails.ProcessingGuarantees
== pb.ProcessingGuarantees_ATMOST_ONCE
autoAck := gi.context.instanceConf.funcDetails.AutoAck
// If the function had an output and the user has specified an output
topic, the output needs to be sent to the
@@ -372,9 +371,9 @@ func (gi *goInstance) processResult(msgInput
pulsar.Message, output []byte) {
gi.stats.incrTotalSysExceptions(err)
log.Fatal(err)
}
- // Otherwise the message succeeded. If the SDK
is entrusted with responding and we are not using
- // at-most-once delivery semantics, ack the
message.
- if autoAck && !atMostOnce {
+ // Otherwise the message succeeded. If the SDK
is entrusted with responding and we are using
+ // atLeastOnce delivery semantics, ack the
message.
+ if autoAck && atLeastOnce {
gi.ackInputMessage(msgInput)
}
gi.stats.incrTotalProcessedSuccessfully()
@@ -463,7 +462,7 @@ func (gi *goInstance) close() {
func (gi *goInstance) healthCheck() *pb.HealthCheckResult {
now := time.Now()
- gi.lastHealthCheckTs = now.UnixNano()
+ gi.lastHealthCheckTS = now.UnixNano()
healthCheckResult := pb.HealthCheckResult{Success: true}
return &healthCheckResult
}
diff --git a/pulsar-function-go/pf/instanceConf.go
b/pulsar-function-go/pf/instanceConf.go
index 2fc8d95218e..d60beef29e8 100644
--- a/pulsar-function-go/pf/instanceConf.go
+++ b/pulsar-function-go/pf/instanceConf.go
@@ -43,13 +43,7 @@ type instanceConf struct {
metricsPort int
}
-func newInstanceConf() *instanceConf {
- config := &conf.Conf{}
- cfg := config.GetConf()
- if cfg == nil {
- panic("config file is nil.")
- }
-
+func newInstanceConfWithConf(cfg *conf.Conf) *instanceConf {
instanceConf := &instanceConf{
instanceID: cfg.InstanceID,
funcID: cfg.FuncID,
@@ -103,9 +97,33 @@ func newInstanceConf() *instanceConf {
UserConfig: cfg.UserConfig,
},
}
+
+ if instanceConf.funcDetails.ProcessingGuarantees ==
pb.ProcessingGuarantees_EFFECTIVELY_ONCE {
+ panic("Go instance current not support EFFECTIVELY_ONCE
processing guarantees.")
+ }
+
+ if !instanceConf.funcDetails.AutoAck &&
+ (instanceConf.funcDetails.ProcessingGuarantees ==
pb.ProcessingGuarantees_ATMOST_ONCE ||
+ instanceConf.funcDetails.ProcessingGuarantees ==
pb.ProcessingGuarantees_ATLEAST_ONCE) {
+ panic("When Guarantees == " +
instanceConf.funcDetails.ProcessingGuarantees.String() +
+ ", autoAck must be equal to true. If you want not to
automatically ack, " +
+ "please configure the processing guarantees as MANUAL."
+
+ " This is a contradictory configuration, autoAck will
be removed later." +
+ " Please refer to PIP:
https://github.com/apache/pulsar/issues/15560")
+ }
+
return instanceConf
}
+func newInstanceConf() *instanceConf {
+ config := &conf.Conf{}
+ cfg := config.GetConf()
+ if cfg == nil {
+ panic("config file is nil.")
+ }
+ return newInstanceConfWithConf(cfg)
+}
+
func (ic *instanceConf) getInstanceName() string {
return "" + fmt.Sprintf("%d", ic.instanceID)
}
diff --git a/pulsar-function-go/pf/instanceConf_test.go
b/pulsar-function-go/pf/instanceConf_test.go
index fa87002b71c..02aef913ebc 100644
--- a/pulsar-function-go/pf/instanceConf_test.go
+++ b/pulsar-function-go/pf/instanceConf_test.go
@@ -22,6 +22,8 @@ package pf
import (
"testing"
+ cfg "github.com/apache/pulsar/pulsar-function-go/conf"
+
pb "github.com/apache/pulsar/pulsar-function-go/pb"
"github.com/stretchr/testify/assert"
)
@@ -96,3 +98,18 @@ func TestInstanceConf_GetInstanceName(t *testing.T) {
assert.Equal(t, "101", instanceName)
}
+
+func TestInstanceConf_Fail(t *testing.T) {
+ assert.Panics(t, func() {
+ newInstanceConfWithConf(&cfg.Conf{ProcessingGuarantees: 0,
AutoACK: false})
+ }, "Should have a panic")
+ assert.Panics(t, func() {
+ newInstanceConfWithConf(&cfg.Conf{ProcessingGuarantees: 1,
AutoACK: false})
+ }, "Should have a panic")
+ assert.Panics(t, func() {
+ newInstanceConfWithConf(&cfg.Conf{ProcessingGuarantees: 2})
+ }, "Should have a panic")
+ assert.NotPanicsf(t, func() {
+ newInstanceConfWithConf(&cfg.Conf{ProcessingGuarantees: 3})
+ }, "Should have a panic")
+}
diff --git a/pulsar-function-go/pf/instance_test.go
b/pulsar-function-go/pf/instance_test.go
index 85441df5ef4..bf45ae3a891 100644
--- a/pulsar-function-go/pf/instance_test.go
+++ b/pulsar-function-go/pf/instance_test.go
@@ -30,12 +30,12 @@ import (
)
func testProcessSpawnerHealthCheckTimer(
- tkr *time.Ticker, lastHealthCheckTs int64, expectedHealthCheckInterval
int32, counter *int) {
+ tkr *time.Ticker, lastHealthCheckTS int64, expectedHealthCheckInterval
int32, counter *int) {
fmt.Println("Starting processSpawnerHealthCheckTimer")
now := time.Now()
maxIdleTime := int64(time.Duration(expectedHealthCheckInterval) * 3 *
time.Second)
fmt.Println("maxIdleTime is: " + strconv.FormatInt(maxIdleTime, 10))
- timeSinceLastCheck := now.UnixNano() - lastHealthCheckTs
+ timeSinceLastCheck := now.UnixNano() - lastHealthCheckTS
fmt.Println("timeSinceLastCheck is: " +
strconv.FormatInt(timeSinceLastCheck, 10))
if (timeSinceLastCheck) > (maxIdleTime) {
fmt.Println("Haven't received health check from spawner in a
while. Stopping instance...")
@@ -49,7 +49,7 @@ func testProcessSpawnerHealthCheckTimer(
func testStartScheduler(counter *int) {
now := time.Now()
- lastHealthCheckTs := now.UnixNano()
+ lastHealthCheckTS := now.UnixNano()
var expectedHealthCheckInterval int32 = 1
if expectedHealthCheckInterval > 0 {
@@ -61,7 +61,7 @@ func testStartScheduler(counter *int) {
tkr := time.NewTicker(period)
for range tkr.C {
fmt.Println("Starting Timer")
- testProcessSpawnerHealthCheckTimer(tkr,
lastHealthCheckTs, expectedHealthCheckInterval, counter)
+ testProcessSpawnerHealthCheckTimer(tkr,
lastHealthCheckTS, expectedHealthCheckInterval, counter)
}
}()
}
diff --git a/pulsar-function-go/pf/stats.go b/pulsar-function-go/pf/stats.go
index 29c6aa0f026..85a7fff8a38 100644
--- a/pulsar-function-go/pf/stats.go
+++ b/pulsar-function-go/pf/stats.go
@@ -273,8 +273,8 @@ func (stat *StatWithLabelValues)
incrTotalUserExceptions(err error) {
func (stat *StatWithLabelValues) addUserException(err error) {
now := time.Now()
ts := now.UnixNano()
- errorTs := LatestException{err, ts}
- stat.latestUserException = append(stat.latestUserException, errorTs)
+ errorTS := LatestException{err, ts}
+ stat.latestUserException = append(stat.latestUserException, errorTS)
if len(stat.latestUserException) > 10 {
stat.latestUserException = stat.latestUserException[1:]
}
@@ -284,8 +284,8 @@ func (stat *StatWithLabelValues) addUserException(err
error) {
//@limits(calls=5, period=60)
func (stat *StatWithLabelValues) reportUserExceptionPrometheus(exception
error) {
- errorTs := []string{exception.Error()}
- exceptionMetricLabels := append(stat.metricsLabels, errorTs...)
+ errorTS := []string{exception.Error()}
+ exceptionMetricLabels := append(stat.metricsLabels, errorTS...)
userExceptions.WithLabelValues(exceptionMetricLabels...).Set(1.0)
}
@@ -303,8 +303,8 @@ func (stat *StatWithLabelValues)
incrTotalSysExceptions(exception error) {
func (stat *StatWithLabelValues) addSysException(exception error) {
now := time.Now()
ts := now.UnixNano()
- errorTs := LatestException{exception, ts}
- stat.latestSysException = append(stat.latestSysException, errorTs)
+ errorTS := LatestException{exception, ts}
+ stat.latestSysException = append(stat.latestSysException, errorTS)
if len(stat.latestSysException) > 10 {
stat.latestSysException = stat.latestSysException[1:]
}
@@ -314,8 +314,8 @@ func (stat *StatWithLabelValues) addSysException(exception
error) {
//@limits(calls=5, period=60)
func (stat *StatWithLabelValues) reportSystemExceptionPrometheus(exception
error) {
- errorTs := []string{exception.Error()}
- exceptionMetricLabels := append(stat.metricsLabels, errorTs...)
+ errorTS := []string{exception.Error()}
+ exceptionMetricLabels := append(stat.metricsLabels, errorTS...)
systemExceptions.WithLabelValues(exceptionMetricLabels...).Set(1.0)
}
diff --git
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ContextImpl.java
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ContextImpl.java
index b3b165ea536..31d8385c1fc 100644
---
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ContextImpl.java
+++
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/ContextImpl.java
@@ -74,6 +74,7 @@ import
org.apache.pulsar.functions.instance.stats.SourceStatsManager;
import org.apache.pulsar.functions.proto.Function;
import org.apache.pulsar.functions.proto.Function.SinkSpec;
import org.apache.pulsar.functions.secretsprovider.SecretsProvider;
+import org.apache.pulsar.functions.source.PulsarFunctionRecord;
import org.apache.pulsar.functions.source.TopicSchema;
import org.apache.pulsar.functions.utils.FunctionCommon;
import org.apache.pulsar.functions.utils.SinkConfigUtils;
@@ -248,7 +249,7 @@ class ContextImpl implements Context, SinkContext,
SourceContext, AutoCloseable
@Override
public Record<?> getCurrentRecord() {
- return record;
+ return new PulsarFunctionRecord(record, config.getFunctionDetails());
}
@Override
diff --git
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceRunnable.java
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceRunnable.java
index 61f809a4cbc..7429156ca50 100644
---
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceRunnable.java
+++
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceRunnable.java
@@ -21,6 +21,7 @@ package org.apache.pulsar.functions.instance;
import static com.google.common.base.Preconditions.checkNotNull;
import static
org.apache.pulsar.functions.utils.FunctionCommon.convertFromFunctionDetailsSubscriptionPosition;
import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.annotations.VisibleForTesting;
import com.scurrilous.circe.checksum.Crc32cIntChecksum;
import java.io.IOException;
import java.util.HashMap;
@@ -350,7 +351,8 @@ public class JavaInstanceRunnable implements AutoCloseable,
Runnable {
}
}
- private void handleResult(Record srcRecord, JavaExecutionResult result)
throws Exception {
+ @VisibleForTesting
+ void handleResult(Record srcRecord, JavaExecutionResult result) throws
Exception {
if (result.getUserException() != null) {
Exception t = result.getUserException();
log.warn("Encountered exception when processing message {}",
@@ -361,9 +363,17 @@ public class JavaInstanceRunnable implements
AutoCloseable, Runnable {
if (result.getResult() != null) {
sendOutputMessage(srcRecord, result.getResult());
} else {
- if (instanceConfig.getFunctionDetails().getAutoAck()) {
- // the function doesn't produce any result or the user
doesn't want the result.
- srcRecord.ack();
+ org.apache.pulsar.functions.proto.Function.FunctionDetails
functionDetails =
+ instanceConfig.getFunctionDetails();
+ // When function return null, needs to be acked directly.
+ if (functionDetails.getProcessingGuarantees()
+ !=
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.MANUAL) {
+ // This condition has been automatically acked.
+ // After waiting to remove the autoAck configuration,can
be removing the judgment condition.
+ if (!functionDetails.getAutoAck() ||
functionDetails.getProcessingGuarantees()
+ !=
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.ATMOST_ONCE) {
+ srcRecord.ack();
+ }
}
}
// increment total successfully processed
diff --git
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/sink/PulsarSink.java
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/sink/PulsarSink.java
index 80aa49e05ae..2f48efe33dc 100644
---
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/sink/PulsarSink.java
+++
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/sink/PulsarSink.java
@@ -277,6 +277,19 @@ public class PulsarSink<T> implements Sink<T> {
}
}
+ @VisibleForTesting
+ class PulsarSinkManualProcessor extends PulsarSinkAtMostOnceProcessor {
+
+ public PulsarSinkManualProcessor(Schema schema, Crypto crypto) {
+ super(schema, crypto);
+ }
+
+ @Override
+ public void sendOutputMessage(TypedMessageBuilder<T> msg,
AbstractSinkRecord<T> record) {
+ super.sendOutputMessage(msg, record);
+ }
+ }
+
@VisibleForTesting
class PulsarSinkEffectivelyOnceProcessor extends PulsarSinkProcessorBase {
@@ -362,6 +375,9 @@ public class PulsarSink<T> implements Sink<T> {
case EFFECTIVELY_ONCE:
this.pulsarSinkProcessor = new
PulsarSinkEffectivelyOnceProcessor(schema, crypto);
break;
+ case MANUAL:
+ this.pulsarSinkProcessor = new
PulsarSinkManualProcessor(schema, crypto);
+ break;
}
}
diff --git
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/source/PulsarFunctionRecord.java
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/source/PulsarFunctionRecord.java
new file mode 100644
index 00000000000..7a27c0a5f38
--- /dev/null
+++
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/source/PulsarFunctionRecord.java
@@ -0,0 +1,113 @@
+/**
+ * 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.
+ */
+package org.apache.pulsar.functions.source;
+
+import java.util.Map;
+import java.util.Optional;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.pulsar.client.api.Message;
+import org.apache.pulsar.client.api.Schema;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.proto.Function;
+
+/**
+ * The record returned by the proxy to the user.
+ */
+@Slf4j
+public class PulsarFunctionRecord<T> implements Record<T> {
+
+ private final Record<T> record;
+ private final Function.FunctionDetails functionConfig;
+
+ public PulsarFunctionRecord(Record<T> record, Function.FunctionDetails
functionConfig) {
+ this.record = record;
+ this.functionConfig = functionConfig;
+ }
+
+ @Override
+ public Optional<String> getTopicName() {
+ return record.getTopicName();
+ }
+
+ @Override
+ public Optional<String> getKey() {
+ return record.getKey();
+ }
+
+ @Override
+ public Schema getSchema() {
+ return record.getSchema();
+ }
+
+ @Override
+ public T getValue() {
+ return record.getValue();
+ }
+
+ @Override
+ public Optional<Long> getEventTime() {
+ return record.getEventTime();
+ }
+
+ @Override
+ public Optional<String> getPartitionId() {
+ return record.getPartitionId();
+ }
+
+ @Override
+ public Optional<Integer> getPartitionIndex() {
+ return record.getPartitionIndex();
+ }
+
+ @Override
+ public Optional<Long> getRecordSequence() {
+ return record.getRecordSequence();
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return record.getProperties();
+ }
+
+ @Override
+ public void ack() {
+ Function.ProcessingGuarantees processingGuarantees =
functionConfig.getProcessingGuarantees();
+ if (processingGuarantees == Function.ProcessingGuarantees.MANUAL) {
+ record.ack();
+ } else {
+ log.warn("Ignore this ack option, under this configuration
Guarantees:[{}] autoAck:[{}], "
+ + "the framework will automatically ack",
processingGuarantees, functionConfig.getAutoAck());
+ }
+ }
+
+ @Override
+ public void fail() {
+ record.fail();
+ }
+
+ @Override
+ public Optional<String> getDestinationTopic() {
+ return record.getDestinationTopic();
+ }
+
+ @Override
+ public Optional<Message<T>> getMessage() {
+ return record.getMessage();
+ }
+}
diff --git
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java
index c1f40ea496d..9610912db3f 100644
---
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java
+++
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutor.java
@@ -203,9 +203,6 @@ public class WindowFunctionExecutor<T, X> implements
Function<T, X> {
return new WindowLifecycleListener<Event<Record<T>>>() {
@Override
public void onExpiry(List<Event<Record<T>>> events) {
- for (Event<Record<T>> event : events) {
- event.getRecord().ack();
- }
}
@Override
@@ -234,7 +231,13 @@ public class WindowFunctionExecutor<T, X> implements
Function<T, X> {
throw new RuntimeException(e);
}
if (output != null) {
- context.publish(context.getOutputTopic(), output,
context.getOutputSchemaType());
+ context.publish(context.getOutputTopic(), output,
context.getOutputSchemaType()).thenAccept(__ -> {
+ if (windowConfig.getProcessingGuarantees() ==
WindowConfig.ProcessingGuarantees.ATLEAST_ONCE) {
+ for (Record<T> record : tuples) {
+ record.ack();
+ }
+ }
+ });
}
}
@@ -275,8 +278,14 @@ public class WindowFunctionExecutor<T, X> implements
Function<T, X> {
initialize(context);
}
+ // record must be PulsarFunctionRecord.
Record<T> record = (Record<T>) context.getCurrentRecord();
+ // windows function processing semantics requires separate processing
+ if (windowConfig.getProcessingGuarantees() ==
WindowConfig.ProcessingGuarantees.ATMOST_ONCE) {
+ record.ack();
+ }
+
if (isEventTime()) {
long ts =
this.timestampExtractor.extractTimestamp(record.getValue());
if
(this.waterMarkEventGenerator.track(record.getTopicName().get(), ts)) {
@@ -289,7 +298,6 @@ public class WindowFunctionExecutor<T, X> implements
Function<T, X> {
"Received a late tuple %s with ts %d. This will
not be " + "processed"
+ ".", input, ts));
}
- record.ack();
}
} else {
this.windowManager.add(record, System.currentTimeMillis(), record);
diff --git
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowManager.java
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowManager.java
index 29785181edd..0dbc0d317a6 100644
---
a/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowManager.java
+++
b/pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/windowing/WindowManager.java
@@ -122,10 +122,10 @@ public class WindowManager<T> implements TriggerHandler {
lock.lock();
try {
- /*
- * scan the entire window to handle out of order events in
- * the case of time based windows.
- */
+ /*
+ * scan the entire window to handle out of order events in
+ * the case of time based windows.
+ */
windowEvents = scanEvents(true);
expired = new ArrayList<>(expiredEvents);
expiredEvents.clear();
diff --git a/pulsar-functions/instance/src/main/python/Function_pb2.py
b/pulsar-functions/instance/src/main/python/Function_pb2.py
index 14a33a1255d..eebfe8589d5 100644
--- a/pulsar-functions/instance/src/main/python/Function_pb2.py
+++ b/pulsar-functions/instance/src/main/python/Function_pb2.py
@@ -17,9 +17,10 @@
# under the License.
#
+# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: Function.proto
-
+"""Generated protocol buffer code."""
from google.protobuf.internal import enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
@@ -38,7 +39,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
syntax='proto3',
serialized_options=b'\n!org.apache.pulsar.functions.protoB\010Function',
create_key=_descriptor._internal_create_key,
-
serialized_pb=b'\n\x0e\x46unction.proto\x12\x05proto\"3\n\tResources\x12\x0b\n\x03\x63pu\x18\x01
\x01(\x01\x12\x0b\n\x03ram\x18\x02 \x01(\x03\x12\x0c\n\x04\x64isk\x18\x03
\x01(\x03\"B\n\x0cRetryDetails\x12\x19\n\x11maxMessageRetries\x18\x01
\x01(\x05\x12\x17\n\x0f\x64\x65\x61\x64LetterTopic\x18\x02
\x01(\t\"\xa2\x06\n\x0f\x46unctionDetails\x12\x0e\n\x06tenant\x18\x01
\x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03
\x01(\t\x12\x11\n\tclassName\x18\x04 \x01(\t\x12\ [...]
+
serialized_pb=b'\n\x0e\x46unction.proto\x12\x05proto\"3\n\tResources\x12\x0b\n\x03\x63pu\x18\x01
\x01(\x01\x12\x0b\n\x03ram\x18\x02 \x01(\x03\x12\x0c\n\x04\x64isk\x18\x03
\x01(\x03\"B\n\x0cRetryDetails\x12\x19\n\x11maxMessageRetries\x18\x01
\x01(\x05\x12\x17\n\x0f\x64\x65\x61\x64LetterTopic\x18\x02
\x01(\t\"\xa6\x06\n\x0f\x46unctionDetails\x12\x0e\n\x06tenant\x18\x01
\x01(\t\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03
\x01(\t\x12\x11\n\tclassName\x18\x04 \x01(\t\x12\ [...]
)
_PROCESSINGGUARANTEES = _descriptor.EnumDescriptor(
@@ -63,11 +64,16 @@ _PROCESSINGGUARANTEES = _descriptor.EnumDescriptor(
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
+ _descriptor.EnumValueDescriptor(
+ name='MANUAL', index=3, number=3,
+ serialized_options=None,
+ type=None,
+ create_key=_descriptor._internal_create_key),
],
containing_type=None,
serialized_options=None,
- serialized_start=3685,
- serialized_end=3764,
+ serialized_start=3711,
+ serialized_end=3802,
)
_sym_db.RegisterEnumDescriptor(_PROCESSINGGUARANTEES)
@@ -97,8 +103,8 @@ _SUBSCRIPTIONTYPE = _descriptor.EnumDescriptor(
],
containing_type=None,
serialized_options=None,
- serialized_start=3766,
- serialized_end=3826,
+ serialized_start=3804,
+ serialized_end=3864,
)
_sym_db.RegisterEnumDescriptor(_SUBSCRIPTIONTYPE)
@@ -123,8 +129,8 @@ _SUBSCRIPTIONPOSITION = _descriptor.EnumDescriptor(
],
containing_type=None,
serialized_options=None,
- serialized_start=3828,
- serialized_end=3876,
+ serialized_start=3866,
+ serialized_end=3914,
)
_sym_db.RegisterEnumDescriptor(_SUBSCRIPTIONPOSITION)
@@ -149,8 +155,8 @@ _FUNCTIONSTATE = _descriptor.EnumDescriptor(
],
containing_type=None,
serialized_options=None,
- serialized_start=3878,
- serialized_end=3919,
+ serialized_start=3916,
+ serialized_end=3957,
)
_sym_db.RegisterEnumDescriptor(_FUNCTIONSTATE)
@@ -158,6 +164,7 @@ FunctionState =
enum_type_wrapper.EnumTypeWrapper(_FUNCTIONSTATE)
ATLEAST_ONCE = 0
ATMOST_ONCE = 1
EFFECTIVELY_ONCE = 2
+MANUAL = 3
SHARED = 0
FAILOVER = 1
KEY_SHARED = 2
@@ -192,8 +199,8 @@ _FUNCTIONDETAILS_RUNTIME = _descriptor.EnumDescriptor(
],
containing_type=None,
serialized_options=None,
- serialized_start=844,
- serialized_end=883,
+ serialized_start=848,
+ serialized_end=887,
)
_sym_db.RegisterEnumDescriptor(_FUNCTIONDETAILS_RUNTIME)
@@ -227,8 +234,8 @@ _FUNCTIONDETAILS_COMPONENTTYPE = _descriptor.EnumDescriptor(
],
containing_type=None,
serialized_options=None,
- serialized_start=885,
- serialized_end=949,
+ serialized_start=889,
+ serialized_end=953,
)
_sym_db.RegisterEnumDescriptor(_FUNCTIONDETAILS_COMPONENTTYPE)
@@ -262,8 +269,8 @@ _CRYPTOSPEC_FAILUREACTION = _descriptor.EnumDescriptor(
],
containing_type=None,
serialized_options=None,
- serialized_start=1873,
- serialized_end=1934,
+ serialized_start=1899,
+ serialized_end=1960,
)
_sym_db.RegisterEnumDescriptor(_CRYPTOSPEC_FAILUREACTION)
@@ -430,7 +437,7 @@ _FUNCTIONDETAILS = _descriptor.Descriptor(
has_default_value=False, default_value=False,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- serialized_options=None, file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
+ serialized_options=b'\030\001', file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='parallelism', full_name='proto.FunctionDetails.parallelism',
index=10,
number=10, type=5, cpp_type=1, label=1,
@@ -537,7 +544,7 @@ _FUNCTIONDETAILS = _descriptor.Descriptor(
oneofs=[
],
serialized_start=147,
- serialized_end=949,
+ serialized_end=953,
)
@@ -568,8 +575,8 @@ _CONSUMERSPEC_RECEIVERQUEUESIZE = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=1283,
- serialized_end=1317,
+ serialized_start=1309,
+ serialized_end=1343,
)
_CONSUMERSPEC_SCHEMAPROPERTIESENTRY = _descriptor.Descriptor(
@@ -606,8 +613,8 @@ _CONSUMERSPEC_SCHEMAPROPERTIESENTRY =
_descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=1319,
- serialized_end=1374,
+ serialized_start=1345,
+ serialized_end=1400,
)
_CONSUMERSPEC_CONSUMERPROPERTIESENTRY = _descriptor.Descriptor(
@@ -644,8 +651,8 @@ _CONSUMERSPEC_CONSUMERPROPERTIESENTRY =
_descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=1376,
- serialized_end=1433,
+ serialized_start=1402,
+ serialized_end=1459,
)
_CONSUMERSPEC = _descriptor.Descriptor(
@@ -705,6 +712,13 @@ _CONSUMERSPEC = _descriptor.Descriptor(
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
+ _descriptor.FieldDescriptor(
+ name='poolMessages', full_name='proto.ConsumerSpec.poolMessages',
index=7,
+ number=8, type=8, cpp_type=7, label=1,
+ has_default_value=False, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ serialized_options=None, file=DESCRIPTOR,
create_key=_descriptor._internal_create_key),
],
extensions=[
],
@@ -717,8 +731,8 @@ _CONSUMERSPEC = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=952,
- serialized_end=1433,
+ serialized_start=956,
+ serialized_end=1459,
)
@@ -777,8 +791,8 @@ _PRODUCERSPEC = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=1436,
- serialized_end=1616,
+ serialized_start=1462,
+ serialized_end=1642,
)
@@ -838,8 +852,8 @@ _CRYPTOSPEC = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=1619,
- serialized_end=1934,
+ serialized_start=1645,
+ serialized_end=1960,
)
@@ -877,8 +891,8 @@ _SOURCESPEC_TOPICSTOSERDECLASSNAMEENTRY =
_descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=2414,
- serialized_end=2475,
+ serialized_start=2440,
+ serialized_end=2501,
)
_SOURCESPEC_INPUTSPECSENTRY = _descriptor.Descriptor(
@@ -915,8 +929,8 @@ _SOURCESPEC_INPUTSPECSENTRY = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=2477,
- serialized_end=2547,
+ serialized_start=2503,
+ serialized_end=2573,
)
_SOURCESPEC = _descriptor.Descriptor(
@@ -1030,8 +1044,8 @@ _SOURCESPEC = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=1937,
- serialized_end=2547,
+ serialized_start=1963,
+ serialized_end=2573,
)
@@ -1069,8 +1083,8 @@ _SINKSPEC_SCHEMAPROPERTIESENTRY = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=1319,
- serialized_end=1374,
+ serialized_start=1345,
+ serialized_end=1400,
)
_SINKSPEC_CONSUMERPROPERTIESENTRY = _descriptor.Descriptor(
@@ -1107,8 +1121,8 @@ _SINKSPEC_CONSUMERPROPERTIESENTRY =
_descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=1376,
- serialized_end=1433,
+ serialized_start=1402,
+ serialized_end=1459,
)
_SINKSPEC = _descriptor.Descriptor(
@@ -1208,8 +1222,8 @@ _SINKSPEC = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=2550,
- serialized_end=3026,
+ serialized_start=2576,
+ serialized_end=3052,
)
@@ -1247,8 +1261,8 @@ _PACKAGELOCATIONMETADATA = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=3028,
- serialized_end=3100,
+ serialized_start=3054,
+ serialized_end=3126,
)
@@ -1286,8 +1300,8 @@ _FUNCTIONMETADATA_INSTANCESTATESENTRY =
_descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=3396,
- serialized_end=3471,
+ serialized_start=3422,
+ serialized_end=3497,
)
_FUNCTIONMETADATA = _descriptor.Descriptor(
@@ -1352,8 +1366,8 @@ _FUNCTIONMETADATA = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=3103,
- serialized_end=3471,
+ serialized_start=3129,
+ serialized_end=3497,
)
@@ -1391,8 +1405,8 @@ _FUNCTIONAUTHENTICATIONSPEC = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=3473,
- serialized_end=3533,
+ serialized_start=3499,
+ serialized_end=3559,
)
@@ -1430,8 +1444,8 @@ _INSTANCE = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=3535,
- serialized_end=3616,
+ serialized_start=3561,
+ serialized_end=3642,
)
@@ -1469,8 +1483,8 @@ _ASSIGNMENT = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=3618,
- serialized_end=3683,
+ serialized_start=3644,
+ serialized_end=3709,
)
_FUNCTIONDETAILS.fields_by_name['processingGuarantees'].enum_type =
_PROCESSINGGUARANTEES
@@ -1690,6 +1704,7 @@ _sym_db.RegisterMessage(Assignment)
DESCRIPTOR._options = None
+_FUNCTIONDETAILS.fields_by_name['autoAck']._options = None
_CONSUMERSPEC_SCHEMAPROPERTIESENTRY._options = None
_CONSUMERSPEC_CONSUMERPROPERTIESENTRY._options = None
_SOURCESPEC_TOPICSTOSERDECLASSNAMEENTRY._options = None
diff --git a/pulsar-functions/instance/src/main/python/python_instance.py
b/pulsar-functions/instance/src/main/python/python_instance.py
index 1a04029ed81..46c01c2ddd4 100755
--- a/pulsar-functions/instance/src/main/python/python_instance.py
+++ b/pulsar-functions/instance/src/main/python/python_instance.py
@@ -100,6 +100,7 @@ class PythonInstance(object):
self.execution_thread = None
self.atmost_once =
self.instance_config.function_details.processingGuarantees ==
Function_pb2.ProcessingGuarantees.Value('ATMOST_ONCE')
self.atleast_once =
self.instance_config.function_details.processingGuarantees ==
Function_pb2.ProcessingGuarantees.Value('ATLEAST_ONCE')
+ self.manual = self.instance_config.function_details.processingGuarantees
== Function_pb2.ProcessingGuarantees.Value('MANUAL')
self.auto_ack = self.instance_config.function_details.autoAck
self.contextimpl = None
self.last_health_check_ts = time.time()
@@ -269,7 +270,7 @@ class PythonInstance(object):
def done_producing(self, consumer, orig_message, topic, result,
sent_message):
if result == pulsar.Result.Ok:
- if self.auto_ack:
+ if self.auto_ack and self.atleast_once:
consumer.acknowledge(orig_message)
else:
error_msg = "Failed to publish to topic [%s] with error [%s] with src
message id [%s]" % (topic, result, orig_message.message_id())
diff --git a/pulsar-functions/instance/src/main/python/python_instance_main.py
b/pulsar-functions/instance/src/main/python/python_instance_main.py
index 5817e5958e6..631d5b47851 100755
--- a/pulsar-functions/instance/src/main/python/python_instance_main.py
+++ b/pulsar-functions/instance/src/main/python/python_instance_main.py
@@ -97,6 +97,18 @@ def main():
args.function_details = args.function_details[:-1]
json_format.Parse(args.function_details, function_details)
+ if function_details.processingGuarantees == "EFFECTIVELY_ONCE":
+ print("Python instance current not support EFFECTIVELY_ONCE processing
guarantees.")
+ sys.exit(1)
+
+ if function_details.autoAck == False and
function_details.processingGuarantees == "ATMOST_ONCE" \
+ or function_details.processingGuarantees == "ATLEAST_ONCE":
+ print("When Guarantees == " + function_details.processingGuarantees + ",
autoAck must be equal to true, "
+ "This is a contradictory configuration, autoAck will be removed
later,"
+ "If you want not to automatically ack, please configure the
processing guarantees as MANUAL."
+ "This is a contradictory configuration, autoAck will be removed
later,"
+ "Please refer to PIP: https://github.com/apache/pulsar/issues/15560")
+ sys.exit(1)
if os.path.splitext(str(args.py))[1] == '.whl':
if args.install_usercode_dependencies:
cmd = "pip install -t %s" % os.path.dirname(str(args.py))
diff --git
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/ContextImplTest.java
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/ContextImplTest.java
index 13c467e1e50..a5fe51d5403 100644
---
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/ContextImplTest.java
+++
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/ContextImplTest.java
@@ -55,6 +55,7 @@ import org.apache.pulsar.client.impl.PulsarClientImpl;
import org.apache.pulsar.client.impl.TypedMessageBuilderImpl;
import org.apache.pulsar.client.impl.conf.ProducerConfigurationData;
import org.apache.pulsar.common.io.SinkConfig;
+import org.apache.pulsar.common.io.SourceConfig;
import org.apache.pulsar.common.naming.TopicName;
import org.apache.pulsar.functions.api.Record;
import org.apache.pulsar.functions.instance.state.BKStateStoreImpl;
@@ -62,7 +63,9 @@ import
org.apache.pulsar.functions.instance.state.InstanceStateManager;
import org.apache.pulsar.functions.instance.stats.FunctionCollectorRegistry;
import org.apache.pulsar.functions.proto.Function.FunctionDetails;
import
org.apache.pulsar.functions.secretsprovider.EnvironmentBasedSecretsProvider;
+import org.apache.pulsar.functions.source.PulsarFunctionRecord;
import org.apache.pulsar.io.core.SinkContext;
+import org.apache.pulsar.io.core.SourceContext;
import org.assertj.core.util.Lists;
import org.mockito.Mockito;
import org.slf4j.Logger;
@@ -152,11 +155,17 @@ public class ContextImplTest {
@Test
public void testGetSourceConfig() {
- SinkContext sourceContext = context;
- SinkConfig sinkConfig = sourceContext.getSinkConfig();
+ SourceContext sourceContext = context;
+ SourceConfig sinkConfig = sourceContext.getSourceConfig();
Assert.assertNotNull(sinkConfig);
}
+ @Test
+ public void testGetCurrentRecord() {
+ Record<?> currentRecord = context.getCurrentRecord();
+ assertTrue(currentRecord instanceof PulsarFunctionRecord<?>);
+ }
+
@Test
public void testIncrCounterStateEnabled() throws Exception {
context.defaultStateStore = mock(BKStateStoreImpl.class);
diff --git
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/JavaInstanceRunnableTest.java
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/JavaInstanceRunnableTest.java
index ec478e2beaf..5029a064311 100644
---
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/JavaInstanceRunnableTest.java
+++
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/instance/JavaInstanceRunnableTest.java
@@ -18,10 +18,14 @@
*/
package org.apache.pulsar.functions.instance;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import lombok.Getter;
@@ -29,12 +33,15 @@ import lombok.Setter;
import org.apache.pulsar.client.api.ClientBuilder;
import org.apache.pulsar.functions.api.Context;
import org.apache.pulsar.functions.api.Function;
+import org.apache.pulsar.functions.api.Record;
import org.apache.pulsar.functions.api.SerDe;
+import org.apache.pulsar.functions.instance.stats.ComponentStatsManager;
import org.apache.pulsar.functions.proto.Function.FunctionDetails;
import org.apache.pulsar.functions.proto.Function.SinkSpec;
import org.apache.pulsar.functions.proto.Function.SinkSpecOrBuilder;
import org.apache.pulsar.functions.proto.Function.SourceSpecOrBuilder;
import org.apache.pulsar.functions.proto.InstanceCommunication;
+import org.jetbrains.annotations.NotNull;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -52,21 +59,25 @@ public class JavaInstanceRunnableTest {
}
}
- private static InstanceConfig createInstanceConfig(String outputSerde) {
- FunctionDetails.Builder functionDetailsBuilder =
FunctionDetails.newBuilder();
- if (outputSerde != null) {
-
functionDetailsBuilder.setSink(SinkSpec.newBuilder().setSerDeClassName(outputSerde).build());
- }
+ private static InstanceConfig createInstanceConfig(FunctionDetails
functionDetails) {
InstanceConfig instanceConfig = new InstanceConfig();
- instanceConfig.setFunctionDetails(functionDetailsBuilder.build());
+ instanceConfig.setFunctionDetails(functionDetails);
instanceConfig.setMaxBufferedTuples(1024);
return instanceConfig;
}
private JavaInstanceRunnable createRunnable(String outputSerde) throws
Exception {
- InstanceConfig config = createInstanceConfig(outputSerde);
+ FunctionDetails.Builder functionDetailsBuilder =
FunctionDetails.newBuilder();
+ if (outputSerde != null) {
+
functionDetailsBuilder.setSink(SinkSpec.newBuilder().setSerDeClassName(outputSerde).build());
+ }
+ return createRunnable(functionDetailsBuilder.build());
+ }
+
+ private JavaInstanceRunnable createRunnable(FunctionDetails
functionDetails) throws Exception {
ClientBuilder clientBuilder = mock(ClientBuilder.class);
when(clientBuilder.build()).thenReturn(null);
+ InstanceConfig config = createInstanceConfig(functionDetails);
JavaInstanceRunnable javaInstanceRunnable = new JavaInstanceRunnable(
config, clientBuilder, null, null, null, null, null, null,
null);
return javaInstanceRunnable;
@@ -119,9 +130,51 @@ public class JavaInstanceRunnableTest {
}
}
+ @Test
+ public void testFunctionResultNull() throws Exception {
+ JavaExecutionResult javaExecutionResult = new JavaExecutionResult();
+
+ // ProcessingGuarantees == MANUAL, not need ack.
+ Record record = mock(Record.class);
+ getJavaInstanceRunnable(true,
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.MANUAL)
+ .handleResult(record, javaExecutionResult);
+ verify(record, times(0)).ack();
+
+ // ProcessingGuarantees == ATMOST_ONCE and autoAck == true, not need
ack
+ clearInvocations(record);
+ getJavaInstanceRunnable(true,
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.ATMOST_ONCE)
+ .handleResult(record, javaExecutionResult);
+ verify(record, times(0)).ack();
+
+ // other case, need ack
+ clearInvocations(record);
+ getJavaInstanceRunnable(true,
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.ATLEAST_ONCE)
+ .handleResult(record, javaExecutionResult);
+ verify(record, times(1)).ack();
+ clearInvocations(record);
+ getJavaInstanceRunnable(true,
org.apache.pulsar.functions.proto.Function.ProcessingGuarantees.EFFECTIVELY_ONCE)
+ .handleResult(record, javaExecutionResult);
+ verify(record, times(1)).ack();
+ }
+
+ @NotNull
+ private JavaInstanceRunnable getJavaInstanceRunnable(boolean autoAck,
+ org.apache.pulsar.functions.proto.Function.ProcessingGuarantees
processingGuarantees) throws Exception {
+ FunctionDetails functionDetails = FunctionDetails.newBuilder()
+ .setAutoAck(autoAck)
+ .setProcessingGuarantees(processingGuarantees).build();
+ JavaInstanceRunnable javaInstanceRunnable =
createRunnable(functionDetails);
+
+ Field stats = JavaInstanceRunnable.class.getDeclaredField("stats");
+ stats.setAccessible(true);
+ stats.set(javaInstanceRunnable, mock(ComponentStatsManager.class));
+ stats.setAccessible(false);
+ return javaInstanceRunnable;
+ }
+
@Test
public void testStatsManagerNull() throws Exception {
- JavaInstanceRunnable javaInstanceRunnable = createRunnable(null);
+ JavaInstanceRunnable javaInstanceRunnable = createRunnable((String)
null);
Assert.assertEquals(javaInstanceRunnable.getFunctionStatus().build(),
InstanceCommunication.FunctionStatus.newBuilder().build());
diff --git
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/sink/PulsarSinkTest.java
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/sink/PulsarSinkTest.java
index 94878e33c57..93104c5eee2 100644
---
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/sink/PulsarSinkTest.java
+++
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/sink/PulsarSinkTest.java
@@ -337,9 +337,9 @@ public class PulsarSinkTest {
pulsarConfig.setTopic(defaultTopic);
PulsarClient pulsarClient;
- /** test At-least-once **/
+ /** test MANUAL **/
pulsarClient = getPulsarClient();
-
pulsarConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE);
+ pulsarConfig.setProcessingGuarantees(ProcessingGuarantees.MANUAL);
PulsarSink pulsarSink = new PulsarSink(pulsarClient, pulsarConfig, new
HashMap<>(), mock(ComponentStatsManager.class),
Thread.currentThread().getContextClassLoader());
pulsarSink.open(new HashMap<>(), mock(SinkContext.class));
@@ -362,6 +362,46 @@ public class PulsarSinkTest {
pulsarSink.write(record);
+ Assert.assertTrue(pulsarSink.pulsarSinkProcessor instanceof
PulsarSink.PulsarSinkManualProcessor);
+ PulsarSink.PulsarSinkManualProcessor pulsarSinkManualProcessor
+ = (PulsarSink.PulsarSinkManualProcessor)
pulsarSink.pulsarSinkProcessor;
+ if (topic != null) {
+
Assert.assertTrue(pulsarSinkManualProcessor.publishProducers.containsKey(topic));
+ } else {
+
Assert.assertTrue(pulsarSinkManualProcessor.publishProducers.containsKey(defaultTopic));
+ }
+ verify(pulsarClient.newProducer(),
times(1)).topic(argThat(otherTopic -> {
+ if (topic != null) {
+ return topic.equals(otherTopic);
+ } else {
+ return defaultTopic.equals(otherTopic);
+ }
+ }));
+ }
+
+ /** test At-least-once **/
+ pulsarClient = getPulsarClient();
+
pulsarConfig.setProcessingGuarantees(ProcessingGuarantees.ATLEAST_ONCE);
+ pulsarSink = new PulsarSink(pulsarClient, pulsarConfig, new
HashMap<>(), mock(ComponentStatsManager.class),
Thread.currentThread().getContextClassLoader());
+
+ pulsarSink.open(new HashMap<>(), mock(SinkContext.class));
+
+ for (String topic : topics) {
+
+ SinkRecord<String> record = new SinkRecord<>(new Record<String>() {
+
+ @Override
+ public String getValue() {
+ return "in1";
+ }
+
+ @Override
+ public Optional<String> getDestinationTopic() {
+ return getTopicOptional(topic);
+ }
+ }, "out1");
+ pulsarSink.write(record);
+
Assert.assertTrue(pulsarSink.pulsarSinkProcessor instanceof
PulsarSink.PulsarSinkAtLeastOnceProcessor);
PulsarSink.PulsarSinkAtLeastOnceProcessor
pulsarSinkAtLeastOnceProcessor
= (PulsarSink.PulsarSinkAtLeastOnceProcessor)
pulsarSink.pulsarSinkProcessor;
@@ -381,7 +421,7 @@ public class PulsarSinkTest {
/** test At-most-once **/
pulsarClient = getPulsarClient();
-
pulsarConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATMOST_ONCE);
+ pulsarConfig.setProcessingGuarantees(ProcessingGuarantees.ATMOST_ONCE);
pulsarSink = new PulsarSink(pulsarClient, pulsarConfig, new
HashMap<>(), mock(ComponentStatsManager.class),
Thread.currentThread().getContextClassLoader());
diff --git
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/source/PulsarFunctionRecordTest.java
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/source/PulsarFunctionRecordTest.java
new file mode 100644
index 00000000000..f4f857354e8
--- /dev/null
+++
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/source/PulsarFunctionRecordTest.java
@@ -0,0 +1,62 @@
+/**
+ * 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.
+ */
+package org.apache.pulsar.functions.source;
+
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.testng.Assert.*;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.proto.Function;
+import org.testng.annotations.Test;
+
+public class PulsarFunctionRecordTest {
+
+ @Test
+ public void testAck() {
+ Record record = mock(Record.class);
+ Function.FunctionDetails functionDetails =
Function.FunctionDetails.newBuilder().setAutoAck(true)
+
.setProcessingGuarantees(Function.ProcessingGuarantees.ATMOST_ONCE).build();
+ PulsarFunctionRecord pulsarFunctionRecord = new
PulsarFunctionRecord<>(record, functionDetails);
+ pulsarFunctionRecord.ack();
+ verify(record, times(0)).ack();
+
+ clearInvocations(record);
+ functionDetails =
Function.FunctionDetails.newBuilder().setAutoAck(true)
+
.setProcessingGuarantees(Function.ProcessingGuarantees.ATLEAST_ONCE).build();
+ pulsarFunctionRecord = new PulsarFunctionRecord<>(record,
functionDetails);
+ pulsarFunctionRecord.ack();
+ verify(record, times(0)).ack();
+
+ clearInvocations(record);
+ functionDetails =
Function.FunctionDetails.newBuilder().setAutoAck(true)
+
.setProcessingGuarantees(Function.ProcessingGuarantees.EFFECTIVELY_ONCE).build();
+ pulsarFunctionRecord = new PulsarFunctionRecord<>(record,
functionDetails);
+ pulsarFunctionRecord.ack();
+ verify(record, times(0)).ack();
+
+ clearInvocations(record);
+ functionDetails =
Function.FunctionDetails.newBuilder().setAutoAck(true)
+
.setProcessingGuarantees(Function.ProcessingGuarantees.MANUAL).build();
+ pulsarFunctionRecord = new PulsarFunctionRecord<>(record,
functionDetails);
+ pulsarFunctionRecord.ack();
+ verify(record, times(1)).ack();
+ }
+}
diff --git
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutorTest.java
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutorTest.java
index 8efc8d0e1ee..bf74824efed 100644
---
a/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutorTest.java
+++
b/pulsar-functions/instance/src/test/java/org/apache/pulsar/functions/windowing/WindowFunctionExecutorTest.java
@@ -20,8 +20,12 @@ package org.apache.pulsar.functions.windowing;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
@@ -127,6 +131,46 @@ public class WindowFunctionExecutorTest {
testWindowedPulsarFunction.shutdown();
}
+ @Test
+ public void testWindowFunctionWithAtmostOnce() throws Exception {
+
windowConfig.setProcessingGuarantees(WindowConfig.ProcessingGuarantees.ATMOST_ONCE);
+ doReturn(Optional.of(new Gson().fromJson(new
Gson().toJson(windowConfig), Map.class))).when(context)
+ .getUserConfigValue(WindowConfig.WINDOW_CONFIG_KEY);
+ Record record = mock(Record.class);
+ when(context.getCurrentRecord()).thenReturn(record);
+ doReturn(Optional.of("test-topic")).when(record).getTopicName();
+ doReturn(record).when(context).getCurrentRecord();
+ doReturn(100l).when(record).getValue();
+ testWindowedPulsarFunction.process(10L, context);
+ verify(record, times(1)).ack();
+ }
+
+ @Test
+ public void testWindowFunctionWithAtleastOnce() throws Exception {
+
+ WindowConfig config = new WindowConfig();
+
config.setProcessingGuarantees(WindowConfig.ProcessingGuarantees.ATLEAST_ONCE);
+ WindowFunctionExecutor windowFunctionExecutor =
spy(WindowFunctionExecutor.class);
+ windowFunctionExecutor.windowConfig = config;
+ doNothing().when(windowFunctionExecutor).initialize(any());
+ doReturn(new
Object()).when(windowFunctionExecutor).process(any(Window.class),
any(WindowContext.class));
+
doReturn(CompletableFuture.completedFuture(null)).when(context).publish(any(),
any(), any());
+
+ List<Event<Record<Long>>> tuples = new ArrayList<>();
+ tuples.add(new EventImpl<>(mock(Record.class), 0l,
mock(Record.class)));
+ WindowLifecycleListener<Event<Record<Long>>>
eventWindowLifecycleListener =
+ windowFunctionExecutor.newWindowLifecycleListener(context);
+
+ eventWindowLifecycleListener.onExpiry(tuples);
+ for (Event<Record<Long>> tuple : tuples) {
+ verify(tuple.getRecord(), times(0)).ack();
+ }
+
+ eventWindowLifecycleListener.onActivation(tuples, new ArrayList<>(),
new ArrayList<>(), 0l);
+ for (Event<Record<Long>> tuple : tuples) {
+ verify(tuple.get(), times(1)).ack();
+ }
+ }
@Test(expectedExceptions = RuntimeException.class)
public void testExecuteWithWrongWrongTimestampExtractorType() throws
Exception {
WindowConfig windowConfig = new WindowConfig();
diff --git a/pulsar-functions/proto/src/main/proto/Function.proto
b/pulsar-functions/proto/src/main/proto/Function.proto
index 02520be305b..09ff9cfc8eb 100644
--- a/pulsar-functions/proto/src/main/proto/Function.proto
+++ b/pulsar-functions/proto/src/main/proto/Function.proto
@@ -27,6 +27,7 @@ enum ProcessingGuarantees {
ATLEAST_ONCE = 0; // [default value]
ATMOST_ONCE = 1;
EFFECTIVELY_ONCE = 2;
+ MANUAL = 3;
}
enum SubscriptionType {
@@ -72,7 +73,8 @@ message FunctionDetails {
string userConfig = 7;
string secretsMap = 16;
Runtime runtime = 8;
- bool autoAck = 9;
+ // Deprecated since, see https://github.com/apache/pulsar/issues/15560
+ bool autoAck = 9 [deprecated = true];
int32 parallelism = 10;
SourceSpec source = 11;
SinkSpec sink = 12;
diff --git
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
index 69b4dcfd647..d24542185e5 100644
---
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
+++
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java
@@ -308,11 +308,22 @@ public class FunctionConfigUtils {
// windowing related
WindowConfig windowConfig = functionConfig.getWindowConfig();
if (windowConfig != null) {
+ // Windows Function not support MANUAL and EFFECTIVELY_ONCE.
+ if (functionConfig.getProcessingGuarantees() ==
FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE
+ || functionConfig.getProcessingGuarantees() ==
FunctionConfig.ProcessingGuarantees.MANUAL) {
+ throw new IllegalArgumentException(
+ "Windows Function not support "
+ + functionConfig.getProcessingGuarantees() + "
delivery semantics.");
+ } else {
+ // Override functionConfig.getProcessingGuarantees to MANUAL,
and set windowsFunction is guarantees
+
windowConfig.setProcessingGuarantees(WindowConfig.ProcessingGuarantees
+
.valueOf(functionDetailsBuilder.getProcessingGuarantees().name()));
+
functionDetailsBuilder.setProcessingGuarantees(Function.ProcessingGuarantees.MANUAL);
+ }
windowConfig.setActualWindowFunctionClassName(extractedDetails.getFunctionClassName());
configs.put(WindowConfig.WINDOW_CONFIG_KEY, windowConfig);
// set class name to window function executor
functionDetailsBuilder.setClassName("org.apache.pulsar.functions.windowing.WindowFunctionExecutor");
-
} else {
if (extractedDetails.getFunctionClassName() != null) {
functionDetailsBuilder.setClassName(extractedDetails.getFunctionClassName());
@@ -321,7 +332,6 @@ public class FunctionConfigUtils {
if (!configs.isEmpty()) {
functionDetailsBuilder.setUserConfig(new Gson().toJson(configs));
}
-
if (functionConfig.getSecrets() != null &&
!functionConfig.getSecrets().isEmpty()) {
functionDetailsBuilder.setSecretsMap(new
Gson().toJson(functionConfig.getSecrets()));
}
@@ -361,10 +371,26 @@ public class FunctionConfigUtils {
functionDetailsBuilder.setBuiltin(builtin);
}
- return functionDetailsBuilder.build();
+ return validateFunctionDetails(functionDetailsBuilder.build());
+ }
+
+ public static FunctionDetails validateFunctionDetails(FunctionDetails
functionDetails)
+ throws IllegalArgumentException {
+ if (!functionDetails.getAutoAck() &&
functionDetails.getProcessingGuarantees()
+ == Function.ProcessingGuarantees.ATMOST_ONCE) {
+ throw new IllegalArgumentException("When Guarantees ==
ATMOST_ONCE, autoAck must be equal to true."
+ + " This is a contradictory configuration, autoAck will be
removed later."
+ + " Please refer to PIP:
https://github.com/apache/pulsar/issues/15560");
+ }
+ if (!functionDetails.getAutoAck()) {
+ log.warn("The autoAck configuration will be deprecated in the
future."
+ + " If you want not to automatically ack, please configure
the processing guarantees as MANUAL.");
+ }
+ return functionDetails;
}
public static FunctionConfig convertFromDetails(FunctionDetails
functionDetails) {
+ functionDetails = validateFunctionDetails(functionDetails);
FunctionConfig functionConfig = new FunctionConfig();
functionConfig.setTenant(functionDetails.getTenant());
functionConfig.setNamespace(functionDetails.getNamespace());
@@ -463,6 +489,10 @@ public class FunctionConfigUtils {
(new
Gson().toJson(userConfig.get(WindowConfig.WINDOW_CONFIG_KEY))),
WindowConfig.class);
userConfig.remove(WindowConfig.WINDOW_CONFIG_KEY);
+ if (windowConfig.getProcessingGuarantees() != null) {
+ functionConfig.setProcessingGuarantees(
+
FunctionConfig.ProcessingGuarantees.valueOf(windowConfig.getProcessingGuarantees().name()));
+ }
functionConfig.setClassName(windowConfig.getActualWindowFunctionClassName());
functionConfig.setWindowConfig(windowConfig);
} else {
diff --git
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java
index a2f0fdde7a2..31b147a1caf 100644
---
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java
+++
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SinkConfigUtils.java
@@ -177,6 +177,7 @@ public class SinkConfigUtils {
} else {
functionDetailsBuilder.setAutoAck(true);
}
+
if (sinkConfig.getTimeoutMs() != null) {
sourceSpecBuilder.setTimeoutMs(sinkConfig.getTimeoutMs());
}
@@ -253,7 +254,7 @@ public class SinkConfigUtils {
functionDetailsBuilder.setCustomRuntimeOptions(sinkConfig.getCustomRuntimeOptions());
}
- return functionDetailsBuilder.build();
+ return
FunctionConfigUtils.validateFunctionDetails(functionDetailsBuilder.build());
}
public static SinkConfig convertFromDetails(FunctionDetails
functionDetails) {
diff --git
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java
index bcb847869e6..f8fc091aece 100644
---
a/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java
+++
b/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java
@@ -196,7 +196,7 @@ public class SourceConfigUtils {
functionDetailsBuilder.setCustomRuntimeOptions(sourceConfig.getCustomRuntimeOptions());
}
- return functionDetailsBuilder.build();
+ return
FunctionConfigUtils.validateFunctionDetails(functionDetailsBuilder.build());
}
public static SourceConfig convertFromDetails(FunctionDetails
functionDetails) {
diff --git
a/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/FunctionConfigUtilsTest.java
b/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/FunctionConfigUtilsTest.java
index b2766b76146..389da88e583 100644
---
a/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/FunctionConfigUtilsTest.java
+++
b/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/FunctionConfigUtilsTest.java
@@ -45,6 +45,7 @@ import static
org.apache.pulsar.common.functions.FunctionConfig.Runtime.PYTHON;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertThrows;
import static org.testng.Assert.assertTrue;
/**
@@ -53,6 +54,18 @@ import static org.testng.Assert.assertTrue;
@Slf4j
public class FunctionConfigUtilsTest {
+ @Test
+ public void testAutoAckConvertFailed() {
+
+ FunctionConfig functionConfig = new FunctionConfig();
+ functionConfig.setAutoAck(false);
+
functionConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATMOST_ONCE);
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ FunctionConfigUtils.convert(functionConfig, (ClassLoader) null);
+ });
+ }
+
@Test
public void testConvertBackFidelity() {
FunctionConfig functionConfig = new FunctionConfig();
@@ -128,6 +141,10 @@ public class FunctionConfigUtilsTest {
Function.FunctionDetails functionDetails =
FunctionConfigUtils.convert(functionConfig, (ClassLoader) null);
FunctionConfig convertedConfig =
FunctionConfigUtils.convertFromDetails(functionDetails);
+ // WindowsFunction guarantees convert to FunctionGuarantees.
+
assertEquals(convertedConfig.getWindowConfig().getProcessingGuarantees(),
+
WindowConfig.ProcessingGuarantees.valueOf(functionConfig.getProcessingGuarantees().name()));
+
// add default resources
functionConfig.setResources(Resources.getDefaultResources());
// set default cleanupSubscription config
diff --git
a/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/SinkConfigUtilsTest.java
b/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/SinkConfigUtilsTest.java
index 677cdb0343c..60f7d30052e 100644
---
a/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/SinkConfigUtilsTest.java
+++
b/pulsar-functions/utils/src/test/java/org/apache/pulsar/functions/utils/SinkConfigUtilsTest.java
@@ -44,6 +44,7 @@ import static
org.apache.pulsar.common.functions.FunctionConfig.ProcessingGuaran
import static
org.apache.pulsar.common.functions.FunctionConfig.ProcessingGuarantees.EFFECTIVELY_ONCE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertThrows;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.expectThrows;
@@ -60,6 +61,19 @@ public class SinkConfigUtilsTest {
private String configParameter;
}
+ @Test
+ public void testAutoAckConvertFailed() throws IOException {
+
+ SinkConfig sinkConfig = new SinkConfig();
+ sinkConfig.setAutoAck(false);
+
sinkConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATMOST_ONCE);
+
+ assertThrows(IllegalArgumentException.class, () -> {
+ SinkConfigUtils.convert(sinkConfig,
+ new SinkConfigUtils.ExtractedSinkDetails(null, null));
+ });
+ }
+
@Test
public void testConvertBackFidelity() throws IOException {
SinkConfig sinkConfig = new SinkConfig();
diff --git
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v2/FunctionApiV2ResourceTest.java
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v2/FunctionApiV2ResourceTest.java
index 306901d436e..420b7c113ca 100644
---
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v2/FunctionApiV2ResourceTest.java
+++
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v2/FunctionApiV2ResourceTest.java
@@ -1298,6 +1298,7 @@ public class FunctionApiV2ResourceTest {
.setName(function)
.setNamespace(namespace)
.setProcessingGuarantees(ProcessingGuarantees.ATMOST_ONCE)
+ .setAutoAck(true)
.setTenant(tenant)
.setParallelism(parallelism)
.setSource(SourceSpec.newBuilder().setSubscriptionType(subscriptionType)
diff --git
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/FunctionApiV3ResourceTest.java
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/FunctionApiV3ResourceTest.java
index 689e7ccbd48..a868d632506 100644
---
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/FunctionApiV3ResourceTest.java
+++
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/rest/api/v3/FunctionApiV3ResourceTest.java
@@ -1482,6 +1482,7 @@ public class FunctionApiV3ResourceTest {
FunctionDetails functionDetails = FunctionDetails.newBuilder()
.setClassName(className)
.setSink(sinkSpec)
+ .setAutoAck(true)
.setName(function)
.setNamespace(namespace)
.setProcessingGuarantees(ProcessingGuarantees.ATMOST_ONCE)
diff --git a/site2/docs/functions-cli.md b/site2/docs/functions-cli.md
index 316266ab069..c2c4f3ee9fa 100644
--- a/site2/docs/functions-cli.md
+++ b/site2/docs/functions-cli.md
@@ -38,7 +38,7 @@ You can configure a function by using a predefined YAML file.
The following tabl
| outputSchemaType | String | `-st`, `--schema-type`
| The built-in schema type or custom schema class name used for message
outputs. |
| outputSerdeClassName | String |
`--output-serde-classname` | The SerDe class used for message outputs. |
| logTopic | String | `--log-topic`
| The topic that the logs of a function are produced to. |
-| processingGuarantees | String | `--processing-guarantees` | The processing
guarantees (delivery semantics) applied to a function. Available values:
`ATLEAST_ONCE`, `ATMOST_ONCE`, `EFFECTIVELY_ONCE`.|
+| processingGuarantees | String | `--processing-guarantees` | The processing
guarantees (delivery semantics) applied to a function. Available values:
`ATLEAST_ONCE`, `ATMOST_ONCE`, `EFFECTIVELY_ONCE`, `MANUAL`.|
| retainOrdering | Boolean | `--retain-ordering`
| Whether functions consume and process messages in order or not. |
| retainKeyOrdering | Boolean | `--retain-key-ordering`
| Whether functions consume and process messages in key order or not. |
| batchBuilder | String | `--batch-builder` | Use
`producerConfig.batchBuilder` instead. <br />**Note**: `batchBuilder` will be
deprecated in code soon. |
@@ -46,7 +46,7 @@ You can configure a function by using a predefined YAML file.
The following tabl
| userConfig | Map`<String,Object>` | `--user-config`
| User-defined config key/values. |
| secrets | Map`<String,Object>` | `--secrets` | The mapping from
secretName to objects that encapsulate how the secret is fetched by the
underlying secrets provider. |
| runtime | String | N/A | The runtime of a
function. Available values: `java`,`python`, `go`. |
-| autoAck | Boolean | `--auto-ack` | Whether the framework
acknowledges messages automatically or not. |
+| autoAck | Boolean | `--auto-ack` | Whether the framework
acknowledges messages automatically or not. <br /><br />**Tip**: This
configuration will be deprecated. If the user specifies delivery semantics, the
framework will automatically ack messages. If you do not want the framework to
ack messages, set the **processingGuarantees** to `MANUAL`. |
| maxMessageRetries | Int | `--max-message-retries` | The number of
retries to process a message before giving up. |
| deadLetterTopic | String | `--dead-letter-topic` | The topic used
for storing messages that are not processed successfully. |
| subName | String | `--subs-name` | The name of
Pulsar source subscription used for input-topic consumers if required.|
diff --git a/site2/docs/functions-concepts.md b/site2/docs/functions-concepts.md
index a758ce45f2c..cfbba46aaf2 100644
--- a/site2/docs/functions-concepts.md
+++ b/site2/docs/functions-concepts.md
@@ -71,13 +71,15 @@ The following table outlines the three types of function
runtime.
## Processing guarantees and subscription types
-Pulsar provides three different messaging delivery semantics that you can
apply to a function.
+Pulsar provides three different messaging delivery semantics that you can
apply to a function. Different delivery semantic implementations are determined
according to the **ack time node**.
| Delivery semantics | Description | Adopted subscription type |
|--------------------|-------------|---------------------------|
-| **At-most-once** delivery | Each message sent to a function is processed at
its best effort. There’s no guarantee that the message will be processed or
not. | Shared |
-| **At-least-once** delivery (default) | Each message sent to the function can
be processed more than once (in case of a processing failure or redelivery).<br
/><br />If you create a function without specifying the
`--processing-guarantees` flag, the function provides `at-least-once` delivery
guarantee. | Shared |
-| **Effectively-once** delivery | Each message sent to the function can be
processed more than once but it has only one output. Duplicated messages are
ignored.<br /><br />`Effectively once` is achieved on top of `at-least-once`
processing and guaranteed server-side deduplication. This means a state update
can happen twice, but the same state update is only applied once, the other
duplicated state update is discarded on the server-side. | Failover |
+| **At-most-once** delivery | Each message sent to a function is processed at
its best effort. There’s no guarantee that the message will be processed or
not. <br /><br /> When setting At-most-once, the `autoAck` configuration must
be equal to true, otherwise the startup will fail(`autoAck` configuration will
be deprecated in future releases). <br/><br/> **Ack time node**: Before
function processing. | Shared |
+| **At-least-once** delivery (default) | Each message sent to the function can
be processed more than once (in case of a processing failure or redelivery).<br
/><br />If you create a function without specifying the
`--processing-guarantees` flag, the function provides `at-least-once` delivery
guarantee. <br/><br/> **Ack time node**: After sending a message to output. |
Shared |
+| **Effectively-once** delivery | Each message sent to the function can be
processed more than once but it has only one output. Duplicated messages are
ignored.<br /><br />`Effectively once` is achieved on top of `at-least-once`
processing and guaranteed server-side deduplication. This means a state update
can happen twice, but the same state update is only applied once, the other
duplicated state update is discarded on the server-side. <br/><br/> **Ack time
node**: After sending a messa [...]
+| **Manual** delivery | Under this semantics, the user needs to call the
method `context.getCurrentRecord().ack()` inside the function to manually
perform the ack operation, and the framework will not help users to do any ack
operations. <br/><br/> **Ack time node**: User decides, in function method. |
Shared |
+
:::tip
@@ -167,6 +169,9 @@ Both processing time and event time are supported.
* Processing time is defined based on the wall time when the function
instance builds and processes a window. The judging of window completeness is
straightforward and you don’t have to worry about data arrival disorder.
* Event time is defined based on the timestamps that come with the event
record. It guarantees event time correctness but also offers more data
buffering and a limited completeness guarantee.
+Delivery Semantic Guarantees.
+ * Currently, window function does not support `MANUAL` and
`Effectively-once` delivery semantics.
+
:::
### Types of window