mirror of
https://github.com/chirpstack/chirpstack.git
synced 2025-01-29 15:13:52 +00:00
Implement api request logging to Redis Streams.
This makes it possible for external services to subscribe (through Redis) for realtime events. E.g. a create, update or delete device event could trigger an external synchronization.
This commit is contained in:
parent
84dc8fd333
commit
963842ef55
1
api/go/Makefile
vendored
1
api/go/Makefile
vendored
@ -26,6 +26,7 @@ api:
|
||||
protoc ${PROTOC_ARGS} api/gateway.proto
|
||||
protoc ${PROTOC_ARGS} api/frame_log.proto
|
||||
protoc ${PROTOC_ARGS} api/multicast_group.proto
|
||||
protoc ${PROTOC_ARGS} api/request_log.proto
|
||||
|
||||
integration:
|
||||
protoc ${PROTOC_ARGS} integration/integration.proto
|
||||
|
184
api/go/api/request_log.pb.go
vendored
Normal file
184
api/go/api/request_log.pb.go
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.0
|
||||
// protoc v3.18.1
|
||||
// source: api/request_log.proto
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
_ "github.com/chirpstack/chirpstack/api/go/v4/common"
|
||||
_ "github.com/chirpstack/chirpstack/api/go/v4/gw"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
_ "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type RequestLog struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// API service name.
|
||||
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
|
||||
// API method name.
|
||||
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
|
||||
// Metadata.
|
||||
Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
}
|
||||
|
||||
func (x *RequestLog) Reset() {
|
||||
*x = RequestLog{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_request_log_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *RequestLog) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RequestLog) ProtoMessage() {}
|
||||
|
||||
func (x *RequestLog) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_request_log_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RequestLog.ProtoReflect.Descriptor instead.
|
||||
func (*RequestLog) Descriptor() ([]byte, []int) {
|
||||
return file_api_request_log_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *RequestLog) GetService() string {
|
||||
if x != nil {
|
||||
return x.Service
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RequestLog) GetMethod() string {
|
||||
if x != nil {
|
||||
return x.Method
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RequestLog) GetMetadata() map[string]string {
|
||||
if x != nil {
|
||||
return x.Metadata
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_api_request_log_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_api_request_log_proto_rawDesc = []byte{
|
||||
0x0a, 0x15, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6c, 0x6f,
|
||||
0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x61, 0x70, 0x69, 0x1a, 0x1f, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x13, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x1a, 0x0b, 0x67, 0x77, 0x2f, 0x67, 0x77, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
|
||||
0xb6, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68,
|
||||
0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
|
||||
0x12, 0x39, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x4c, 0x6f, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 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, 0x42, 0x51, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63,
|
||||
0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0a, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4c, 0x6f, 0x67, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61,
|
||||
0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70,
|
||||
0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_api_request_log_proto_rawDescOnce sync.Once
|
||||
file_api_request_log_proto_rawDescData = file_api_request_log_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_api_request_log_proto_rawDescGZIP() []byte {
|
||||
file_api_request_log_proto_rawDescOnce.Do(func() {
|
||||
file_api_request_log_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_request_log_proto_rawDescData)
|
||||
})
|
||||
return file_api_request_log_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_api_request_log_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_api_request_log_proto_goTypes = []interface{}{
|
||||
(*RequestLog)(nil), // 0: api.RequestLog
|
||||
nil, // 1: api.RequestLog.MetadataEntry
|
||||
}
|
||||
var file_api_request_log_proto_depIdxs = []int32{
|
||||
1, // 0: api.RequestLog.metadata:type_name -> api.RequestLog.MetadataEntry
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_api_request_log_proto_init() }
|
||||
func file_api_request_log_proto_init() {
|
||||
if File_api_request_log_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_api_request_log_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RequestLog); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_api_request_log_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_api_request_log_proto_goTypes,
|
||||
DependencyIndexes: file_api_request_log_proto_depIdxs,
|
||||
MessageInfos: file_api_request_log_proto_msgTypes,
|
||||
}.Build()
|
||||
File_api_request_log_proto = out.File
|
||||
file_api_request_log_proto_rawDesc = nil
|
||||
file_api_request_log_proto_goTypes = nil
|
||||
file_api_request_log_proto_depIdxs = nil
|
||||
}
|
1
api/grpc-web/Makefile
vendored
1
api/grpc-web/Makefile
vendored
@ -25,6 +25,7 @@ api:
|
||||
protoc -I=$(GOOGLEAPIS_PATH) -I=../protobuf -I=../proto $(PROTOC_ARGS) ../proto/api/gateway.proto
|
||||
protoc -I=$(GOOGLEAPIS_PATH) -I=../protobuf -I=../proto $(PROTOC_ARGS) ../proto/api/frame_log.proto
|
||||
protoc -I=$(GOOGLEAPIS_PATH) -I=../protobuf -I=../proto $(PROTOC_ARGS) ../proto/api/multicast_group.proto
|
||||
protoc -I=$(GOOGLEAPIS_PATH) -I=../protobuf -I=../proto $(PROTOC_ARGS) ../proto/api/request_log.proto
|
||||
|
||||
integration:
|
||||
mkdir -p integration
|
||||
|
33
api/grpc-web/api/request_log_pb.d.ts
vendored
Normal file
33
api/grpc-web/api/request_log_pb.d.ts
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
import * as jspb from 'google-protobuf'
|
||||
|
||||
import * as google_protobuf_timestamp_pb from 'google-protobuf/google/protobuf/timestamp_pb';
|
||||
import * as common_common_pb from '../common/common_pb';
|
||||
import * as gw_gw_pb from '../gw/gw_pb';
|
||||
|
||||
|
||||
export class RequestLog extends jspb.Message {
|
||||
getService(): string;
|
||||
setService(value: string): RequestLog;
|
||||
|
||||
getMethod(): string;
|
||||
setMethod(value: string): RequestLog;
|
||||
|
||||
getMetadataMap(): jspb.Map<string, string>;
|
||||
clearMetadataMap(): RequestLog;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): RequestLog.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: RequestLog): RequestLog.AsObject;
|
||||
static serializeBinaryToWriter(message: RequestLog, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): RequestLog;
|
||||
static deserializeBinaryFromReader(message: RequestLog, reader: jspb.BinaryReader): RequestLog;
|
||||
}
|
||||
|
||||
export namespace RequestLog {
|
||||
export type AsObject = {
|
||||
service: string,
|
||||
method: string,
|
||||
metadataMap: Array<[string, string]>,
|
||||
}
|
||||
}
|
||||
|
239
api/grpc-web/api/request_log_pb.js
vendored
Normal file
239
api/grpc-web/api/request_log_pb.js
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
// source: api/request_log.proto
|
||||
/**
|
||||
* @fileoverview
|
||||
* @enhanceable
|
||||
* @suppress {missingRequire} reports error on implicit type usages.
|
||||
* @suppress {messageConventions} JS Compiler reports an error if a variable or
|
||||
* field starts with 'MSG_' and isn't a translatable message.
|
||||
* @public
|
||||
*/
|
||||
// GENERATED CODE -- DO NOT EDIT!
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
var jspb = require('google-protobuf');
|
||||
var goog = jspb;
|
||||
var global = Function('return this')();
|
||||
|
||||
var google_protobuf_timestamp_pb = require('google-protobuf/google/protobuf/timestamp_pb.js');
|
||||
goog.object.extend(proto, google_protobuf_timestamp_pb);
|
||||
var common_common_pb = require('../common/common_pb.js');
|
||||
goog.object.extend(proto, common_common_pb);
|
||||
var gw_gw_pb = require('../gw/gw_pb.js');
|
||||
goog.object.extend(proto, gw_gw_pb);
|
||||
goog.exportSymbol('proto.api.RequestLog', null, global);
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.api.RequestLog = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.api.RequestLog, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.api.RequestLog.displayName = 'proto.api.RequestLog';
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.api.RequestLog.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.api.RequestLog.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.api.RequestLog} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.api.RequestLog.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
service: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
||||
method: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
metadataMap: (f = msg.getMetadataMap()) ? f.toObject(includeInstance, undefined) : []
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.api.RequestLog}
|
||||
*/
|
||||
proto.api.RequestLog.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.api.RequestLog;
|
||||
return proto.api.RequestLog.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.api.RequestLog} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.api.RequestLog}
|
||||
*/
|
||||
proto.api.RequestLog.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setService(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setMethod(value);
|
||||
break;
|
||||
case 3:
|
||||
var value = msg.getMetadataMap();
|
||||
reader.readMessage(value, function(message, reader) {
|
||||
jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readString, null, "", "");
|
||||
});
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.api.RequestLog.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.api.RequestLog.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.api.RequestLog} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.api.RequestLog.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getService();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getMethod();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getMetadataMap(true);
|
||||
if (f && f.getLength() > 0) {
|
||||
f.serializeBinary(3, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string service = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.api.RequestLog.prototype.getService = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.api.RequestLog} returns this
|
||||
*/
|
||||
proto.api.RequestLog.prototype.setService = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string method = 2;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.api.RequestLog.prototype.getMethod = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.api.RequestLog} returns this
|
||||
*/
|
||||
proto.api.RequestLog.prototype.setMethod = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* map<string, string> metadata = 3;
|
||||
* @param {boolean=} opt_noLazyCreate Do not create the map if
|
||||
* empty, instead returning `undefined`
|
||||
* @return {!jspb.Map<string,string>}
|
||||
*/
|
||||
proto.api.RequestLog.prototype.getMetadataMap = function(opt_noLazyCreate) {
|
||||
return /** @type {!jspb.Map<string,string>} */ (
|
||||
jspb.Message.getMapField(this, 3, opt_noLazyCreate,
|
||||
null));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears values from the map. The map will be non-null.
|
||||
* @return {!proto.api.RequestLog} returns this
|
||||
*/
|
||||
proto.api.RequestLog.prototype.clearMetadataMap = function() {
|
||||
this.getMetadataMap().clear();
|
||||
return this;};
|
||||
|
||||
|
||||
goog.object.extend(exports, proto.api);
|
1
api/js/Makefile
vendored
1
api/js/Makefile
vendored
@ -28,6 +28,7 @@ api:
|
||||
protoc ${PROTOC_GRPC_ARGS} ../proto/api/gateway.proto
|
||||
protoc ${PROTOC_GRPC_ARGS} ../proto/api/frame_log.proto
|
||||
protoc ${PROTOC_GRPC_ARGS} ../proto/api/multicast_group.proto
|
||||
protoc ${PROTOC_GRPC_ARGS} ../proto/api/request_log.proto
|
||||
|
||||
integration:
|
||||
protoc ${PROTOC_ARGS} ../proto/integration/integration.proto
|
||||
|
1
api/js/api/request_log_grpc_pb.d.ts
vendored
Normal file
1
api/js/api/request_log_grpc_pb.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
// GENERATED CODE -- NO SERVICES IN PROTO
|
1
api/js/api/request_log_grpc_pb.js
vendored
Normal file
1
api/js/api/request_log_grpc_pb.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// GENERATED CODE -- NO SERVICES IN PROTO
|
35
api/js/api/request_log_pb.d.ts
vendored
Normal file
35
api/js/api/request_log_pb.d.ts
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
// package: api
|
||||
// file: api/request_log.proto
|
||||
|
||||
import * as jspb from "google-protobuf";
|
||||
import * as google_protobuf_timestamp_pb from "google-protobuf/google/protobuf/timestamp_pb";
|
||||
import * as common_common_pb from "../common/common_pb";
|
||||
import * as gw_gw_pb from "../gw/gw_pb";
|
||||
|
||||
export class RequestLog extends jspb.Message {
|
||||
getService(): string;
|
||||
setService(value: string): void;
|
||||
|
||||
getMethod(): string;
|
||||
setMethod(value: string): void;
|
||||
|
||||
getMetadataMap(): jspb.Map<string, string>;
|
||||
clearMetadataMap(): void;
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): RequestLog.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: RequestLog): RequestLog.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: RequestLog, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): RequestLog;
|
||||
static deserializeBinaryFromReader(message: RequestLog, reader: jspb.BinaryReader): RequestLog;
|
||||
}
|
||||
|
||||
export namespace RequestLog {
|
||||
export type AsObject = {
|
||||
service: string,
|
||||
method: string,
|
||||
metadataMap: Array<[string, string]>,
|
||||
}
|
||||
}
|
||||
|
226
api/js/api/request_log_pb.js
vendored
Normal file
226
api/js/api/request_log_pb.js
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
/**
|
||||
* @fileoverview
|
||||
* @enhanceable
|
||||
* @public
|
||||
*/
|
||||
// GENERATED CODE -- DO NOT EDIT!
|
||||
|
||||
var jspb = require('google-protobuf');
|
||||
var goog = jspb;
|
||||
var global = Function('return this')();
|
||||
|
||||
var google_protobuf_timestamp_pb = require('google-protobuf/google/protobuf/timestamp_pb.js');
|
||||
var common_common_pb = require('../common/common_pb.js');
|
||||
var gw_gw_pb = require('../gw/gw_pb.js');
|
||||
goog.exportSymbol('proto.api.RequestLog', null, global);
|
||||
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.api.RequestLog = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.api.RequestLog, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
proto.api.RequestLog.displayName = 'proto.api.RequestLog';
|
||||
}
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto suitable for use in Soy templates.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
|
||||
* @param {boolean=} opt_includeInstance Whether to include the JSPB instance
|
||||
* for transitional soy proto support: http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.api.RequestLog.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.api.RequestLog.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Whether to include the JSPB
|
||||
* instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.api.RequestLog} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.api.RequestLog.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
service: msg.getService(),
|
||||
method: msg.getMethod(),
|
||||
metadataMap: (f = msg.getMetadataMap(true)) ? f.toArray() : []
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.api.RequestLog}
|
||||
*/
|
||||
proto.api.RequestLog.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.api.RequestLog;
|
||||
return proto.api.RequestLog.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.api.RequestLog} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.api.RequestLog}
|
||||
*/
|
||||
proto.api.RequestLog.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setService(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setMethod(value);
|
||||
break;
|
||||
case 3:
|
||||
var value = msg.getMetadataMap();
|
||||
reader.readMessage(value, function(message, reader) {
|
||||
jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readString);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class method variant: serializes the given message to binary data
|
||||
* (in protobuf wire format), writing to the given BinaryWriter.
|
||||
* @param {!proto.api.RequestLog} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
*/
|
||||
proto.api.RequestLog.serializeBinaryToWriter = function(message, writer) {
|
||||
message.serializeBinaryToWriter(writer);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.api.RequestLog.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
this.serializeBinaryToWriter(writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format),
|
||||
* writing to the given BinaryWriter.
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
*/
|
||||
proto.api.RequestLog.prototype.serializeBinaryToWriter = function (writer) {
|
||||
var f = undefined;
|
||||
f = this.getService();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = this.getMethod();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = this.getMetadataMap(true);
|
||||
if (f && f.getLength() > 0) {
|
||||
f.serializeBinary(3, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a deep clone of this proto. No data is shared with the original.
|
||||
* @return {!proto.api.RequestLog} The clone.
|
||||
*/
|
||||
proto.api.RequestLog.prototype.cloneMessage = function() {
|
||||
return /** @type {!proto.api.RequestLog} */ (jspb.Message.cloneMessage(this));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string service = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.api.RequestLog.prototype.getService = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldProto3(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/** @param {string} value */
|
||||
proto.api.RequestLog.prototype.setService = function(value) {
|
||||
jspb.Message.setField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string method = 2;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.api.RequestLog.prototype.getMethod = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldProto3(this, 2, ""));
|
||||
};
|
||||
|
||||
|
||||
/** @param {string} value */
|
||||
proto.api.RequestLog.prototype.setMethod = function(value) {
|
||||
jspb.Message.setField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* map<string, string> metadata = 3;
|
||||
* @param {boolean=} opt_noLazyCreate Do not create the map if
|
||||
* empty, instead returning `undefined`
|
||||
* @return {!jspb.Map<string,string>}
|
||||
*/
|
||||
proto.api.RequestLog.prototype.getMetadataMap = function(opt_noLazyCreate) {
|
||||
return /** @type {!jspb.Map<string,string>} */ (
|
||||
jspb.Message.getMapField(this, 3, opt_noLazyCreate,
|
||||
null));
|
||||
};
|
||||
|
||||
|
||||
goog.object.extend(exports, proto.api);
|
23
api/proto/api/request_log.proto
vendored
Normal file
23
api/proto/api/request_log.proto
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package api;
|
||||
|
||||
option go_package = "github.com/chirpstack/chirpstack/api/go/v4/api";
|
||||
option java_package = "io.chirpstack.api";
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "RequestLog";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "common/common.proto";
|
||||
import "gw/gw.proto";
|
||||
|
||||
message RequestLog {
|
||||
// API service name.
|
||||
string service = 1;
|
||||
|
||||
// API method name.
|
||||
string method = 2;
|
||||
|
||||
// Metadata.
|
||||
map<string, string> metadata = 3;
|
||||
}
|
1
api/python/Makefile
vendored
1
api/python/Makefile
vendored
@ -37,6 +37,7 @@ api:
|
||||
$(PROTOC) ${PROTOC_ARGS} chirpstack-api/api/gateway.proto
|
||||
$(PROTOC) ${PROTOC_ARGS} chirpstack-api/api/frame_log.proto
|
||||
$(PROTOC) ${PROTOC_ARGS} chirpstack-api/api/multicast_group.proto
|
||||
$(PROTOC) ${PROTOC_ARGS} chirpstack-api/api/request_log.proto
|
||||
|
||||
integration:
|
||||
$(PROTOC) ${PROTOC_ARGS} chirpstack-api/integration/integration.proto
|
||||
|
23
api/python/proto/chirpstack-api/api/request_log.proto
vendored
Normal file
23
api/python/proto/chirpstack-api/api/request_log.proto
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package api;
|
||||
|
||||
option go_package = "github.com/chirpstack/chirpstack/api/go/v4/api";
|
||||
option java_package = "io.chirpstack.api";
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "RequestLog";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "chirpstack-api/common/common.proto";
|
||||
import "chirpstack-api/gw/gw.proto";
|
||||
|
||||
message RequestLog {
|
||||
// API service name.
|
||||
string service = 1;
|
||||
|
||||
// API method name.
|
||||
string method = 2;
|
||||
|
||||
// Metadata.
|
||||
map<string, string> metadata = 3;
|
||||
}
|
@ -18,3 +18,4 @@ from .tenant_pb2 import *
|
||||
from .tenant_pb2_grpc import *
|
||||
from .user_pb2 import *
|
||||
from .user_pb2_grpc import *
|
||||
from .request_log_pb2 import *
|
||||
|
33
api/python/src/chirpstack_api/api/request_log_pb2.py
vendored
Normal file
33
api/python/src/chirpstack_api/api/request_log_pb2.py
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: chirpstack-api/api/request_log.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
|
||||
from chirpstack_api.common import common_pb2 as chirpstack__api_dot_common_dot_common__pb2
|
||||
from chirpstack_api.gw import gw_pb2 as chirpstack__api_dot_gw_dot_gw__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$chirpstack-api/api/request_log.proto\x12\x03\x61pi\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\"chirpstack-api/common/common.proto\x1a\x1a\x63hirpstack-api/gw/gw.proto\"\x8f\x01\n\nRequestLog\x12\x0f\n\x07service\x18\x01 \x01(\t\x12\x0e\n\x06method\x18\x02 \x01(\t\x12/\n\x08metadata\x18\x03 \x03(\x0b\x32\x1d.api.RequestLog.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42Q\n\x11io.chirpstack.apiB\nRequestLogP\x01Z.github.com/chirpstack/chirpstack/api/go/v4/apib\x06proto3')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'chirpstack_api.api.request_log_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\021io.chirpstack.apiB\nRequestLogP\001Z.github.com/chirpstack/chirpstack/api/go/v4/api'
|
||||
_REQUESTLOG_METADATAENTRY._options = None
|
||||
_REQUESTLOG_METADATAENTRY._serialized_options = b'8\001'
|
||||
_REQUESTLOG._serialized_start=143
|
||||
_REQUESTLOG._serialized_end=286
|
||||
_REQUESTLOG_METADATAENTRY._serialized_start=239
|
||||
_REQUESTLOG_METADATAENTRY._serialized_end=286
|
||||
# @@protoc_insertion_point(module_scope)
|
4
api/python/src/chirpstack_api/api/request_log_pb2_grpc.py
vendored
Normal file
4
api/python/src/chirpstack_api/api/request_log_pb2_grpc.py
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
||||
"""Client and server classes corresponding to protobuf-defined services."""
|
||||
import grpc
|
||||
|
2
api/rust/build.rs
vendored
2
api/rust/build.rs
vendored
@ -141,6 +141,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
"api/gateway.proto",
|
||||
"api/frame_log.proto",
|
||||
"api/multicast_group.proto",
|
||||
"api/frame_log.proto",
|
||||
"api/request_log.proto",
|
||||
],
|
||||
&[
|
||||
proto_dir.join("chirpstack").to_str().unwrap(),
|
||||
|
23
api/rust/proto/chirpstack/api/request_log.proto
vendored
Normal file
23
api/rust/proto/chirpstack/api/request_log.proto
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package api;
|
||||
|
||||
option go_package = "github.com/chirpstack/chirpstack/api/go/v4/api";
|
||||
option java_package = "io.chirpstack.api";
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "RequestLog";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "common/common.proto";
|
||||
import "gw/gw.proto";
|
||||
|
||||
message RequestLog {
|
||||
// API service name.
|
||||
string service = 1;
|
||||
|
||||
// API method name.
|
||||
string method = 2;
|
||||
|
||||
// Metadata.
|
||||
map<string, string> metadata = 3;
|
||||
}
|
@ -52,9 +52,13 @@ impl ApplicationService for Application {
|
||||
|
||||
let a = application::create(a).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::CreateApplicationResponse {
|
||||
let mut resp = Response::new(api::CreateApplicationResponse {
|
||||
id: a.id.to_string(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", a.id.to_string().parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get(
|
||||
@ -76,7 +80,7 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::GetApplicationResponse {
|
||||
let mut resp = Response::new(api::GetApplicationResponse {
|
||||
application: Some(api::Application {
|
||||
id: a.id.to_string(),
|
||||
tenant_id: a.tenant_id.to_string(),
|
||||
@ -86,7 +90,11 @@ impl ApplicationService for Application {
|
||||
created_at: Some(helpers::datetime_to_prost_timestamp(&a.created_at)),
|
||||
updated_at: Some(helpers::datetime_to_prost_timestamp(&a.updated_at)),
|
||||
measurement_keys,
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn update(
|
||||
@ -117,7 +125,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req_app.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete(
|
||||
@ -136,7 +148,11 @@ impl ApplicationService for Application {
|
||||
|
||||
application::delete(&app_id).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list(
|
||||
@ -169,7 +185,7 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::ListApplicationsResponse {
|
||||
let mut resp = Response::new(api::ListApplicationsResponse {
|
||||
total_count: count as u32,
|
||||
result: results
|
||||
.iter()
|
||||
@ -181,7 +197,11 @@ impl ApplicationService for Application {
|
||||
description: a.description.clone(),
|
||||
})
|
||||
.collect(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req.tenant_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list_integrations(
|
||||
@ -226,10 +246,14 @@ impl ApplicationService for Application {
|
||||
kind: api::IntegrationKind::MqttGlobal.into(),
|
||||
});
|
||||
|
||||
Ok(Response::new(api::ListIntegrationsResponse {
|
||||
let mut resp = Response::new(api::ListIntegrationsResponse {
|
||||
total_count: (result.len() + 1) as u32,
|
||||
result: items,
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_http_integration(
|
||||
@ -271,7 +295,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_http_integration(
|
||||
@ -293,7 +323,7 @@ impl ApplicationService for Application {
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
if let application::IntegrationConfiguration::Http(conf) = &i.configuration {
|
||||
Ok(Response::new(api::GetHttpIntegrationResponse {
|
||||
let mut resp = Response::new(api::GetHttpIntegrationResponse {
|
||||
integration: Some(api::HttpIntegration {
|
||||
application_id: app_id.to_string(),
|
||||
headers: conf.headers.clone(),
|
||||
@ -304,7 +334,11 @@ impl ApplicationService for Application {
|
||||
.into(),
|
||||
event_endpoint_url: conf.event_endpoint_url.clone(),
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
} else {
|
||||
Err(Status::internal("Integration has no Http configuration"))
|
||||
}
|
||||
@ -347,7 +381,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_http_integration(
|
||||
@ -368,7 +408,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_influx_db_integration(
|
||||
@ -414,7 +458,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_influx_db_integration(
|
||||
@ -436,7 +486,7 @@ impl ApplicationService for Application {
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
if let application::IntegrationConfiguration::InfluxDb(conf) = &i.configuration {
|
||||
Ok(Response::new(api::GetInfluxDbIntegrationResponse {
|
||||
let mut resp = Response::new(api::GetInfluxDbIntegrationResponse {
|
||||
integration: Some(api::InfluxDbIntegration {
|
||||
application_id: app_id.to_string(),
|
||||
endpoint: conf.endpoint.clone(),
|
||||
@ -450,7 +500,11 @@ impl ApplicationService for Application {
|
||||
organization: conf.organization.clone(),
|
||||
bucket: conf.bucket.clone(),
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
} else {
|
||||
Err(Status::internal(
|
||||
"Integration has no InfluxDb configuration",
|
||||
@ -499,7 +553,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_influx_db_integration(
|
||||
@ -520,7 +580,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_things_board_integration(
|
||||
@ -557,7 +621,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_things_board_integration(
|
||||
@ -579,12 +649,16 @@ impl ApplicationService for Application {
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
if let application::IntegrationConfiguration::ThingsBoard(conf) = &i.configuration {
|
||||
Ok(Response::new(api::GetThingsBoardIntegrationResponse {
|
||||
let mut resp = Response::new(api::GetThingsBoardIntegrationResponse {
|
||||
integration: Some(api::ThingsBoardIntegration {
|
||||
application_id: app_id.to_string(),
|
||||
server: conf.server.clone(),
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
} else {
|
||||
Err(Status::internal(
|
||||
"Integration has no ThingsBoard configuration",
|
||||
@ -624,7 +698,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_things_board_integration(
|
||||
@ -645,7 +725,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_my_devices_integration(
|
||||
@ -680,7 +764,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_my_devices_integration(
|
||||
@ -702,12 +792,16 @@ impl ApplicationService for Application {
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
if let application::IntegrationConfiguration::MyDevices(conf) = &i.configuration {
|
||||
Ok(Response::new(api::GetMyDevicesIntegrationResponse {
|
||||
let mut resp = Response::new(api::GetMyDevicesIntegrationResponse {
|
||||
integration: Some(api::MyDevicesIntegration {
|
||||
application_id: app_id.to_string(),
|
||||
endpoint: conf.endpoint.clone(),
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
} else {
|
||||
Err(Status::internal(
|
||||
"Integration has no MyDevices configuration",
|
||||
@ -747,7 +841,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_my_devices_integration(
|
||||
@ -768,7 +868,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_lora_cloud_integration(
|
||||
@ -832,7 +936,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_lora_cloud_integration(
|
||||
@ -856,7 +966,7 @@ impl ApplicationService for Application {
|
||||
if let application::IntegrationConfiguration::LoraCloud(conf) = &i.configuration {
|
||||
let mgs = &conf.modem_geolocation_services;
|
||||
|
||||
Ok(Response::new(api::GetLoraCloudIntegrationResponse {
|
||||
let mut resp = Response::new(api::GetLoraCloudIntegrationResponse {
|
||||
integration: Some(api::LoraCloudIntegration {
|
||||
application_id: app_id.to_string(),
|
||||
modem_geolocation_services: Some(api::LoraCloudModemGeolocationServices {
|
||||
@ -877,7 +987,11 @@ impl ApplicationService for Application {
|
||||
geolocation_wifi_payload_field: mgs.geolocation_wifi_payload_field.clone(),
|
||||
}),
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
} else {
|
||||
Err(Status::internal(
|
||||
"Integration has no LoraCloud configuration",
|
||||
@ -946,7 +1060,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_lora_cloud_integration(
|
||||
@ -967,7 +1087,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_gcp_pub_sub_integration(
|
||||
@ -1005,7 +1129,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_gcp_pub_sub_integration(
|
||||
@ -1027,7 +1157,7 @@ impl ApplicationService for Application {
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
if let application::IntegrationConfiguration::GcpPubSub(conf) = &i.configuration {
|
||||
Ok(Response::new(api::GetGcpPubSubIntegrationResponse {
|
||||
let mut resp = Response::new(api::GetGcpPubSubIntegrationResponse {
|
||||
integration: Some(api::GcpPubSubIntegration {
|
||||
application_id: app_id.to_string(),
|
||||
encoding: conf.encoding,
|
||||
@ -1035,7 +1165,11 @@ impl ApplicationService for Application {
|
||||
project_id: conf.project_id.clone(),
|
||||
topic_name: conf.topic_name.clone(),
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
} else {
|
||||
Err(Status::internal(
|
||||
"Integration has no GcpPubSub configuration",
|
||||
@ -1078,7 +1212,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_gcp_pub_sub_integration(
|
||||
@ -1099,7 +1239,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_aws_sns_integration(
|
||||
@ -1138,7 +1282,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_aws_sns_integration(
|
||||
@ -1160,7 +1310,7 @@ impl ApplicationService for Application {
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
if let application::IntegrationConfiguration::AwsSns(conf) = &i.configuration {
|
||||
Ok(Response::new(api::GetAwsSnsIntegrationResponse {
|
||||
let mut resp = Response::new(api::GetAwsSnsIntegrationResponse {
|
||||
integration: Some(api::AwsSnsIntegration {
|
||||
application_id: app_id.to_string(),
|
||||
encoding: conf.encoding,
|
||||
@ -1169,7 +1319,11 @@ impl ApplicationService for Application {
|
||||
secret_access_key: conf.secret_access_key.clone(),
|
||||
topic_arn: conf.topic_arn.clone(),
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
} else {
|
||||
Err(Status::internal("Integration has no AwsSns configuration"))
|
||||
}
|
||||
@ -1211,7 +1365,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_aws_sns_integration(
|
||||
@ -1232,7 +1392,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_azure_service_bus_integration(
|
||||
@ -1269,7 +1433,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_azure_service_bus_integration(
|
||||
@ -1292,14 +1462,18 @@ impl ApplicationService for Application {
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
if let application::IntegrationConfiguration::AzureServiceBus(conf) = &i.configuration {
|
||||
Ok(Response::new(api::GetAzureServiceBusIntegrationResponse {
|
||||
let mut resp = Response::new(api::GetAzureServiceBusIntegrationResponse {
|
||||
integration: Some(api::AzureServiceBusIntegration {
|
||||
application_id: app_id.to_string(),
|
||||
encoding: conf.encoding,
|
||||
connection_string: conf.connection_string.clone(),
|
||||
publish_name: conf.publish_name.clone(),
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
} else {
|
||||
Err(Status::internal(
|
||||
"Integration has no AzureServiceBus configuration",
|
||||
@ -1341,7 +1515,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_azure_service_bus_integration(
|
||||
@ -1362,7 +1542,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_pilot_things_integration(
|
||||
@ -1398,7 +1582,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_pilot_things_integration(
|
||||
@ -1420,13 +1610,17 @@ impl ApplicationService for Application {
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
if let application::IntegrationConfiguration::PilotThings(conf) = &i.configuration {
|
||||
Ok(Response::new(api::GetPilotThingsIntegrationResponse {
|
||||
let mut resp = Response::new(api::GetPilotThingsIntegrationResponse {
|
||||
integration: Some(api::PilotThingsIntegration {
|
||||
application_id: app_id.to_string(),
|
||||
server: conf.server.clone(),
|
||||
token: conf.token.clone(),
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
} else {
|
||||
Err(Status::internal(
|
||||
"Integration has no PilotThings configuration",
|
||||
@ -1467,7 +1661,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_pilot_things_integration(
|
||||
@ -1488,7 +1688,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_ifttt_integration(
|
||||
@ -1527,7 +1731,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_ifttt_integration(
|
||||
@ -1549,13 +1759,17 @@ impl ApplicationService for Application {
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
if let application::IntegrationConfiguration::Ifttt(conf) = &i.configuration {
|
||||
Ok(Response::new(api::GetIftttIntegrationResponse {
|
||||
let mut resp = Response::new(api::GetIftttIntegrationResponse {
|
||||
integration: Some(api::IftttIntegration {
|
||||
application_id: app_id.to_string(),
|
||||
key: conf.key.clone(),
|
||||
uplink_values: conf.uplink_values.to_vec(),
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
} else {
|
||||
Err(Status::internal("Integration has no Ifttt configuration"))
|
||||
}
|
||||
@ -1597,7 +1811,13 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-application_id",
|
||||
req_int.application_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_ifttt_integration(
|
||||
@ -1618,7 +1838,11 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn generate_mqtt_integration_client_certificate(
|
||||
@ -1643,14 +1867,16 @@ impl ApplicationService for Application {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(
|
||||
api::GenerateMqttIntegrationClientCertificateResponse {
|
||||
ca_cert,
|
||||
tls_cert: cert,
|
||||
tls_key: key,
|
||||
expires_at: Some(ttl.into()),
|
||||
},
|
||||
))
|
||||
let mut resp = Response::new(api::GenerateMqttIntegrationClientCertificateResponse {
|
||||
ca_cert,
|
||||
tls_cert: cert,
|
||||
tls_key: key,
|
||||
expires_at: Some(ttl.into()),
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,7 @@ impl DeviceService for Device {
|
||||
name: req_d.name.clone(),
|
||||
description: req_d.description.clone(),
|
||||
skip_fcnt_check: req_d.skip_fcnt_check,
|
||||
is_disabled: req_d.is_disabled,
|
||||
tags: fields::KeyValue::new(req_d.tags.clone()),
|
||||
variables: fields::KeyValue::new(req_d.variables.clone()),
|
||||
..Default::default()
|
||||
@ -68,7 +69,15 @@ impl DeviceService for Device {
|
||||
|
||||
let _ = device::create(d).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req_d.dev_eui.parse().unwrap());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-is_disabled",
|
||||
req_d.is_disabled.to_string().parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get(
|
||||
@ -87,7 +96,7 @@ impl DeviceService for Device {
|
||||
|
||||
let d = device::get(&dev_eui).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::GetDeviceResponse {
|
||||
let mut resp = Response::new(api::GetDeviceResponse {
|
||||
device: Some(api::Device {
|
||||
dev_eui: d.dev_eui.to_string(),
|
||||
name: d.name.clone(),
|
||||
@ -116,7 +125,11 @@ impl DeviceService for Device {
|
||||
}),
|
||||
false => None,
|
||||
},
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn update(
|
||||
@ -175,7 +188,15 @@ impl DeviceService for Device {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req_d.dev_eui.parse().unwrap());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-is_disabled",
|
||||
req_d.is_disabled.to_string().parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete(
|
||||
@ -193,7 +214,12 @@ impl DeviceService for Device {
|
||||
.await?;
|
||||
|
||||
device::delete(&dev_eui).await.map_err(|e| e.status())?;
|
||||
Ok(Response::new(()))
|
||||
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list(
|
||||
@ -235,7 +261,7 @@ impl DeviceService for Device {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::ListDevicesResponse {
|
||||
let mut resp = Response::new(api::ListDevicesResponse {
|
||||
total_count: count as u32,
|
||||
result: items
|
||||
.iter()
|
||||
@ -264,7 +290,11 @@ impl DeviceService for Device {
|
||||
},
|
||||
})
|
||||
.collect(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn create_keys(
|
||||
@ -298,7 +328,12 @@ impl DeviceService for Device {
|
||||
};
|
||||
|
||||
let _ = device_keys::create(dk).await.map_err(|e| e.status())?;
|
||||
Ok(Response::new(()))
|
||||
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req_dk.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_keys(
|
||||
@ -317,7 +352,7 @@ impl DeviceService for Device {
|
||||
|
||||
let dk = device_keys::get(&dev_eui).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::GetDeviceKeysResponse {
|
||||
let mut resp = Response::new(api::GetDeviceKeysResponse {
|
||||
device_keys: Some(api::DeviceKeys {
|
||||
dev_eui: dk.dev_eui.to_string(),
|
||||
nwk_key: dk.nwk_key.to_string(),
|
||||
@ -325,7 +360,11 @@ impl DeviceService for Device {
|
||||
}),
|
||||
created_at: Some(helpers::datetime_to_prost_timestamp(&dk.created_at)),
|
||||
updated_at: Some(helpers::datetime_to_prost_timestamp(&dk.updated_at)),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn update_keys(
|
||||
@ -363,7 +402,11 @@ impl DeviceService for Device {
|
||||
};
|
||||
let _ = device_keys::update(dk).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req_dk.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_keys(
|
||||
@ -383,7 +426,12 @@ impl DeviceService for Device {
|
||||
device_keys::delete(&dev_eui)
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
Ok(Response::new(()))
|
||||
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn flush_dev_nonces(
|
||||
@ -403,7 +451,12 @@ impl DeviceService for Device {
|
||||
device_keys::set_dev_nonces(&dev_eui, &Vec::new())
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
Ok(Response::new(()))
|
||||
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn activate(
|
||||
@ -469,7 +522,11 @@ impl DeviceService for Device {
|
||||
.map_err(|e| e.status())?;
|
||||
}
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req_da.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn deactivate(
|
||||
@ -493,7 +550,11 @@ impl DeviceService for Device {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_activation(
|
||||
@ -524,7 +585,7 @@ impl DeviceService for Device {
|
||||
},
|
||||
};
|
||||
|
||||
Ok(Response::new(api::GetDeviceActivationResponse {
|
||||
let mut resp = Response::new(api::GetDeviceActivationResponse {
|
||||
device_activation: Some(api::DeviceActivation {
|
||||
dev_eui: hex::encode(&ds.dev_eui),
|
||||
dev_addr: hex::encode(&ds.dev_addr),
|
||||
@ -539,7 +600,11 @@ impl DeviceService for Device {
|
||||
n_f_cnt_down: ds.n_f_cnt_down,
|
||||
a_f_cnt_down: ds.a_f_cnt_down,
|
||||
}),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_random_dev_addr(
|
||||
@ -664,7 +729,11 @@ impl DeviceService for Device {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Response::new(out))
|
||||
let mut resp = Response::new(out);
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_link_metrics(
|
||||
@ -906,7 +975,11 @@ impl DeviceService for Device {
|
||||
}),
|
||||
};
|
||||
|
||||
Ok(Response::new(out))
|
||||
let mut resp = Response::new(out);
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn enqueue(
|
||||
@ -960,9 +1033,13 @@ impl DeviceService for Device {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::EnqueueDeviceQueueItemResponse {
|
||||
let mut resp = Response::new(api::EnqueueDeviceQueueItemResponse {
|
||||
id: qi.id.to_string(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req_qi.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn flush_queue(
|
||||
@ -983,7 +1060,11 @@ impl DeviceService for Device {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_queue(
|
||||
@ -1004,7 +1085,7 @@ impl DeviceService for Device {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::GetDeviceQueueItemsResponse {
|
||||
let mut resp = Response::new(api::GetDeviceQueueItemsResponse {
|
||||
total_count: items.len() as u32,
|
||||
result: items
|
||||
.iter()
|
||||
@ -1022,7 +1103,11 @@ impl DeviceService for Device {
|
||||
},
|
||||
})
|
||||
.collect(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,9 +91,15 @@ impl DeviceProfileService for DeviceProfile {
|
||||
|
||||
dp = device_profile::create(dp).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::CreateDeviceProfileResponse {
|
||||
let mut resp = Response::new(api::CreateDeviceProfileResponse {
|
||||
id: dp.id.to_string(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-device_profile_id",
|
||||
dp.id.to_string().parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get(
|
||||
@ -112,7 +118,7 @@ impl DeviceProfileService for DeviceProfile {
|
||||
|
||||
let dp = device_profile::get(&dp_id).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::GetDeviceProfileResponse {
|
||||
let mut resp = Response::new(api::GetDeviceProfileResponse {
|
||||
device_profile: Some(api::DeviceProfile {
|
||||
id: dp.id.to_string(),
|
||||
tenant_id: dp.tenant_id.to_string(),
|
||||
@ -158,7 +164,11 @@ impl DeviceProfileService for DeviceProfile {
|
||||
}),
|
||||
created_at: Some(helpers::datetime_to_prost_timestamp(&dp.created_at)),
|
||||
updated_at: Some(helpers::datetime_to_prost_timestamp(&dp.updated_at)),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-device_profile_id", req.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn update(
|
||||
@ -228,7 +238,11 @@ impl DeviceProfileService for DeviceProfile {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-device_profile_id", req_dp.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete(
|
||||
@ -248,7 +262,12 @@ impl DeviceProfileService for DeviceProfile {
|
||||
device_profile::delete(&dp_id)
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
Ok(Response::new(()))
|
||||
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-device_profile_id", req.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list(
|
||||
@ -281,7 +300,7 @@ impl DeviceProfileService for DeviceProfile {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::ListDeviceProfilesResponse {
|
||||
let mut resp = Response::new(api::ListDeviceProfilesResponse {
|
||||
total_count: count as u32,
|
||||
result: items
|
||||
.iter()
|
||||
@ -298,7 +317,11 @@ impl DeviceProfileService for DeviceProfile {
|
||||
supports_class_c: dp.supports_class_c,
|
||||
})
|
||||
.collect(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req.tenant_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list_adr_algorithms(
|
||||
|
@ -66,7 +66,11 @@ impl GatewayService for Gateway {
|
||||
|
||||
let _ = gateway::create(gw).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-gateway_id", req_gw.gateway_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get(
|
||||
@ -85,7 +89,7 @@ impl GatewayService for Gateway {
|
||||
|
||||
let gw = gateway::get(&gw_id).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::GetGatewayResponse {
|
||||
let mut resp = Response::new(api::GetGatewayResponse {
|
||||
gateway: Some(api::Gateway {
|
||||
gateway_id: gw.gateway_id.to_string(),
|
||||
name: gw.name,
|
||||
@ -106,7 +110,11 @@ impl GatewayService for Gateway {
|
||||
.last_seen_at
|
||||
.as_ref()
|
||||
.map(helpers::datetime_to_prost_timestamp),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-gateway_id", req.gateway_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn update(
|
||||
@ -147,7 +155,11 @@ impl GatewayService for Gateway {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-gateway_id", req_gw.gateway_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete(
|
||||
@ -165,7 +177,12 @@ impl GatewayService for Gateway {
|
||||
.await?;
|
||||
|
||||
gateway::delete(&gw_id).await.map_err(|e| e.status())?;
|
||||
Ok(Response::new(()))
|
||||
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-gateway_id", req.gateway_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list(
|
||||
@ -203,7 +220,7 @@ impl GatewayService for Gateway {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::ListGatewaysResponse {
|
||||
let mut resp = Response::new(api::ListGatewaysResponse {
|
||||
total_count: count as u32,
|
||||
result: result
|
||||
.iter()
|
||||
@ -227,7 +244,13 @@ impl GatewayService for Gateway {
|
||||
.map(helpers::datetime_to_prost_timestamp),
|
||||
})
|
||||
.collect(),
|
||||
}))
|
||||
});
|
||||
if !req.tenant_id.is_empty() {
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req.tenant_id.parse().unwrap());
|
||||
}
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn generate_client_certificate(
|
||||
@ -252,14 +275,16 @@ impl GatewayService for Gateway {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(
|
||||
api::GenerateGatewayClientCertificateResponse {
|
||||
ca_cert,
|
||||
tls_cert: cert,
|
||||
tls_key: key,
|
||||
expires_at: Some(ttl.into()),
|
||||
},
|
||||
))
|
||||
let mut resp = Response::new(api::GenerateGatewayClientCertificateResponse {
|
||||
ca_cert,
|
||||
tls_cert: cert,
|
||||
tls_key: key,
|
||||
expires_at: Some(ttl.into()),
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-gateway_id", req.gateway_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_metrics(
|
||||
@ -544,7 +569,11 @@ impl GatewayService for Gateway {
|
||||
}),
|
||||
};
|
||||
|
||||
Ok(Response::new(out))
|
||||
let mut resp = Response::new(out);
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-gateway_id", req.gateway_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,15 +15,16 @@ use prometheus_client::metrics::counter::Counter;
|
||||
use prometheus_client::metrics::family::Family;
|
||||
use prometheus_client::metrics::histogram::Histogram;
|
||||
use rust_embed::RustEmbed;
|
||||
use tokio::try_join;
|
||||
use tokio::{task, try_join};
|
||||
use tonic::transport::Server as TonicServer;
|
||||
use tonic::Code;
|
||||
use tonic_reflection::server::Builder as TonicReflectionBuilder;
|
||||
use tower::{Service, ServiceBuilder};
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing::{event, Level};
|
||||
use tracing::{error, info};
|
||||
use warp::{http::header::HeaderValue, path::Tail, reply::Response, Filter, Rejection, Reply};
|
||||
|
||||
use chirpstack_api::api;
|
||||
use chirpstack_api::api::application_service_server::ApplicationServiceServer;
|
||||
use chirpstack_api::api::device_profile_service_server::DeviceProfileServiceServer;
|
||||
use chirpstack_api::api::device_profile_template_service_server::DeviceProfileTemplateServiceServer;
|
||||
@ -37,6 +38,7 @@ use chirpstack_api::api::user_service_server::UserServiceServer;
|
||||
use super::config;
|
||||
use crate::api::auth::validator;
|
||||
use crate::monitoring::prometheus;
|
||||
use crate::requestlog;
|
||||
|
||||
pub mod application;
|
||||
pub mod auth;
|
||||
@ -92,11 +94,7 @@ pub async fn setup() -> Result<()> {
|
||||
let conf = config::get();
|
||||
let addr = conf.api.bind.parse()?;
|
||||
|
||||
event!(
|
||||
Level::INFO,
|
||||
bind = conf.api.bind.as_str(),
|
||||
"Setting up API interface"
|
||||
);
|
||||
info!(bind = %conf.api.bind, "Setting up API interface");
|
||||
|
||||
// Taken from the tonic hyper_warp_multiplex example:
|
||||
// https://github.com/hyperium/tonic/blob/master/examples/src/hyper_warp_multiplex/server.rs#L101
|
||||
@ -172,7 +170,7 @@ pub async fn setup() -> Result<()> {
|
||||
.on_request(OnRequest {})
|
||||
.on_response(OnResponse {}),
|
||||
)
|
||||
.layer(PrometheusLogger {})
|
||||
.layer(ApiLogger {})
|
||||
.service(tonic_service);
|
||||
|
||||
// HTTP service
|
||||
@ -316,22 +314,22 @@ struct GrpcLabels {
|
||||
status_code: String,
|
||||
}
|
||||
|
||||
struct PrometheusLogger {}
|
||||
struct ApiLogger {}
|
||||
|
||||
impl<S> tower::Layer<S> for PrometheusLogger {
|
||||
type Service = PrometheusLoggerService<S>;
|
||||
impl<S> tower::Layer<S> for ApiLogger {
|
||||
type Service = ApiLoggerService<S>;
|
||||
|
||||
fn layer(&self, service: S) -> Self::Service {
|
||||
PrometheusLoggerService { inner: service }
|
||||
ApiLoggerService { inner: service }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct PrometheusLoggerService<S> {
|
||||
struct ApiLoggerService<S> {
|
||||
inner: S,
|
||||
}
|
||||
|
||||
impl<S, ReqBody, ResBody> Service<http::Request<ReqBody>> for PrometheusLoggerService<S>
|
||||
impl<S, ReqBody, ResBody> Service<http::Request<ReqBody>> for ApiLoggerService<S>
|
||||
where
|
||||
S: Service<http::Request<ReqBody>, Response = http::Response<ResBody>>,
|
||||
ReqBody: http_body::Body,
|
||||
@ -339,7 +337,7 @@ where
|
||||
{
|
||||
type Response = S::Response;
|
||||
type Error = S::Error;
|
||||
type Future = PrometheusLoggerResponseFuture<S::Future>;
|
||||
type Future = ApiLoggerResponseFuture<S::Future>;
|
||||
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
self.inner.poll_ready(cx)
|
||||
@ -350,7 +348,7 @@ where
|
||||
let uri_parts: Vec<&str> = uri.split('/').collect();
|
||||
let response_future = self.inner.call(request);
|
||||
let start = Instant::now();
|
||||
PrometheusLoggerResponseFuture {
|
||||
ApiLoggerResponseFuture {
|
||||
response_future,
|
||||
start,
|
||||
service: uri_parts.get(1).map(|v| v.to_string()).unwrap_or_default(),
|
||||
@ -360,7 +358,7 @@ where
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct PrometheusLoggerResponseFuture<F> {
|
||||
struct ApiLoggerResponseFuture<F> {
|
||||
#[pin]
|
||||
response_future: F,
|
||||
start: Instant,
|
||||
@ -368,7 +366,7 @@ struct PrometheusLoggerResponseFuture<F> {
|
||||
method: String,
|
||||
}
|
||||
|
||||
impl<F, ResBody, Error> Future for PrometheusLoggerResponseFuture<F>
|
||||
impl<F, ResBody, Error> Future for ApiLoggerResponseFuture<F>
|
||||
where
|
||||
F: Future<Output = Result<http::Response<ResBody>, Error>>,
|
||||
ResBody: http_body::Body,
|
||||
@ -389,6 +387,8 @@ where
|
||||
},
|
||||
};
|
||||
let status_code = Code::from_i32(status_code);
|
||||
|
||||
// Log to Prometheus
|
||||
let labels = GrpcLabels {
|
||||
service: this.service.clone(),
|
||||
method: this.method.clone(),
|
||||
@ -398,6 +398,32 @@ where
|
||||
GRPC_HISTOGRAM
|
||||
.get_or_create(&labels)
|
||||
.observe(this.start.elapsed().as_secs_f64());
|
||||
|
||||
// Log API request to Redis
|
||||
let req_log = api::RequestLog {
|
||||
service: this.service.to_string(),
|
||||
method: this.method.to_string(),
|
||||
metadata: response
|
||||
.headers()
|
||||
.iter()
|
||||
.filter(|(k, _)| k.as_str().starts_with("x-log-"))
|
||||
.map(|(k, v)| {
|
||||
(
|
||||
k.as_str()
|
||||
.strip_prefix("x-log-")
|
||||
.unwrap_or_default()
|
||||
.to_string(),
|
||||
v.to_str().unwrap().to_string(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
task::spawn(async move {
|
||||
if let Err(err) = requestlog::log_request(&req_log).await {
|
||||
error!("Log request error, error: {}", err);
|
||||
}
|
||||
});
|
||||
}
|
||||
Poll::Ready(result)
|
||||
}
|
||||
|
@ -65,9 +65,16 @@ impl MulticastGroupService for MulticastGroup {
|
||||
..Default::default()
|
||||
};
|
||||
let mg = multicast::create(mg).await.map_err(|e| e.status())?;
|
||||
Ok(Response::new(api::CreateMulticastGroupResponse {
|
||||
|
||||
let mut resp = Response::new(api::CreateMulticastGroupResponse {
|
||||
id: mg.id.to_string(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-multicast_group_id",
|
||||
mg.id.to_string().parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get(
|
||||
@ -86,7 +93,7 @@ impl MulticastGroupService for MulticastGroup {
|
||||
|
||||
let mg = multicast::get(&mg_id).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::GetMulticastGroupResponse {
|
||||
let mut resp = Response::new(api::GetMulticastGroupResponse {
|
||||
multicast_group: Some(api::MulticastGroup {
|
||||
id: mg.id.to_string(),
|
||||
name: mg.name.clone(),
|
||||
@ -110,7 +117,11 @@ impl MulticastGroupService for MulticastGroup {
|
||||
}),
|
||||
created_at: Some(helpers::datetime_to_prost_timestamp(&mg.created_at)),
|
||||
updated_at: Some(helpers::datetime_to_prost_timestamp(&mg.updated_at)),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-multicast_group_id", req.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn update(
|
||||
@ -153,7 +164,11 @@ impl MulticastGroupService for MulticastGroup {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-multicast_group_id", req_mg.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete(
|
||||
@ -171,7 +186,12 @@ impl MulticastGroupService for MulticastGroup {
|
||||
.await?;
|
||||
|
||||
multicast::delete(&mg_id).await.map_err(|e| e.status())?;
|
||||
Ok(Response::new(()))
|
||||
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-multicast_group_id", req.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list(
|
||||
@ -204,7 +224,7 @@ impl MulticastGroupService for MulticastGroup {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::ListMulticastGroupsResponse {
|
||||
let mut resp = Response::new(api::ListMulticastGroupsResponse {
|
||||
total_count: count as u32,
|
||||
result: items
|
||||
.iter()
|
||||
@ -222,7 +242,11 @@ impl MulticastGroupService for MulticastGroup {
|
||||
.into(),
|
||||
})
|
||||
.collect(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-application_id", req.application_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn add_device(
|
||||
@ -243,7 +267,16 @@ impl MulticastGroupService for MulticastGroup {
|
||||
multicast::add_device(&mg_id, &dev_eui)
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
Ok(Response::new(()))
|
||||
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-multicast_group_id",
|
||||
req.multicast_group_id.parse().unwrap(),
|
||||
);
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn remove_device(
|
||||
@ -264,7 +297,16 @@ impl MulticastGroupService for MulticastGroup {
|
||||
multicast::remove_device(&mg_id, &dev_eui)
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
Ok(Response::new(()))
|
||||
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-multicast_group_id",
|
||||
req.multicast_group_id.parse().unwrap(),
|
||||
);
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-dev_eui", req.dev_eui.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn enqueue(
|
||||
@ -296,9 +338,13 @@ impl MulticastGroupService for MulticastGroup {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::EnqueueMulticastGroupQueueItemResponse {
|
||||
f_cnt,
|
||||
}))
|
||||
let mut resp = Response::new(api::EnqueueMulticastGroupQueueItemResponse { f_cnt });
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-multicast_group_id",
|
||||
req_enq.multicast_group_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn flush_queue(
|
||||
@ -319,7 +365,13 @@ impl MulticastGroupService for MulticastGroup {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-multicast_group_id",
|
||||
req.multicast_group_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list_queue(
|
||||
@ -352,9 +404,15 @@ impl MulticastGroupService for MulticastGroup {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Response::new(api::ListMulticastGroupQueueResponse {
|
||||
let mut resp = Response::new(api::ListMulticastGroupQueueResponse {
|
||||
items: deduped_items,
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut().insert(
|
||||
"x-log-multicast_group_id",
|
||||
req.multicast_group_id.parse().unwrap(),
|
||||
);
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,9 +53,13 @@ impl TenantService for Tenant {
|
||||
|
||||
let t = tenant::create(t).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::CreateTenantResponse {
|
||||
let mut resp = Response::new(api::CreateTenantResponse {
|
||||
id: t.id.to_string(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", t.id.to_string().parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get(
|
||||
@ -74,7 +78,7 @@ impl TenantService for Tenant {
|
||||
|
||||
let t = tenant::get(&tenant_id).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::GetTenantResponse {
|
||||
let mut resp = Response::new(api::GetTenantResponse {
|
||||
tenant: Some(api::Tenant {
|
||||
id: t.id.to_string(),
|
||||
name: t.name,
|
||||
@ -86,7 +90,11 @@ impl TenantService for Tenant {
|
||||
}),
|
||||
created_at: Some(helpers::datetime_to_prost_timestamp(&t.created_at)),
|
||||
updated_at: Some(helpers::datetime_to_prost_timestamp(&t.updated_at)),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn update(
|
||||
@ -122,7 +130,11 @@ impl TenantService for Tenant {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req_tenant.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete(
|
||||
@ -141,7 +153,11 @@ impl TenantService for Tenant {
|
||||
|
||||
tenant::delete(&tenant_id).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list(
|
||||
@ -245,7 +261,13 @@ impl TenantService for Tenant {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req_user.tenant_id.parse().unwrap());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-user_id", user_id.to_string().parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get_user(
|
||||
@ -268,7 +290,7 @@ impl TenantService for Tenant {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::GetTenantUserResponse {
|
||||
let mut resp = Response::new(api::GetTenantUserResponse {
|
||||
tenant_user: Some(api::TenantUser {
|
||||
tenant_id: tenant_id.to_string(),
|
||||
user_id: tu.user_id.to_string(),
|
||||
@ -279,7 +301,13 @@ impl TenantService for Tenant {
|
||||
}),
|
||||
created_at: Some(helpers::datetime_to_prost_timestamp(&tu.created_at)),
|
||||
updated_at: Some(helpers::datetime_to_prost_timestamp(&tu.updated_at)),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req.tenant_id.parse().unwrap());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-user_id", req.user_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn update_user(
|
||||
@ -317,7 +345,13 @@ impl TenantService for Tenant {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req_user.tenant_id.parse().unwrap());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-user_id", req_user.user_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete_user(
|
||||
@ -352,7 +386,13 @@ impl TenantService for Tenant {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req.tenant_id.parse().unwrap());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-user_id", req.user_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list_users(
|
||||
@ -376,7 +416,7 @@ impl TenantService for Tenant {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::ListTenantUsersResponse {
|
||||
let mut resp = Response::new(api::ListTenantUsersResponse {
|
||||
total_count: count as u32,
|
||||
result: result
|
||||
.iter()
|
||||
@ -391,7 +431,11 @@ impl TenantService for Tenant {
|
||||
is_gateway_admin: tu.is_gateway_admin,
|
||||
})
|
||||
.collect(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-tenant_id", req.tenant_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,9 +75,13 @@ impl UserService for User {
|
||||
.map_err(|e| e.status())?;
|
||||
}
|
||||
|
||||
Ok(Response::new(api::CreateUserResponse {
|
||||
let mut resp = Response::new(api::CreateUserResponse {
|
||||
id: u.id.to_string(),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-user_id", u.id.to_string().parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn get(
|
||||
@ -96,7 +100,7 @@ impl UserService for User {
|
||||
|
||||
let u = user::get(&user_id).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(api::GetUserResponse {
|
||||
let mut resp = Response::new(api::GetUserResponse {
|
||||
user: Some(api::User {
|
||||
id: u.id.to_string(),
|
||||
is_admin: u.is_admin,
|
||||
@ -106,7 +110,11 @@ impl UserService for User {
|
||||
}),
|
||||
created_at: Some(helpers::datetime_to_prost_timestamp(&u.created_at)),
|
||||
updated_at: Some(helpers::datetime_to_prost_timestamp(&u.updated_at)),
|
||||
}))
|
||||
});
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-user_id", req.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn update(
|
||||
@ -141,7 +149,11 @@ impl UserService for User {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-user_id", req_user.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn delete(
|
||||
@ -169,7 +181,11 @@ impl UserService for User {
|
||||
|
||||
user::delete(&user_id).await.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-user_id", req.id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn list(
|
||||
@ -231,7 +247,11 @@ impl UserService for User {
|
||||
.await
|
||||
.map_err(|e| e.status())?;
|
||||
|
||||
Ok(Response::new(()))
|
||||
let mut resp = Response::new(());
|
||||
resp.metadata_mut()
|
||||
.insert("x-log-user_id", req.user_id.parse().unwrap());
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,6 +211,7 @@ impl Default for Scheduler {
|
||||
#[serde(default)]
|
||||
pub struct Monitoring {
|
||||
pub bind: String,
|
||||
pub api_request_log_max_history: usize,
|
||||
pub meta_log_max_history: usize,
|
||||
pub gateway_frame_log_max_history: usize,
|
||||
pub device_frame_log_max_history: usize,
|
||||
@ -230,6 +231,7 @@ impl Default for Monitoring {
|
||||
fn default() -> Self {
|
||||
Monitoring {
|
||||
bind: "".to_string(),
|
||||
api_request_log_max_history: 10,
|
||||
meta_log_max_history: 10,
|
||||
gateway_frame_log_max_history: 10,
|
||||
device_frame_log_max_history: 10,
|
||||
|
@ -36,6 +36,7 @@ mod maccommand;
|
||||
mod metalog;
|
||||
mod monitoring;
|
||||
mod region;
|
||||
mod requestlog;
|
||||
mod sensitivity;
|
||||
mod storage;
|
||||
#[cfg(test)]
|
||||
|
80
chirpstack/src/requestlog.rs
Normal file
80
chirpstack/src/requestlog.rs
Normal file
@ -0,0 +1,80 @@
|
||||
use anyhow::Result;
|
||||
use prost::Message;
|
||||
use tokio::task;
|
||||
|
||||
use crate::config;
|
||||
use crate::storage::{get_redis_conn, redis_key};
|
||||
use chirpstack_api::api;
|
||||
|
||||
pub async fn log_request(pl: &api::RequestLog) -> Result<()> {
|
||||
task::spawn_blocking({
|
||||
let pl = pl.clone();
|
||||
|
||||
move || -> Result<()> {
|
||||
let conf = config::get();
|
||||
let mut c = get_redis_conn()?;
|
||||
|
||||
if conf.monitoring.api_request_log_max_history == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let key = redis_key("api:stream:request".to_string());
|
||||
let b = pl.encode_to_vec();
|
||||
redis::cmd("XADD")
|
||||
.arg(&key)
|
||||
.arg("MAXLEN")
|
||||
.arg(conf.monitoring.api_request_log_max_history)
|
||||
.arg("*")
|
||||
.arg("request")
|
||||
.arg(&b)
|
||||
.query(&mut *c)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.await?
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::test;
|
||||
use redis::streams::StreamReadReply;
|
||||
use std::io::Cursor;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_log_request() {
|
||||
let _guard = test::prepare().await;
|
||||
|
||||
let pl = api::RequestLog {
|
||||
service: "ap.Foo".to_string(),
|
||||
method: "bar".to_string(),
|
||||
metadata: [("user_id".to_string(), "foo_user".to_string())]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect(),
|
||||
};
|
||||
log_request(&pl).await.unwrap();
|
||||
|
||||
let mut c = get_redis_conn().unwrap();
|
||||
let key = redis_key("api:stream:request".to_string());
|
||||
let srr: StreamReadReply = redis::cmd("XREAD")
|
||||
.arg("COUNT")
|
||||
.arg(1 as usize)
|
||||
.arg("STREAMS")
|
||||
.arg(&key)
|
||||
.arg("0")
|
||||
.query(&mut *c)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(1, srr.keys.len());
|
||||
assert_eq!(1, srr.keys[0].ids.len());
|
||||
|
||||
if let Some(redis::Value::Data(b)) = srr.keys[0].ids[0].map.get("request") {
|
||||
let pl_recv = api::RequestLog::decode(&mut Cursor::new(b)).unwrap();
|
||||
assert_eq!(pl, pl_recv);
|
||||
} else {
|
||||
panic!("No request log");
|
||||
}
|
||||
}
|
||||
}
|
1
examples/request_log/go/.gitignore
vendored
Normal file
1
examples/request_log/go/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
request-log
|
20
examples/request_log/go/go.mod
Normal file
20
examples/request_log/go/go.mod
Normal file
@ -0,0 +1,20 @@
|
||||
module request-log
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/chirpstack/chirpstack/api/go/v4 v4.1.0
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
google.golang.org/protobuf v1.28.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
|
||||
google.golang.org/grpc v1.45.0 // indirect
|
||||
)
|
145
examples/request_log/go/go.sum
Normal file
145
examples/request_log/go/go.sum
Normal file
@ -0,0 +1,145 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chirpstack/chirpstack/api/go/v4 v4.0.2 h1:qyblQmhC66zlKFoM5gj9TjHpvCNBMZ+qt11EEpBAb6U=
|
||||
github.com/chirpstack/chirpstack/api/go/v4 v4.0.2/go.mod h1:KBW7imf70O9ifrMmoFH8+dn0+MUFS1PdC5shXH7W3dI=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
63
examples/request_log/go/main.go
Normal file
63
examples/request_log/go/main.go
Normal file
@ -0,0 +1,63 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/chirpstack/chirpstack/api/go/v4/api"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
server string
|
||||
key string
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&server, "server", "localhost:6379", "Redis hostname:port")
|
||||
flag.StringVar(&key, "key", "api:stream:request", "Redis Streams key to read from")
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func main() {
|
||||
rdb := redis.NewClient(&redis.Options{
|
||||
Addr: server,
|
||||
})
|
||||
ctx := context.Background()
|
||||
lastID := "0"
|
||||
|
||||
for {
|
||||
resp, err := rdb.XRead(ctx, &redis.XReadArgs{
|
||||
Streams: []string{key, lastID},
|
||||
Count: 10,
|
||||
Block: 0,
|
||||
}).Result()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if len(resp) != 1 {
|
||||
log.Fatal("Exactly one stream response is expected")
|
||||
}
|
||||
|
||||
for _, msg := range resp[0].Messages {
|
||||
lastID = msg.ID
|
||||
|
||||
if b, ok := msg.Values["request"].(string); ok {
|
||||
var pl api.RequestLog
|
||||
if err := proto.Unmarshal([]byte(b), &pl); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("=== Request ===")
|
||||
fmt.Println(protojson.Format(&pl))
|
||||
fmt.Println("===============")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user