From 2a6b1317357b5387f98e846c3b0387384cbadf4b Mon Sep 17 00:00:00 2001 From: elinuxhenrik Date: Wed, 19 Jan 2022 16:51:36 +0100 Subject: [PATCH] Improve Swagger DMaaP Mediator Producer Issue-ID: NONRTRIC-702 Signed-off-by: elinuxhenrik Change-Id: Ib0a1c5c31b21b14174b48af9c0b577014cb88e36 --- dmaap-mediator-producer/{docs => api}/docs.go | 81 ++++++++++++++++++---- dmaap-mediator-producer/{docs => api}/swagger.json | 77 +++++++++++++++++--- dmaap-mediator-producer/{docs => api}/swagger.yaml | 65 ++++++++++++++--- dmaap-mediator-producer/generate_swagger_docs.sh | 4 +- dmaap-mediator-producer/go.mod | 6 +- dmaap-mediator-producer/internal/jobs/jobs.go | 6 +- dmaap-mediator-producer/internal/server/server.go | 38 ++++++++-- .../internal/server/server_test.go | 57 +++++++++++---- dmaap-mediator-producer/main.go | 41 ++++++----- dmaap-mediator-producer/main_test.go | 6 +- docs/api-docs.rst | 2 +- docs/conf.py | 2 +- 12 files changed, 306 insertions(+), 79 deletions(-) rename dmaap-mediator-producer/{docs => api}/docs.go (67%) rename dmaap-mediator-producer/{docs => api}/swagger.json (62%) rename dmaap-mediator-producer/{docs => api}/swagger.yaml (55%) diff --git a/dmaap-mediator-producer/docs/docs.go b/dmaap-mediator-producer/api/docs.go similarity index 67% rename from dmaap-mediator-producer/docs/docs.go rename to dmaap-mediator-producer/api/docs.go index 823df03a..dbfc42be 100644 --- a/dmaap-mediator-producer/docs/docs.go +++ b/dmaap-mediator-producer/api/docs.go @@ -1,6 +1,6 @@ -// Package docs GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Package api GENERATED BY THE COMMAND ABOVE; DO NOT EDIT // This file was generated by swaggo/swag -package docs +package api import ( "bytes" @@ -53,9 +53,15 @@ var doc = `{ "description": "" }, "400": { - "description": "Bad Request", + "description": "Problem as defined in https://tools.ietf.org/html/rfc7807", "schema": { - "type": "string" + "$ref": "#/definitions/ErrorInfo" + }, + "headers": { + "Content-Type": { + "type": "string", + "description": "application/problem+json" + } } } } @@ -64,13 +70,19 @@ var doc = `{ "/health_check": { "get": { "description": "Get the status of the producer. Will show if the producer has registered in ICS.", + "produces": [ + "application/json" + ], "tags": [ "Data producer (callbacks)" ], "summary": "Get status", "responses": { "200": { - "description": "" + "description": "OK", + "schema": { + "$ref": "#/definitions/" + } } } } @@ -92,7 +104,7 @@ var doc = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/jobs.JobInfo" + "$ref": "#/definitions/JobInfo" } } ], @@ -101,9 +113,15 @@ var doc = `{ "description": "" }, "400": { - "description": "Bad Request", + "description": "Problem as defined in https://tools.ietf.org/html/rfc7807", "schema": { - "type": "string" + "$ref": "#/definitions/ErrorInfo" + }, + "headers": { + "Content-Type": { + "type": "string", + "description": "application/problem+json" + } } } } @@ -148,7 +166,17 @@ var doc = `{ } }, "definitions": { - "jobs.BufferTimeout": { + "": { + "type": "object", + "properties": { + "registeredStatus": { + "description": "The registration status of the producer in Information Coordinator Service. Either ` + "`" + `registered` + "`" + ` or ` + "`" + `not registered` + "`" + `", + "type": "string", + "example": "registered" + } + } + }, + "BufferTimeout": { "type": "object", "properties": { "maxSize": { @@ -159,11 +187,38 @@ var doc = `{ } } }, - "jobs.JobInfo": { + "ErrorInfo": { + "type": "object", + "properties": { + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.", + "type": "string", + "example": "Info job type not found" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem.", + "type": "string" + }, + "status": { + "description": "The HTTP status code generated by the origin server for this occurrence of the problem.", + "type": "integer", + "example": 400 + }, + "title": { + "description": "A short, human-readable summary of the problem type.", + "type": "string" + }, + "type": { + "description": "A URI reference that identifies the problem type.", + "type": "string" + } + } + }, + "JobInfo": { "type": "object", "properties": { "info_job_data": { - "$ref": "#/definitions/jobs.Parameters" + "$ref": "#/definitions/Parameters" }, "info_job_identity": { "type": "string" @@ -182,11 +237,11 @@ var doc = `{ } } }, - "jobs.Parameters": { + "Parameters": { "type": "object", "properties": { "bufferTimeout": { - "$ref": "#/definitions/jobs.BufferTimeout" + "$ref": "#/definitions/BufferTimeout" } } } diff --git a/dmaap-mediator-producer/docs/swagger.json b/dmaap-mediator-producer/api/swagger.json similarity index 62% rename from dmaap-mediator-producer/docs/swagger.json rename to dmaap-mediator-producer/api/swagger.json index 11e030e8..89100227 100644 --- a/dmaap-mediator-producer/docs/swagger.json +++ b/dmaap-mediator-producer/api/swagger.json @@ -36,9 +36,15 @@ "description": "" }, "400": { - "description": "Bad Request", + "description": "Problem as defined in https://tools.ietf.org/html/rfc7807", "schema": { - "type": "string" + "$ref": "#/definitions/ErrorInfo" + }, + "headers": { + "Content-Type": { + "type": "string", + "description": "application/problem+json" + } } } } @@ -47,13 +53,19 @@ "/health_check": { "get": { "description": "Get the status of the producer. Will show if the producer has registered in ICS.", + "produces": [ + "application/json" + ], "tags": [ "Data producer (callbacks)" ], "summary": "Get status", "responses": { "200": { - "description": "" + "description": "OK", + "schema": { + "$ref": "#/definitions/" + } } } } @@ -75,7 +87,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/jobs.JobInfo" + "$ref": "#/definitions/JobInfo" } } ], @@ -84,9 +96,15 @@ "description": "" }, "400": { - "description": "Bad Request", + "description": "Problem as defined in https://tools.ietf.org/html/rfc7807", "schema": { - "type": "string" + "$ref": "#/definitions/ErrorInfo" + }, + "headers": { + "Content-Type": { + "type": "string", + "description": "application/problem+json" + } } } } @@ -131,7 +149,17 @@ } }, "definitions": { - "jobs.BufferTimeout": { + "": { + "type": "object", + "properties": { + "registeredStatus": { + "description": "The registration status of the producer in Information Coordinator Service. Either `registered` or `not registered`", + "type": "string", + "example": "registered" + } + } + }, + "BufferTimeout": { "type": "object", "properties": { "maxSize": { @@ -142,11 +170,38 @@ } } }, - "jobs.JobInfo": { + "ErrorInfo": { + "type": "object", + "properties": { + "detail": { + "description": "A human-readable explanation specific to this occurrence of the problem.", + "type": "string", + "example": "Info job type not found" + }, + "instance": { + "description": "A URI reference that identifies the specific occurrence of the problem.", + "type": "string" + }, + "status": { + "description": "The HTTP status code generated by the origin server for this occurrence of the problem.", + "type": "integer", + "example": 400 + }, + "title": { + "description": "A short, human-readable summary of the problem type.", + "type": "string" + }, + "type": { + "description": "A URI reference that identifies the problem type.", + "type": "string" + } + } + }, + "JobInfo": { "type": "object", "properties": { "info_job_data": { - "$ref": "#/definitions/jobs.Parameters" + "$ref": "#/definitions/Parameters" }, "info_job_identity": { "type": "string" @@ -165,11 +220,11 @@ } } }, - "jobs.Parameters": { + "Parameters": { "type": "object", "properties": { "bufferTimeout": { - "$ref": "#/definitions/jobs.BufferTimeout" + "$ref": "#/definitions/BufferTimeout" } } } diff --git a/dmaap-mediator-producer/docs/swagger.yaml b/dmaap-mediator-producer/api/swagger.yaml similarity index 55% rename from dmaap-mediator-producer/docs/swagger.yaml rename to dmaap-mediator-producer/api/swagger.yaml index 501b0620..adf70a80 100644 --- a/dmaap-mediator-producer/docs/swagger.yaml +++ b/dmaap-mediator-producer/api/swagger.yaml @@ -1,15 +1,46 @@ definitions: - jobs.BufferTimeout: + "": + properties: + registeredStatus: + description: The registration status of the producer in Information Coordinator + Service. Either `registered` or `not registered` + example: registered + type: string + type: object + BufferTimeout: properties: maxSize: type: integer maxTimeMiliseconds: type: integer type: object - jobs.JobInfo: + ErrorInfo: + properties: + detail: + description: A human-readable explanation specific to this occurrence of the + problem. + example: Info job type not found + type: string + instance: + description: A URI reference that identifies the specific occurrence of the + problem. + type: string + status: + description: The HTTP status code generated by the origin server for this + occurrence of the problem. + example: 400 + type: integer + title: + description: A short, human-readable summary of the problem type. + type: string + type: + description: A URI reference that identifies the problem type. + type: string + type: object + JobInfo: properties: info_job_data: - $ref: '#/definitions/jobs.Parameters' + $ref: '#/definitions/Parameters' info_job_identity: type: string info_type_identity: @@ -21,10 +52,10 @@ definitions: target_uri: type: string type: object - jobs.Parameters: + Parameters: properties: bufferTimeout: - $ref: '#/definitions/jobs.BufferTimeout' + $ref: '#/definitions/BufferTimeout' type: object info: contact: {} @@ -51,9 +82,13 @@ paths: "200": description: "" "400": - description: Bad Request + description: Problem as defined in https://tools.ietf.org/html/rfc7807 + headers: + Content-Type: + description: application/problem+json + type: string schema: - type: string + $ref: '#/definitions/ErrorInfo' summary: Set log level tags: - Admin @@ -61,9 +96,13 @@ paths: get: description: Get the status of the producer. Will show if the producer has registered in ICS. + produces: + - application/json responses: "200": - description: "" + description: OK + schema: + $ref: '#/definitions/' summary: Get status tags: - Data producer (callbacks) @@ -78,14 +117,18 @@ paths: name: user required: true schema: - $ref: '#/definitions/jobs.JobInfo' + $ref: '#/definitions/JobInfo' responses: "200": description: "" "400": - description: Bad Request + description: Problem as defined in https://tools.ietf.org/html/rfc7807 + headers: + Content-Type: + description: application/problem+json + type: string schema: - type: string + $ref: '#/definitions/ErrorInfo' summary: Add info job tags: - Data producer (callbacks) diff --git a/dmaap-mediator-producer/generate_swagger_docs.sh b/dmaap-mediator-producer/generate_swagger_docs.sh index 63bc20d0..8a13f304 100755 --- a/dmaap-mediator-producer/generate_swagger_docs.sh +++ b/dmaap-mediator-producer/generate_swagger_docs.sh @@ -17,4 +17,6 @@ # ############################################################################## -swag init \ No newline at end of file +go get -u github.com/swaggo/swag/cmd/swag +swag init --output api +swag fmt \ No newline at end of file diff --git a/dmaap-mediator-producer/go.mod b/dmaap-mediator-producer/go.mod index 1a035784..ea7b3615 100644 --- a/dmaap-mediator-producer/go.mod +++ b/dmaap-mediator-producer/go.mod @@ -3,17 +3,19 @@ module oransc.org/nonrtric/dmaapmediatorproducer go 1.17 require ( + github.com/confluentinc/confluent-kafka-go v1.8.2 github.com/gorilla/mux v1.8.0 github.com/hashicorp/go-retryablehttp v0.7.0 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 + github.com/swaggo/http-swagger v1.1.2 + github.com/swaggo/swag v1.7.8 ) require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect - github.com/confluentinc/confluent-kafka-go v1.8.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect @@ -29,8 +31,6 @@ require ( github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/stretchr/objx v0.1.0 // indirect github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 // indirect - github.com/swaggo/http-swagger v1.1.2 // indirect - github.com/swaggo/swag v1.7.8 // indirect github.com/urfave/cli/v2 v2.3.0 // indirect golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect diff --git a/dmaap-mediator-producer/internal/jobs/jobs.go b/dmaap-mediator-producer/internal/jobs/jobs.go index c84e2773..86bfe05c 100644 --- a/dmaap-mediator-producer/internal/jobs/jobs.go +++ b/dmaap-mediator-producer/internal/jobs/jobs.go @@ -51,7 +51,7 @@ type JobInfo struct { InfoJobData Parameters `json:"info_job_data"` InfoTypeIdentity string `json:"info_type_identity"` sourceType sourceType -} +} // @name JobInfo type JobTypesManager interface { LoadTypesFromConfiguration(types []config.TypeDefinition) []config.TypeDefinition @@ -327,12 +327,12 @@ func newJob(j JobInfo, c restclient.HTTPClient) job { type Parameters struct { BufferTimeout BufferTimeout `json:"bufferTimeout"` -} +} // @name Parameters type BufferTimeout struct { MaxSize int `json:"maxSize"` MaxTimeMiliseconds int64 `json:"maxTimeMiliseconds"` -} +} // @name BufferTimeout func (j *job) start() { if j.isJobBuffered() { diff --git a/dmaap-mediator-producer/internal/server/server.go b/dmaap-mediator-producer/internal/server/server.go index bc4a1dab..46bc2a23 100644 --- a/dmaap-mediator-producer/internal/server/server.go +++ b/dmaap-mediator-producer/internal/server/server.go @@ -38,6 +38,19 @@ const deleteJobPath = AddJobPath + "/{" + jobIdToken + "}" const logLevelToken = "level" const logAdminPath = "/admin/log" +type ErrorInfo struct { + // A URI reference that identifies the problem type. + Type string `json:"type" swaggertype:"string"` + // A short, human-readable summary of the problem type. + Title string `json:"title" swaggertype:"string"` + // The HTTP status code generated by the origin server for this occurrence of the problem. + Status int `json:"status" swaggertype:"integer" example:"400"` + // A human-readable explanation specific to this occurrence of the problem. + Detail string `json:"detail" swaggertype:"string" example:"Info job type not found"` + // A URI reference that identifies the specific occurrence of the problem. + Instance string `json:"instance" swaggertype:"string"` +} // @name ErrorInfo + type ProducerCallbackHandler struct { jobsManager jobs.JobsManager } @@ -66,21 +79,23 @@ func NewRouter(jm jobs.JobsManager, hcf func(http.ResponseWriter, *http.Request) // @Accept json // @Param user body jobs.JobInfo true "Info job data" // @Success 200 -// @Failure 400 {string} Cause of error +// @Failure 400 {object} ErrorInfo "Problem as defined in https://tools.ietf.org/html/rfc7807" +// @Header 400 {string} Content-Type "application/problem+json" // @Router /info_job [post] func (h *ProducerCallbackHandler) addInfoJobHandler(w http.ResponseWriter, r *http.Request) { b, readErr := ioutil.ReadAll(r.Body) if readErr != nil { - http.Error(w, fmt.Sprintf("Unable to read body due to: %v", readErr), http.StatusBadRequest) + returnError(fmt.Sprintf("Unable to read body due to: %v", readErr), w) return } jobInfo := jobs.JobInfo{} if unmarshalErr := json.Unmarshal(b, &jobInfo); unmarshalErr != nil { - http.Error(w, fmt.Sprintf("Invalid json body. Cause: %v", unmarshalErr), http.StatusBadRequest) + returnError(fmt.Sprintf("Invalid json body. Cause: %v", unmarshalErr), w) return } if err := h.jobsManager.AddJobFromRESTCall(jobInfo); err != nil { - http.Error(w, fmt.Sprintf("Invalid job info. Cause: %v", err), http.StatusBadRequest) + returnError(fmt.Sprintf("Invalid job info. Cause: %v", err), w) + return } } @@ -106,7 +121,8 @@ func (h *ProducerCallbackHandler) deleteInfoJobHandler(w http.ResponseWriter, r // @Tags Admin // @Param level query string false "string enums" Enums(Error, Warn, Info, Debug) // @Success 200 -// @Failure 400 {string} Cause of error +// @Failure 400 {object} ErrorInfo "Problem as defined in https://tools.ietf.org/html/rfc7807" +// @Header 400 {string} Content-Type "application/problem+json" // @Router /admin/log [put] func (h *ProducerCallbackHandler) setLogLevel(w http.ResponseWriter, r *http.Request) { query := r.URL.Query() @@ -114,7 +130,7 @@ func (h *ProducerCallbackHandler) setLogLevel(w http.ResponseWriter, r *http.Req if loglevel, err := log.ParseLevel(logLevelStr); err == nil { log.SetLevel(loglevel) } else { - http.Error(w, fmt.Sprintf("Invalid log level: %v. Log level will not be changed!", logLevelStr), http.StatusBadRequest) + returnError(fmt.Sprintf("Invalid log level: %v. Log level will not be changed!", logLevelStr), w) return } } @@ -130,3 +146,13 @@ type methodNotAllowedHandler struct{} func (h *methodNotAllowedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, "Method is not supported.", http.StatusMethodNotAllowed) } + +func returnError(msg string, w http.ResponseWriter) { + errInfo := ErrorInfo{ + Status: http.StatusBadRequest, + Detail: msg, + } + w.Header().Add("Content-Type", "application/problem+json") + w.WriteHeader(http.StatusBadRequest) + json.NewEncoder(w).Encode(errInfo) +} diff --git a/dmaap-mediator-producer/internal/server/server_test.go b/dmaap-mediator-producer/internal/server/server_test.go index 6fe4d7a7..dbe503dd 100644 --- a/dmaap-mediator-producer/internal/server/server_test.go +++ b/dmaap-mediator-producer/internal/server/server_test.go @@ -96,10 +96,10 @@ func TestAddInfoJobToJobsHandler(t *testing.T) { mockReturn error } tests := []struct { - name string - args args - wantedStatus int - wantedBody string + name string + args args + wantedStatus int + wantedErrorInfo *ErrorInfo }{ { name: "AddInfoJobToJobsHandler with correct job, should return OK", @@ -124,7 +124,10 @@ func TestAddInfoJobToJobsHandler(t *testing.T) { mockReturn: errors.New("error"), }, wantedStatus: http.StatusBadRequest, - wantedBody: "Invalid job info. Cause: error", + wantedErrorInfo: &ErrorInfo{ + Status: http.StatusBadRequest, + Detail: "Invalid job info. Cause: error", + }, }, } for _, tt := range tests { @@ -141,7 +144,16 @@ func TestAddInfoJobToJobsHandler(t *testing.T) { handler.ServeHTTP(responseRecorder, r) assertions.Equal(tt.wantedStatus, responseRecorder.Code, tt.name) - assertions.Contains(responseRecorder.Body.String(), tt.wantedBody, tt.name) + if tt.wantedErrorInfo != nil { + var actualErrInfo ErrorInfo + err := json.Unmarshal(getBody(responseRecorder, t), &actualErrInfo) + if err != nil { + t.Error("Unable to unmarshal error body", err) + t.Fail() + } + assertions.Equal(*tt.wantedErrorInfo, actualErrInfo, tt.name) + assertions.Equal("application/problem+json", responseRecorder.Result().Header.Get("Content-Type")) + } jobsHandlerMock.AssertCalled(t, "AddJobFromRESTCall", tt.args.job) }) } @@ -172,10 +184,10 @@ func TestSetLogLevel(t *testing.T) { logLevel string } tests := []struct { - name string - args args - wantedStatus int - wantedBody string + name string + args args + wantedStatus int + wantedErrorInfo *ErrorInfo }{ { name: "Set to valid log level, should return OK", @@ -190,7 +202,10 @@ func TestSetLogLevel(t *testing.T) { logLevel: "bad", }, wantedStatus: http.StatusBadRequest, - wantedBody: "Invalid log level: bad", + wantedErrorInfo: &ErrorInfo{ + Detail: "Invalid log level: bad. Log level will not be changed!", + Status: http.StatusBadRequest, + }, }, } for _, tt := range tests { @@ -204,7 +219,16 @@ func TestSetLogLevel(t *testing.T) { handler.ServeHTTP(responseRecorder, r) assertions.Equal(tt.wantedStatus, responseRecorder.Code, tt.name) - assertions.Contains(responseRecorder.Body.String(), tt.wantedBody, tt.name) + if tt.wantedErrorInfo != nil { + var actualErrInfo ErrorInfo + err := json.Unmarshal(getBody(responseRecorder, t), &actualErrInfo) + if err != nil { + t.Error("Unable to unmarshal error body", err) + t.Fail() + } + assertions.Equal(*tt.wantedErrorInfo, actualErrInfo, tt.name) + assertions.Equal("application/problem+json", responseRecorder.Result().Header.Get("Content-Type")) + } }) } } @@ -222,3 +246,12 @@ func newRequest(method string, url string, jobInfo *jobs.JobInfo, t *testing.T) return nil } } + +func getBody(responseRecorder *httptest.ResponseRecorder, t *testing.T) []byte { + buf := new(bytes.Buffer) + if _, err := buf.ReadFrom(responseRecorder.Body); err != nil { + t.Error("Unable to read error body", err) + t.Fail() + } + return buf.Bytes() +} diff --git a/dmaap-mediator-producer/main.go b/dmaap-mediator-producer/main.go index ab28c6bc..65a84a21 100644 --- a/dmaap-mediator-producer/main.go +++ b/dmaap-mediator-producer/main.go @@ -22,13 +22,14 @@ package main import ( "crypto/tls" + "encoding/json" "fmt" "net/http" "time" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" - _ "oransc.org/nonrtric/dmaapmediatorproducer/docs" + _ "oransc.org/nonrtric/dmaapmediatorproducer/api" "oransc.org/nonrtric/dmaapmediatorproducer/internal/config" "oransc.org/nonrtric/dmaapmediatorproducer/internal/jobs" "oransc.org/nonrtric/dmaapmediatorproducer/internal/kafkaclient" @@ -45,8 +46,8 @@ func init() { configuration = config.New() } -// @title DMaaP Mediator Producer -// @version 1.1.0 +// @title DMaaP Mediator Producer +// @version 1.1.0 // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html @@ -130,24 +131,32 @@ func startCallbackServer(jobsManager jobs.JobsManager, callbackAddress string) { } } -// @Summary Get status -// @Description Get the status of the producer. Will show if the producer has registered in ICS. -// @Tags Data producer (callbacks) -// @Success 200 -// @Router /health_check [get] +type ProducerStatus struct { + // The registration status of the producer in Information Coordinator Service. Either `registered` or `not registered` + RegisteredStatus string `json:"registeredStatus" swaggertype:"string" example:"registered"` +} // @name ProducerStatus + +// @Summary Get status +// @Description Get the status of the producer. Will show if the producer has registered in ICS. +// @Tags Data producer (callbacks) +// @Produce json +// @Success 200 {object} ProducerStatus +// @Router /health_check [get] func statusHandler(w http.ResponseWriter, r *http.Request) { - registeredStatus := "not registered" + status := ProducerStatus{ + RegisteredStatus: "not registered", + } if registered { - registeredStatus = "registered" + status.RegisteredStatus = "registered" } - fmt.Fprintf(w, `{"status": "%v"}`, registeredStatus) + json.NewEncoder(w).Encode(status) } -// @Summary Get Swagger Documentation -// @Description Get the Swagger API documentation for the producer. -// @Tags Admin -// @Success 200 -// @Router /swagger [get] +// @Summary Get Swagger Documentation +// @Description Get the Swagger API documentation for the producer. +// @Tags Admin +// @Success 200 +// @Router /swagger [get] func addSwaggerHandler(r *mux.Router) { r.PathPrefix("/swagger").Handler(httpSwagger.WrapHandler) } diff --git a/dmaap-mediator-producer/main_test.go b/dmaap-mediator-producer/main_test.go index 3653e9e9..19851be5 100644 --- a/dmaap-mediator-producer/main_test.go +++ b/dmaap-mediator-producer/main_test.go @@ -22,6 +22,7 @@ package main import ( "bytes" + "fmt" "io/ioutil" "net/http" "os/exec" @@ -40,7 +41,10 @@ import ( func TestGenerateSwaggerDocs(t *testing.T) { cmd := exec.Command("./generate_swagger_docs.sh") - cmd.Run() + err := cmd.Run() + if err != nil { + fmt.Println("Error generating Swagger:", err) + } } func TestValidateConfiguration(t *testing.T) { diff --git a/docs/api-docs.rst b/docs/api-docs.rst index c0baa17c..29207b8f 100644 --- a/docs/api-docs.rst +++ b/docs/api-docs.rst @@ -73,7 +73,7 @@ The API is also described in Swagger-JSON and YAML: :header: "API name", "|swagger-icon|", "|yaml-icon|" :widths: 10,5, 5 - "DMaaP Mediator Producer API", ":download:`link <../dmaap-mediator-producer/docs/swagger.json>`", ":download:`link <../dmaap-mediator-producer/docs/swagger.yaml>`" + "DMaaP Mediator Producer API", ":download:`link <../dmaap-mediator-producer/api/swagger.json>`", ":download:`link <../dmaap-mediator-producer/api/swagger.yaml>`" Non-RT-RIC App Catalogue (Initial) ================================== diff --git a/docs/conf.py b/docs/conf.py index d4cdb81e..4ee69983 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -37,7 +37,7 @@ redoc = [ { 'name': 'DMaaP Mediator Producer API', 'page': 'dmaap-mediator-producer-api', - 'spec': '../dmaap-mediator-producer/docs/swagger.json', + 'spec': '../dmaap-mediator-producer/api/swagger.json', 'embed': True, } ] -- 2.16.6