init
This commit is contained in:
commit
c034dbdae0
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
vendor
|
||||||
20
.golangci.yml
Normal file
20
.golangci.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# https://golangci-lint.run/usage/configuration/#config-file
|
||||||
|
|
||||||
|
run:
|
||||||
|
allow-parallel-runners: true
|
||||||
|
|
||||||
|
linters:
|
||||||
|
enable:
|
||||||
|
- megacheck
|
||||||
|
- govet
|
||||||
|
- gocritic
|
||||||
|
- gocyclo
|
||||||
|
- lll
|
||||||
|
- exportloopref
|
||||||
|
disable-all: false
|
||||||
|
disable:
|
||||||
|
- scopelint
|
||||||
|
presets:
|
||||||
|
- bugs
|
||||||
|
- unused
|
||||||
|
fast: false
|
||||||
36
docker-compose.yml
Normal file
36
docker-compose.yml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
cassandra:
|
||||||
|
container_name: cassandra
|
||||||
|
environment:
|
||||||
|
- CASSANDRA_KEYSPACE=userprofileservice
|
||||||
|
- TABLE_NAME=users
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./docker/db/Dockerfile
|
||||||
|
command: /cassandra-init.sh
|
||||||
|
ports:
|
||||||
|
- 9042:9042
|
||||||
|
service:
|
||||||
|
container_name: service
|
||||||
|
environment:
|
||||||
|
- CASSANDRA_HOST=cassandra
|
||||||
|
- CASSANDRA_PORT=9042
|
||||||
|
- CASSANDRA_KEYSPACE=userprofileservice
|
||||||
|
- CASSANDRA_CONSISTANCY=LOCAL_QUORUM
|
||||||
|
- TABLE_NAME=users
|
||||||
|
- BIDN_SERVICE=:8080
|
||||||
|
- AWS_REGION=fake-region
|
||||||
|
- AWS_ACCESS_KEY_ID=fake-key
|
||||||
|
- AWS_SECRET_ACCESS_KEY=fake-secret
|
||||||
|
- BUCKET_NAME=fake-bucket
|
||||||
|
- AWS_ACL=public-read
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./docker/api/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
depends_on:
|
||||||
|
- cassandra
|
||||||
12
docker/api/Dockerfile
Normal file
12
docker/api/Dockerfile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
FROM golang as builder
|
||||||
|
RUN mkdir -p /build/src
|
||||||
|
WORKDIR /build
|
||||||
|
COPY ./src/. /build/src/
|
||||||
|
COPY ./go.mod /build/
|
||||||
|
RUN go mod vendor && go test ./src/ && CGO_ENABLED=0 GOOS=linux go build -o apiservice ./src/main.go
|
||||||
|
|
||||||
|
FROM alpine
|
||||||
|
ENV TZ=Europe/Helsinki
|
||||||
|
RUN apk add --no-cache tzdata && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||||
|
COPY --from=builder /build/apiservice .
|
||||||
|
ENTRYPOINT [ "./apiservice" ]
|
||||||
3
docker/db/Dockerfile
Normal file
3
docker/db/Dockerfile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
FROM cassandra
|
||||||
|
COPY docker/db/cassandra-init.sh /cassandra-init.sh
|
||||||
|
RUN chmod +x /cassandra-init.sh
|
||||||
10
docker/db/cassandra-init.sh
Normal file
10
docker/db/cassandra-init.sh
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
cat >/import.cql <<EOF
|
||||||
|
CREATE keyspace IF NOT EXISTS ${CASSANDRA_KEYSPACE} with replication = {'class':'SimpleStrategy', 'replication_factor' : 1};
|
||||||
|
USE ${CASSANDRA_KEYSPACE};
|
||||||
|
CREATE TABLE IF NOT EXISTS ${TABLE_NAME}(id TIMEUUID, firstname TEXT, lastname TEXT, birthday date, currentlocation TEXT, userpicture TEXT, certificate TEXT, PRIMARY KEY(id));
|
||||||
|
EOF
|
||||||
|
|
||||||
|
bash -c 'sleep 60; cqlsh -f /import.cql;' &
|
||||||
|
exec /docker-entrypoint.sh "$@";
|
||||||
|
|
||||||
15
go.mod
Normal file
15
go.mod
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
module userprofileservice
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||||
|
github.com/aws/aws-sdk-go v1.38.37
|
||||||
|
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible
|
||||||
|
github.com/gocql/gocql v0.0.0-20210504150947-558dfae50b5d
|
||||||
|
github.com/golang/mock v1.5.0
|
||||||
|
github.com/gorilla/mux v1.8.0
|
||||||
|
github.com/swaggo/http-swagger v1.0.0
|
||||||
|
github.com/swaggo/swag v1.7.0
|
||||||
|
)
|
||||||
154
go.sum
Normal file
154
go.sum
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||||
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||||
|
github.com/aws/aws-sdk-go v1.38.37 h1:Eh3/jog9t2NhGcOi086NRfRqVKduRXkaH6svI8yF1Jg=
|
||||||
|
github.com/aws/aws-sdk-go v1.38.37/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||||
|
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
|
||||||
|
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||||
|
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
|
||||||
|
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
|
github.com/go-openapi/jsonreference v0.19.4 h1:3Vw+rh13uq2JFNxgnMTGE1rnoieU9FmyE1gvnyylsYg=
|
||||||
|
github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
||||||
|
github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
|
||||||
|
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
||||||
|
github.com/go-openapi/spec v0.19.14 h1:r4fbYFo6N4ZelmSX8G6p+cv/hZRXzcuqQIADGT1iNKM=
|
||||||
|
github.com/go-openapi/spec v0.19.14/go.mod h1:gwrgJS15eCUgjLpMjBJmbZezCsw88LmgeEip0M63doA=
|
||||||
|
github.com/go-openapi/spec v0.20.0 h1:HGLc8AJ7ynOxwv0Lq4TsnwLsWMawHAYiJIFzbcML86I=
|
||||||
|
github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
|
||||||
|
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
|
github.com/go-openapi/swag v0.19.11 h1:RFTu/dlFySpyVvJDfp/7674JY4SDglYWKztbiIGFpmc=
|
||||||
|
github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY=
|
||||||
|
github.com/go-openapi/swag v0.19.12 h1:Bc0bnY2c3AoF7Gc+IMIAQQsD8fLHjHpc19wXvYuayQI=
|
||||||
|
github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M=
|
||||||
|
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/GeYW1cILu7Nuuj1N3BBkE=
|
||||||
|
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU=
|
||||||
|
github.com/gocql/gocql v0.0.0-20210504150947-558dfae50b5d h1:QbC6FK7LDUrgkZPYdtaKiXGCIw41fdk39H+vrTgHFMs=
|
||||||
|
github.com/gocql/gocql v0.0.0-20210504150947-558dfae50b5d/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY=
|
||||||
|
github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
|
||||||
|
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||||
|
github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk=
|
||||||
|
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||||
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||||
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||||
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||||
|
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||||
|
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||||
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||||
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||||
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
||||||
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
|
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||||
|
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||||
|
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
|
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM=
|
||||||
|
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
||||||
|
github.com/swaggo/http-swagger v1.0.0 h1:ksYgVBCYmAaxFsGVGojlPROgYfiQQSllETTWMtHJHTo=
|
||||||
|
github.com/swaggo/http-swagger v1.0.0/go.mod h1:cKIcshBU9yEAnfWv6ZzVKSsEf8h5ozxB8/zHQWyOQ/8=
|
||||||
|
github.com/swaggo/swag v1.7.0 h1:5bCA/MTLQoIqDXXyHfOpMeDvL9j68OY/udlK4pQoo4E=
|
||||||
|
github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo=
|
||||||
|
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||||
|
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||||
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
|
||||||
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201207224615-747e23833adb h1:xj2oMIbduz83x7tzglytWT7spn6rP+9hvKjTpro6/pM=
|
||||||
|
golang.org/x/net v0.0.0-20201207224615-747e23833adb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||||
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
||||||
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e h1:aZzprAO9/8oim3qStq3wc1Xuxx4QmAGriC4VU4ojemQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e h1:t96dS3DO8DGjawSLJL/HIdz8CycAd2v07XxqB3UPTi0=
|
||||||
|
golang.org/x/tools v0.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20201208062317-e652b2f42cc7 h1:2OSu5vYyX4LVqZAtqZXnFEcN26SDKIJYlEVIRl1tj8U=
|
||||||
|
golang.org/x/tools v0.0.0-20201208062317-e652b2f42cc7/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||||
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
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-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
21
readme.md
Normal file
21
readme.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# INIT SERVICE
|
||||||
|
|
||||||
|
docker-compose up --build
|
||||||
|
|
||||||
|
# AFTER STARTING WILL BE AVAILABLE POINTS
|
||||||
|
|
||||||
|
GET http://localhost:8080/user/e2bb359d-b347-11eb-b01c-0242ac120003 - with parameter will return user info, url parameter [uuid]
|
||||||
|
|
||||||
|
POST http://localhost:8080/user - add or change user, request in json format
|
||||||
|
- {
|
||||||
|
- "firstname":"John",
|
||||||
|
- "lastname":"Dou",
|
||||||
|
- "birthday":"1972-10-06",
|
||||||
|
- "currentlocation":"Helsinki"
|
||||||
|
- }
|
||||||
|
with id UUID in request user will be changed
|
||||||
|
|
||||||
|
POST http://localhost:8080/upload/userpicture - add image or document to user record with form-data request, url parameter [userpicture|certificate]
|
||||||
|
|
||||||
|
# SWAGGER
|
||||||
|
http://localhost:8080/swagger/
|
||||||
68
src/aws/aws.go
Normal file
68
src/aws/aws.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"userprofileservice/src/utils"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AWS struct {
|
||||||
|
aws_region string
|
||||||
|
aws_access_key_id string
|
||||||
|
aws_secret_ascess_key string
|
||||||
|
bucket_name string
|
||||||
|
acl string
|
||||||
|
Session *session.Session
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitDB create ClusterConfig and init DB struct
|
||||||
|
func InitAWS() *AWS {
|
||||||
|
aws := &AWS{
|
||||||
|
aws_region: utils.GetEnv("AWS_REGION", "fake-region"),
|
||||||
|
aws_access_key_id: utils.GetEnv("AWS_ACCESS_KEY_ID ", "fake-key"),
|
||||||
|
aws_secret_ascess_key: utils.GetEnv("AWS_SECRET_ACCESS_KEY ", "fake-secret"),
|
||||||
|
bucket_name: utils.GetEnv("BUCKET_NAME ", "fake-bucket"),
|
||||||
|
acl: utils.GetEnv("AWS_ACL ", "public-read"),
|
||||||
|
}
|
||||||
|
|
||||||
|
aws.connectAWS()
|
||||||
|
return aws
|
||||||
|
}
|
||||||
|
|
||||||
|
// connectAWS connect to AWS if not connected
|
||||||
|
// Comment in for the test and not connect to AWS
|
||||||
|
func (a *AWS) connectAWS() {
|
||||||
|
// if a.Session == nil {
|
||||||
|
// sess, err := session.NewSession(
|
||||||
|
// &aws.Config{
|
||||||
|
// Region: aws.String(a.aws_region),
|
||||||
|
// Credentials: credentials.NewStaticCredentials(
|
||||||
|
// a.aws_access_key_id,
|
||||||
|
// a.aws_secret_ascess_key,
|
||||||
|
// "", // a token will be created when the session it's used.
|
||||||
|
// ),
|
||||||
|
// })
|
||||||
|
// if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
// a.Session = sess
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// uploadFile upload file to AWS and return filename
|
||||||
|
// comment in for fake upload
|
||||||
|
func (a *AWS) UploadFile(file io.Reader, filename string) (string, error) {
|
||||||
|
// uploader := s3manager.NewUploader(a.Session)
|
||||||
|
// _, err := uploader.Upload(&s3manager.UploadInput{
|
||||||
|
// Bucket: aws.String(a.bucket_name),
|
||||||
|
// ACL: aws.String(a.acl),
|
||||||
|
// Key: aws.String(filename),
|
||||||
|
// Body: file,
|
||||||
|
// })
|
||||||
|
// if err != nil {
|
||||||
|
// return "", err
|
||||||
|
// }
|
||||||
|
filepath := "https://" + a.bucket_name + "." + "s3-" + a.aws_region + ".amazonaws.com/" + filename
|
||||||
|
return filepath, nil
|
||||||
|
}
|
||||||
23
src/controller/controller.go
Normal file
23
src/controller/controller.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"userprofileservice/src/model"
|
||||||
|
"userprofileservice/src/structs"
|
||||||
|
|
||||||
|
"github.com/gocql/gocql"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate mockgen -source=controller.go -destination=mocks/mock.go
|
||||||
|
|
||||||
|
type IController interface {
|
||||||
|
CreateUser(user *structs.USER) error
|
||||||
|
GetUser(id gocql.UUID) (*structs.USER, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Controller struct {
|
||||||
|
IController
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewController(model *model.Model) *Controller {
|
||||||
|
return &Controller{IController: NewUserController(model)}
|
||||||
|
}
|
||||||
65
src/controller/mocks/mock.go
Normal file
65
src/controller/mocks/mock.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
|
// Source: controller.go
|
||||||
|
|
||||||
|
// Package mock_controller is a generated GoMock package.
|
||||||
|
package mock_controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
reflect "reflect"
|
||||||
|
structs "userprofileservice/src/structs"
|
||||||
|
|
||||||
|
gocql "github.com/gocql/gocql"
|
||||||
|
gomock "github.com/golang/mock/gomock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockIController is a mock of IController interface.
|
||||||
|
type MockIController struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockIControllerMockRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockIControllerMockRecorder is the mock recorder for MockIController.
|
||||||
|
type MockIControllerMockRecorder struct {
|
||||||
|
mock *MockIController
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockIController creates a new mock instance.
|
||||||
|
func NewMockIController(ctrl *gomock.Controller) *MockIController {
|
||||||
|
mock := &MockIController{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockIControllerMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockIController) EXPECT() *MockIControllerMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateUser mocks base method.
|
||||||
|
func (m *MockIController) CreateUser(user *structs.USER) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "CreateUser", user)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateUser indicates an expected call of CreateUser.
|
||||||
|
func (mr *MockIControllerMockRecorder) CreateUser(user interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUser", reflect.TypeOf((*MockIController)(nil).CreateUser), user)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUser mocks base method.
|
||||||
|
func (m *MockIController) GetUser(id gocql.UUID) (*structs.USER, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "GetUser", id)
|
||||||
|
ret0, _ := ret[0].(*structs.USER)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUser indicates an expected call of GetUser.
|
||||||
|
func (mr *MockIControllerMockRecorder) GetUser(id interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUser", reflect.TypeOf((*MockIController)(nil).GetUser), id)
|
||||||
|
}
|
||||||
24
src/controller/usercontroller.go
Normal file
24
src/controller/usercontroller.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"userprofileservice/src/model"
|
||||||
|
"userprofileservice/src/structs"
|
||||||
|
|
||||||
|
"github.com/gocql/gocql"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserController struct {
|
||||||
|
model *model.Model
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserController(model *model.Model) *UserController {
|
||||||
|
return &UserController{model: model}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserController) CreateUser(user *structs.USER) error {
|
||||||
|
return u.model.CreateUser(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserController) GetUser(id gocql.UUID) (*structs.USER, error) {
|
||||||
|
return u.model.GetUser(id)
|
||||||
|
}
|
||||||
314
src/docs/docs.go
Normal file
314
src/docs/docs.go
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
|
// This file was generated by swaggo/swag
|
||||||
|
|
||||||
|
package docs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/alecthomas/template"
|
||||||
|
"github.com/swaggo/swag"
|
||||||
|
)
|
||||||
|
|
||||||
|
var doc = `{
|
||||||
|
"schemes": {{ marshal .Schemes }},
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "{{.Description}}",
|
||||||
|
"title": "{{.Title}}",
|
||||||
|
"contact": {},
|
||||||
|
"version": "{{.Version}}"
|
||||||
|
},
|
||||||
|
"host": "{{.Host}}",
|
||||||
|
"basePath": "{{.BasePath}}",
|
||||||
|
"paths": {
|
||||||
|
"/upload/{field}": {
|
||||||
|
"post": {
|
||||||
|
"description": "upload file for user, one by one",
|
||||||
|
"consumes": [
|
||||||
|
"multipart/form-data"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"uploadfile"
|
||||||
|
],
|
||||||
|
"summary": "Upload File",
|
||||||
|
"operationId": "upload-file",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "User struct field",
|
||||||
|
"name": "field",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "UUID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "formData",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "File name",
|
||||||
|
"name": "file_name",
|
||||||
|
"in": "formData",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"description": "File data",
|
||||||
|
"name": "input",
|
||||||
|
"in": "formData",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.USER"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/user": {
|
||||||
|
"post": {
|
||||||
|
"description": "create or update user",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"createuser"
|
||||||
|
],
|
||||||
|
"summary": "Create User",
|
||||||
|
"operationId": "create-user",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "User data",
|
||||||
|
"name": "input",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.USER"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.USER"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/user/{id}": {
|
||||||
|
"get": {
|
||||||
|
"description": "get user by uuid",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"getuser"
|
||||||
|
],
|
||||||
|
"summary": "Get User by UID",
|
||||||
|
"operationId": "get-user-by-uid",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "User ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.USER"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"structs.ANSWERAPI": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"additional": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"structs.USER": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"birthday": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"certificate": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"currentlocation": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"firstname": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"lastname": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"userpicture": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
type swaggerInfo struct {
|
||||||
|
Version string
|
||||||
|
Host string
|
||||||
|
BasePath string
|
||||||
|
Schemes []string
|
||||||
|
Title string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||||
|
var SwaggerInfo = swaggerInfo{
|
||||||
|
Version: "0.1",
|
||||||
|
Host: "localhost:8080",
|
||||||
|
BasePath: "/",
|
||||||
|
Schemes: []string{},
|
||||||
|
Title: "User Profile Service API",
|
||||||
|
Description: "API Server for User Profile Service",
|
||||||
|
}
|
||||||
|
|
||||||
|
type s struct{}
|
||||||
|
|
||||||
|
func (s *s) ReadDoc() string {
|
||||||
|
sInfo := SwaggerInfo
|
||||||
|
sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1)
|
||||||
|
|
||||||
|
t, err := template.New("swagger_info").Funcs(template.FuncMap{
|
||||||
|
"marshal": func(v interface{}) string {
|
||||||
|
a, _ := json.Marshal(v)
|
||||||
|
return string(a)
|
||||||
|
},
|
||||||
|
}).Parse(doc)
|
||||||
|
if err != nil {
|
||||||
|
return doc
|
||||||
|
}
|
||||||
|
|
||||||
|
var tpl bytes.Buffer
|
||||||
|
if err := t.Execute(&tpl, sInfo); err != nil {
|
||||||
|
return doc
|
||||||
|
}
|
||||||
|
|
||||||
|
return tpl.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
swag.Register(swag.Name, &s{})
|
||||||
|
}
|
||||||
252
src/docs/swagger.json
Normal file
252
src/docs/swagger.json
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
{
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "API Server for User Profile Service",
|
||||||
|
"title": "User Profile Service API",
|
||||||
|
"contact": {},
|
||||||
|
"version": "0.1"
|
||||||
|
},
|
||||||
|
"host": "localhost:8080",
|
||||||
|
"basePath": "/",
|
||||||
|
"paths": {
|
||||||
|
"/upload/{field}": {
|
||||||
|
"post": {
|
||||||
|
"description": "upload file for user, one by one",
|
||||||
|
"consumes": [
|
||||||
|
"multipart/form-data"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"uploadfile"
|
||||||
|
],
|
||||||
|
"summary": "Upload File",
|
||||||
|
"operationId": "upload-file",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "User struct field",
|
||||||
|
"name": "field",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "UUID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "formData",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "File name",
|
||||||
|
"name": "file_name",
|
||||||
|
"in": "formData",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"description": "File data",
|
||||||
|
"name": "input",
|
||||||
|
"in": "formData",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.USER"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/user": {
|
||||||
|
"post": {
|
||||||
|
"description": "create or update user",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"createuser"
|
||||||
|
],
|
||||||
|
"summary": "Create User",
|
||||||
|
"operationId": "create-user",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "User data",
|
||||||
|
"name": "input",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.USER"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.USER"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/user/{id}": {
|
||||||
|
"get": {
|
||||||
|
"description": "get user by uuid",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"getuser"
|
||||||
|
],
|
||||||
|
"summary": "Get User by UID",
|
||||||
|
"operationId": "get-user-by-uid",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "User ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.USER"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/structs.ANSWERAPI"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"structs.ANSWERAPI": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"additional": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"structs.USER": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"birthday": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"certificate": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"currentlocation": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"firstname": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"lastname": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"userpicture": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
168
src/docs/swagger.yaml
Normal file
168
src/docs/swagger.yaml
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
basePath: /
|
||||||
|
definitions:
|
||||||
|
structs.ANSWERAPI:
|
||||||
|
properties:
|
||||||
|
additional:
|
||||||
|
type: string
|
||||||
|
data:
|
||||||
|
type: object
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
type: boolean
|
||||||
|
type: object
|
||||||
|
structs.USER:
|
||||||
|
properties:
|
||||||
|
birthday:
|
||||||
|
type: string
|
||||||
|
certificate:
|
||||||
|
type: string
|
||||||
|
currentlocation:
|
||||||
|
type: string
|
||||||
|
firstname:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
lastname:
|
||||||
|
type: string
|
||||||
|
userpicture:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
host: localhost:8080
|
||||||
|
info:
|
||||||
|
contact: {}
|
||||||
|
description: API Server for User Profile Service
|
||||||
|
title: User Profile Service API
|
||||||
|
version: "0.1"
|
||||||
|
paths:
|
||||||
|
/upload/{field}:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- multipart/form-data
|
||||||
|
description: upload file for user, one by one
|
||||||
|
operationId: upload-file
|
||||||
|
parameters:
|
||||||
|
- description: User struct field
|
||||||
|
in: path
|
||||||
|
name: field
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: UUID
|
||||||
|
in: formData
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: File name
|
||||||
|
in: formData
|
||||||
|
name: file_name
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: File data
|
||||||
|
in: formData
|
||||||
|
name: input
|
||||||
|
required: true
|
||||||
|
type: file
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.USER'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
"404":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
default:
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
summary: Upload File
|
||||||
|
tags:
|
||||||
|
- uploadfile
|
||||||
|
/user:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: create or update user
|
||||||
|
operationId: create-user
|
||||||
|
parameters:
|
||||||
|
- description: User data
|
||||||
|
in: body
|
||||||
|
name: input
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.USER'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.USER'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
"404":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
default:
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
summary: Create User
|
||||||
|
tags:
|
||||||
|
- createuser
|
||||||
|
/user/{id}:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: get user by uuid
|
||||||
|
operationId: get-user-by-uid
|
||||||
|
parameters:
|
||||||
|
- description: User ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.USER'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
"404":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
default:
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/structs.ANSWERAPI'
|
||||||
|
summary: Get User by UID
|
||||||
|
tags:
|
||||||
|
- getuser
|
||||||
|
swagger: "2.0"
|
||||||
30
src/main.go
Normal file
30
src/main.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"userprofileservice/src/controller"
|
||||||
|
"userprofileservice/src/model"
|
||||||
|
"userprofileservice/src/utils"
|
||||||
|
"userprofileservice/src/view"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// catch panic
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
log.Println("Recovered in f ", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
db := model.NewCassandra()
|
||||||
|
model := model.NewModel(db)
|
||||||
|
controller := controller.NewController(model)
|
||||||
|
view := view.NewView(controller)
|
||||||
|
|
||||||
|
bind := utils.GetEnv("BIDN_SERVICE", ":8080")
|
||||||
|
log.Printf("start service on port %s", bind)
|
||||||
|
if err := http.ListenAndServe(bind, view.InitRouting()); err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
61
src/main_test.go
Normal file
61
src/main_test.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
"userprofileservice/src/controller"
|
||||||
|
mock_controller "userprofileservice/src/controller/mocks"
|
||||||
|
"userprofileservice/src/structs"
|
||||||
|
|
||||||
|
"github.com/gocql/gocql"
|
||||||
|
"github.com/golang/mock/gomock"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
uid = gocql.TimeUUID()
|
||||||
|
user = &structs.USER{
|
||||||
|
Firstname: "Sergey",
|
||||||
|
Lastname: "Melnikov",
|
||||||
|
Birthday: "1972-10-06",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCreateUser(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
mocklUserController := mock_controller.NewMockIController(ctrl)
|
||||||
|
|
||||||
|
mocklUserController.
|
||||||
|
EXPECT().
|
||||||
|
CreateUser(user).
|
||||||
|
Return(nil)
|
||||||
|
testCreateUser(mocklUserController)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCreateUser(c controller.IController) {
|
||||||
|
err := c.CreateUser(user)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Wrong added user %v", err)
|
||||||
|
}
|
||||||
|
log.Printf("User added %v", user)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetUser(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
mocklUserController := mock_controller.NewMockIController(ctrl)
|
||||||
|
|
||||||
|
mocklUserController.
|
||||||
|
EXPECT().
|
||||||
|
GetUser(uid).
|
||||||
|
Return(user, nil)
|
||||||
|
testGetUser(mocklUserController)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGetUser(c controller.IController) {
|
||||||
|
u, err := c.GetUser(uid)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Wrong get user %v", err)
|
||||||
|
}
|
||||||
|
log.Printf("Get user %v", u)
|
||||||
|
}
|
||||||
42
src/model/cassandra.go
Normal file
42
src/model/cassandra.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
"userprofileservice/src/utils"
|
||||||
|
|
||||||
|
"github.com/gocql/gocql"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewCassandra() *gocql.Session {
|
||||||
|
conf := gocql.NewCluster(utils.GetEnv("CASSANDRA_HOST", "cassandra"))
|
||||||
|
conf.Port = utils.ParsePort(utils.GetEnv("CASSANDRA_PORT", "9042"))
|
||||||
|
conf.Keyspace = utils.GetEnv("CASSANDRA_KEYSPACE", "userprofileservice")
|
||||||
|
conf.Consistency = gocql.ParseConsistency(utils.GetEnv("CASSANDRA_CONSISTANCY", "LOCAL_QUORUM"))
|
||||||
|
sess, err := conf.CreateSession()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("waiting for cassandra session, %s", err.Error())
|
||||||
|
// added ticker for long cassandra initializing
|
||||||
|
ticker := time.NewTicker(time.Second * 10)
|
||||||
|
defer ticker.Stop()
|
||||||
|
timeout := time.Second * 120
|
||||||
|
|
||||||
|
timeoutExceeded := time.After(timeout)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-timeoutExceeded:
|
||||||
|
log.Panicf("cassandra connection failed after %s timeout", timeout)
|
||||||
|
|
||||||
|
case <-ticker.C:
|
||||||
|
sess, err = conf.CreateSession()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("waiting for cassandra session, %s", err.Error())
|
||||||
|
} else {
|
||||||
|
log.Printf("cassandra session init")
|
||||||
|
return sess
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sess
|
||||||
|
}
|
||||||
22
src/model/model.go
Normal file
22
src/model/model.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"userprofileservice/src/structs"
|
||||||
|
|
||||||
|
"github.com/gocql/gocql"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IModel interface {
|
||||||
|
CreateUser(user *structs.USER) error
|
||||||
|
GetUser(id gocql.UUID) (*structs.USER, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
IModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewModel(db *gocql.Session) *Model {
|
||||||
|
return &Model{
|
||||||
|
IModel: NewUserModel(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
89
src/model/user_model.go
Normal file
89
src/model/user_model.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"userprofileservice/src/structs"
|
||||||
|
"userprofileservice/src/utils"
|
||||||
|
|
||||||
|
"github.com/gocql/gocql"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ModelCassandra struct {
|
||||||
|
db *gocql.Session
|
||||||
|
TableName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserModel(db *gocql.Session) *ModelCassandra {
|
||||||
|
return &ModelCassandra{
|
||||||
|
db: db,
|
||||||
|
TableName: utils.GetEnv("TABLE_NAME", "users"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateUser create or update user
|
||||||
|
func (c *ModelCassandra) CreateUser(user *structs.USER) error {
|
||||||
|
var query *gocql.Query
|
||||||
|
// if user ID empty - create new user, else update user fields
|
||||||
|
if user.Id.Clock() == 0 {
|
||||||
|
user.Id = gocql.TimeUUID()
|
||||||
|
query = c.db.Query(`
|
||||||
|
INSERT INTO `+c.TableName+` (
|
||||||
|
id,
|
||||||
|
firstname,
|
||||||
|
lastname,
|
||||||
|
birthday,
|
||||||
|
currentlocation,
|
||||||
|
userpicture,
|
||||||
|
certificate
|
||||||
|
)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||||
|
`,
|
||||||
|
user.Id,
|
||||||
|
user.Firstname,
|
||||||
|
user.Lastname,
|
||||||
|
user.Birthday,
|
||||||
|
user.Currentlocation,
|
||||||
|
user.Userpicture,
|
||||||
|
user.Certificate)
|
||||||
|
} else {
|
||||||
|
query = c.db.Query(`
|
||||||
|
UPDATE `+c.TableName+` SET
|
||||||
|
firstname = ?,
|
||||||
|
lastname = ?,
|
||||||
|
birthday = ?,
|
||||||
|
currentlocation = ?,
|
||||||
|
userpicture = ?,
|
||||||
|
certificate = ?
|
||||||
|
WHERE id = ?
|
||||||
|
IF EXISTS
|
||||||
|
`,
|
||||||
|
user.Firstname,
|
||||||
|
user.Lastname,
|
||||||
|
user.Birthday,
|
||||||
|
user.Currentlocation,
|
||||||
|
user.Userpicture,
|
||||||
|
user.Certificate,
|
||||||
|
user.Id)
|
||||||
|
}
|
||||||
|
err := query.Exec()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUser return user data by id
|
||||||
|
func (c *ModelCassandra) GetUser(id gocql.UUID) (*structs.USER, error) {
|
||||||
|
q := `SELECT id, firstname, lastname, currentlocation, birthday, userpicture, certificate
|
||||||
|
FROM ` + c.TableName + ` WHERE id = ? LIMIT 1`
|
||||||
|
|
||||||
|
user := &structs.USER{}
|
||||||
|
err := c.db.Query(q, id).Consistency(gocql.One).Scan(
|
||||||
|
&user.Id,
|
||||||
|
&user.Firstname,
|
||||||
|
&user.Lastname,
|
||||||
|
&user.Currentlocation,
|
||||||
|
&user.Birthday,
|
||||||
|
&user.Userpicture,
|
||||||
|
&user.Certificate,
|
||||||
|
)
|
||||||
|
|
||||||
|
return user, err
|
||||||
|
}
|
||||||
44
src/structs/structs.go
Normal file
44
src/structs/structs.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package structs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
valid "github.com/go-ozzo/ozzo-validation"
|
||||||
|
"github.com/gocql/gocql"
|
||||||
|
)
|
||||||
|
|
||||||
|
// User struct for user
|
||||||
|
type USER struct {
|
||||||
|
Id gocql.UUID `cql:"id" json:"id,omitempty"`
|
||||||
|
Firstname string `cql:"firstname" json:"firstname"`
|
||||||
|
Lastname string `cql:"lastname" json:"lastname"`
|
||||||
|
Birthday string `cql:"birthday" json:"birthday"`
|
||||||
|
Currentlocation string `cql:"currentlocation" json:"currentlocation"`
|
||||||
|
Userpicture string `cql:"userpicture" json:"userpicture"`
|
||||||
|
Certificate string `cql:"certificate" json:"certificate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate check Birthday for format yyyy-mm-dd
|
||||||
|
func (u *USER) Validate() error {
|
||||||
|
var fieldRules []*valid.FieldRules
|
||||||
|
fieldRules = append(fieldRules, valid.Field(&u.Birthday, valid.Date("2006-01-02")))
|
||||||
|
return valid.ValidateStruct(u, fieldRules...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ANSWERAPI struct for api answer
|
||||||
|
type ANSWERAPI struct {
|
||||||
|
STATUS bool `json:"status"`
|
||||||
|
DATA interface{} `json:"data"`
|
||||||
|
ERROR string `json:"error"`
|
||||||
|
ADDITIONAL string `json:"additional"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare to bool and uppercase errors
|
||||||
|
func (a *ANSWERAPI) Prepare() {
|
||||||
|
if a.ERROR != "" {
|
||||||
|
a.STATUS = false
|
||||||
|
} else {
|
||||||
|
a.STATUS = true
|
||||||
|
}
|
||||||
|
a.ERROR = strings.ToUpper(a.ERROR)
|
||||||
|
}
|
||||||
45
src/utils/utils.go
Normal file
45
src/utils/utils.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"userprofileservice/src/structs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetEnv look up ENV settings
|
||||||
|
func GetEnv(key, fallback string) string {
|
||||||
|
if value, ok := os.LookupEnv(key); ok {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
return fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParsePort return port for cassandra
|
||||||
|
func ParsePort(p string) int {
|
||||||
|
i, err := strconv.Atoi(p)
|
||||||
|
if err != nil {
|
||||||
|
return 9042
|
||||||
|
}
|
||||||
|
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
// AvailableField check field struct and add value
|
||||||
|
func AvailableAndAddValue(v *structs.USER, field, link string) bool {
|
||||||
|
s := reflect.ValueOf(v).Elem()
|
||||||
|
typeOfT := s.Type()
|
||||||
|
|
||||||
|
for i := 0; i < s.NumField(); i++ {
|
||||||
|
name := typeOfT.Field(i).Name
|
||||||
|
if strings.ToLower(name) == field {
|
||||||
|
if link != "" {
|
||||||
|
reflect.ValueOf(v).Elem().FieldByName(name).SetString(link)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
255
src/view/api.go
Normal file
255
src/view/api.go
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
package view
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"userprofileservice/src/aws"
|
||||||
|
"userprofileservice/src/controller"
|
||||||
|
"userprofileservice/src/structs"
|
||||||
|
"userprofileservice/src/utils"
|
||||||
|
|
||||||
|
_ "userprofileservice/src/docs"
|
||||||
|
|
||||||
|
"github.com/gocql/gocql"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
httpSwagger "github.com/swaggo/http-swagger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type API struct {
|
||||||
|
services *controller.Controller
|
||||||
|
aws *aws.AWS
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewView(controller *controller.Controller) *API {
|
||||||
|
a := &API{
|
||||||
|
services: controller,
|
||||||
|
aws: aws.InitAWS(),
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) InitRouting() *mux.Router {
|
||||||
|
routing := mux.NewRouter()
|
||||||
|
routing.PathPrefix("/swagger").Handler(httpSwagger.WrapHandler)
|
||||||
|
routing.HandleFunc("/", a.handleRoot()).Methods("GET")
|
||||||
|
routing.HandleFunc("/user/{id:[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}}",
|
||||||
|
a.getUser()).Methods("GET")
|
||||||
|
routing.HandleFunc("/user", a.createUser()).Methods("POST")
|
||||||
|
routing.HandleFunc("/upload/{field:\\w+}", a.uploadFiles()).Methods("POST")
|
||||||
|
|
||||||
|
routing.NotFoundHandler = http.HandlerFunc(a.notFound)
|
||||||
|
routing.MethodNotAllowedHandler = http.HandlerFunc(a.notAllowed)
|
||||||
|
return routing
|
||||||
|
}
|
||||||
|
|
||||||
|
// swag init -g src/view/api.go -o src/docs/
|
||||||
|
|
||||||
|
// @title User Profile Service API
|
||||||
|
// @version 0.1
|
||||||
|
// @description API Server for User Profile Service
|
||||||
|
// @host localhost:8080
|
||||||
|
// @BasePath /
|
||||||
|
|
||||||
|
// @Summary Get User by UID
|
||||||
|
// @Tags getuser
|
||||||
|
// @Description get user by uuid
|
||||||
|
// @ID get-user-by-uid
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "User ID"
|
||||||
|
// @Success 200 {object} structs.USER
|
||||||
|
// @Failure 400,404 {object} structs.ANSWERAPI
|
||||||
|
// @Failure 500 {object} structs.ANSWERAPI
|
||||||
|
// @Failure default {object} structs.ANSWERAPI
|
||||||
|
// @Router /user/{id} [get]
|
||||||
|
// getUser return one user data in json
|
||||||
|
func (a *API) getUser() http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
uid, err := gocql.ParseUUID(vars["id"])
|
||||||
|
if err != nil {
|
||||||
|
a.respond(w, r, http.StatusBadRequest, nil, err, "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user, err := a.services.GetUser(uid)
|
||||||
|
if err != nil {
|
||||||
|
a.respond(w, r, http.StatusInternalServerError, nil, err, "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
a.respond(w, r, http.StatusOK, user, nil, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Create User
|
||||||
|
// @Tags createuser
|
||||||
|
// @Description create or update user
|
||||||
|
// @ID create-user
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param input body structs.USER true "User data"
|
||||||
|
// @Success 200 {object} structs.USER
|
||||||
|
// @Failure 400,404 {object} structs.ANSWERAPI
|
||||||
|
// @Failure 500 {object} structs.ANSWERAPI
|
||||||
|
// @Failure default {object} structs.ANSWERAPI
|
||||||
|
// @Router /user [post]
|
||||||
|
// writeUser gets json request and write to nosql, without id - create new user
|
||||||
|
// {
|
||||||
|
// "firstname":"username",
|
||||||
|
// "lastname":"username",
|
||||||
|
// "birthday":"1972-06-10",
|
||||||
|
// "currentlocation":"Location"
|
||||||
|
// }
|
||||||
|
func (a *API) createUser() http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var user *structs.USER
|
||||||
|
err := json.NewDecoder(r.Body).Decode(&user)
|
||||||
|
if err != nil {
|
||||||
|
a.respond(w, r, http.StatusBadRequest, nil, err, "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = user.Validate()
|
||||||
|
if err != nil {
|
||||||
|
a.respond(w, r, http.StatusBadRequest, nil, err, "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = a.services.CreateUser(user)
|
||||||
|
if err != nil {
|
||||||
|
a.respond(w, r, http.StatusInternalServerError, nil, err, "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
a.respond(w, r, http.StatusOK, user, nil, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary Upload File
|
||||||
|
// @Tags uploadfile
|
||||||
|
// @Description upload file for user, one by one
|
||||||
|
// @ID upload-file
|
||||||
|
// @Accept mpfd
|
||||||
|
// @Produce json
|
||||||
|
// @Param field path string true "User struct field"
|
||||||
|
// @Param id formData string true "UUID"
|
||||||
|
// @Param file_name formData string true "File name"
|
||||||
|
// @Param input formData file true "File data"
|
||||||
|
// @Success 200 {object} structs.USER
|
||||||
|
// @Failure 400,404 {object} structs.ANSWERAPI
|
||||||
|
// @Failure 500 {object} structs.ANSWERAPI
|
||||||
|
// @Failure default {object} structs.ANSWERAPI
|
||||||
|
// @Router /upload/{field} [post]
|
||||||
|
// uploadFiles get form-data request
|
||||||
|
// params:
|
||||||
|
// url /upload/<field of user struct> e.g. /upload/userpicture
|
||||||
|
// uid - User UUID
|
||||||
|
// file - file data
|
||||||
|
// file_name - e.g. 1234.jpg
|
||||||
|
func (a *API) uploadFiles() http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
file_field := vars["field"]
|
||||||
|
// get uuid from request
|
||||||
|
uid, err := gocql.ParseUUID(r.FormValue("id"))
|
||||||
|
if err != nil {
|
||||||
|
a.respond(w, r, http.StatusBadRequest, nil, err, "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// find user by uuid
|
||||||
|
user, err := a.services.GetUser(uid)
|
||||||
|
if err != nil {
|
||||||
|
a.respond(w, r, http.StatusNotFound, nil, err, "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// check available field in struct
|
||||||
|
if !utils.AvailableAndAddValue(user, file_field, "") {
|
||||||
|
a.respond(w, r, http.StatusBadRequest, nil, errors.New("wrong url parameter"), "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
file_name := r.FormValue("file_name")
|
||||||
|
fileUrl, err := a.fileHandler(r, file_name)
|
||||||
|
if err != nil {
|
||||||
|
a.respond(w, r, http.StatusInternalServerError, nil, err, file_name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// add aws url to struct user
|
||||||
|
utils.AvailableAndAddValue(user, file_field, fileUrl)
|
||||||
|
err = a.services.CreateUser(user)
|
||||||
|
if err != nil {
|
||||||
|
a.respond(w, r, http.StatusInternalServerError, nil, err, "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
a.respond(w, r, http.StatusOK, user, nil, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fileHandler get data from MultipartForm and send to AWS S3
|
||||||
|
func (a *API) fileHandler(r *http.Request, filename string) (string, error) {
|
||||||
|
// total of maxMemory bytes
|
||||||
|
err := r.ParseMultipartForm(10 << 20)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// file upload as form-data
|
||||||
|
m := r.MultipartForm
|
||||||
|
fileUrl := ""
|
||||||
|
|
||||||
|
for _, v := range m.File {
|
||||||
|
for _, f := range v {
|
||||||
|
file, err := f.Open()
|
||||||
|
if err != nil {
|
||||||
|
return fileUrl, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
// upload file to aws
|
||||||
|
fileUrl, err = a.aws.UploadFile(file, filename)
|
||||||
|
if err != nil {
|
||||||
|
return fileUrl, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileUrl, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleRoot paga page
|
||||||
|
func (a *API) handleRoot() http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
a.respond(w, r, http.StatusOK, nil, nil, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// notFound page not found
|
||||||
|
func (a *API) notFound(w http.ResponseWriter, r *http.Request) {
|
||||||
|
a.respond(w, r, http.StatusNotFound, nil, errors.New("page not found"), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// notAllowed return custom method method not allowed
|
||||||
|
func (a *API) notAllowed(w http.ResponseWriter, r *http.Request) {
|
||||||
|
a.respond(w, r, http.StatusMethodNotAllowed, nil, errors.New("method not allowed"), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// setAnswer set api's answer
|
||||||
|
func setAnswer(data interface{}, e error, add string) *structs.ANSWERAPI {
|
||||||
|
err := ""
|
||||||
|
if e != nil {
|
||||||
|
err = e.Error()
|
||||||
|
}
|
||||||
|
a := &structs.ANSWERAPI{
|
||||||
|
DATA: data,
|
||||||
|
ERROR: err,
|
||||||
|
ADDITIONAL: add,
|
||||||
|
}
|
||||||
|
a.Prepare()
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// respond generate http response for api
|
||||||
|
func (a *API) respond(w http.ResponseWriter, r *http.Request, code int, data interface{}, e error, add string) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
|
||||||
|
w.WriteHeader(code)
|
||||||
|
if r.Method == "OPTIONS" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_ = json.NewEncoder(w).Encode(setAnswer(data, e, add))
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user