mirror of https://github.com/milvus-io/milvus.git
support high-level RESTFUL API, listen on the same port as grpc (#24761)
Signed-off-by: PowderLi <min.li@zilliz.com>pull/25468/head
parent
ca3d70bd4e
commit
4dd028363b
|
@ -51,6 +51,8 @@ issues:
|
|||
- G304
|
||||
# Deferring unsafe method like *os.File Close
|
||||
- G307
|
||||
# TLS MinVersion too low
|
||||
- G402
|
||||
# Use of weak random number generator math/rand
|
||||
- G404
|
||||
# Exclude copylocks
|
||||
|
|
21
go.mod
21
go.mod
|
@ -52,7 +52,7 @@ require (
|
|||
golang.org/x/crypto v0.9.0
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17
|
||||
golang.org/x/sync v0.1.0
|
||||
google.golang.org/grpc v1.46.0
|
||||
google.golang.org/grpc v1.48.0
|
||||
google.golang.org/grpc/examples v0.0.0-20220617181431-3e7b97febc7f
|
||||
google.golang.org/protobuf v1.30.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
|
@ -115,7 +115,7 @@ require (
|
|||
github.com/linkedin/goavro/v2 v2.11.1 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-colorable v0.1.11 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect
|
||||
|
@ -138,7 +138,7 @@ require (
|
|||
github.com/rs/xid v1.2.1 // indirect
|
||||
github.com/samber/lo v1.27.0
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/soheilhy/cmux v0.1.5 // indirect
|
||||
github.com/soheilhy/cmux v0.1.5
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
|
@ -181,11 +181,12 @@ require (
|
|||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
)
|
||||
|
||||
require github.com/cockroachdb/errors v1.2.4
|
||||
require github.com/cockroachdb/errors v1.9.1
|
||||
|
||||
require (
|
||||
github.com/aliyun/credentials-go v1.2.7
|
||||
github.com/milvus-io/milvus-proto/go-api/v2 v2.2.11
|
||||
github.com/tidwall/gjson v1.14.4
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -193,14 +194,19 @@ require (
|
|||
github.com/alibabacloud-go/tea v1.1.8 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
|
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect
|
||||
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f // indirect
|
||||
github.com/cockroachdb/redact v1.1.3 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/getsentry/raven-go v0.2.0 // indirect
|
||||
github.com/getsentry/sentry-go v0.12.0 // indirect
|
||||
github.com/google/flatbuffers v2.0.5+incompatible // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.12 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.1 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1 // indirect
|
||||
|
@ -210,7 +216,6 @@ require (
|
|||
replace (
|
||||
github.com/apache/pulsar-client-go => github.com/milvus-io/pulsar-client-go v0.6.8
|
||||
github.com/bketelsen/crypt => github.com/bketelsen/crypt v0.0.4 // Fix security alert for core-os/etcd
|
||||
github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt v3.2.2+incompatible // Fix security alert for jwt-go 3.2.0
|
||||
github.com/go-kit/kit => github.com/go-kit/kit v0.1.0
|
||||
github.com/streamnative/pulsarctl => github.com/xiaofan-luan/pulsarctl v0.5.1
|
||||
github.com/tecbot/gorocksdb => github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b // indirect
|
||||
|
|
151
go.sum
151
go.sum
|
@ -46,12 +46,15 @@ github.com/99designs/keyring v1.1.5/go.mod h1:7hsVvt2qXgtadGevGJ4ujg+u8m6SpJ5TpH
|
|||
github.com/99designs/keyring v1.1.6/go.mod h1:16e0ds7LGQQcT59QqkTg72Hh5ShM51Byv5PEmW6uoRU=
|
||||
github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o=
|
||||
github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA=
|
||||
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
|
||||
github.com/AthenZ/athenz v1.10.15 h1:8Bc2W313k/ev/SGokuthNbzpwfg9W3frg3PKq1r943I=
|
||||
github.com/AthenZ/athenz v1.10.15/go.mod h1:7KMpEuJ9E4+vMCMI3UQJxwWs0RZtQq7YXZ1IteUjdsc=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
|
||||
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
||||
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
|
@ -61,12 +64,15 @@ github.com/HdrHistogram/hdrhistogram-go v1.0.1 h1:GX8GAYDuhlFQnI2fRDHQhTlkHMz8bE
|
|||
github.com/HdrHistogram/hdrhistogram-go v1.0.1/go.mod h1:BWJ+nMSHY3L41Zj7CA3uXnloDp7xxV0YvstAE7nKTaM=
|
||||
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU=
|
||||
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
|
||||
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
|
||||
github.com/actgardner/gogen-avro/v10 v10.1.0/go.mod h1:o+ybmVjEa27AAr35FRqU98DJu1fXES56uXniYFv4yDA=
|
||||
github.com/actgardner/gogen-avro/v10 v10.2.1/go.mod h1:QUhjeHPchheYmMDni/Nx7VB0RsT/ee8YIgGY/xpEQgQ=
|
||||
github.com/actgardner/gogen-avro/v9 v9.1.0/go.mod h1:nyTj6wPqDJoxM3qdnjcLv+EnMDSDFqE0qDpva2QRmKc=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
|
@ -97,9 +103,11 @@ github.com/ardielle/ardielle-go v1.5.2 h1:TilHTpHIQJ27R1Tl/iITBzMwiUGSlVfiVhwDNG
|
|||
github.com/ardielle/ardielle-go v1.5.2/go.mod h1:I4hy1n795cUhaVt/ojz83SNVCYIGsAFAONtv2Dr7HUI=
|
||||
github.com/ardielle/ardielle-tools v1.5.4/go.mod h1:oZN+JRMnqGiIhrzkRN9l26Cej9dEx4jeNG6A+AdkShk=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aws/aws-sdk-go v1.32.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
||||
github.com/beefsack/go-rate v0.0.0-20180408011153-efa7637bb9b6/go.mod h1:6YNgTHLutezwnBvyneBbwvB8C82y3dcoOj5EQJIdGXA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
|
@ -130,7 +138,6 @@ github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuD
|
|||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI=
|
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
|
@ -152,23 +159,33 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH
|
|||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5 h1:xD/lrqdvwsc+O2bjSSi3YqY73Ke3LAiSCx49aCesA0E=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
|
||||
github.com/cockroachdb/errors v1.2.4 h1:Lap807SXTH5tri2TivECb/4abUkMZC9zRoLarvcKDqs=
|
||||
github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA=
|
||||
github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
|
||||
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY=
|
||||
github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8=
|
||||
github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk=
|
||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
||||
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f h1:6jduT9Hfc0njg5jJ1DdKCFPdMBrp/mdZfCpa5h+WM74=
|
||||
github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
|
||||
github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ=
|
||||
github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
|
||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
|
||||
github.com/confluentinc/confluent-kafka-go v1.9.1 h1:L3aW6KvTyrq/+BOMnDm9xJylhAEoAgqhoaJbMPe3GQI=
|
||||
github.com/confluentinc/confluent-kafka-go v1.9.1/go.mod h1:ptXNqsuDfYbAE/LBW6pnwWZElUoWxHoV8E43DCrliyo=
|
||||
github.com/containerd/cgroups v1.0.2 h1:mZBclaSgNDfPWtfhj2xJY28LZ9nYIgzB0pwSURPl6JM=
|
||||
github.com/containerd/cgroups v1.0.2/go.mod h1:qpbpJ1jmlqsR9f2IyaLPsdkCdnt0rbDVqIDlhuu5tRY=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
|
@ -180,6 +197,9 @@ github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4wg/adLLz5xh5CmpiCA=
|
||||
github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0=
|
||||
|
@ -192,6 +212,7 @@ github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a/go.mod h1:7Bv
|
|||
github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM=
|
||||
github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM=
|
||||
github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU=
|
||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||
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=
|
||||
|
@ -202,14 +223,17 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m
|
|||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=
|
||||
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
|
||||
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk=
|
||||
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
|
||||
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=
|
||||
|
@ -225,18 +249,24 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
|
|||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||
github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM=
|
||||
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
|
||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk=
|
||||
github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/go-basic/ipv4 v1.0.0 h1:gjyFAa1USC1hhXTkPOwBWDPfMcUaIM+tvo1XzV9EZxs=
|
||||
github.com/go-basic/ipv4 v1.0.0/go.mod h1:etLBnaxbidQfuqE6wgZQfs38nEWNmzALkxDZe4xY8Dg=
|
||||
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
|
||||
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
|
||||
github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
|
||||
github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
|
||||
|
@ -251,6 +281,7 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
|||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
|
@ -264,6 +295,9 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
|
|||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||
github.com/goccy/go-json v0.7.10/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
|
@ -273,11 +307,15 @@ github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
|
|||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||
github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
|
@ -317,6 +355,7 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
|
|||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||
|
@ -339,6 +378,7 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
|
@ -366,6 +406,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
|
|||
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
|
@ -391,6 +432,7 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
|
|||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
|
@ -402,13 +444,20 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
|
|||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/heetch/avro v0.3.1/go.mod h1:4xn38Oz/+hiEUTpbVfGVLfvOg0yKLlRP7Q9+gJJILgA=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
|
||||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/invopop/jsonschema v0.4.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
|
||||
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
|
||||
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
|
||||
github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk=
|
||||
github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g=
|
||||
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
|
||||
github.com/jarcoal/httpmock v1.0.8 h1:8kI16SoO6LQKgPE7PvQuV+YuD/inwHd7fOOe2zMbo4k=
|
||||
github.com/jarcoal/httpmock v1.0.8/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
|
||||
github.com/jawher/mow.cli v1.0.4/go.mod h1:5hQj2V8g+qYmLUVWqu4Wuja1pI57M83EChYLVZ0sMKk=
|
||||
|
@ -429,6 +478,7 @@ github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9q
|
|||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
|
@ -442,6 +492,12 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
|
|||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
|
||||
github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8=
|
||||
github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE=
|
||||
github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE=
|
||||
github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro=
|
||||
github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8=
|
||||
github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
|
@ -449,10 +505,13 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
|||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/asmfmt v1.3.1 h1:7xZi1N7s9gTLbqiM8KUv8TLyysavbTRGBT5/ly0bRtw=
|
||||
github.com/klauspost/asmfmt v1.3.1/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE=
|
||||
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.10.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.14.2 h1:S0OHlFk/Gbon/yauFJ4FfJJF5V0fc5HbBTJazi28pRw=
|
||||
github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
|
||||
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
|
||||
|
@ -474,6 +533,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kris-nova/logger v0.0.0-20181127235838-fd0d87064b06 h1:vN4d3jSss3ExzUn2cE0WctxztfOgiKvMKnDrydBsg00=
|
||||
github.com/kris-nova/lolgopher v0.0.0-20180921204813-313b3abb0d9b h1:xYEM2oBUhBEhQjrV+KJ9lEWDWYZoNVZUaBF++Wyljq4=
|
||||
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/lingdor/stackerror v0.0.0-20191119040541-976d8885ed76 h1:IVlcvV0CjvfBYYod5ePe89l+3LBAl//6n9kJ9Vr2i0k=
|
||||
|
@ -488,23 +549,32 @@ github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1
|
|||
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
|
||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
|
||||
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b h1:TfeY0NxYxZzUfIfYe5qYDBzt4ZYRqzUjTR6CvUzjat8=
|
||||
github.com/milvus-io/gorocksdb v0.0.0-20220624081344-8c5f4212846b/go.mod h1:iwW+9cWfIzzDseEBCCeDSN5SD16Tidvy8cwQ7ZY8Qj4=
|
||||
|
@ -540,10 +610,15 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
|||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||
github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs=
|
||||
github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nrwiersma/avro-benchmarks v0.0.0-20210913175520-21aec48c8f76/go.mod h1:iKyFMidsk/sVYONJRE372sJuX/QTRPacU7imPqqsu7g=
|
||||
|
@ -552,6 +627,7 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI
|
|||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
|
@ -578,6 +654,8 @@ github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUM
|
|||
github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pierrec/lz4/v4 v4.1.12 h1:44l88ehTZAUGW4VlO1QC4zkilL99M6Y9MXNwEs0uzP8=
|
||||
github.com/pierrec/lz4/v4 v4.1.12/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
|
@ -623,21 +701,26 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So
|
|||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samber/lo v1.27.0 h1:GOyDWxsblvqYobqsmUuMddPa2/mMzkKyojlXol4+LaQ=
|
||||
github.com/samber/lo v1.27.0/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg=
|
||||
github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
|
||||
github.com/sbinet/npyio v0.6.0 h1:IyqqQIzRjDym9xnIXsToCKei/qCzxDP+Y74KoMlMgXo=
|
||||
github.com/sbinet/npyio v0.6.0/go.mod h1:/q3BNr6dJOy+t6h7RZchTJ0nwRJO52mivaem29WE1j8=
|
||||
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA=
|
||||
github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
|
@ -665,6 +748,7 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
|
|||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
|
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
|
@ -673,6 +757,7 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0
|
|||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44=
|
||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
||||
|
@ -699,6 +784,12 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
|
|||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
|
||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
||||
|
@ -712,13 +803,31 @@ github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24sz
|
|||
github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible h1:fY7QsGQWiCt8pajv4r7JEvmATdCVaWxXbjwyYwsNaLQ=
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xiaofan-luan/pulsarctl v0.5.1 h1:2V+IWFarElzcln5WBbU3VNu3zC8Q7RS6rMpVs9oUfLg=
|
||||
github.com/xiaofan-luan/pulsarctl v0.5.1/go.mod h1:kfeG1rRglz+QDSxyBB21H2Q4hMnzfirW32bs8yx/Q0Q=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
|
||||
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
@ -797,14 +906,17 @@ golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
|||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
|
@ -875,6 +987,7 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
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-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
|
@ -883,6 +996,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
@ -909,6 +1023,7 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
|
@ -947,7 +1062,9 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -956,8 +1073,10 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -1005,11 +1124,14 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -1034,18 +1156,21 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/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-20190206041539-40960b6deb8e/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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
|
@ -1096,6 +1221,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
|
|||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
|
@ -1143,6 +1269,7 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID
|
|||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
|
@ -1186,9 +1313,11 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D
|
|||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
|
||||
google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220503193339-ba3ae3f07e29 h1:DJUvgAPiJWeMBiT+RzBVcJGQN7bAEWS5UEoMshES9xs=
|
||||
google.golang.org/genproto v0.0.0-20220503193339-ba3ae3f07e29/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
|
||||
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
|
@ -1213,8 +1342,9 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ
|
|||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8=
|
||||
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
|
||||
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/grpc/examples v0.0.0-20220617181431-3e7b97febc7f h1:rqzndB2lIQGivcXdTuY3Y9NBvr70X+y77woofSRluec=
|
||||
google.golang.org/grpc/examples v0.0.0-20220617181431-3e7b97febc7f/go.mod h1:gxndsbNG1n4TZcHGgsYEfVGnTxqfEdfiDv6/DADXX9o=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
|
@ -1244,12 +1374,16 @@ gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8
|
|||
gopkg.in/errgo.v1 v1.0.0/go.mod h1:CxwszS/Xz1C49Ucd2i6Zil5UToP1EmyrFhKaMVbg1mk=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||
gopkg.in/httprequest.v1 v1.2.1/go.mod h1:x2Otw96yda5+8+6ZeWwHIJTFkEHWP/qP8pJOzqEtWPM=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
|
@ -1269,6 +1403,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package httpserver
|
||||
|
||||
const (
|
||||
ContextUsername = "username"
|
||||
VectorCollectionsPath = "/vector/collections"
|
||||
VectorCollectionsCreatePath = "/vector/collections/create"
|
||||
VectorCollectionsDescribePath = "/vector/collections/describe"
|
||||
VectorCollectionsDropPath = "/vector/collections/drop"
|
||||
VectorInsertPath = "/vector/insert"
|
||||
VectorSearchPath = "/vector/search"
|
||||
VectorGetPath = "/vector/get"
|
||||
VectorQueryPath = "/vector/query"
|
||||
VectorDeletePath = "/vector/delete"
|
||||
|
||||
ShardNumDefault = 2
|
||||
|
||||
EnableDynamic = true
|
||||
EnableAutoID = true
|
||||
DisableAutoID = false
|
||||
|
||||
HTTPCollectionName = "collectionName"
|
||||
HTTPDbName = "dbName"
|
||||
DefaultDbName = "default"
|
||||
|
||||
HTTPReturnCode = "code"
|
||||
HTTPReturnMessage = "message"
|
||||
HTTPReturnError = "error"
|
||||
HTTPReturnData = "data"
|
||||
|
||||
HTTPReturnFieldName = "name"
|
||||
HTTPReturnFieldType = "type"
|
||||
HTTPReturnFieldPrimaryKey = "primaryKey"
|
||||
HTTPReturnFieldAutoID = "autoId"
|
||||
HTTPReturnDescription = "description"
|
||||
|
||||
HTTPReturnIndexName = "indexName"
|
||||
HTTPReturnIndexField = "fieldName"
|
||||
HTTPReturnIndexMetricsType = "metricType"
|
||||
|
||||
HTTPReturnDistance = "distance"
|
||||
|
||||
DefaultMetricType = "L2"
|
||||
DefaultPrimaryFieldName = "id"
|
||||
DefaultVectorFieldName = "vector"
|
||||
|
||||
Dim = "dim"
|
||||
)
|
||||
|
||||
const (
|
||||
ParamAnnsField = "anns_field"
|
||||
Params = "params"
|
||||
ParamRoundDecimal = "round_decimal"
|
||||
ParamOffset = "offset"
|
||||
BoundedTimestamp = 2
|
||||
)
|
|
@ -0,0 +1,527 @@
|
|||
package httpserver
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/common"
|
||||
"github.com/milvus-io/milvus/internal/log"
|
||||
"github.com/milvus-io/milvus/internal/proxy"
|
||||
"github.com/tidwall/gjson"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func (h *Handlers) describeCollection(c *gin.Context, dbName string, collectionName string, needAuth bool) (*milvuspb.DescribeCollectionResponse, error) {
|
||||
req := milvuspb.DescribeCollectionRequest{
|
||||
DbName: dbName,
|
||||
CollectionName: collectionName,
|
||||
}
|
||||
if needAuth {
|
||||
username, ok := c.Get(ContextUsername)
|
||||
if !ok {
|
||||
msg := "the user hasn't authenticate"
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusProxyAuthRequired, HTTPReturnMessage: msg})
|
||||
return nil, errors.New(msg)
|
||||
}
|
||||
_, authErr := proxy.PrivilegeInterceptorWithUsername(c, username.(string), &req)
|
||||
if authErr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusUnauthorized, HTTPReturnMessage: authErr.Error()})
|
||||
return nil, authErr
|
||||
}
|
||||
}
|
||||
response, err := h.proxy.DescribeCollection(c, &req)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "describe collection " + collectionName + " fail", HTTPReturnError: err.Error()})
|
||||
return nil, err
|
||||
} else if response.Status.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: response.Status.ErrorCode, HTTPReturnMessage: response.Status.Reason})
|
||||
return nil, errors.New(response.Status.Reason)
|
||||
}
|
||||
primaryField, ok := getPrimaryField(response.Schema)
|
||||
if ok && primaryField.AutoID && !response.Schema.AutoID {
|
||||
log.Warn("primary filed autoID VS schema autoID", zap.String("collectionName", collectionName), zap.Bool("primary Field", primaryField.AutoID), zap.Bool("schema", response.Schema.AutoID))
|
||||
response.Schema.AutoID = EnableAutoID
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (h *Handlers) hasCollection(c *gin.Context, dbName string, collectionName string) (bool, error) {
|
||||
req := milvuspb.HasCollectionRequest{
|
||||
DbName: dbName,
|
||||
CollectionName: collectionName,
|
||||
}
|
||||
response, err := h.proxy.HasCollection(c, &req)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "check collections " + req.CollectionName + " exists fail", HTTPReturnError: err.Error()})
|
||||
return false, err
|
||||
} else if response.Status.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: response.Status.ErrorCode, HTTPReturnMessage: "check collections " + req.CollectionName + " exists fail", HTTPReturnError: response.Status.Reason})
|
||||
return false, errors.New(response.Status.Reason)
|
||||
} else {
|
||||
return response.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handlers) RegisterRoutesToV1(router gin.IRouter) {
|
||||
router.GET(VectorCollectionsPath, h.listCollections)
|
||||
router.POST(VectorCollectionsCreatePath, h.createCollection)
|
||||
router.GET(VectorCollectionsDescribePath, h.getCollectionDetails)
|
||||
router.POST(VectorCollectionsDropPath, h.dropCollection)
|
||||
router.POST(VectorQueryPath, h.query)
|
||||
router.POST(VectorGetPath, h.get)
|
||||
router.POST(VectorDeletePath, h.delete)
|
||||
router.POST(VectorInsertPath, h.insert)
|
||||
router.POST(VectorSearchPath, h.search)
|
||||
}
|
||||
|
||||
func (h *Handlers) listCollections(c *gin.Context) {
|
||||
dbName := c.DefaultQuery(HTTPDbName, DefaultDbName)
|
||||
req := milvuspb.ShowCollectionsRequest{
|
||||
DbName: dbName,
|
||||
}
|
||||
username, _ := c.Get(ContextUsername)
|
||||
_, authErr := proxy.PrivilegeInterceptorWithUsername(c, username.(string), &req)
|
||||
if authErr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusUnauthorized, HTTPReturnMessage: authErr.Error()})
|
||||
return
|
||||
}
|
||||
response, err := h.proxy.ShowCollections(c, &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "show collections fail", HTTPReturnError: err.Error()})
|
||||
} else if response.Status.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "show collections fail", HTTPReturnError: response.Status.Reason})
|
||||
} else {
|
||||
var collections []string
|
||||
if response.CollectionNames != nil {
|
||||
collections = response.CollectionNames
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnData: collections})
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handlers) createCollection(c *gin.Context) {
|
||||
httpReq := CreateCollectionReq{
|
||||
DbName: DefaultDbName,
|
||||
MetricType: DefaultMetricType,
|
||||
PrimaryField: DefaultPrimaryFieldName,
|
||||
VectorField: DefaultVectorFieldName,
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&httpReq, binding.JSON); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "check your parameters conform to the json format", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
if httpReq.CollectionName == "" || httpReq.Dimension == 0 {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "collectionName and dimension are both required."})
|
||||
return
|
||||
}
|
||||
schema, err := proto.Marshal(&schemapb.CollectionSchema{
|
||||
Name: httpReq.CollectionName,
|
||||
Description: httpReq.Description,
|
||||
AutoID: EnableAutoID,
|
||||
Fields: []*schemapb.FieldSchema{
|
||||
{
|
||||
FieldID: common.StartOfUserFieldID,
|
||||
Name: httpReq.PrimaryField,
|
||||
IsPrimaryKey: true,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
AutoID: EnableAutoID,
|
||||
}, {
|
||||
FieldID: common.StartOfUserFieldID + 1,
|
||||
Name: httpReq.VectorField,
|
||||
IsPrimaryKey: false,
|
||||
DataType: schemapb.DataType_FloatVector,
|
||||
TypeParams: []*commonpb.KeyValuePair{
|
||||
{
|
||||
Key: Dim,
|
||||
Value: strconv.FormatInt(int64(httpReq.Dimension), 10),
|
||||
},
|
||||
},
|
||||
AutoID: DisableAutoID,
|
||||
},
|
||||
},
|
||||
EnableDynamicField: EnableDynamic,
|
||||
})
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "marshal collection schema to string", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
req := milvuspb.CreateCollectionRequest{
|
||||
CollectionName: httpReq.CollectionName,
|
||||
Schema: schema,
|
||||
ShardsNum: ShardNumDefault,
|
||||
ConsistencyLevel: commonpb.ConsistencyLevel_Bounded,
|
||||
}
|
||||
username, _ := c.Get(ContextUsername)
|
||||
_, authErr := proxy.PrivilegeInterceptorWithUsername(c, username.(string), &req)
|
||||
if authErr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusUnauthorized, HTTPReturnMessage: authErr.Error()})
|
||||
return
|
||||
}
|
||||
resp, err := h.proxy.CreateCollection(c, &req)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "create collection " + httpReq.CollectionName + " fail", HTTPReturnError: err.Error()})
|
||||
return
|
||||
} else if resp.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: resp.ErrorCode, HTTPReturnMessage: "create collection " + httpReq.CollectionName + " fail", HTTPReturnError: resp.Reason})
|
||||
return
|
||||
}
|
||||
|
||||
resp, err = h.proxy.CreateIndex(c, &milvuspb.CreateIndexRequest{
|
||||
CollectionName: httpReq.CollectionName,
|
||||
FieldName: httpReq.VectorField,
|
||||
ExtraParams: []*commonpb.KeyValuePair{{Key: common.MetricTypeKey, Value: httpReq.MetricType}},
|
||||
})
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "create index for collection " + httpReq.CollectionName + " fail, after the collection was created", HTTPReturnError: err.Error()})
|
||||
return
|
||||
} else if resp.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: resp.ErrorCode, HTTPReturnMessage: "create index for collection " + httpReq.CollectionName + " fail, after the collection was created", HTTPReturnError: resp.Reason})
|
||||
return
|
||||
}
|
||||
resp, err = h.proxy.LoadCollection(c, &milvuspb.LoadCollectionRequest{
|
||||
CollectionName: httpReq.CollectionName,
|
||||
})
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "load collection " + httpReq.CollectionName + " fail, after the index was created", HTTPReturnError: err.Error()})
|
||||
return
|
||||
} else if resp.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: resp.ErrorCode, HTTPReturnMessage: "load collection " + httpReq.CollectionName + " fail, after the index was created", HTTPReturnError: resp.Reason})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnData: gin.H{}})
|
||||
}
|
||||
|
||||
func (h *Handlers) getCollectionDetails(c *gin.Context) {
|
||||
collectionName := c.Query(HTTPCollectionName)
|
||||
if collectionName == "" {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "collectionName is required."})
|
||||
return
|
||||
}
|
||||
dbName := c.DefaultQuery(HTTPDbName, DefaultDbName)
|
||||
coll, err := h.describeCollection(c, dbName, collectionName, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
stateResp, stateErr := h.proxy.GetLoadState(c, &milvuspb.GetLoadStateRequest{
|
||||
CollectionName: collectionName,
|
||||
})
|
||||
collLoadState := ""
|
||||
if stateErr != nil {
|
||||
log.Warn("get collection load state fail", zap.String("collection", collectionName), zap.String("err", stateErr.Error()))
|
||||
} else if stateResp.Status.ErrorCode != commonpb.ErrorCode_Success {
|
||||
log.Warn("get collection load state fail", zap.String("collection", collectionName), zap.String("err", stateResp.Status.Reason))
|
||||
} else {
|
||||
collLoadState = stateResp.State.String()
|
||||
}
|
||||
vectorField := ""
|
||||
for _, field := range coll.Schema.Fields {
|
||||
if field.DataType == schemapb.DataType_BinaryVector || field.DataType == schemapb.DataType_FloatVector {
|
||||
vectorField = field.Name
|
||||
break
|
||||
}
|
||||
}
|
||||
indexResp, indexErr := h.proxy.DescribeIndex(c, &milvuspb.DescribeIndexRequest{
|
||||
CollectionName: collectionName,
|
||||
FieldName: vectorField,
|
||||
})
|
||||
var indexDesc []gin.H
|
||||
if indexErr != nil {
|
||||
log.Warn("get indexes description fail", zap.String("collection", collectionName), zap.String("vectorField", vectorField), zap.String("err", indexErr.Error()))
|
||||
} else if indexResp.Status.ErrorCode != commonpb.ErrorCode_Success {
|
||||
log.Warn("get indexes description fail", zap.String("collection", collectionName), zap.String("vectorField", vectorField), zap.String("err", indexResp.Status.Reason))
|
||||
} else {
|
||||
indexDesc = printIndexes(indexResp.IndexDescriptions)
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnData: gin.H{
|
||||
HTTPCollectionName: coll.CollectionName,
|
||||
HTTPReturnDescription: coll.Schema.Description,
|
||||
"fields": printFields(coll.Schema.Fields),
|
||||
"indexes": indexDesc,
|
||||
"load": collLoadState,
|
||||
"shardsNum": coll.ShardsNum,
|
||||
"enableDynamic": coll.Schema.EnableDynamicField,
|
||||
}})
|
||||
}
|
||||
|
||||
func (h *Handlers) dropCollection(c *gin.Context) {
|
||||
httpReq := DropCollectionReq{
|
||||
DbName: DefaultDbName,
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&httpReq, binding.JSON); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "check your parameters conform to the json format", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
if httpReq.CollectionName == "" {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "collectionName is required."})
|
||||
return
|
||||
}
|
||||
has, err := h.hasCollection(c, httpReq.DbName, httpReq.CollectionName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !has {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnMessage: "can't find collection: " + httpReq.CollectionName})
|
||||
return
|
||||
}
|
||||
req := milvuspb.DropCollectionRequest{
|
||||
CollectionName: httpReq.CollectionName,
|
||||
}
|
||||
username, _ := c.Get(ContextUsername)
|
||||
_, authErr := proxy.PrivilegeInterceptorWithUsername(c, username.(string), &req)
|
||||
if authErr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusUnauthorized, HTTPReturnMessage: authErr.Error()})
|
||||
return
|
||||
}
|
||||
response, err := h.proxy.DropCollection(c, &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "drop collection " + httpReq.CollectionName + " fail", HTTPReturnError: err.Error()})
|
||||
} else if response.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: response.ErrorCode, HTTPReturnMessage: "drop collection " + httpReq.CollectionName + " fail", HTTPReturnError: response.Reason})
|
||||
} else {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnData: gin.H{}})
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handlers) query(c *gin.Context) {
|
||||
httpReq := QueryReq{
|
||||
DbName: DefaultDbName,
|
||||
Limit: 100,
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&httpReq, binding.JSON); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "check your parameters conform to the json format", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
if httpReq.CollectionName == "" {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "collectionName is required."})
|
||||
return
|
||||
}
|
||||
req := milvuspb.QueryRequest{
|
||||
CollectionName: httpReq.CollectionName,
|
||||
Expr: httpReq.Filter,
|
||||
OutputFields: httpReq.OutputFields,
|
||||
GuaranteeTimestamp: BoundedTimestamp,
|
||||
}
|
||||
username, _ := c.Get(ContextUsername)
|
||||
_, authErr := proxy.PrivilegeInterceptorWithUsername(c, username.(string), &req)
|
||||
if authErr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusUnauthorized, HTTPReturnMessage: authErr.Error()})
|
||||
return
|
||||
}
|
||||
response, err := h.proxy.Query(c, &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "query fail", HTTPReturnError: err.Error()})
|
||||
} else if response.Status.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: response.Status.ErrorCode, HTTPReturnMessage: response.Status.Reason})
|
||||
} else {
|
||||
outputData, err := buildQueryResp(int64(0), response.OutputFields, response.FieldsData, nil)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "show result by row wrong", "originData": response.FieldsData, HTTPReturnError: err.Error()})
|
||||
} else {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnData: outputData})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handlers) get(c *gin.Context) {
|
||||
httpReq := GetReq{
|
||||
DbName: DefaultDbName,
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&httpReq, binding.JSON); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "check your parameters conform to the json format", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
if httpReq.CollectionName == "" {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "collectionName is required."})
|
||||
return
|
||||
}
|
||||
coll, err := h.describeCollection(c, httpReq.DbName, httpReq.CollectionName, false)
|
||||
if err != nil || coll == nil {
|
||||
return
|
||||
}
|
||||
body, _ := c.Get(gin.BodyBytesKey)
|
||||
filter, err := checkGetPrimaryKey(coll.Schema, gjson.Get(string(body.([]byte)), "id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "make sure the collection's primary field", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
req := milvuspb.QueryRequest{
|
||||
CollectionName: httpReq.CollectionName,
|
||||
Expr: filter,
|
||||
OutputFields: httpReq.OutputFields,
|
||||
GuaranteeTimestamp: BoundedTimestamp,
|
||||
}
|
||||
username, _ := c.Get(ContextUsername)
|
||||
_, authErr := proxy.PrivilegeInterceptorWithUsername(c, username.(string), &req)
|
||||
if authErr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusUnauthorized, HTTPReturnMessage: authErr.Error()})
|
||||
return
|
||||
}
|
||||
response, err := h.proxy.Query(c, &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "query fail", HTTPReturnError: err.Error()})
|
||||
} else if response.Status.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: response.Status.ErrorCode, HTTPReturnMessage: response.Status.Reason})
|
||||
} else {
|
||||
outputData, err := buildQueryResp(int64(0), response.OutputFields, response.FieldsData, nil)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "show result by row wrong", "originData": response.FieldsData, HTTPReturnError: err.Error()})
|
||||
} else {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnData: outputData})
|
||||
log.Error("get resultIS: ", zap.Any("res", outputData))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handlers) delete(c *gin.Context) {
|
||||
httpReq := DeleteReq{
|
||||
DbName: DefaultDbName,
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&httpReq, binding.JSON); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "check your parameters conform to the json format", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
if httpReq.CollectionName == "" {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "collectionName is required."})
|
||||
return
|
||||
}
|
||||
coll, err := h.describeCollection(c, httpReq.DbName, httpReq.CollectionName, false)
|
||||
if err != nil || coll == nil {
|
||||
return
|
||||
}
|
||||
body, _ := c.Get(gin.BodyBytesKey)
|
||||
filter, err := checkGetPrimaryKey(coll.Schema, gjson.Get(string(body.([]byte)), "id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "make sure the collection's primary field", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
req := milvuspb.DeleteRequest{
|
||||
CollectionName: httpReq.CollectionName,
|
||||
Expr: filter,
|
||||
}
|
||||
username, _ := c.Get(ContextUsername)
|
||||
_, authErr := proxy.PrivilegeInterceptorWithUsername(c, username.(string), &req)
|
||||
if authErr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusUnauthorized, HTTPReturnMessage: authErr.Error()})
|
||||
return
|
||||
}
|
||||
response, err := h.proxy.Delete(c, &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "delete fail", HTTPReturnError: err.Error()})
|
||||
} else if response.Status.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: response.Status.ErrorCode, HTTPReturnMessage: "delete fail", HTTPReturnError: response.Status.Reason})
|
||||
} else {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnData: gin.H{}})
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handlers) insert(c *gin.Context) {
|
||||
httpReq := InsertReq{
|
||||
DbName: DefaultDbName,
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&httpReq, binding.JSON); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "check your parameters conform to the json format", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
if httpReq.CollectionName == "" {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "collectionName is required."})
|
||||
return
|
||||
}
|
||||
coll, err := h.describeCollection(c, httpReq.DbName, httpReq.CollectionName, false)
|
||||
if err != nil || coll == nil {
|
||||
return
|
||||
}
|
||||
body, _ := c.Get(gin.BodyBytesKey)
|
||||
err = checkAndSetData(string(body.([]byte)), coll, &httpReq)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "checkout your params", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
req := milvuspb.InsertRequest{
|
||||
CollectionName: httpReq.CollectionName,
|
||||
PartitionName: "_default",
|
||||
NumRows: uint32(len(httpReq.Data)),
|
||||
}
|
||||
req.FieldsData, err = anyToColumns(httpReq.Data, coll.Schema)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "insert data by column wrong", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
username, _ := c.Get(ContextUsername)
|
||||
_, authErr := proxy.PrivilegeInterceptorWithUsername(c, username.(string), &req)
|
||||
if authErr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusUnauthorized, HTTPReturnMessage: authErr.Error()})
|
||||
return
|
||||
}
|
||||
response, err := h.proxy.Insert(c, &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "insert fail", HTTPReturnError: err.Error()})
|
||||
} else if response.Status.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: response.Status.ErrorCode, HTTPReturnMessage: "insert fail", HTTPReturnError: response.Status.Reason})
|
||||
} else {
|
||||
switch response.IDs.GetIdField().(type) {
|
||||
case *schemapb.IDs_IntId:
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnData: gin.H{"insertCount": response.InsertCnt, "insertIds": response.IDs.IdField.(*schemapb.IDs_IntId).IntId.Data}})
|
||||
case *schemapb.IDs_StrId:
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnData: gin.H{"insertCount": response.InsertCnt, "insertIds": response.IDs.IdField.(*schemapb.IDs_StrId).StrId.Data}})
|
||||
default:
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "ids' type neither int or string"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handlers) search(c *gin.Context) {
|
||||
httpReq := SearchReq{
|
||||
DbName: DefaultDbName,
|
||||
Limit: 100,
|
||||
}
|
||||
if err := c.ShouldBindBodyWith(&httpReq, binding.JSON); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "check your parameters conform to the json format", HTTPReturnError: err.Error()})
|
||||
return
|
||||
}
|
||||
if httpReq.CollectionName == "" {
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "collectionName is required."})
|
||||
return
|
||||
}
|
||||
|
||||
searchParams := []*commonpb.KeyValuePair{
|
||||
{Key: common.TopKKey, Value: strconv.FormatInt(int64(httpReq.Limit), 10)},
|
||||
{Key: ParamRoundDecimal, Value: "-1"},
|
||||
{Key: ParamOffset, Value: strconv.FormatInt(int64(httpReq.Offset), 10)},
|
||||
}
|
||||
req := milvuspb.SearchRequest{
|
||||
CollectionName: httpReq.CollectionName,
|
||||
Dsl: httpReq.Filter,
|
||||
PlaceholderGroup: vector2PlaceholderGroupBytes(httpReq.Vector),
|
||||
DslType: commonpb.DslType_BoolExprV1,
|
||||
OutputFields: httpReq.OutputFields,
|
||||
SearchParams: searchParams,
|
||||
GuaranteeTimestamp: BoundedTimestamp,
|
||||
Nq: int64(1),
|
||||
}
|
||||
username, _ := c.Get(ContextUsername)
|
||||
_, authErr := proxy.PrivilegeInterceptorWithUsername(c, username.(string), &req)
|
||||
if authErr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusUnauthorized, HTTPReturnMessage: authErr.Error()})
|
||||
return
|
||||
}
|
||||
response, err := h.proxy.Search(c, &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "search fail", HTTPReturnError: err.Error()})
|
||||
} else if response.Status.ErrorCode != commonpb.ErrorCode_Success {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: response.Status.ErrorCode, HTTPReturnMessage: "search fail", HTTPReturnError: response.Status.Reason})
|
||||
} else {
|
||||
outputData, err := buildQueryResp(response.Results.TopK, response.Results.OutputFields, response.Results.FieldsData, response.Results.Scores)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusBadRequest, HTTPReturnMessage: "show result by row wrong", HTTPReturnError: err.Error()})
|
||||
} else {
|
||||
c.JSON(http.StatusOK, gin.H{HTTPReturnCode: http.StatusOK, HTTPReturnData: outputData})
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,54 @@
|
|||
package httpserver
|
||||
|
||||
type CreateCollectionReq struct {
|
||||
DbName string `json:"dbName"`
|
||||
CollectionName string `json:"collectionName" validate:"required"`
|
||||
Dimension int32 `json:"dimension" validate:"required"`
|
||||
Description string `json:"description"`
|
||||
MetricType string `json:"metricType"`
|
||||
PrimaryField string `json:"primaryField"`
|
||||
VectorField string `json:"vectorField"`
|
||||
}
|
||||
|
||||
type DropCollectionReq struct {
|
||||
DbName string `json:"dbName"`
|
||||
CollectionName string `json:"collectionName" validate:"required"`
|
||||
}
|
||||
|
||||
type QueryReq struct {
|
||||
DbName string `json:"dbName"`
|
||||
CollectionName string `json:"collectionName" validate:"required"`
|
||||
OutputFields []string `json:"outputFields"`
|
||||
Filter string `json:"filter" validate:"required"`
|
||||
Limit int32 `json:"limit"`
|
||||
Offset int32 `json:"offset"`
|
||||
}
|
||||
|
||||
type GetReq struct {
|
||||
DbName string `json:"dbName"`
|
||||
CollectionName string `json:"collectionName" validate:"required"`
|
||||
OutputFields []string `json:"outputFields"`
|
||||
ID interface{} `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
type DeleteReq struct {
|
||||
DbName string `json:"dbName"`
|
||||
CollectionName string `json:"collectionName" validate:"required"`
|
||||
ID interface{} `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
type InsertReq struct {
|
||||
DbName string `json:"dbName"`
|
||||
CollectionName string `json:"collectionName" validate:"required"`
|
||||
Data []map[string]interface{} `json:"data" validate:"required"`
|
||||
}
|
||||
|
||||
type SearchReq struct {
|
||||
DbName string `json:"dbName"`
|
||||
CollectionName string `json:"collectionName" validate:"required"`
|
||||
Filter string `json:"filter"`
|
||||
Limit int32 `json:"limit"`
|
||||
Offset int32 `json:"offset"`
|
||||
OutputFields []string `json:"outputFields"`
|
||||
Vector []float32 `json:"vector"`
|
||||
}
|
|
@ -0,0 +1,829 @@
|
|||
package httpserver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/common"
|
||||
"github.com/milvus-io/milvus/internal/log"
|
||||
"github.com/milvus-io/milvus/internal/util/funcutil"
|
||||
)
|
||||
|
||||
func ParseUsernamePassword(c *gin.Context) (string, string, bool) {
|
||||
username, password, ok := c.Request.BasicAuth()
|
||||
if !ok {
|
||||
auth := c.Request.Header.Get("Authorization")
|
||||
if auth != "" {
|
||||
token := strings.TrimPrefix(auth, "Bearer ")
|
||||
if token != auth {
|
||||
i := strings.IndexAny(token, ":")
|
||||
if i != -1 {
|
||||
username = token[:i]
|
||||
password = token[i+1:]
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
c.Header("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
|
||||
}
|
||||
return username, password, username != "" && password != ""
|
||||
}
|
||||
|
||||
// find the primary field of collection
|
||||
func getPrimaryField(schema *schemapb.CollectionSchema) (*schemapb.FieldSchema, bool) {
|
||||
for _, field := range schema.Fields {
|
||||
if field.IsPrimaryKey {
|
||||
return field, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func joinArray(data interface{}) string {
|
||||
var buffer bytes.Buffer
|
||||
arr := reflect.ValueOf(data)
|
||||
|
||||
for i := 0; i < arr.Len(); i++ {
|
||||
if i > 0 {
|
||||
buffer.WriteString(",")
|
||||
}
|
||||
|
||||
buffer.WriteString(fmt.Sprintf("%v", arr.Index(i)))
|
||||
}
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func convertRange(field *schemapb.FieldSchema, result gjson.Result) (string, error) {
|
||||
var resultStr string
|
||||
fieldType := field.DataType
|
||||
|
||||
if fieldType == schemapb.DataType_Int64 {
|
||||
var dataArray []int64
|
||||
for _, data := range result.Array() {
|
||||
if data.Type == gjson.String {
|
||||
value, err := cast.ToInt64E(data.Str)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
dataArray = append(dataArray, value)
|
||||
} else {
|
||||
value, err := cast.ToInt64E(data.Raw)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
dataArray = append(dataArray, value)
|
||||
}
|
||||
}
|
||||
resultStr = joinArray(dataArray)
|
||||
} else if fieldType == schemapb.DataType_VarChar {
|
||||
var dataArray []string
|
||||
for _, data := range result.Array() {
|
||||
value, err := cast.ToStringE(data.Str)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
dataArray = append(dataArray, value)
|
||||
}
|
||||
resultStr = joinArray(dataArray)
|
||||
}
|
||||
return resultStr, nil
|
||||
}
|
||||
|
||||
// generate the expression: $primaryFieldName in [1,2,3]
|
||||
func checkGetPrimaryKey(coll *schemapb.CollectionSchema, idResult gjson.Result) (string, error) {
|
||||
primaryField, ok := getPrimaryField(coll)
|
||||
if !ok {
|
||||
return "", errors.New("fail to find primary key from collection description")
|
||||
}
|
||||
resultStr, err := convertRange(primaryField, idResult)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
filter := primaryField.Name + " in [" + resultStr + "]"
|
||||
return filter, nil
|
||||
}
|
||||
|
||||
// --------------------- collection details --------------------- //
|
||||
func printFields(fields []*schemapb.FieldSchema) []gin.H {
|
||||
var res []gin.H
|
||||
for _, field := range fields {
|
||||
res = append(res, gin.H{
|
||||
HTTPReturnFieldName: field.Name,
|
||||
HTTPReturnFieldType: field.DataType.String(),
|
||||
HTTPReturnFieldPrimaryKey: field.IsPrimaryKey,
|
||||
HTTPReturnFieldAutoID: field.AutoID,
|
||||
HTTPReturnDescription: field.Description,
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func getMetricType(pairs []*commonpb.KeyValuePair) string {
|
||||
metricType := DefaultMetricType
|
||||
for _, pair := range pairs {
|
||||
if pair.Key == common.MetricTypeKey {
|
||||
metricType = pair.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
return metricType
|
||||
}
|
||||
|
||||
func printIndexes(indexes []*milvuspb.IndexDescription) []gin.H {
|
||||
var res []gin.H
|
||||
for _, index := range indexes {
|
||||
res = append(res, gin.H{
|
||||
HTTPReturnIndexName: index.IndexName,
|
||||
HTTPReturnIndexField: index.FieldName,
|
||||
HTTPReturnIndexMetricsType: getMetricType(index.Params),
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// --------------------- insert param --------------------- //
|
||||
|
||||
func checkAndSetData(body string, collDescResp *milvuspb.DescribeCollectionResponse, req *InsertReq) error {
|
||||
var reallyDataArray []map[string]interface{}
|
||||
dataResult := gjson.Get(body, "data")
|
||||
dataResultArray := dataResult.Array()
|
||||
if len(dataResultArray) == 0 {
|
||||
return errors.New("data is required")
|
||||
}
|
||||
|
||||
var fieldNames []string
|
||||
for _, field := range collDescResp.Schema.Fields {
|
||||
fieldNames = append(fieldNames, field.Name)
|
||||
}
|
||||
|
||||
for _, data := range dataResultArray {
|
||||
reallyData := map[string]interface{}{}
|
||||
var vectorArray []float32
|
||||
var binaryArray []byte
|
||||
if data.Type == gjson.JSON {
|
||||
for _, field := range collDescResp.Schema.Fields {
|
||||
fieldType := field.DataType
|
||||
fieldName := field.Name
|
||||
|
||||
dataString := gjson.Get(data.Raw, fieldName).String()
|
||||
|
||||
if field.IsPrimaryKey && collDescResp.Schema.AutoID {
|
||||
if dataString != "" {
|
||||
return fmt.Errorf("fieldName %s AutoId already open, not support insert data %s", fieldName, dataString)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
switch fieldType {
|
||||
case schemapb.DataType_FloatVector:
|
||||
for _, vector := range gjson.Get(data.Raw, fieldName).Array() {
|
||||
vectorArray = append(vectorArray, cast.ToFloat32(vector.Num))
|
||||
}
|
||||
reallyData[fieldName] = vectorArray
|
||||
case schemapb.DataType_BinaryVector:
|
||||
for _, vector := range gjson.Get(data.Raw, fieldName).Array() {
|
||||
binaryArray = append(binaryArray, cast.ToUint8(vector.Num))
|
||||
}
|
||||
reallyData[fieldName] = binaryArray
|
||||
case schemapb.DataType_Bool:
|
||||
result, err := cast.ToBoolE(dataString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dataString %s cast to bool error: %s", dataString, err.Error())
|
||||
}
|
||||
reallyData[fieldName] = result
|
||||
case schemapb.DataType_Int8:
|
||||
result, err := cast.ToInt8E(dataString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dataString %s cast to int8 error: %s", dataString, err.Error())
|
||||
}
|
||||
reallyData[fieldName] = result
|
||||
case schemapb.DataType_Int16:
|
||||
result, err := cast.ToInt16E(dataString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dataString %s cast to int16 error: %s", dataString, err.Error())
|
||||
}
|
||||
reallyData[fieldName] = result
|
||||
case schemapb.DataType_Int32:
|
||||
result, err := cast.ToInt32E(dataString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dataString %s cast to int32 error: %s", dataString, err.Error())
|
||||
}
|
||||
reallyData[fieldName] = result
|
||||
case schemapb.DataType_Int64:
|
||||
result, err := cast.ToInt64E(dataString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dataString %s cast to int64 error: %s", dataString, err.Error())
|
||||
}
|
||||
reallyData[fieldName] = result
|
||||
case schemapb.DataType_JSON:
|
||||
reallyData[fieldName] = []byte(dataString)
|
||||
case schemapb.DataType_Float:
|
||||
result, err := cast.ToFloat32E(dataString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dataString %s cast to float32 error: %s", dataString, err.Error())
|
||||
}
|
||||
reallyData[fieldName] = result
|
||||
case schemapb.DataType_Double:
|
||||
result, err := cast.ToFloat64E(dataString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dataString %s cast to float64 error: %s", dataString, err.Error())
|
||||
}
|
||||
reallyData[fieldName] = result
|
||||
case schemapb.DataType_VarChar:
|
||||
reallyData[fieldName] = dataString
|
||||
case schemapb.DataType_String:
|
||||
reallyData[fieldName] = dataString
|
||||
default:
|
||||
return fmt.Errorf("not support fieldName %s dataType %s", fieldName, fieldType)
|
||||
}
|
||||
}
|
||||
|
||||
// fill dynamic schema
|
||||
if collDescResp.Schema.EnableDynamicField {
|
||||
for mapKey, mapValue := range data.Map() {
|
||||
if !containsString(fieldNames, mapKey) {
|
||||
mapValueStr := mapValue.String()
|
||||
if mapValue.Type == gjson.True || mapValue.Type == gjson.False {
|
||||
reallyData[mapKey] = cast.ToBool(mapValueStr)
|
||||
} else if mapValue.Type == gjson.String {
|
||||
reallyData[mapKey] = mapValueStr
|
||||
} else if mapValue.Type == gjson.Number {
|
||||
if strings.Contains(mapValue.Raw, ".") {
|
||||
reallyData[mapKey] = cast.ToFloat64(mapValue.Raw)
|
||||
} else {
|
||||
reallyData[mapKey] = cast.ToInt64(mapValueStr)
|
||||
}
|
||||
} else if mapValue.Type == gjson.JSON {
|
||||
reallyData[mapKey] = mapValue.Value()
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reallyDataArray = append(reallyDataArray, reallyData)
|
||||
} else {
|
||||
return fmt.Errorf("dataType %s not Json", data.Type)
|
||||
}
|
||||
}
|
||||
req.Data = reallyDataArray
|
||||
return nil
|
||||
}
|
||||
|
||||
func containsString(arr []string, s string) bool {
|
||||
for _, str := range arr {
|
||||
if str == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getDim(field *schemapb.FieldSchema) (int64, error) {
|
||||
dimensionInSchema, err := funcutil.GetAttrByKeyFromRepeatedKV(common.DimKey, field.TypeParams)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
dim, err := strconv.Atoi(dimensionInSchema)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int64(dim), nil
|
||||
}
|
||||
|
||||
func convertFloatVectorToArray(vector [][]float32, dim int64) ([]float32, error) {
|
||||
floatArray := make([]float32, 0)
|
||||
for _, arr := range vector {
|
||||
if int64(len(arr)) != dim {
|
||||
return nil, errors.New("vector length diff from dimension")
|
||||
}
|
||||
for i := int64(0); i < dim; i++ {
|
||||
floatArray = append(floatArray, arr[i])
|
||||
}
|
||||
}
|
||||
return floatArray, nil
|
||||
}
|
||||
|
||||
func convertBinaryVectorToArray(vector [][]byte, dim int64) ([]byte, error) {
|
||||
binaryArray := make([]byte, 0)
|
||||
bytesLen := dim / 8
|
||||
for _, arr := range vector {
|
||||
if int64(len(arr)) != bytesLen {
|
||||
return nil, errors.New("vector length diff from dimension")
|
||||
}
|
||||
for i := int64(0); i < bytesLen; i++ {
|
||||
binaryArray = append(binaryArray, arr[i])
|
||||
}
|
||||
}
|
||||
return binaryArray, nil
|
||||
}
|
||||
|
||||
type fieldCandi struct {
|
||||
name string
|
||||
v reflect.Value
|
||||
options map[string]string
|
||||
}
|
||||
|
||||
func reflectValueCandi(v reflect.Value) (map[string]fieldCandi, error) {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
result := make(map[string]fieldCandi)
|
||||
switch v.Kind() {
|
||||
case reflect.Map: // map[string]interface{}
|
||||
iter := v.MapRange()
|
||||
for iter.Next() {
|
||||
key := iter.Key().String()
|
||||
result[key] = fieldCandi{
|
||||
name: key,
|
||||
v: iter.Value(),
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupport row type: %s", v.Kind().String())
|
||||
}
|
||||
}
|
||||
|
||||
func convertToIntArray(dataType schemapb.DataType, arr interface{}) []int32 {
|
||||
var res []int32
|
||||
switch dataType {
|
||||
case schemapb.DataType_Int8:
|
||||
for _, num := range arr.([]int8) {
|
||||
res = append(res, int32(num))
|
||||
}
|
||||
case schemapb.DataType_Int16:
|
||||
for _, num := range arr.([]int16) {
|
||||
res = append(res, int32(num))
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func anyToColumns(rows []map[string]interface{}, sch *schemapb.CollectionSchema) ([]*schemapb.FieldData, error) {
|
||||
rowsLen := len(rows)
|
||||
if rowsLen == 0 {
|
||||
return []*schemapb.FieldData{}, errors.New("0 length column")
|
||||
}
|
||||
|
||||
isDynamic := sch.EnableDynamicField
|
||||
var dim int64
|
||||
|
||||
nameColumns := make(map[string]interface{})
|
||||
fieldData := make(map[string]*schemapb.FieldData)
|
||||
for _, field := range sch.Fields {
|
||||
// skip auto id pk field
|
||||
if field.IsPrimaryKey && field.AutoID {
|
||||
continue
|
||||
}
|
||||
var data interface{}
|
||||
switch field.DataType {
|
||||
case schemapb.DataType_Bool:
|
||||
data = make([]bool, 0, rowsLen)
|
||||
case schemapb.DataType_Int8:
|
||||
data = make([]int8, 0, rowsLen)
|
||||
case schemapb.DataType_Int16:
|
||||
data = make([]int16, 0, rowsLen)
|
||||
case schemapb.DataType_Int32:
|
||||
data = make([]int32, 0, rowsLen)
|
||||
case schemapb.DataType_Int64:
|
||||
data = make([]int64, 0, rowsLen)
|
||||
case schemapb.DataType_Float:
|
||||
data = make([]float32, 0, rowsLen)
|
||||
case schemapb.DataType_Double:
|
||||
data = make([]float64, 0, rowsLen)
|
||||
case schemapb.DataType_String:
|
||||
data = make([]string, 0, rowsLen)
|
||||
case schemapb.DataType_VarChar:
|
||||
data = make([]string, 0, rowsLen)
|
||||
case schemapb.DataType_JSON:
|
||||
data = make([][]byte, 0, rowsLen)
|
||||
case schemapb.DataType_FloatVector:
|
||||
data = make([][]float32, 0, rowsLen)
|
||||
dim, _ = getDim(field)
|
||||
case schemapb.DataType_BinaryVector:
|
||||
data = make([][]byte, 0, rowsLen)
|
||||
dim, _ = getDim(field)
|
||||
default:
|
||||
return nil, fmt.Errorf("the type(%v) of field(%v) is not supported, use other sdk please", field.DataType, field.Name)
|
||||
}
|
||||
nameColumns[field.Name] = data
|
||||
fieldData[field.Name] = &schemapb.FieldData{
|
||||
Type: field.DataType,
|
||||
FieldName: field.Name,
|
||||
FieldId: field.FieldID,
|
||||
IsDynamic: field.IsDynamic,
|
||||
}
|
||||
}
|
||||
if dim == 0 {
|
||||
return nil, errors.New("cannot find dimension")
|
||||
}
|
||||
|
||||
dynamicFieldName := ""
|
||||
dynamicCol := make([][]byte, 0, rowsLen)
|
||||
|
||||
for _, row := range rows {
|
||||
// collection schema name need not be same, since receiver could have other names
|
||||
v := reflect.ValueOf(row)
|
||||
set, err := reflectValueCandi(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for idx, field := range sch.Fields {
|
||||
// skip dynamic field if visible
|
||||
if isDynamic && field.IsDynamic {
|
||||
dynamicFieldName = field.Name
|
||||
continue
|
||||
}
|
||||
// skip auto id pk field
|
||||
if field.IsPrimaryKey && field.AutoID {
|
||||
// remove pk field from candidates set, avoid adding it into dynamic column
|
||||
delete(set, field.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
candi, ok := set[field.Name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("row %d does not has field %s", idx, field.Name)
|
||||
}
|
||||
switch field.DataType {
|
||||
case schemapb.DataType_Bool:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([]bool), candi.v.Interface().(bool))
|
||||
case schemapb.DataType_Int8:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([]int8), candi.v.Interface().(int8))
|
||||
case schemapb.DataType_Int16:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([]int16), candi.v.Interface().(int16))
|
||||
case schemapb.DataType_Int32:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([]int32), candi.v.Interface().(int32))
|
||||
case schemapb.DataType_Int64:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([]int64), candi.v.Interface().(int64))
|
||||
case schemapb.DataType_Float:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([]float32), candi.v.Interface().(float32))
|
||||
case schemapb.DataType_Double:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([]float64), candi.v.Interface().(float64))
|
||||
case schemapb.DataType_String:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([]string), candi.v.Interface().(string))
|
||||
case schemapb.DataType_VarChar:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([]string), candi.v.Interface().(string))
|
||||
case schemapb.DataType_JSON:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([][]byte), candi.v.Interface().([]byte))
|
||||
case schemapb.DataType_FloatVector:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([][]float32), candi.v.Interface().([]float32))
|
||||
case schemapb.DataType_BinaryVector:
|
||||
nameColumns[field.Name] = append(nameColumns[field.Name].([][]byte), candi.v.Interface().([]byte))
|
||||
default:
|
||||
return nil, fmt.Errorf("the type(%v) of field(%v) is not supported, use other sdk please", field.DataType, field.Name)
|
||||
}
|
||||
|
||||
delete(set, field.Name)
|
||||
}
|
||||
|
||||
if isDynamic && dynamicFieldName != "" {
|
||||
m := make(map[string]interface{})
|
||||
for name, candi := range set {
|
||||
m[name] = candi.v.Interface()
|
||||
}
|
||||
bs, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal dynamic field %w", err)
|
||||
}
|
||||
dynamicCol = append(dynamicCol, bs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to append value to dynamic field %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
columns := make([]*schemapb.FieldData, 0, len(nameColumns))
|
||||
for name, column := range nameColumns {
|
||||
colData := fieldData[name]
|
||||
switch colData.Type {
|
||||
case schemapb.DataType_Bool:
|
||||
colData.Field = &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_BoolData{
|
||||
BoolData: &schemapb.BoolArray{
|
||||
Data: column.([]bool),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_Int8:
|
||||
colData.Field = &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_IntData{
|
||||
IntData: &schemapb.IntArray{
|
||||
Data: convertToIntArray(colData.Type, column),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_Int16:
|
||||
colData.Field = &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_IntData{
|
||||
IntData: &schemapb.IntArray{
|
||||
Data: convertToIntArray(colData.Type, column),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_Int32:
|
||||
colData.Field = &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_IntData{
|
||||
IntData: &schemapb.IntArray{
|
||||
Data: column.([]int32),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_Int64:
|
||||
colData.Field = &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_LongData{
|
||||
LongData: &schemapb.LongArray{
|
||||
Data: column.([]int64),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_Float:
|
||||
colData.Field = &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_FloatData{
|
||||
FloatData: &schemapb.FloatArray{
|
||||
Data: column.([]float32),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_Double:
|
||||
colData.Field = &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_DoubleData{
|
||||
DoubleData: &schemapb.DoubleArray{
|
||||
Data: column.([]float64),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_String:
|
||||
colData.Field = &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_StringData{
|
||||
StringData: &schemapb.StringArray{
|
||||
Data: column.([]string),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_VarChar:
|
||||
colData.Field = &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_StringData{
|
||||
StringData: &schemapb.StringArray{
|
||||
Data: column.([]string),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_JSON:
|
||||
colData.Field = &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_BytesData{
|
||||
BytesData: &schemapb.BytesArray{
|
||||
Data: column.([][]byte),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_FloatVector:
|
||||
arr, err := convertFloatVectorToArray(column.([][]float32), dim)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
colData.Field = &schemapb.FieldData_Vectors{
|
||||
Vectors: &schemapb.VectorField{
|
||||
Dim: dim,
|
||||
Data: &schemapb.VectorField_FloatVector{
|
||||
FloatVector: &schemapb.FloatArray{
|
||||
Data: arr,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
case schemapb.DataType_BinaryVector:
|
||||
arr, err := convertBinaryVectorToArray(column.([][]byte), dim)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
colData.Field = &schemapb.FieldData_Vectors{
|
||||
Vectors: &schemapb.VectorField{
|
||||
Dim: dim,
|
||||
Data: &schemapb.VectorField_BinaryVector{
|
||||
BinaryVector: arr,
|
||||
},
|
||||
},
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("the type(%v) of field(%v) is not supported, use other sdk please", colData.Type, name)
|
||||
}
|
||||
columns = append(columns, colData)
|
||||
}
|
||||
if isDynamic && dynamicFieldName != "" {
|
||||
columns = append(columns, &schemapb.FieldData{
|
||||
Type: fieldData[dynamicFieldName].Type,
|
||||
FieldName: dynamicFieldName,
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_JsonData{
|
||||
JsonData: &schemapb.JSONArray{
|
||||
Data: dynamicCol,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
FieldId: fieldData[dynamicFieldName].FieldId,
|
||||
IsDynamic: true,
|
||||
})
|
||||
}
|
||||
return columns, nil
|
||||
}
|
||||
|
||||
// --------------------- search param --------------------- //
|
||||
func serialize(fv []float32) []byte {
|
||||
data := make([]byte, 0, 4*len(fv)) // float32 occupies 4 bytes
|
||||
buf := make([]byte, 4)
|
||||
for _, f := range fv {
|
||||
binary.LittleEndian.PutUint32(buf, math.Float32bits(f))
|
||||
data = append(data, buf...)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func vector2PlaceholderGroupBytes(vectors []float32) []byte {
|
||||
var placeHolderType commonpb.PlaceholderType
|
||||
ph := &commonpb.PlaceholderValue{
|
||||
Tag: "$0",
|
||||
Values: make([][]byte, 0, len(vectors)),
|
||||
}
|
||||
if len(vectors) != 0 {
|
||||
placeHolderType = commonpb.PlaceholderType_FloatVector
|
||||
|
||||
ph.Type = placeHolderType
|
||||
ph.Values = append(ph.Values, serialize(vectors))
|
||||
}
|
||||
phg := &commonpb.PlaceholderGroup{
|
||||
Placeholders: []*commonpb.PlaceholderValue{
|
||||
ph,
|
||||
},
|
||||
}
|
||||
|
||||
bs, _ := proto.Marshal(phg)
|
||||
return bs
|
||||
}
|
||||
|
||||
// --------------------- get/query/search response --------------------- //
|
||||
func genDynamicFields(fields []string, list []*schemapb.FieldData) []string {
|
||||
nonDynamicFieldNames := make(map[string]struct{})
|
||||
for _, field := range list {
|
||||
if !field.IsDynamic {
|
||||
nonDynamicFieldNames[field.FieldName] = struct{}{}
|
||||
}
|
||||
}
|
||||
dynamicFields := []string{}
|
||||
for _, fieldName := range fields {
|
||||
if _, exist := nonDynamicFieldNames[fieldName]; !exist {
|
||||
dynamicFields = append(dynamicFields, fieldName)
|
||||
}
|
||||
}
|
||||
return dynamicFields
|
||||
}
|
||||
|
||||
func buildQueryResp(rowsNum int64, needFields []string, fieldDataList []*schemapb.FieldData, scores []float32) ([]map[string]interface{}, error) {
|
||||
dynamicOutputFields := genDynamicFields(needFields, fieldDataList)
|
||||
if len(fieldDataList) == 0 {
|
||||
return []map[string]interface{}{}, nil
|
||||
}
|
||||
|
||||
var queryResp []map[string]interface{}
|
||||
|
||||
columnNum := len(fieldDataList)
|
||||
if rowsNum == int64(0) {
|
||||
switch fieldDataList[0].Type {
|
||||
case schemapb.DataType_Bool:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetBoolData().Data))
|
||||
case schemapb.DataType_Int8:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetIntData().Data))
|
||||
case schemapb.DataType_Int16:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetIntData().Data))
|
||||
case schemapb.DataType_Int32:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetIntData().Data))
|
||||
case schemapb.DataType_Int64:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetLongData().Data))
|
||||
case schemapb.DataType_Float:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetFloatData().Data))
|
||||
case schemapb.DataType_Double:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetDoubleData().Data))
|
||||
case schemapb.DataType_String:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetStringData().Data))
|
||||
case schemapb.DataType_VarChar:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetStringData().Data))
|
||||
case schemapb.DataType_JSON:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetJsonData().Data))
|
||||
case schemapb.DataType_Array:
|
||||
rowsNum = int64(len(fieldDataList[0].GetScalars().GetArrayData().Data))
|
||||
case schemapb.DataType_BinaryVector:
|
||||
rowsNum = int64(len(fieldDataList[0].GetVectors().GetBinaryVector())*8) / fieldDataList[0].GetVectors().GetDim()
|
||||
case schemapb.DataType_FloatVector:
|
||||
rowsNum = int64(len(fieldDataList[0].GetVectors().GetFloatVector().Data)) / fieldDataList[0].GetVectors().GetDim()
|
||||
default:
|
||||
return nil, fmt.Errorf("the type(%v) of field(%v) is not supported, use other sdk please", fieldDataList[0].Type, fieldDataList[0].FieldName)
|
||||
}
|
||||
}
|
||||
for i := int64(0); i < rowsNum; i++ {
|
||||
row := map[string]interface{}{}
|
||||
for j := 0; j < columnNum; j++ {
|
||||
switch fieldDataList[j].Type {
|
||||
case schemapb.DataType_Bool:
|
||||
row[fieldDataList[j].FieldName] = fieldDataList[j].GetScalars().GetBoolData().Data[i]
|
||||
case schemapb.DataType_Int8:
|
||||
row[fieldDataList[j].FieldName] = int8(fieldDataList[j].GetScalars().GetIntData().Data[i])
|
||||
case schemapb.DataType_Int16:
|
||||
row[fieldDataList[j].FieldName] = int16(fieldDataList[j].GetScalars().GetIntData().Data[i])
|
||||
case schemapb.DataType_Int32:
|
||||
row[fieldDataList[j].FieldName] = fieldDataList[j].GetScalars().GetIntData().Data[i]
|
||||
case schemapb.DataType_Int64:
|
||||
row[fieldDataList[j].FieldName] = fieldDataList[j].GetScalars().GetLongData().Data[i]
|
||||
case schemapb.DataType_Float:
|
||||
row[fieldDataList[j].FieldName] = fieldDataList[j].GetScalars().GetFloatData().Data[i]
|
||||
case schemapb.DataType_Double:
|
||||
row[fieldDataList[j].FieldName] = fieldDataList[j].GetScalars().GetDoubleData().Data[i]
|
||||
case schemapb.DataType_String:
|
||||
row[fieldDataList[j].FieldName] = fieldDataList[j].GetScalars().GetStringData().Data[i]
|
||||
case schemapb.DataType_VarChar:
|
||||
row[fieldDataList[j].FieldName] = fieldDataList[j].GetScalars().GetStringData().Data[i]
|
||||
case schemapb.DataType_BinaryVector:
|
||||
row[fieldDataList[j].FieldName] = fieldDataList[j].GetVectors().GetBinaryVector()[i*(fieldDataList[j].GetVectors().GetDim()/8) : (i+1)*(fieldDataList[j].GetVectors().GetDim()/8)]
|
||||
case schemapb.DataType_FloatVector:
|
||||
row[fieldDataList[j].FieldName] = fieldDataList[j].GetVectors().GetFloatVector().Data[i*fieldDataList[j].GetVectors().GetDim() : (i+1)*fieldDataList[j].GetVectors().GetDim()]
|
||||
case schemapb.DataType_Array:
|
||||
row[fieldDataList[j].FieldName] = fieldDataList[j].GetScalars().GetArrayData().Data[i]
|
||||
case schemapb.DataType_JSON:
|
||||
data, ok := fieldDataList[j].GetScalars().Data.(*schemapb.ScalarField_JsonData)
|
||||
if ok && !fieldDataList[j].IsDynamic {
|
||||
row[fieldDataList[j].FieldName] = data.JsonData.Data[i]
|
||||
} else {
|
||||
var dataMap map[string]interface{}
|
||||
|
||||
err := json.Unmarshal(fieldDataList[j].GetScalars().GetJsonData().Data[i], &dataMap)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("[BuildQueryResp] Unmarshal error %s", err.Error()))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if containsString(dynamicOutputFields, fieldDataList[j].FieldName) {
|
||||
for key, value := range dataMap {
|
||||
row[key] = value
|
||||
}
|
||||
} else {
|
||||
for _, dynamicField := range dynamicOutputFields {
|
||||
if _, ok := dataMap[dynamicField]; ok {
|
||||
row[dynamicField] = dataMap[dynamicField]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
default:
|
||||
row[fieldDataList[j].FieldName] = ""
|
||||
}
|
||||
}
|
||||
if scores != nil && int64(len(scores)) == rowsNum {
|
||||
row[HTTPReturnDistance] = scores[i]
|
||||
}
|
||||
queryResp = append(queryResp, row)
|
||||
}
|
||||
|
||||
return queryResp, nil
|
||||
}
|
|
@ -0,0 +1,751 @@
|
|||
package httpserver
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
const (
|
||||
FieldWordCount = "word_count"
|
||||
FieldBookID = "book_id"
|
||||
FieldBookIntro = "book_intro"
|
||||
)
|
||||
|
||||
func generatePrimaryField(datatype schemapb.DataType) schemapb.FieldSchema {
|
||||
return schemapb.FieldSchema{
|
||||
FieldID: common.StartOfUserFieldID,
|
||||
Name: FieldBookID,
|
||||
IsPrimaryKey: true,
|
||||
Description: "",
|
||||
DataType: datatype,
|
||||
AutoID: false,
|
||||
}
|
||||
}
|
||||
|
||||
func generateVectorFieldSchema(useBinary bool) schemapb.FieldSchema {
|
||||
if useBinary {
|
||||
return schemapb.FieldSchema{
|
||||
FieldID: common.StartOfUserFieldID + 2,
|
||||
Name: "field-binary",
|
||||
IsPrimaryKey: false,
|
||||
Description: "",
|
||||
DataType: 100,
|
||||
AutoID: false,
|
||||
TypeParams: []*commonpb.KeyValuePair{
|
||||
{
|
||||
Key: common.DimKey,
|
||||
Value: "8",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return schemapb.FieldSchema{
|
||||
FieldID: common.StartOfUserFieldID + 2,
|
||||
Name: FieldBookIntro,
|
||||
IsPrimaryKey: false,
|
||||
Description: "",
|
||||
DataType: 101,
|
||||
AutoID: false,
|
||||
TypeParams: []*commonpb.KeyValuePair{
|
||||
{
|
||||
Key: common.DimKey,
|
||||
Value: "2",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func generateCollectionSchema(useBinary bool) *schemapb.CollectionSchema {
|
||||
primaryField := generatePrimaryField(schemapb.DataType_Int64)
|
||||
vectorField := generateVectorFieldSchema(useBinary)
|
||||
return &schemapb.CollectionSchema{
|
||||
Name: DefaultCollectionName,
|
||||
Description: "",
|
||||
AutoID: false,
|
||||
Fields: []*schemapb.FieldSchema{
|
||||
&primaryField, {
|
||||
FieldID: common.StartOfUserFieldID + 1,
|
||||
Name: FieldWordCount,
|
||||
IsPrimaryKey: false,
|
||||
Description: "",
|
||||
DataType: 5,
|
||||
AutoID: false,
|
||||
}, &vectorField,
|
||||
},
|
||||
EnableDynamicField: true,
|
||||
}
|
||||
}
|
||||
|
||||
func generateIndexes() []*milvuspb.IndexDescription {
|
||||
return []*milvuspb.IndexDescription{
|
||||
{
|
||||
IndexName: "_default_idx_102",
|
||||
IndexID: 442051985533243300,
|
||||
Params: []*commonpb.KeyValuePair{
|
||||
{
|
||||
Key: common.MetricTypeKey,
|
||||
Value: DefaultMetricType,
|
||||
},
|
||||
{
|
||||
Key: "index_type",
|
||||
Value: "IVF_FLAT",
|
||||
}, {
|
||||
Key: Params,
|
||||
Value: "{\"nlist\":1024}",
|
||||
},
|
||||
},
|
||||
State: 3,
|
||||
FieldName: FieldBookIntro,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func generateVectorFieldData(useBinary bool) schemapb.FieldData {
|
||||
if useBinary {
|
||||
return schemapb.FieldData{
|
||||
Type: schemapb.DataType_BinaryVector,
|
||||
FieldName: "field-binary",
|
||||
Field: &schemapb.FieldData_Vectors{
|
||||
Vectors: &schemapb.VectorField{
|
||||
Dim: 8,
|
||||
Data: &schemapb.VectorField_BinaryVector{
|
||||
BinaryVector: []byte{byte(0), byte(1), byte(2)},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
}
|
||||
return schemapb.FieldData{
|
||||
Type: schemapb.DataType_FloatVector,
|
||||
FieldName: FieldBookIntro,
|
||||
Field: &schemapb.FieldData_Vectors{
|
||||
Vectors: &schemapb.VectorField{
|
||||
Dim: 2,
|
||||
Data: &schemapb.VectorField_FloatVector{
|
||||
FloatVector: &schemapb.FloatArray{
|
||||
Data: []float32{0.1, 0.11, 0.2, 0.22, 0.3, 0.33},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
}
|
||||
|
||||
func generateFieldData() []*schemapb.FieldData {
|
||||
fieldData1 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_Int64,
|
||||
FieldName: FieldBookID,
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_LongData{
|
||||
LongData: &schemapb.LongArray{
|
||||
Data: []int64{1, 2, 3},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
|
||||
fieldData2 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_Int64,
|
||||
FieldName: FieldWordCount,
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_LongData{
|
||||
LongData: &schemapb.LongArray{
|
||||
Data: []int64{1000, 2000, 3000},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
|
||||
fieldData3 := generateVectorFieldData(false)
|
||||
return []*schemapb.FieldData{&fieldData1, &fieldData2, &fieldData3}
|
||||
}
|
||||
|
||||
func generateSearchResult() []map[string]interface{} {
|
||||
row1 := map[string]interface{}{
|
||||
FieldBookID: int64(1),
|
||||
FieldWordCount: int64(1000),
|
||||
FieldBookIntro: []float32{0.1, 0.11},
|
||||
HTTPReturnDistance: float32(0.01),
|
||||
}
|
||||
row2 := map[string]interface{}{
|
||||
FieldBookID: int64(2),
|
||||
FieldWordCount: int64(2000),
|
||||
FieldBookIntro: []float32{0.2, 0.22},
|
||||
HTTPReturnDistance: float32(0.04),
|
||||
}
|
||||
row3 := map[string]interface{}{
|
||||
FieldBookID: int64(3),
|
||||
FieldWordCount: int64(3000),
|
||||
FieldBookIntro: []float32{0.3, 0.33},
|
||||
HTTPReturnDistance: float32(0.09),
|
||||
}
|
||||
return []map[string]interface{}{row1, row2, row3}
|
||||
}
|
||||
|
||||
func generateQueryResult64(withDistance bool) []map[string]interface{} {
|
||||
row1 := map[string]interface{}{
|
||||
FieldBookID: float64(1),
|
||||
FieldWordCount: float64(1000),
|
||||
FieldBookIntro: []float64{0.1, 0.11},
|
||||
}
|
||||
row2 := map[string]interface{}{
|
||||
FieldBookID: float64(2),
|
||||
FieldWordCount: float64(2000),
|
||||
FieldBookIntro: []float64{0.2, 0.22},
|
||||
}
|
||||
row3 := map[string]interface{}{
|
||||
FieldBookID: float64(3),
|
||||
FieldWordCount: float64(3000),
|
||||
FieldBookIntro: []float64{0.3, 0.33},
|
||||
}
|
||||
if withDistance {
|
||||
row1[HTTPReturnDistance] = float64(0.01)
|
||||
row2[HTTPReturnDistance] = float64(0.04)
|
||||
row3[HTTPReturnDistance] = float64(0.09)
|
||||
}
|
||||
return []map[string]interface{}{row1, row2, row3}
|
||||
}
|
||||
|
||||
func TestPrintCollectionDetails(t *testing.T) {
|
||||
coll := generateCollectionSchema(false)
|
||||
indexes := generateIndexes()
|
||||
assert.Equal(t, printFields(coll.Fields), []gin.H{
|
||||
{
|
||||
HTTPReturnFieldName: FieldBookID,
|
||||
HTTPReturnFieldType: "Int64",
|
||||
HTTPReturnFieldPrimaryKey: true,
|
||||
HTTPReturnFieldAutoID: false,
|
||||
HTTPReturnDescription: ""},
|
||||
{
|
||||
HTTPReturnFieldName: FieldWordCount,
|
||||
HTTPReturnFieldType: "Int64",
|
||||
HTTPReturnFieldPrimaryKey: false,
|
||||
HTTPReturnFieldAutoID: false,
|
||||
HTTPReturnDescription: ""},
|
||||
{
|
||||
HTTPReturnFieldName: FieldBookIntro,
|
||||
HTTPReturnFieldType: "FloatVector",
|
||||
HTTPReturnFieldPrimaryKey: false,
|
||||
HTTPReturnFieldAutoID: false,
|
||||
HTTPReturnDescription: ""},
|
||||
})
|
||||
assert.Equal(t, printIndexes(indexes), []gin.H{
|
||||
{
|
||||
HTTPReturnIndexName: "_default_idx_102",
|
||||
HTTPReturnIndexField: FieldBookIntro,
|
||||
HTTPReturnIndexMetricsType: DefaultMetricType},
|
||||
})
|
||||
assert.Equal(t, getMetricType(indexes[0].Params), DefaultMetricType)
|
||||
assert.Equal(t, getMetricType(nil), DefaultMetricType)
|
||||
}
|
||||
|
||||
func TestPrimaryField(t *testing.T) {
|
||||
coll := generateCollectionSchema(false)
|
||||
primaryField := generatePrimaryField(schemapb.DataType_Int64)
|
||||
field, ok := getPrimaryField(coll)
|
||||
assert.Equal(t, ok, true)
|
||||
assert.Equal(t, *field, primaryField)
|
||||
|
||||
assert.Equal(t, joinArray([]int64{1, 2, 3}), "1,2,3")
|
||||
assert.Equal(t, joinArray([]string{"1", "2", "3"}), "1,2,3")
|
||||
|
||||
jsonStr := "{\"id\": [1, 2, 3]}"
|
||||
idStr := gjson.Get(jsonStr, "id")
|
||||
rangeStr, err := convertRange(&primaryField, idStr)
|
||||
assert.Equal(t, err, nil)
|
||||
assert.Equal(t, rangeStr, "1,2,3")
|
||||
filter, err := checkGetPrimaryKey(coll, idStr)
|
||||
assert.Equal(t, err, nil)
|
||||
assert.Equal(t, filter, "book_id in [1,2,3]")
|
||||
|
||||
primaryField = generatePrimaryField(schemapb.DataType_VarChar)
|
||||
jsonStr = "{\"id\": [\"1\", \"2\", \"3\"]}"
|
||||
idStr = gjson.Get(jsonStr, "id")
|
||||
rangeStr, err = convertRange(&primaryField, idStr)
|
||||
assert.Equal(t, err, nil)
|
||||
assert.Equal(t, rangeStr, "1,2,3")
|
||||
filter, err = checkGetPrimaryKey(coll, idStr)
|
||||
assert.Equal(t, err, nil)
|
||||
assert.Equal(t, filter, "book_id in [1,2,3]")
|
||||
}
|
||||
|
||||
func TestSerialize(t *testing.T) {
|
||||
parameters := []float32{0.11111, 0.22222}
|
||||
//assert.Equal(t, string(serialize(parameters)), "\ufffd\ufffd\ufffd=\ufffd\ufffdc\u003e")
|
||||
//assert.Equal(t, string(vector2PlaceholderGroupBytes(parameters)), "vector2PlaceholderGroupBytes") // todo
|
||||
assert.Equal(t, string(serialize(parameters)), "\xa4\x8d\xe3=\xa4\x8dc>")
|
||||
assert.Equal(t, string(vector2PlaceholderGroupBytes(parameters)), "\n\x10\n\x02$0\x10e\x1a\b\xa4\x8d\xe3=\xa4\x8dc>") // todo
|
||||
}
|
||||
|
||||
func compareRow64(m1 map[string]interface{}, m2 map[string]interface{}) bool {
|
||||
for key, value := range m1 {
|
||||
if key == FieldBookIntro {
|
||||
arr1 := value.([]interface{})
|
||||
arr2 := m2[key].([]float64)
|
||||
if len(arr1) != len(arr2) {
|
||||
return false
|
||||
}
|
||||
for j, element := range arr1 {
|
||||
if element != arr2[j] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else if value != m2[key] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for key, value := range m2 {
|
||||
if key == FieldBookIntro {
|
||||
continue
|
||||
} else if value != m1[key] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
func compareRow(m1 map[string]interface{}, m2 map[string]interface{}) bool {
|
||||
for key, value := range m1 {
|
||||
if key == FieldBookIntro {
|
||||
arr1 := value.([]float32)
|
||||
arr2 := m2[key].([]float32)
|
||||
if len(arr1) != len(arr2) {
|
||||
return false
|
||||
}
|
||||
for j, element := range arr1 {
|
||||
if element != arr2[j] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else if (key == "field-binary") || (key == "field-json") {
|
||||
arr1 := value.([]byte)
|
||||
arr2 := m2[key].([]byte)
|
||||
if len(arr1) != len(arr2) {
|
||||
return false
|
||||
}
|
||||
for j, element := range arr1 {
|
||||
if element != arr2[j] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else if value != m2[key] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for key, value := range m2 {
|
||||
if (key == FieldBookIntro) || (key == "field-binary") || (key == "field-json") {
|
||||
continue
|
||||
} else if value != m1[key] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
type CompareFunc func(map[string]interface{}, map[string]interface{}) bool
|
||||
|
||||
func compareRows(row1 []map[string]interface{}, row2 []map[string]interface{}, compareFunc CompareFunc) bool {
|
||||
if len(row1) != len(row2) {
|
||||
return false
|
||||
}
|
||||
for i, row := range row1 {
|
||||
if !compareFunc(row, row2[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func TestBuildQueryResp(t *testing.T) {
|
||||
outputFields := []string{FieldBookID, FieldWordCount, "author", "date"}
|
||||
rows, err := buildQueryResp(int64(0), outputFields, generateFieldData(), []float32{0.01, 0.04, 0.09}) // []*schemapb.FieldData{&fieldData1, &fieldData2, &fieldData3}
|
||||
assert.Equal(t, err, nil)
|
||||
exceptRows := generateSearchResult()
|
||||
assert.Equal(t, compareRows(rows, exceptRows, compareRow), true)
|
||||
}
|
||||
|
||||
func newCollectionSchema(coll *schemapb.CollectionSchema) *schemapb.CollectionSchema {
|
||||
fieldSchema1 := schemapb.FieldSchema{
|
||||
Name: "field-bool",
|
||||
DataType: schemapb.DataType_Bool,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema1)
|
||||
|
||||
fieldSchema2 := schemapb.FieldSchema{
|
||||
Name: "field-int8",
|
||||
DataType: schemapb.DataType_Int8,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema2)
|
||||
|
||||
fieldSchema3 := schemapb.FieldSchema{
|
||||
Name: "field-int16",
|
||||
DataType: schemapb.DataType_Int16,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema3)
|
||||
|
||||
fieldSchema4 := schemapb.FieldSchema{
|
||||
Name: "field-int32",
|
||||
DataType: schemapb.DataType_Int32,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema4)
|
||||
|
||||
fieldSchema5 := schemapb.FieldSchema{
|
||||
Name: "field-float",
|
||||
DataType: schemapb.DataType_Float,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema5)
|
||||
|
||||
fieldSchema6 := schemapb.FieldSchema{
|
||||
Name: "field-double",
|
||||
DataType: schemapb.DataType_Double,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema6)
|
||||
|
||||
fieldSchema7 := schemapb.FieldSchema{
|
||||
Name: "field-string",
|
||||
DataType: schemapb.DataType_String,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema7)
|
||||
|
||||
fieldSchema8 := schemapb.FieldSchema{
|
||||
Name: "field-varchar",
|
||||
DataType: schemapb.DataType_VarChar,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema8)
|
||||
|
||||
fieldSchema9 := schemapb.FieldSchema{
|
||||
Name: "field-json",
|
||||
DataType: schemapb.DataType_JSON,
|
||||
IsDynamic: false,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema9)
|
||||
|
||||
//fieldSchema10 := schemapb.FieldSchema{
|
||||
// Name: "$meta",
|
||||
// DataType: schemapb.DataType_JSON,
|
||||
// IsDynamic: true,
|
||||
//}
|
||||
//coll.Fields = append(coll.Fields, &fieldSchema10)
|
||||
|
||||
return coll
|
||||
}
|
||||
|
||||
func withUnsupportField(coll *schemapb.CollectionSchema) *schemapb.CollectionSchema {
|
||||
fieldSchema10 := schemapb.FieldSchema{
|
||||
Name: "field-array",
|
||||
DataType: schemapb.DataType_Array,
|
||||
IsDynamic: false,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema10)
|
||||
|
||||
return coll
|
||||
}
|
||||
|
||||
func withDynamicField(coll *schemapb.CollectionSchema) *schemapb.CollectionSchema {
|
||||
fieldSchema11 := schemapb.FieldSchema{
|
||||
Name: "$meta",
|
||||
DataType: schemapb.DataType_JSON,
|
||||
IsDynamic: true,
|
||||
}
|
||||
coll.Fields = append(coll.Fields, &fieldSchema11)
|
||||
|
||||
return coll
|
||||
}
|
||||
|
||||
func newFieldData(fieldDatas []*schemapb.FieldData, firstFieldType schemapb.DataType) []*schemapb.FieldData {
|
||||
fieldData1 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_Bool,
|
||||
FieldName: "field-bool",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_BoolData{
|
||||
BoolData: &schemapb.BoolArray{
|
||||
Data: []bool{true, true, true},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
fieldDatas = append(fieldDatas, &fieldData1)
|
||||
|
||||
fieldData2 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_Int8,
|
||||
FieldName: "field-int8",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_IntData{
|
||||
IntData: &schemapb.IntArray{
|
||||
Data: []int32{0, 1, 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
fieldDatas = append(fieldDatas, &fieldData2)
|
||||
|
||||
fieldData3 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_Int16,
|
||||
FieldName: "field-int16",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_IntData{
|
||||
IntData: &schemapb.IntArray{
|
||||
Data: []int32{0, 1, 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
fieldDatas = append(fieldDatas, &fieldData3)
|
||||
|
||||
fieldData4 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_Int32,
|
||||
FieldName: "field-int32",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_IntData{
|
||||
IntData: &schemapb.IntArray{
|
||||
Data: []int32{0, 1, 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
fieldDatas = append(fieldDatas, &fieldData4)
|
||||
|
||||
fieldData5 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_Float,
|
||||
FieldName: "field-float",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_FloatData{
|
||||
FloatData: &schemapb.FloatArray{
|
||||
Data: []float32{0, 1, 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
fieldDatas = append(fieldDatas, &fieldData5)
|
||||
|
||||
fieldData6 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_Double,
|
||||
FieldName: "field-double",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_DoubleData{
|
||||
DoubleData: &schemapb.DoubleArray{
|
||||
Data: []float64{0, 1, 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
fieldDatas = append(fieldDatas, &fieldData6)
|
||||
|
||||
fieldData7 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_String,
|
||||
FieldName: "field-string",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_StringData{
|
||||
StringData: &schemapb.StringArray{
|
||||
Data: []string{"0", "1", "2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
fieldDatas = append(fieldDatas, &fieldData7)
|
||||
|
||||
fieldData8 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_VarChar,
|
||||
FieldName: "field-varchar",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_StringData{
|
||||
StringData: &schemapb.StringArray{
|
||||
Data: []string{"0", "1", "2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
fieldDatas = append(fieldDatas, &fieldData8)
|
||||
|
||||
fieldData9 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_JSON,
|
||||
FieldName: "field-json",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_JsonData{
|
||||
JsonData: &schemapb.JSONArray{
|
||||
Data: [][]byte{[]byte(`{"XXX": 0}`), []byte(`{"XXX": 0}`), []byte(`{"XXX": 0}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
fieldDatas = append(fieldDatas, &fieldData9)
|
||||
|
||||
fieldData10 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_Array,
|
||||
FieldName: "field-array",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_ArrayData{
|
||||
ArrayData: &schemapb.ArrayArray{
|
||||
Data: []*schemapb.ScalarField{
|
||||
{Data: &schemapb.ScalarField_BoolData{BoolData: &schemapb.BoolArray{Data: []bool{true}}}},
|
||||
{Data: &schemapb.ScalarField_BoolData{BoolData: &schemapb.BoolArray{Data: []bool{true}}}},
|
||||
{Data: &schemapb.ScalarField_BoolData{BoolData: &schemapb.BoolArray{Data: []bool{true}}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: false,
|
||||
}
|
||||
|
||||
fieldData11 := schemapb.FieldData{
|
||||
Type: schemapb.DataType_JSON,
|
||||
FieldName: "$meta",
|
||||
Field: &schemapb.FieldData_Scalars{
|
||||
Scalars: &schemapb.ScalarField{
|
||||
Data: &schemapb.ScalarField_JsonData{
|
||||
JsonData: &schemapb.JSONArray{
|
||||
Data: [][]byte{[]byte(`{"XXX": 0, "YYY": "0"}`), []byte(`{"XXX": 1, "YYY": "1"}`), []byte(`{"XXX": 2, "YYY": "2"}`)},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
IsDynamic: true,
|
||||
}
|
||||
fieldDatas = append(fieldDatas, &fieldData11)
|
||||
|
||||
switch firstFieldType {
|
||||
case schemapb.DataType_None:
|
||||
break
|
||||
case schemapb.DataType_Bool:
|
||||
return []*schemapb.FieldData{&fieldData1}
|
||||
case schemapb.DataType_Int8:
|
||||
return []*schemapb.FieldData{&fieldData2}
|
||||
case schemapb.DataType_Int16:
|
||||
return []*schemapb.FieldData{&fieldData3}
|
||||
case schemapb.DataType_Int32:
|
||||
return []*schemapb.FieldData{&fieldData4}
|
||||
case schemapb.DataType_Float:
|
||||
return []*schemapb.FieldData{&fieldData5}
|
||||
case schemapb.DataType_Double:
|
||||
return []*schemapb.FieldData{&fieldData6}
|
||||
case schemapb.DataType_String:
|
||||
return []*schemapb.FieldData{&fieldData7}
|
||||
case schemapb.DataType_VarChar:
|
||||
return []*schemapb.FieldData{&fieldData8}
|
||||
case schemapb.DataType_BinaryVector:
|
||||
vectorField := generateVectorFieldData(true)
|
||||
return []*schemapb.FieldData{&vectorField}
|
||||
case schemapb.DataType_FloatVector:
|
||||
vectorField := generateVectorFieldData(false)
|
||||
return []*schemapb.FieldData{&vectorField}
|
||||
case schemapb.DataType_Array:
|
||||
return []*schemapb.FieldData{&fieldData10}
|
||||
case schemapb.DataType_JSON:
|
||||
return []*schemapb.FieldData{&fieldData9}
|
||||
default:
|
||||
return []*schemapb.FieldData{
|
||||
{
|
||||
FieldName: "wrong-field-type",
|
||||
Type: firstFieldType,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return fieldDatas
|
||||
}
|
||||
|
||||
func newSearchResult(results []map[string]interface{}) []map[string]interface{} {
|
||||
for i, result := range results {
|
||||
result["field-bool"] = true
|
||||
result["field-int8"] = int8(i)
|
||||
result["field-int16"] = int16(i)
|
||||
result["field-int32"] = int32(i)
|
||||
result["field-float"] = float32(i)
|
||||
result["field-double"] = float64(i)
|
||||
result["field-varchar"] = strconv.Itoa(i)
|
||||
result["field-string"] = strconv.Itoa(i)
|
||||
result["field-binary"] = []byte{byte(i)}
|
||||
result["field-json"] = []byte(`{"XXX": 0}`)
|
||||
result["XXX"] = float64(i)
|
||||
result["YYY"] = strconv.Itoa(i)
|
||||
results[i] = result
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
func TestAnyToColumn(t *testing.T) {
|
||||
data, err := anyToColumns(newSearchResult(generateSearchResult()), newCollectionSchema(generateCollectionSchema(false)))
|
||||
assert.Equal(t, err, nil)
|
||||
assert.Equal(t, len(data), 12)
|
||||
}
|
||||
|
||||
func TestBuildQueryResps(t *testing.T) {
|
||||
outputFields := []string{"XXX", "YYY"}
|
||||
outputFieldsList := [][]string{outputFields, {"$meta"}, {"$meta", FieldBookID, FieldBookIntro, "XXX", "YYY"}}
|
||||
for _, theOutputFields := range outputFieldsList {
|
||||
rows, err := buildQueryResp(int64(0), theOutputFields, newFieldData(generateFieldData(), schemapb.DataType_None), []float32{0.01, 0.04, 0.09})
|
||||
assert.Equal(t, err, nil)
|
||||
exceptRows := newSearchResult(generateSearchResult())
|
||||
assert.Equal(t, compareRows(rows, exceptRows, compareRow), true)
|
||||
}
|
||||
|
||||
dataTypes := []schemapb.DataType{schemapb.DataType_FloatVector, schemapb.DataType_BinaryVector,
|
||||
schemapb.DataType_Bool, schemapb.DataType_Int8, schemapb.DataType_Int16, schemapb.DataType_Int32,
|
||||
schemapb.DataType_Float, schemapb.DataType_Double,
|
||||
schemapb.DataType_String, schemapb.DataType_VarChar,
|
||||
schemapb.DataType_JSON, schemapb.DataType_Array}
|
||||
for _, dateType := range dataTypes {
|
||||
_, err := buildQueryResp(int64(0), outputFields, newFieldData([]*schemapb.FieldData{}, dateType), []float32{0.01, 0.04, 0.09})
|
||||
assert.Equal(t, err, nil)
|
||||
}
|
||||
|
||||
_, err := buildQueryResp(int64(0), outputFields, newFieldData([]*schemapb.FieldData{}, 1000), []float32{0.01, 0.04, 0.09})
|
||||
assert.Equal(t, err.Error(), "the type(1000) of field(wrong-field-type) is not supported, use other sdk please")
|
||||
|
||||
res, err := buildQueryResp(int64(0), outputFields, []*schemapb.FieldData{}, []float32{0.01, 0.04, 0.09})
|
||||
assert.Equal(t, len(res), 0)
|
||||
assert.Equal(t, err, nil)
|
||||
|
||||
// len(rows) != len(scores), didn't show distance
|
||||
_, err = buildQueryResp(int64(0), outputFields, newFieldData(generateFieldData(), schemapb.DataType_None), []float32{0.01, 0.04})
|
||||
assert.Equal(t, err, nil)
|
||||
}
|
|
@ -30,6 +30,11 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/management"
|
||||
"github.com/soheilhy/cmux"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
|
||||
|
@ -39,7 +44,6 @@ import (
|
|||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/health/grpc_health_v1"
|
||||
"google.golang.org/grpc/keepalive"
|
||||
"google.golang.org/grpc/status"
|
||||
|
@ -85,6 +89,10 @@ type Server struct {
|
|||
ctx context.Context
|
||||
wg sync.WaitGroup
|
||||
proxy types.ProxyComponent
|
||||
httpListener net.Listener
|
||||
grpcListener net.Listener
|
||||
tcpServer cmux.CMux
|
||||
httpServer *http.Server
|
||||
grpcInternalServer *grpc.Server
|
||||
grpcExternalServer *grpc.Server
|
||||
|
||||
|
@ -113,6 +121,18 @@ func NewServer(ctx context.Context, factory dependency.Factory) (*Server, error)
|
|||
return server, err
|
||||
}
|
||||
|
||||
func authenticate(c *gin.Context) {
|
||||
username, password, ok := httpserver.ParseUsernamePassword(c)
|
||||
if ok {
|
||||
if proxy.PasswordVerify(c, username, password) {
|
||||
log.Debug("auth successful", zap.String("username", username))
|
||||
c.Set(httpserver.ContextUsername, username)
|
||||
return
|
||||
}
|
||||
}
|
||||
c.AbortWithStatusJSON(http.StatusProxyAuthRequired, gin.H{"code": http.StatusProxyAuthRequired, "message": proxy.ErrUnauthenticated().Error()})
|
||||
}
|
||||
|
||||
// registerHTTPServer register the http server, panic when failed
|
||||
func (s *Server) registerHTTPServer() {
|
||||
// (Embedded Milvus Only) Discard gin logs if logging is disabled.
|
||||
|
@ -125,10 +145,27 @@ func (s *Server) registerHTTPServer() {
|
|||
if !HTTPParams.DebugMode {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
ginHandler := gin.Default()
|
||||
apiv1 := ginHandler.Group(apiPathPrefix)
|
||||
metricsGinHandler := gin.Default()
|
||||
apiv1 := metricsGinHandler.Group(apiPathPrefix)
|
||||
httpserver.NewHandlers(s.proxy).RegisterRoutesTo(apiv1)
|
||||
http.Handle("/", ginHandler)
|
||||
management.Register(&management.HTTPHandler{
|
||||
Path: "/",
|
||||
HandlerFunc: nil,
|
||||
Handler: metricsGinHandler.Handler(),
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) startHTTPServer() {
|
||||
defer s.wg.Done()
|
||||
ginHandler := gin.Default()
|
||||
app := ginHandler.Group("/v1", authenticate)
|
||||
httpserver.NewHandlers(s.proxy).RegisterRoutesToV1(app)
|
||||
s.httpServer = &http.Server{Handler: ginHandler}
|
||||
if err := s.httpServer.Serve(s.httpListener); err != nil && err != cmux.ErrServerClosed {
|
||||
log.Warn("start Proxy http server to listen failed", zap.Error(err))
|
||||
return
|
||||
}
|
||||
log.Info("Proxy http server exited")
|
||||
}
|
||||
|
||||
func (s *Server) startInternalRPCServer(grpcInternalPort int, errChan chan error) {
|
||||
|
@ -153,15 +190,6 @@ func (s *Server) startExternalGrpc(grpcPort int, errChan chan error) {
|
|||
Timeout: 10 * time.Second, // Wait 10 second for the ping ack before assuming the connection is dead
|
||||
}
|
||||
|
||||
log.Info("Proxy server listen on tcp", zap.Int("port", grpcPort))
|
||||
lis, err := net.Listen("tcp", ":"+strconv.Itoa(grpcPort))
|
||||
if err != nil {
|
||||
log.Warn("Proxy server failed to listen on", zap.Error(err), zap.Int("port", grpcPort))
|
||||
errChan <- err
|
||||
return
|
||||
}
|
||||
log.Info("Proxy server already listen on tcp", zap.Int("port", grpcPort))
|
||||
|
||||
limiter, err := s.proxy.GetRateLimiter()
|
||||
if err != nil {
|
||||
log.Error("Get proxy rate limiter failed", zap.Int("port", grpcPort), zap.Error(err))
|
||||
|
@ -235,11 +263,12 @@ func (s *Server) startExternalGrpc(grpcPort int, errChan chan error) {
|
|||
zap.Any("enforcement policy", kaep),
|
||||
zap.Any("server parameters", kasp))
|
||||
|
||||
if err := s.grpcExternalServer.Serve(lis); err != nil {
|
||||
if err := s.grpcExternalServer.Serve(s.grpcListener); err != nil && err != cmux.ErrServerClosed {
|
||||
log.Error("failed to serve on Proxy's listener", zap.Error(err))
|
||||
errChan <- err
|
||||
return
|
||||
}
|
||||
log.Info("Proxy external grpc server exited")
|
||||
}
|
||||
|
||||
func (s *Server) startInternalGrpc(grpcPort int, errChan chan error) {
|
||||
|
@ -290,6 +319,7 @@ func (s *Server) startInternalGrpc(grpcPort int, errChan chan error) {
|
|||
errChan <- err
|
||||
return
|
||||
}
|
||||
log.Info("Proxy internal grpc server exited")
|
||||
}
|
||||
|
||||
// Start start the Proxy Server
|
||||
|
@ -307,6 +337,17 @@ func (s *Server) Run() error {
|
|||
}
|
||||
log.Info("start Proxy server done")
|
||||
|
||||
if s.tcpServer != nil {
|
||||
s.wg.Add(1)
|
||||
go func() {
|
||||
defer s.wg.Done()
|
||||
if err := s.tcpServer.Serve(); err != nil && err != cmux.ErrServerClosed {
|
||||
log.Warn("Proxy server for tcp port failed", zap.Error(err))
|
||||
return
|
||||
}
|
||||
log.Info("Proxy tcp server exited")
|
||||
}()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -353,6 +394,25 @@ func (s *Server) init() error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
{
|
||||
log.Info("Proxy server listen on tcp", zap.Int("port", Params.Port))
|
||||
var lis net.Listener
|
||||
var listenErr error
|
||||
|
||||
log.Info("Proxy server already listen on tcp", zap.Int("port", Params.Port))
|
||||
lis, listenErr = net.Listen("tcp", ":"+strconv.Itoa(Params.Port))
|
||||
if listenErr != nil {
|
||||
log.Error("Proxy server(grpc/http) failed to listen on", zap.Error(err), zap.Int("port", Params.Port))
|
||||
return err
|
||||
}
|
||||
if HTTPParams.Enabled && Params.TLSMode == 0 {
|
||||
s.tcpServer = cmux.New(lis)
|
||||
s.grpcListener = s.tcpServer.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"))
|
||||
s.httpListener = s.tcpServer.Match(cmux.Any())
|
||||
} else {
|
||||
s.grpcListener = lis
|
||||
}
|
||||
}
|
||||
{
|
||||
s.startExternalRPCServer(Params.Port, errChan)
|
||||
if err := <-errChan; err != nil {
|
||||
|
@ -363,7 +423,7 @@ func (s *Server) init() error {
|
|||
|
||||
if HTTPParams.Enabled {
|
||||
registerHTTPHandlerOnce.Do(func() {
|
||||
log.Info("register http server of proxy")
|
||||
log.Info("register Proxy http server")
|
||||
s.registerHTTPServer()
|
||||
})
|
||||
}
|
||||
|
@ -502,6 +562,12 @@ func (s *Server) start() error {
|
|||
return err
|
||||
}
|
||||
|
||||
if s.tcpServer != nil {
|
||||
log.Info("start Proxy http server")
|
||||
s.wg.Add(1)
|
||||
go s.startHTTPServer()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -528,7 +594,10 @@ func (s *Server) Stop() error {
|
|||
log.Info("Graceful stop grpc internal server...")
|
||||
s.grpcInternalServer.GracefulStop()
|
||||
}
|
||||
if s.grpcExternalServer != nil {
|
||||
if s.tcpServer != nil {
|
||||
log.Info("Graceful stop Proxy tcp server...")
|
||||
s.tcpServer.Close()
|
||||
} else if s.grpcExternalServer != nil {
|
||||
log.Info("Graceful stop grpc external server...")
|
||||
s.grpcExternalServer.GracefulStop()
|
||||
}
|
||||
|
|
|
@ -1127,12 +1127,14 @@ func waitForGrpcReady(opt *WaitOption) {
|
|||
ch <- err
|
||||
return
|
||||
}
|
||||
_, err = grpc.Dial(address, grpc.WithBlock(), grpc.WithTransportCredentials(creds))
|
||||
conn, err := grpc.Dial(address, grpc.WithBlock(), grpc.WithTransportCredentials(creds))
|
||||
ch <- err
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
if _, err := grpc.Dial(address, grpc.WithBlock(), grpc.WithInsecure()); true {
|
||||
if conn, err := grpc.Dial(address, grpc.WithBlock(), grpc.WithInsecure()); true {
|
||||
ch <- err
|
||||
conn.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -1703,7 +1705,7 @@ func Test_NewServer_HTTPServer_Enabled(t *testing.T) {
|
|||
t.Fatalf("test should have panicked but did not")
|
||||
}
|
||||
}()
|
||||
// if disable workds path not registered, so it shall not panic
|
||||
// if disable works path not registered, so it shall not panic
|
||||
server.registerHTTPServer()
|
||||
}
|
||||
|
||||
|
@ -1729,6 +1731,7 @@ func Test_NewServer_TLS_TwoWay(t *testing.T) {
|
|||
Params.ServerPemPath = "../../../configs/cert/server.pem"
|
||||
Params.ServerKeyPath = "../../../configs/cert/server.key"
|
||||
Params.CaPemPath = "../../../configs/cert/ca.pem"
|
||||
HTTPParams.InitOnce()
|
||||
HTTPParams.Enabled = false
|
||||
|
||||
err := runAndWaitForServerReady(server)
|
||||
|
@ -1745,6 +1748,7 @@ func Test_NewServer_TLS_OneWay(t *testing.T) {
|
|||
Params.TLSMode = 1
|
||||
Params.ServerPemPath = "../../../configs/cert/server.pem"
|
||||
Params.ServerKeyPath = "../../../configs/cert/server.key"
|
||||
HTTPParams.InitOnce()
|
||||
HTTPParams.Enabled = false
|
||||
|
||||
err := runAndWaitForServerReady(server)
|
||||
|
@ -1761,6 +1765,7 @@ func Test_NewServer_TLS_FileNotExisted(t *testing.T) {
|
|||
Params.TLSMode = 1
|
||||
Params.ServerPemPath = "../not/existed/server.pem"
|
||||
Params.ServerKeyPath = "../../../configs/cert/server.key"
|
||||
HTTPParams.InitOnce()
|
||||
HTTPParams.Enabled = false
|
||||
err := runAndWaitForServerReady(server)
|
||||
assert.NotNil(t, err)
|
||||
|
@ -1786,6 +1791,75 @@ func Test_NewServer_TLS_FileNotExisted(t *testing.T) {
|
|||
server.Stop()
|
||||
}
|
||||
|
||||
func Test_NewHTTPServer_TLS_TwoWay(t *testing.T) {
|
||||
server := getServer(t)
|
||||
|
||||
Params.InitOnce("proxy")
|
||||
Params.TLSMode = 2
|
||||
Params.ServerPemPath = "../../../configs/cert/server.pem"
|
||||
Params.ServerKeyPath = "../../../configs/cert/server.key"
|
||||
Params.CaPemPath = "../../../configs/cert/ca.pem"
|
||||
HTTPParams.InitOnce()
|
||||
HTTPParams.Enabled = true
|
||||
|
||||
err := runAndWaitForServerReady(server)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, server.grpcExternalServer)
|
||||
time.Sleep(100 * time.Second)
|
||||
err = server.Stop()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func Test_NewHTTPServer_TLS_OneWay(t *testing.T) {
|
||||
server := getServer(t)
|
||||
|
||||
Params.InitOnce("proxy")
|
||||
Params.TLSMode = 1
|
||||
Params.ServerPemPath = "../../../configs/cert/server.pem"
|
||||
Params.ServerKeyPath = "../../../configs/cert/server.key"
|
||||
HTTPParams.InitOnce()
|
||||
HTTPParams.Enabled = true
|
||||
|
||||
err := runAndWaitForServerReady(server)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, server.grpcExternalServer)
|
||||
err = server.Stop()
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func Test_NewHTTPServer_TLS_FileNotExisted(t *testing.T) {
|
||||
server := getServer(t)
|
||||
|
||||
Params.InitOnce("proxy")
|
||||
Params.TLSMode = 1
|
||||
Params.ServerPemPath = "../not/existed/server.pem"
|
||||
Params.ServerKeyPath = "../../../configs/cert/server.key"
|
||||
HTTPParams.InitOnce()
|
||||
HTTPParams.Enabled = true
|
||||
err := runAndWaitForServerReady(server)
|
||||
assert.NotNil(t, err)
|
||||
server.Stop()
|
||||
|
||||
Params.TLSMode = 2
|
||||
Params.ServerPemPath = "../not/existed/server.pem"
|
||||
Params.CaPemPath = "../../../configs/cert/ca.pem"
|
||||
err = runAndWaitForServerReady(server)
|
||||
assert.NotNil(t, err)
|
||||
server.Stop()
|
||||
|
||||
Params.ServerPemPath = "../../../configs/cert/server.pem"
|
||||
Params.CaPemPath = "../not/existed/ca.pem"
|
||||
err = runAndWaitForServerReady(server)
|
||||
assert.NotNil(t, err)
|
||||
server.Stop()
|
||||
|
||||
Params.ServerPemPath = "../../../configs/cert/server.pem"
|
||||
Params.CaPemPath = "service.go"
|
||||
err = runAndWaitForServerReady(server)
|
||||
assert.NotNil(t, err)
|
||||
server.Stop()
|
||||
}
|
||||
|
||||
func Test_NewServer_GetVersion(t *testing.T) {
|
||||
req := &milvuspb.GetVersionRequest{}
|
||||
t.Run("test get version failed", func(t *testing.T) {
|
||||
|
|
|
@ -76,6 +76,22 @@ func PrivilegeInterceptor(ctx context.Context, req interface{}) (context.Context
|
|||
log.Warn("GetCurUserFromContext fail", zap.Error(err))
|
||||
return ctx, err
|
||||
}
|
||||
return privilegeInterceptor(ctx, privilegeExt, username, req)
|
||||
}
|
||||
|
||||
func PrivilegeInterceptorWithUsername(ctx context.Context, username string, req interface{}) (context.Context, error) {
|
||||
if !Params.CommonCfg.AuthorizationEnabled {
|
||||
return ctx, nil
|
||||
}
|
||||
log.Debug("PrivilegeInterceptor", zap.String("type", reflect.TypeOf(req).String()))
|
||||
privilegeExt, err := funcutil.GetPrivilegeExtObj(req)
|
||||
if err != nil {
|
||||
log.Warn("GetPrivilegeExtObj err", zap.Error(err))
|
||||
return ctx, nil
|
||||
}
|
||||
return privilegeInterceptor(ctx, privilegeExt, username, req)
|
||||
}
|
||||
func privilegeInterceptor(ctx context.Context, privilegeExt commonpb.PrivilegeExt, username string, req interface{}) (context.Context, error) {
|
||||
if username == util.UserRoot {
|
||||
return ctx, nil
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/allocator"
|
||||
"github.com/milvus-io/milvus/internal/log"
|
||||
"github.com/milvus-io/milvus/internal/mq/msgstream"
|
||||
|
@ -819,8 +820,8 @@ func GetCurUserFromContext(ctx context.Context) (string, error) {
|
|||
if !ok {
|
||||
return "", fmt.Errorf("fail to get md from the context")
|
||||
}
|
||||
authorization := md[strings.ToLower(util.HeaderAuthorize)]
|
||||
if len(authorization) < 1 {
|
||||
authorization, ok := md[strings.ToLower(util.HeaderAuthorize)]
|
||||
if !ok || len(authorization) < 1 {
|
||||
return "", fmt.Errorf("fail to get authorization from the md, authorize:[%s]", util.HeaderAuthorize)
|
||||
}
|
||||
token := authorization[0]
|
||||
|
@ -855,6 +856,10 @@ func GetRole(username string) ([]string, error) {
|
|||
return globalMetaCache.GetUserRole(username), nil
|
||||
}
|
||||
|
||||
func PasswordVerify(ctx context.Context, username, rawPwd string) bool {
|
||||
return passwordVerify(ctx, username, rawPwd, globalMetaCache)
|
||||
}
|
||||
|
||||
// PasswordVerify verify password
|
||||
func passwordVerify(ctx context.Context, username, rawPwd string, globalMetaCache Cache) bool {
|
||||
// it represents the cache miss if Sha256Password is empty within credInfo, which shall be updated first connection.
|
||||
|
|
Loading…
Reference in New Issue