From c0a2bc23de25061a685071f6dc7782a00f66c658 Mon Sep 17 00:00:00 2001 From: wubin1989 <328454505@qq.com> Date: Wed, 11 Jan 2023 10:57:32 +0800 Subject: [PATCH 1/7] ... --- cmd/internal/openapi/v3/codegen/common.go | 28 +- cmd/internal/openapi/v3/codegen/server.go | 2 +- .../openapi/v3/codegen/server/svc_test.go | 32 + .../codegen/testdata/prometheus_openapi3.json | 2547 +++++++++++++++++ .../testdata/testgensvcgo/.dockerignore | 1 + .../v3/codegen/testdata/testgensvcgo/.env | 0 .../codegen/testdata/testgensvcgo/.gitignore | 15 + .../codegen/testdata/testgensvcgo/Dockerfile | 34 + .../codegen/testdata/testgensvcgo/dto/dto.go | 276 ++ .../v3/codegen/testdata/testgensvcgo/go.mod | 26 + .../v3/codegen/testdata/testgensvcgo/svc.go | 623 ++++ toolkit/openapi/v3/model.go | 8 + 12 files changed, 3581 insertions(+), 11 deletions(-) create mode 100644 cmd/internal/openapi/v3/codegen/server/svc_test.go create mode 100644 cmd/internal/openapi/v3/codegen/testdata/prometheus_openapi3.json create mode 100644 cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.dockerignore create mode 100644 cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.env create mode 100644 cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.gitignore create mode 100644 cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/Dockerfile create mode 100644 cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go create mode 100644 cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/go.mod create mode 100644 cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go diff --git a/cmd/internal/openapi/v3/codegen/common.go b/cmd/internal/openapi/v3/codegen/common.go index 6504d903..ebc88c90 100644 --- a/cmd/internal/openapi/v3/codegen/common.go +++ b/cmd/internal/openapi/v3/codegen/common.go @@ -275,7 +275,15 @@ func (receiver *OpenAPICodeGenerator) GenGoDto(schemas map[string]v3.Schema, out astutils.FixImport([]byte(source), output) } -func (receiver *OpenAPICodeGenerator) schema2Field(schema *v3.Schema, name string) *astutils.FieldMeta { +// TODO example2Schema converts example to *v3.Schema +func (receiver *OpenAPICodeGenerator) example2Schema(example interface{}, exampleType v3.ExampleType) *v3.Schema { + return v3.Any +} + +func (receiver *OpenAPICodeGenerator) schema2Field(schema *v3.Schema, name string, example interface{}, exampleType v3.ExampleType) *astutils.FieldMeta { + if schema == nil { + schema = receiver.example2Schema(example, exampleType) + } var comments []string if stringutils.IsNotEmpty(schema.Description) { comments = append(comments, strings.Split(schema.Description, "\n")...) @@ -303,16 +311,16 @@ func (receiver *OpenAPICodeGenerator) responseBody(endpoint, httpMethod string, } if content.JSON != nil { - results = append(results, *receiver.schema2Field(content.JSON.Schema, "ret")) + results = append(results, *receiver.schema2Field(content.JSON.Schema, "ret", content.JSON.Example, v3.JSON_EXAMPLE)) } else if content.Stream != nil { results = append(results, astutils.FieldMeta{ Name: "_downloadFile", Type: "*os.File", }) } else if content.TextPlain != nil { - results = append(results, *receiver.schema2Field(content.TextPlain.Schema, "ret")) + results = append(results, *receiver.schema2Field(content.TextPlain.Schema, "ret", content.TextPlain.Example, v3.TEXT_EXAMPLE)) } else if content.Default != nil { - results = append(results, *receiver.schema2Field(content.Default.Schema, "ret")) + results = append(results, *receiver.schema2Field(content.Default.Schema, "ret", content.TextPlain.Example, v3.TEXT_EXAMPLE)) } else { return nil, errors.Errorf("200 response content definition not support yet in api %s %s", httpMethod, endpoint) } @@ -434,7 +442,7 @@ func (receiver *ClientOperationConverter) form(operation *v3.Operation) (bodyPar content := operation.RequestBody.Content if content.JSON != nil { } else if content.FormURL != nil { - bodyParams = receiver.Generator.schema2Field(content.FormURL.Schema, "bodyParams") + bodyParams = receiver.Generator.schema2Field(content.FormURL.Schema, "bodyParams", content.FormURL.Example, v3.TEXT_EXAMPLE) if !operation.RequestBody.Required && bodyParams != nil { bodyParams.Type = v3.ToOptional(bodyParams.Type) } @@ -455,7 +463,7 @@ func (receiver *ClientOperationConverter) ConvertOperation(endpoint, httpMethod receiver.operationParams(operation.Parameters, &qSchema, &pathvars, &headervars) if len(qSchema.Properties) > 0 { - qparams = receiver.Generator.schema2Field(&qSchema, "queryParams") + qparams = receiver.Generator.schema2Field(&qSchema, "queryParams", nil, v3.UNKNOWN_EXAMPLE) if qSchema.Type == v3.ObjectT && len(qSchema.Required) == 0 { qparams.Type = v3.ToOptional(qparams.Type) } @@ -535,7 +543,7 @@ func (receiver *OpenAPICodeGenerator) requestBody(operation *v3.Operation) (body content := operation.RequestBody.Content if content.JSON != nil { - bodyJSON = receiver.schema2Field(content.JSON.Schema, "bodyJSON") + bodyJSON = receiver.schema2Field(content.JSON.Schema, "bodyJSON", content.JSON.Example, v3.JSON_EXAMPLE) if !operation.RequestBody.Required && bodyJSON != nil { bodyJSON.Type = v3.ToOptional(bodyJSON.Type) } @@ -551,12 +559,12 @@ func (receiver *OpenAPICodeGenerator) requestBody(operation *v3.Operation) (body } files = append(files, f) } else if content.TextPlain != nil { - bodyJSON = receiver.schema2Field(content.TextPlain.Schema, "bodyJSON") + bodyJSON = receiver.schema2Field(content.TextPlain.Schema, "bodyJSON", content.TextPlain.Example, v3.TEXT_EXAMPLE) if !operation.RequestBody.Required && bodyJSON != nil { bodyJSON.Type = v3.ToOptional(bodyJSON.Type) } } else if content.Default != nil { - bodyJSON = receiver.schema2Field(content.Default.Schema, "bodyJSON") + bodyJSON = receiver.schema2Field(content.Default.Schema, "bodyJSON", content.TextPlain.Example, v3.TEXT_EXAMPLE) if !operation.RequestBody.Required && bodyJSON != nil { bodyJSON.Type = v3.ToOptional(bodyJSON.Type) } @@ -596,7 +604,7 @@ func (receiver *OpenAPICodeGenerator) parseFormData(formData *v3.MediaType) (bod } } if len(aSchema.Properties) > 0 { - bodyParams = receiver.schema2Field(&aSchema, "bodyParams") + bodyParams = receiver.schema2Field(&aSchema, "bodyParams", nil, v3.UNKNOWN_EXAMPLE) } return } diff --git a/cmd/internal/openapi/v3/codegen/server.go b/cmd/internal/openapi/v3/codegen/server.go index f21fa49f..4e9616ee 100644 --- a/cmd/internal/openapi/v3/codegen/server.go +++ b/cmd/internal/openapi/v3/codegen/server.go @@ -102,7 +102,7 @@ func (receiver *ServerOperationConverter) parseForm(form *v3.MediaType) (bodyPar if stringutils.IsNotEmpty(gotype) { continue } - field := receiver.Generator.schema2Field(v, k) + field := receiver.Generator.schema2Field(v, k, nil, v3.UNKNOWN_EXAMPLE) if !sliceutils.StringContains(schema.Required, k) { field.Type = v3.ToOptional(field.Type) } diff --git a/cmd/internal/openapi/v3/codegen/server/svc_test.go b/cmd/internal/openapi/v3/codegen/server/svc_test.go new file mode 100644 index 00000000..5bf31e99 --- /dev/null +++ b/cmd/internal/openapi/v3/codegen/server/svc_test.go @@ -0,0 +1,32 @@ +package server + +import ( + "path/filepath" + "testing" +) + +var dir = "../testdata" + +func TestGenSvcGo(t *testing.T) { + type args struct { + dir string + docPath string + } + tests := []struct { + name string + args args + }{ + { + name: "", + args: args{ + dir: filepath.Join(dir, "testgensvcgo"), + docPath: filepath.Join(dir, "prometheus_openapi3.json"), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + GenSvcGo(tt.args.dir, tt.args.docPath) + }) + } +} diff --git a/cmd/internal/openapi/v3/codegen/testdata/prometheus_openapi3.json b/cmd/internal/openapi/v3/codegen/testdata/prometheus_openapi3.json new file mode 100644 index 00000000..0be395f1 --- /dev/null +++ b/cmd/internal/openapi/v3/codegen/testdata/prometheus_openapi3.json @@ -0,0 +1,2547 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Prometheus HTTP API", + "description": "The current stable HTTP API is reachable under /api/v1 on a Prometheus server. Any non-breaking additions will be added under that endpoint.\n\n# Format overview\nThe API response format is JSON. Every successful API request returns a ```2xx``` status code.\n\nInvalid requests that reach the API handlers return a JSON error object and one of the following HTTP response codes:\n\n```400 Bad Request``` when parameters are missing or incorrect.\n```422 Unprocessable Entity``` when an expression can't be executed ([RFC4918](https://datatracker.ietf.org/doc/html/rfc4918#page-78)).\n```503 Service Unavailable``` when queries time out or abort.\n\nOther non-```2xx``` codes may be returned for errors occurring before the API endpoint is reached.\n\nAn array of warnings may be returned if there are errors that do not inhibit the request execution. All of the data that was successfully collected will be returned in the data field.\n\nThe JSON response envelope format is as follows:\n\n```\n{\n \"status\": \"success\" | \"error\",\n \"data\": ,\n\n // Only set if status is \"error\". The data field may still hold\n // additional data.\n \"errorType\": \"\",\n \"error\": \"\",\n\n // Only if there were warnings while executing the request.\n // There will still be data in the data field.\n \"warnings\": [\"\"]\n}\n```\n# Generic placeholders:\n\n``````: Input timestamps may be provided either in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format or as a Unix timestamp in seconds, with optional decimal places for sub-second precision. Output timestamps are always represented as Unix timestamps in seconds.\n\n``````: Prometheus [time series selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors) like ```http_requests_total``` or ```http_requests_total{method=~\"(GET|POST)\"}``` and need to be URL-encoded.\n\n``````: [Prometheus duration strings](https://prometheus.io/docs/prometheus/latest/querying/basics/#time_durations). For example, ```5m``` refers to a duration of 5 minutes.\n\n``````: boolean values (strings ```true``` and ```false```).\n\n**Note**: Names of query parameters that may be repeated end with ```[]```.\n", + "version": "v2" + }, + "servers": [ + { + "url": "/api/v1" + } + ], + "tags": [ + { + "name": "Expression query", + "description": "Query language expressions may be evaluated at a single instant or over a range of time.\n", + "x-displayName": "Expression queries" + }, + { + "name": "Querying metadata", + "description": "Query metadata about series and their labels.\n", + "x-displayName": "Querying metadata" + }, + { + "name": "Default", + "x-displayName": "Default" + }, + { + "name": "Status", + "description": "Expose current Prometheus configuration.\n", + "x-displayName": "Status" + }, + { + "name": "TSDB Admin API", + "description": "Expose database functionalities for the advanced user. \n\nThese APIs are not enabled unless the ```--web.enable-admin-api``` is set.\n", + "x-displayName": "TSDB Admin APIs" + } + ], + "paths": { + "/admin/tsdb/clean_tombstones": { + "put": { + "tags": [ + "TSDB Admin API" + ], + "summary": "Removes deleted data", + "description": "CleanTombstones removes the deleted data from disk and cleans up the existing tombstones. This can be used after deleting series to free up space.\n\nNew in v2.1 and supports PUT from v2.9\n", + "operationId": "cleanTombstonesPUT", + "responses": { + "204": { + "description": "Successful", + "content": {} + } + } + }, + "post": { + "tags": [ + "TSDB Admin API" + ], + "summary": "Removes deleted data", + "description": "CleanTombstones removes the deleted data from disk and cleans up the existing tombstones. This can be used after deleting series to free up space.\n\nNew in v2.1 and supports PUT from v2.9\n", + "operationId": "cleanTombstonesPOST", + "responses": { + "204": { + "description": "Successful", + "content": {} + } + } + } + }, + "/admin/tsdb/delete_series": { + "put": { + "tags": [ + "TSDB Admin API" + ], + "summary": "Deletes selected data", + "description": "DeleteSeries deletes data for a selection of series in a time range. The actual data still exists on disk and is cleaned up in future compactions or can be explicitly cleaned up by hitting the [Clean Tombstones](https://prometheus.io/docs/prometheus/latest/querying/api/#clean-tombstones) endpoint.\n\nNew in v2.1 and supports PUT from v2.9\n", + "operationId": "deleteSeriesPUT", + "parameters": [ + { + "name": "match[]", + "in": "query", + "description": "Repeated label matcher argument that selects the series to delete. At least one match[] argument must be provided.\n\nExample: ```?match[]=up&match[]=process_start_time_seconds{job=\"prometheus\"}'```\n", + "required": true, + "schema": { + "type": "string", + "format": "series_selector" + } + }, + { + "name": "start", + "in": "query", + "description": "Start timestamp. Optional and defaults to minimum possible time.", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp. Optional and defaults to maximum possible time.\n\nNot mentioning both start and end times would clear all the data for the matched series in the database.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + } + ], + "responses": { + "204": { + "description": "Successful", + "content": {} + } + } + }, + "post": { + "tags": [ + "TSDB Admin API" + ], + "summary": "Deletes selected data", + "description": "DeleteSeries deletes data for a selection of series in a time range. The actual data still exists on disk and is cleaned up in future compactions or can be explicitly cleaned up by hitting the [Clean Tombstones](https://prometheus.io/docs/prometheus/latest/querying/api/#clean-tombstones) endpoint.\n\n---\n**NOTE:** This endpoint marks samples from series as deleted, but will not necessarily prevent associated series metadata from still being returned in metadata queries for the affected time range (even after cleaning tombstones). The exact extent of metadata deletion is an implementation detail that may change in the future.\n\n---\n\nNew in v2.1 and supports PUT from v2.9\n", + "operationId": "deleteSeriesPOST", + "parameters": [ + { + "name": "match[]", + "in": "query", + "description": "Repeated label matcher argument that selects the series to delete. At least one match[] argument must be provided.\n\nExample: ```?match[]=up&match[]=process_start_time_seconds{job=\"prometheus\"}'```\n", + "required": true, + "schema": { + "type": "string", + "format": "series_selector" + } + }, + { + "name": "start", + "in": "query", + "description": "Start timestamp. Optional and defaults to minimum possible time.", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp. Optional and defaults to maximum possible time.\n\nNot mentioning both start and end times would clear all the data for the matched series in the database.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + } + ], + "responses": { + "204": { + "description": "Successful", + "content": {} + } + } + } + }, + "/admin/tsdb/snapshot": { + "put": { + "tags": [ + "TSDB Admin API" + ], + "summary": "Creates Snapshot of current data", + "description": "Snapshot creates a snapshot of all current data into ```snapshots/-``` under the TSDB's data directory and returns the directory as response. It will optionally skip snapshotting data that is only present in the head block, and which has not yet been compacted to disk.\n\nNew in v2.1 and supports PUT from v2.9\n", + "operationId": "snapshotPUT", + "parameters": [ + { + "name": "skip_head", + "in": "query", + "description": "Skip data present in the head block. Optional.\n", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "The snapshot now exists at ```/snapshots/20171210T211224Z-2be650b6d019eb54```", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseSnapshot" + }, + "example": { + "status": "success", + "data": { + "name": "20171210T211224Z-2be650b6d019eb54" + } + } + } + } + } + } + }, + "post": { + "tags": [ + "TSDB Admin API" + ], + "summary": "Creates Snapshot of current data", + "description": "Snapshot creates a snapshot of all current data into ```snapshots/-``` under the TSDB's data directory and returns the directory as response. It will optionally skip snapshotting data that is only present in the head block, and which has not yet been compacted to disk.\n\nNew in v2.1 and supports PUT from v2.9\n", + "operationId": "snapshotPOST", + "parameters": [ + { + "name": "skip_head", + "in": "query", + "description": "Skip data present in the head block. Optional.\n", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "The snapshot now exists at ```/snapshots/20171210T211224Z-2be650b6d019eb54```", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseSnapshot" + }, + "example": { + "status": "success", + "data": { + "name": "20171210T211224Z-2be650b6d019eb54" + } + } + } + } + } + } + } + }, + "/alertmanagers": { + "get": { + "tags": [ + "Default" + ], + "summary": "Returns current alertmanager discovery", + "description": "Returns an overview of the current state of the Prometheus alertmanager discovery\n\nBoth the active and dropped Alertmanagers are part of the response.\n", + "operationId": "alertManagersGET", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AlertmanagerDiscovery" + }, + "example": { + "status": "success", + "data": { + "activeAlertmanagers": [ + { + "url": "http://127.0.0.1:9090/api/v1/alerts" + } + ], + "droppedAlertmanagers": [ + { + "url": "http://127.0.0.1:9093/api/v1/alerts" + } + ] + } + } + } + } + } + } + } + }, + "/alerts": { + "get": { + "tags": [ + "Default" + ], + "summary": "Returns active alerts", + "description": "The /alerts endpoint returns a list of all active alerts.\n\nAs the /alerts endpoint is fairly new, it does not have the same stability guarantees as the overarching API v1.\n", + "operationId": "AlertsGET", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Alert" + }, + "example": { + "data": { + "alerts": [ + { + "activeAt": "2018-07-04T18:27:12.606Z", + "annotations": {}, + "labels": { + "alertname": "my-alert" + }, + "state": "firing", + "value": 1 + } + ] + }, + "status": "success" + } + } + } + } + } + } + }, + "/label/{label_name}/values": { + "get": { + "tags": [ + "Querying metadata" + ], + "summary": "Returns label values", + "description": "The following endpoint returns a list of label values for a provided label name\n\nThe ```data``` section of the JSON response is a list of string label values.\n\n---\n**NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future.\n\n---\n", + "operationId": "labelValuesGET", + "parameters": [ + { + "name": "label_name", + "in": "path", + "description": "Label name\n\nExample: ```/label/job/values```\n", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "start", + "in": "query", + "description": "Start timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "match[]", + "in": "query", + "description": "Repeated series selector argument that selects the series from which to read the label values. Optional.\n", + "schema": { + "type": "string", + "format": "series_selector" + } + } + ], + "responses": { + "200": { + "description": "Success\n\nThis example queries for all label values for the job label\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseLabelValues" + }, + "example": { + "status": "success", + "data": [ + "node", + "prometheus" + ] + } + } + } + } + } + } + }, + "/labels": { + "get": { + "tags": [ + "Querying metadata" + ], + "summary": "Returns label names", + "description": "The following endpoint returns a list of label names\n\nThe ```data``` section of the JSON response is a list of string label names.\n\n---\n**NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future.\n\n---\n", + "operationId": "labelNamesGET", + "parameters": [ + { + "name": "start", + "in": "query", + "description": "Start timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "match[]", + "in": "query", + "description": "Repeated series selector argument that selects the series from which to read the label values. Optional.\n", + "schema": { + "type": "string", + "format": "series_selector" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseLabelNames" + }, + "example": { + "status": "success", + "data": [ + "__name__", + "call", + "code", + "config", + "dialer_name", + "endpoint", + "event", + "goversion", + "handler", + "instance", + "interval", + "job", + "le", + "listener_name", + "name", + "quantile", + "reason", + "role", + "scrape_job", + "slice", + "version" + ] + } + } + } + } + } + }, + "post": { + "tags": [ + "Querying metadata" + ], + "summary": "Returns label names", + "description": "The following endpoint returns a list of label names\n\nThe ```data``` section of the JSON response is a list of string label names.\n", + "operationId": "labelNamesPOST", + "parameters": [ + { + "name": "start", + "in": "query", + "description": "Start timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "match[]", + "in": "query", + "description": "Repeated series selector argument that selects the series from which to read the label values. Optional.\n", + "schema": { + "type": "string", + "format": "series_selector" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseLabelNames" + }, + "example": { + "status": "success", + "data": [ + "__name__", + "call", + "code", + "config", + "dialer_name", + "endpoint", + "event", + "goversion", + "handler", + "instance", + "interval", + "job", + "le", + "listener_name", + "name", + "quantile", + "reason", + "role", + "scrape_job", + "slice", + "version" + ] + } + } + } + } + } + } + }, + "/metadata": { + "get": { + "tags": [ + "Default" + ], + "summary": "Returns metric metadata", + "description": "It returns metadata about metrics currently scrapped from targets. However, it does not provide any target information. This is considered experimental and might change in the future.\n\nThe data section of the query result consists of an object where each key is a metric name and each value is a list of unique metadata objects, as exposed for that metric name across all targets.\n", + "operationId": "metricMetadataGET", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "Maximum number of metrics to return.\n\nExample: ```?limit=2```\n", + "required": true, + "schema": { + "type": "number" + } + }, + { + "name": "metric", + "in": "query", + "description": "A metric name to filter metadata for. All metric metadata is retrieved if left empty.\n\nExample: ```?metric=http_requests_total```\n", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success\n\nThe following example returns two metrics. Note that the metric ```http_requests_total``` has more than one object in the list. At least one target has a value for ```HELP``` that do not match with the rest.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseMetadata" + }, + "example": { + "status": "success", + "data": { + "cortex_ring_tokens": [ + { + "type": "gauge", + "help": "Number of tokens in the ring", + "unit": "" + } + ], + "http_requests_total": [ + { + "type": "counter", + "help": "Number of HTTP requests", + "unit": "" + }, + { + "type": "counter", + "help": "Amount of HTTP requests", + "unit": "" + } + ] + } + } + } + } + }, + "201": { + "description": "Success\n\nThe following example returns metadata only for the metric ```http_requests_total```.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseMetadata" + }, + "example": { + "status": "success", + "data": { + "http_requests_total": [ + { + "type": "counter", + "help": "Number of HTTP requests", + "unit": "" + }, + { + "type": "counter", + "help": "Amount of HTTP requests", + "unit": "" + } + ] + } + } + } + } + } + } + } + }, + "/query": { + "get": { + "tags": [ + "Expression query" + ], + "summary": "Evaluates instant query", + "description": "The following endpoint evaluates an instant query at a single point in time\n\nYou can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits.\n\nThe data section of the query result has the following format\n```\n{\n \"resultType\": \"matrix\" | \"vector\" | \"scalar\" | \"string\",\n \"result\": \n}\n```\n`````` refers to the query result data, which has varying formats depending on the ```resultType```. See the [expression query result formats](https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats).\n", + "operationId": "queryGET", + "parameters": [ + { + "name": "query", + "in": "query", + "description": "Prometheus expression query string.\n\nExample: ```?query=up```\n", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "Evaluation timestamp. Optional.\n\nThe current server time is used if the ```time``` parameter is omitted.\n\nExample: ```?metric=http_requests_total```\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "timeout", + "in": "query", + "description": "Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag.\n\nExample: ```?metric=http_requests_total```\n", + "schema": { + "type": "string", + "format": "duration" + } + } + ], + "responses": { + "200": { + "description": "Success\n\nThe following example evaluates the expression ```up``` at the time ```2015-07-01T20:10:51.781Z```\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/queryData" + }, + "example": { + "status": "success", + "data": { + "resultType": "vector", + "result": [ + { + "metric": { + "__name__": "up", + "job": "prometheus", + "instance": "localhost:9090" + }, + "value": [ + 1435781451.781, + "1" + ] + }, + { + "metric": { + "__name__": "up", + "job": "node", + "instance": "localhost:9100" + }, + "value": [ + 1435781451.781, + "0" + ] + } + ] + } + } + } + } + } + } + }, + "post": { + "tags": [ + "Expression query" + ], + "summary": "Evaluates instant query", + "description": "The following endpoint evaluates an instant query at a single point in time\n\nYou can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits.\n\nThe data section of the query result has the following format\n```\n{\n \"resultType\": \"matrix\" | \"vector\" | \"scalar\" | \"string\",\n \"result\": \n}\n```\n`````` refers to the query result data, which has varying formats depending on the ```resultType```. See the [expression query result formats](https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats).\n", + "operationId": "queryPOST", + "parameters": [ + { + "name": "query", + "in": "query", + "description": "Prometheus expression query string.\n\nExample: ```?query=up```\n", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "time", + "in": "query", + "description": "Evaluation timestamp. Optional.\n\nThe current server time is used if the ```time``` parameter is omitted.\n\nExample: ```?metric=http_requests_total```\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "timeout", + "in": "query", + "description": "Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag.\n\nExample: ```?metric=http_requests_total```\n", + "schema": { + "type": "string", + "format": "duration" + } + } + ], + "responses": { + "200": { + "description": "Success\n\nThe following example evaluates the expression ```up``` at the time ```2015-07-01T20:10:51.781Z```\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/queryData" + }, + "example": { + "status": "success", + "data": { + "resultType": "vector", + "result": [ + { + "metric": { + "__name__": "up", + "job": "prometheus", + "instance": "localhost:9090" + }, + "value": [ + 1435781451.781, + "1" + ] + }, + { + "metric": { + "__name__": "up", + "job": "node", + "instance": "localhost:9100" + }, + "value": [ + 1435781451.781, + "0" + ] + } + ] + } + } + } + } + } + } + } + }, + "/query_exemplars": { + "get": { + "tags": [ + "Expression query" + ], + "summary": "Returns list of Exemplars", + "description": "This is experimental and might change in the future. The following endpoint returns a list of exemplars for a valid PromQL query for a specific time range\n", + "operationId": "queryExemplarsGET", + "parameters": [ + { + "name": "query", + "in": "query", + "description": "Prometheus expression query string.\n\nExample: ```?query=test_exemplar_metric_total```\n", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "start", + "in": "query", + "description": "Start timestamp.\n\nExample: ```&start=2020-09-14T15:22:25.479Z```\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp.\n\nExample: ```&end=020-09-14T15:23:25.479Z```\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseQuery_exemplars" + }, + "example": { + "status": "success", + "data": [ + { + "seriesLabels": { + "__name__": "test_exemplar_metric_total", + "instance": "localhost:8090", + "job": "prometheus", + "service": "bar" + }, + "exemplars": [ + { + "labels": { + "traceID": "EpTxMJ40fUus7aGY" + }, + "value": "6", + "timestamp": 1600096945.479 + } + ] + }, + { + "seriesLabels": { + "__name__": "test_exemplar_metric_total", + "instance": "localhost:8090", + "job": "prometheus", + "service": "foo" + }, + "exemplars": [ + { + "labels": { + "traceID": "Olp9XHlq763ccsfa" + }, + "value": "19", + "timestamp": 1600096955.479 + }, + { + "labels": { + "traceID": "hCtjygkIHwAN9vs4" + }, + "value": "20", + "timestamp": 1600096965.489 + } + ] + } + ] + } + } + } + } + } + }, + "post": { + "tags": [ + "Expression query" + ], + "summary": "Returns list of Exemplars", + "description": "This is experimental and might change in the future. The following endpoint returns a list of exemplars for a valid PromQL query for a specific time range\n", + "operationId": "queryExemplarsPOST", + "parameters": [ + { + "name": "query", + "in": "query", + "description": "Prometheus expression query string.\n\nExample: ```?query=test_exemplar_metric_total```\n", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "start", + "in": "query", + "description": "Start timestamp.\n\nExample: ```&start=2020-09-14T15:22:25.479Z```\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp.\n\nExample: ```&end=020-09-14T15:23:25.479Z```\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseQuery_exemplars" + }, + "example": { + "status": "success", + "data": [ + { + "seriesLabels": { + "__name__": "test_exemplar_metric_total", + "instance": "localhost:8090", + "job": "prometheus", + "service": "bar" + }, + "exemplars": [ + { + "labels": { + "traceID": "EpTxMJ40fUus7aGY" + }, + "value": "6", + "timestamp": 1600096945.479 + } + ] + }, + { + "seriesLabels": { + "__name__": "test_exemplar_metric_total", + "instance": "localhost:8090", + "job": "prometheus", + "service": "foo" + }, + "exemplars": [ + { + "labels": { + "traceID": "Olp9XHlq763ccsfa" + }, + "value": "19", + "timestamp": 1600096955.479 + }, + { + "labels": { + "traceID": "hCtjygkIHwAN9vs4" + }, + "value": "20", + "timestamp": 1600096965.489 + } + ] + } + ] + } + } + } + } + } + } + }, + "/query_range": { + "get": { + "tags": [ + "Expression query" + ], + "summary": "Evaluates query over range of time.", + "description": "The following endpoint evaluates an expression query over a range of time\n\nYou can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits.\n\nThe data section of the query result has the following format\n```\n{\n \"resultType\": \"matrix\",\n \"result\": \n}\n```\nFor the format of the `````` placeholder, see the [range-vector result format](https://prometheus.io/docs/prometheus/latest/querying/api/#range-vectors).\n", + "operationId": "queryRangeGET", + "parameters": [ + { + "name": "query", + "in": "query", + "description": "Prometheus expression query string.\n\nExample: ```?query=up```\n", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "start", + "in": "query", + "description": "Start timestamp.\n\nExample: ```&start=2015-07-01T20:10:30.781Z```\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp.\n\nExample: ```&end=2015-07-01T20:11:00.781Z```\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "step", + "in": "query", + "description": "Query resolution step width in ```duration``` format or float number of seconds.\n\nExample: ```&step=15s```\n", + "schema": { + "type": "string", + "format": "duration | float" + } + }, + { + "name": "timeout", + "in": "query", + "description": "Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag.\n\nExample: ```?metric=http_requests_total```\n", + "schema": { + "type": "string", + "format": "duration" + } + } + ], + "responses": { + "200": { + "description": "Success\n\nThe following example evaluates the expression ```up``` over a 30-second range with a query resolution of 15 seconds.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseQuery_range" + }, + "example": { + "status": "success", + "data": { + "resultType": "matrix", + "result": [ + { + "metric": { + "__name__": "up", + "job": "prometheus", + "instance": "localhost:9090" + }, + "values": [ + [ + 1435781430.781, + "1" + ], + [ + 1435781445.781, + "1" + ], + [ + 1435781460.781, + "1" + ] + ] + }, + { + "metric": { + "__name__": "up", + "job": "node", + "instance": "localhost:9091" + }, + "values": [ + [ + 1435781430.781, + "0" + ], + [ + 1435781445.781, + "0" + ], + [ + 1435781460.781, + "1" + ] + ] + } + ] + } + } + } + } + } + } + }, + "post": { + "tags": [ + "Expression query" + ], + "summary": "Evaluates query over range of time.", + "description": "The following endpoint evaluates an expression query over a range of time\n\nYou can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits.\n\nThe data section of the query result has the following format\n```\n{\n \"resultType\": \"matrix\",\n \"result\": \n}\n```\nFor the format of the `````` placeholder, see the [range-vector result format](https://prometheus.io/docs/prometheus/latest/querying/api/#range-vectors).\n", + "operationId": "queryRangePOST", + "parameters": [ + { + "name": "query", + "in": "query", + "description": "Prometheus expression query string.\n\nExample: ```?query=up```\n", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "start", + "in": "query", + "description": "Start timestamp.\n\nExample: ```&start=2015-07-01T20:10:30.781Z```\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp.\n\nExample: ```&end=2015-07-01T20:11:00.781Z```\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "step", + "in": "query", + "description": "Query resolution step width in ```duration``` format or float number of seconds.\n\nExample: ```&step=15s```\n", + "schema": { + "type": "string", + "format": "duration | float" + } + }, + { + "name": "timeout", + "in": "query", + "description": "Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag.\n\nExample: ```?metric=http_requests_total```\n", + "schema": { + "type": "string", + "format": "duration" + } + } + ], + "responses": { + "200": { + "description": "Success\n\nThe following example evaluates the expression ```up``` over a 30-second range with a query resolution of 15 seconds.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseQuery_range" + }, + "example": { + "status": "success", + "data": { + "resultType": "matrix", + "result": [ + { + "metric": { + "__name__": "up", + "job": "prometheus", + "instance": "localhost:9090" + }, + "values": [ + [ + 1435781430.781, + "1" + ], + [ + 1435781445.781, + "1" + ], + [ + 1435781460.781, + "1" + ] + ] + }, + { + "metric": { + "__name__": "up", + "job": "node", + "instance": "localhost:9091" + }, + "values": [ + [ + 1435781430.781, + "0" + ], + [ + 1435781445.781, + "0" + ], + [ + 1435781460.781, + "1" + ] + ] + } + ] + } + } + } + } + } + } + } + }, + "/rules": { + "get": { + "tags": [ + "Default" + ], + "summary": "Returns currently loaded rules", + "description": "The ```/rules``` API endpoint returns a list of alerting and recording rules that are currently loaded. In addition it returns the currently active alerts fired by the Prometheus instance of each alerting rule.\n\nAs the ```/rules``` endpoint is fairly new, it does not have the same stability guarantees as the overarching API v1.", + "operationId": "rulesGET", + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Return only the alerting rules (e.g. ```type=alert```) or the recording rules (e.g. ```type=record```). When the parameter is absent or empty, no filtering is done.\n", + "schema": { + "type": "string", + "enum": [ + "alert", + "record" + ] + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleDiscovery" + }, + "example": { + "data": { + "groups": [ + { + "rules": [ + { + "alerts": [ + { + "activeAt": "2018-07-04T18:27:12.606Z", + "annotations": { + "summary": "High request latency" + }, + "labels": { + "alertname": "HighRequestLatency", + "severity": "page" + }, + "state": "firing", + "value": 1 + } + ], + "annotations": { + "summary": "High request latency" + }, + "duration": 600, + "health": "ok", + "labels": { + "severity": "page" + }, + "name": "HighRequestLatency", + "query": "job:request_latency_seconds:mean5m{job=\"myjob\"} > 0.5", + "type": "alerting" + }, + { + "health": "ok", + "name": "job:http_inprogress_requests:sum", + "query": "sum by (job) (http_inprogress_requests)", + "type": "recording" + } + ], + "file": "/rules.yaml", + "interval": 60, + "name": "example" + } + ] + }, + "status": "success" + } + } + } + } + } + } + }, + "/series": { + "get": { + "tags": [ + "Querying metadata" + ], + "summary": "Returns time series", + "description": "The following endpoint returns the list of time series that match a certain label set.\n\nYou can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits.\n\nThe ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series.\n", + "operationId": "seriesGET", + "parameters": [ + { + "name": "start", + "in": "query", + "description": "Start timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "match[]", + "in": "query", + "description": "Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided.\n\nExample: ```?' --data-urlencode 'match[]=up'```\n", + "required": true, + "schema": { + "type": "string", + "format": "series_selector" + } + } + ], + "responses": { + "200": { + "description": "Success\n\nThe following example returns all series that match either of the selectors ```up``` or ```process_start_time_seconds{job=\"prometheus\"}```\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseSeries" + }, + "example": { + "status": "success", + "data": [ + { + "__name__": "up", + "job": "prometheus", + "instance": "localhost:9090" + }, + { + "__name__": "up", + "job": "node", + "instance": "localhost:9091" + }, + { + "__name__": "process_start_time_seconds", + "job": "prometheus", + "instance": "localhost:9090" + } + ] + } + } + } + } + } + }, + "post": { + "tags": [ + "Querying metadata" + ], + "summary": "Returns time series", + "description": "The following endpoint returns the list of time series that match a certain label set.\n\nYou can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits.\n\nThe ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series.\n", + "operationId": "seriesPOST", + "parameters": [ + { + "name": "start", + "in": "query", + "description": "Start timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "match[]", + "in": "query", + "description": "Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided.\n\nExample: ```?' --data-urlencode 'match[]=up'```\n", + "required": true, + "schema": { + "type": "string", + "format": "series_selector" + } + } + ], + "responses": { + "200": { + "description": "Success\n\nThe following example returns all series that match either of the selectors ```up``` or ```process_start_time_seconds{job=\"prometheus\"}```\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseSeries" + }, + "example": { + "status": "success", + "data": [ + { + "__name__": "up", + "job": "prometheus", + "instance": "localhost:9090" + }, + { + "__name__": "up", + "job": "node", + "instance": "localhost:9091" + }, + { + "__name__": "process_start_time_seconds", + "job": "prometheus", + "instance": "localhost:9090" + } + ] + } + } + } + } + } + }, + "delete": { + "tags": [ + "Querying metadata" + ], + "summary": "Returns time series", + "description": "The following endpoint returns the list of time series that match a certain label set.\n\nYou can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits.\n\nThe ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series.\n\n---\n**NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future.\n\n---\n", + "operationId": "seriesDELETE", + "parameters": [ + { + "name": "start", + "in": "query", + "description": "Start timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "end", + "in": "query", + "description": "End timestamp. Optional.\n", + "schema": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + } + }, + { + "name": "match[]", + "in": "query", + "description": "Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided.\n\nExample: ```?' --data-urlencode 'match[]=up'```\n", + "required": true, + "schema": { + "type": "string", + "format": "series_selector" + } + } + ], + "responses": { + "200": { + "description": "Success\n\nThe following example returns all series that match either of the selectors ```up``` or ```process_start_time_seconds{job=\"prometheus\"}```\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseSeries" + }, + "example": { + "status": "success", + "data": [ + { + "__name__": "up", + "job": "prometheus", + "instance": "localhost:9090" + }, + { + "__name__": "up", + "job": "node", + "instance": "localhost:9091" + }, + { + "__name__": "process_start_time_seconds", + "job": "prometheus", + "instance": "localhost:9090" + } + ] + } + } + } + } + } + } + }, + "/status/buildinfo": { + "get": { + "tags": [ + "Status" + ], + "summary": "Returns build information", + "description": "The following endpoint returns various build information properties about the Prometheus server\n\nAll values are of the result type ```string```.\n\n---\n**NOTE:** The exact returned build properties may change without notice between Prometheus versions.\n\n---\n\nNew in v2.14\n", + "operationId": "serveBuildInfo", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PrometheusVersion" + }, + "example": { + "status": "success", + "data": { + "version": "2.13.1", + "revision": "cb7cbad5f9a2823a622aaa668833ca04f50a0ea7", + "branch": "master", + "buildUser": "julius@desktop", + "buildDate": "20191102-16:19:59", + "goVersion": "go1.13.1" + } + } + } + } + } + } + } + }, + "/status/config": { + "get": { + "tags": [ + "Status" + ], + "summary": "Returns configuration file", + "description": "The following endpoint returns currently loaded configuration file\n\nThe config is returned as dumped YAML file. Due to limitation of\nthe YAML library, YAML comments are not included.\n", + "operationId": "serveConfig", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/prometheusConfig" + }, + "example": { + "status": "success", + "data": { + "yaml": "" + } + } + } + } + } + } + } + }, + "/status/flags": { + "get": { + "tags": [ + "Status" + ], + "summary": "Returns flag values", + "description": "The following endpoint returns flag values that Prometheus was configured with\n\nAll values are of the result type ```string```.\n\nNew in v2.2\n", + "operationId": "serveFlags", + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "example": { + "status": "success", + "data": { + "alertmanager.notification-queue-capacity": "10000", + "alertmanager.timeout": "10s", + "log.level": "info", + "query.lookback-delta": "5m", + "query.max-concurrency": "20" + } + } + } + } + } + } + } + }, + "/status/runtimeinfo": { + "get": { + "tags": [ + "Status" + ], + "summary": "Returns runtime info", + "description": "The following endpoint returns various runtime information properties about the Prometheus server\n\nThe returned values are of different types, depending on the nature\nof the runtime property\n\n---\n**NOTE:** The exact returned runtime properties may change without notice between Prometheus versions.\n\n---\n\nNew in v2.14\n", + "operationId": "serveRuntimeInfo", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuntimeInfo" + }, + "example": { + "status": "success", + "data": { + "startTime": "2019-11-02T16:23:59.301Z", + "CWD": "/", + "reloadConfigSuccess": true, + "lastConfigTime": "2019-11-02T16:23:59.000Z", + "timeSeriesCount": 873, + "corruptionCount": 0, + "goroutineCount": 48, + "GOMAXPROCS": 4, + "GOGC": "", + "GODEBUG": "", + "storageRetention": "15d" + } + } + } + } + } + } + } + }, + "/status/tsdb": { + "get": { + "tags": [ + "Status" + ], + "summary": "Returns statistics about TSBD", + "description": "The following endpoint returns various cardinality statistics about the Prometheus TSDB\n\nResponse Data\n---\n\n**headStats:** This provides the following data about the head block of the TSDB:\n>**numSeries:** The number of series.\n**chunkCount:** The number of chunks.\n**minTime:** The current minimum timestamp in milliseconds.\n**maxTime:** The current maximum timestamp in milliseconds.\n\n**seriesCountByMetricName:** This will provide a list of metrics names and their series count.\n**labelValueCountByLabelName:** This will provide a list of the label names and their value count.\n**memoryInBytesByLabelName:** This will provide a list of the label names and memory used in bytes. Memory usage is calculated by adding the length of all values for a given label name.\n**seriesCountByLabelPair:** This will provide a list of label value pairs and their series count.\n", + "operationId": "serveTSDBStatus", + "responses": { + "200": { + "description": "Success\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/tsdbStatus" + }, + "example": { + "status": "success", + "data": { + "headStats": { + "numSeries": 508, + "chunkCount": 937, + "minTime": 1591516800000, + "maxTime": 1598896800143 + }, + "seriesCountByMetricName": [ + { + "name": "net_conntrack_dialer_conn_failed_total", + "value": 20 + }, + { + "name": "prometheus_http_request_duration_seconds_bucket", + "value": 20 + } + ], + "labelValueCountByLabelName": [ + { + "name": "__name__", + "value": 211 + }, + { + "name": "event", + "value": 3 + } + ], + "memoryInBytesByLabelName": [ + { + "name": "__name__", + "value": 8266 + }, + { + "name": "instance", + "value": 28 + } + ], + "seriesCountByLabelValuePair": [ + { + "name": "job=prometheus", + "value": 425 + }, + { + "name": "instance=localhost:9090", + "value": 425 + } + ] + } + } + } + } + } + } + } + }, + "/status/walreplay": { + "get": { + "tags": [ + "Status" + ], + "summary": "Returns info about WAL replay.", + "description": "The following endpoint returns information about the WAL replay\n\nResponse Data\n---\n\n**read:** The number of segments replayed so far. \n**total:** The total number segments needed to be replayed. \n**progress:** The progress of the replay (0 - 100%). \n**state:** The state of the replay. \n**Possible states:** \n - **waiting:** Waiting for the replay to start. \n - **in progress:** The replay is in progress. \n - **done:** The replay has finished.\n \n---\n**NOTE:** This endpoint is available before the server has been marked ready and is updated in real time to facilitate monitoring the progress of the WAL replay.\n\n---\n\nNew in v2.28\n", + "operationId": "serveWALReplayStatus", + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/walReplayStatus" + }, + "example": { + "status": "success", + "data": { + "min": 2, + "max": 5, + "current": 40, + "state": "in progress" + } + } + } + } + } + } + } + }, + "/targets": { + "get": { + "tags": [ + "Default" + ], + "summary": "Returns current target discovery.", + "description": "Both the active and dropped targets are part of the response by default. ```labels``` represents the label set after relabelling has occurred. ```discoveredLabels``` represent the unmodified labels retrieved during service discovery before relabelling has occurred.\n", + "operationId": "targetsGET", + "parameters": [ + { + "name": "state", + "in": "query", + "description": "The ```state``` query parameter allows the caller to filter by active or dropped targets, (e.g., ```state=active```, ```state=dropped```, ```state=any```).\n", + "schema": { + "type": "string", + "enum": [ + "active", + "dropped", + "any" + ] + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TargetDiscovery" + }, + "example": { + "status": "success", + "data": { + "activeTargets": [ + { + "discoveredLabels": { + "__address__": "127.0.0.1:9090", + "__metrics_path__": "/metrics", + "__scheme__": "http", + "job": "prometheus" + }, + "labels": { + "instance": "127.0.0.1:9090", + "job": "prometheus" + }, + "scrapePool": "prometheus", + "scrapeUrl": "http://127.0.0.1:9090/metrics", + "globalUrl": "http://example-prometheus:9090/metrics", + "lastError": "", + "lastScrape": "2017-01-17T14:07:44.723Z", + "lastScrapeDuration": 0.050688943, + "health": "up" + } + ], + "droppedTargets": [ + { + "discoveredLabels": { + "__address__": "127.0.0.1:9100", + "__metrics_path__": "/metrics", + "__scheme__": "http", + "job": "node" + } + } + ] + } + } + } + } + }, + "201": { + "description": "Success\n\nNote that an empty array is still returned for targets that are filtered out. Other values are ignored.\n\nExample: ?state=active\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TargetDiscovery" + }, + "example": { + "status": "success", + "data": { + "activeTargets": [ + { + "discoveredLabels": { + "__address__": "127.0.0.1:9090", + "__metrics_path__": "/metrics", + "__scheme__": "http", + "job": "prometheus" + }, + "labels": { + "instance": "127.0.0.1:9090", + "job": "prometheus" + }, + "scrapePool": "prometheus", + "scrapeUrl": "http://127.0.0.1:9090/metrics", + "globalUrl": "http://example-prometheus:9090/metrics", + "lastError": "", + "lastScrape": "2017-01-17T14:07:44.723Z", + "lastScrapeDuration": 50688943, + "health": "up" + } + ], + "droppedTargets": [] + } + } + } + } + } + } + } + }, + "/targets/metadata": { + "get": { + "tags": [ + "Default" + ], + "summary": "Returns target metadata", + "description": "The following endpoint returns metadata about metrics currently scraped from targets. This is experimental and might change in the future.\n\nThe ```data``` section of the query result consists of a list of objects that contain metric metadata and the target label set.", + "operationId": "TargetMetadataGET", + "parameters": [ + { + "name": "match_target", + "in": "query", + "description": "Label selectors that match targets by their label sets. All targets are selected if left empty.\n\nExample: ```match_target={job=\"prometheus\"}```\n", + "schema": { + "type": "string", + "format": "label_selectors" + } + }, + { + "name": "metric", + "in": "query", + "description": "A metric name to retrieve metadata for. All metric metadata is retrieved if left empty.\n\nExample: ```metric=go_goroutines```\n", + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of targets to match.\n\nExample: ```limit=2```\n", + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Success\n\nThe following example returns all metadata entries for the ```go_goroutines``` metric from the first two targets with label ```job=\"prometheus\"```.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseTargetMetadata" + }, + "example": { + "status": "success", + "data": [ + { + "target": { + "instance": "127.0.0.1:9090", + "job": "prometheus" + }, + "type": "gauge", + "help": "Number of goroutines that currently exist.", + "unit": "" + }, + { + "target": { + "instance": "127.0.0.1:9091", + "job": "prometheus" + }, + "type": "gauge", + "help": "Number of goroutines that currently exist.", + "unit": "" + } + ] + } + } + } + }, + "201": { + "description": "Success\n\nThe following example returns metadata for all metrics for all targets with label ```instance=\"127.0.0.1:9090```.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/responseTargetMetadata" + }, + "example": { + "status": "success", + "data": [ + { + "target": { + "instance": "127.0.0.1:9090", + "job": "prometheus" + }, + "type": "gauge", + "help": "Number of goroutines that currently exist.", + "unit": "" + }, + { + "target": { + "instance": "127.0.0.1:9091", + "job": "prometheus" + }, + "type": "gauge", + "help": "Number of goroutines that currently exist.", + "unit": "" + } + ] + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Alert": { + "type": "object", + "properties": { + "Labels": { + "$ref": "#/components/schemas/Labels" + }, + "Annotations": { + "$ref": "#/components/schemas/Labels" + }, + "State": { + "type": "string" + }, + "ActiveAt": { + "type": "string", + "format": "unix_timestamp" + }, + "Value": { + "type": "string" + } + }, + "description": "Alert has info for an alert." + }, + "AlertmanagerDiscovery": { + "type": "object", + "properties": { + "ActiveAlertmanagers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AlertmanagerTarget" + } + }, + "DroppedAlertmanagers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AlertmanagerTarget" + } + } + }, + "description": "AlertmanagerDiscovery has all the active Alertmanagers." + }, + "AlertmanagerTarget": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "description": "AlertmanagerTarget has info on one AM." + }, + "DiscoveredLabels": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Labels before any processing." + }, + "DroppedTarget": { + "type": "object", + "properties": { + "DiscoveredLabels": { + "$ref": "#/components/schemas/DiscoveredLabels" + } + }, + "description": "DroppedTarget has the information for one target that was dropped during relabelling." + }, + "HeadStats": { + "type": "object", + "properties": { + "chunkCount": { + "type": "integer", + "format": "int64" + }, + "maxTime": { + "type": "integer", + "format": "int64" + }, + "minTime": { + "type": "integer", + "format": "int64" + }, + "numLabelPairs": { + "type": "integer", + "format": "int64" + }, + "numSeries": { + "type": "integer", + "format": "uint64" + } + }, + "description": "HeadStats has information about the TSDB head." + }, + "Label": { + "type": "object", + "properties": { + "Name": { + "type": "string" + }, + "Value": { + "type": "string" + } + }, + "description": "Label is a key/value pair of strings." + }, + "Labels": { + "type": "array", + "description": "Labels is a sorted set of labels. Order has to be guaranteed upon\ninstantiation.", + "items": { + "$ref": "#/components/schemas/Label" + } + }, + "MetricType": { + "type": "string", + "description": "MetricType represents metric type values." + }, + "PrometheusVersion": { + "type": "object", + "properties": { + "branch": { + "type": "string" + }, + "buildDate": { + "type": "string" + }, + "buildUser": { + "type": "string" + }, + "goVersion": { + "type": "string" + }, + "revision": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "description": "PrometheusVersion contains build information about Prometheus." + }, + "RuleDiscovery": { + "type": "object", + "properties": { + "RuleGroups": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RuleGroup" + } + } + }, + "description": "RuleDiscovery has info for all rules" + }, + "RuleGroup": { + "type": "object", + "properties": { + "EvaluationTime": { + "type": "number", + "format": "float64" + }, + "File": { + "type": "string" + }, + "Interval": { + "type": "number", + "format": "float64" + }, + "LastEvaluation": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + }, + "Name": { + "type": "string" + }, + "Rules": { + "type": "array", + "description": "In order to preserve rule ordering, while exposing type (alerting or recording)\nspecific properties, both alerting and recording rules are exposed in the\nsame array.", + "items": { + "$ref": "#/components/schemas/rule" + } + } + }, + "description": "RuleGroup has info for rules which are part of a group" + }, + "RuntimeInfo": { + "type": "object", + "properties": { + "CWD": { + "type": "string" + }, + "GODEBUG": { + "type": "string" + }, + "GOGC": { + "type": "string" + }, + "GOMAXPROCS": { + "type": "integer", + "format": "int" + }, + "corruptionCount": { + "type": "integer", + "format": "int64" + }, + "goroutineCount": { + "type": "integer", + "format": "int" + }, + "lastConfigTime": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + }, + "reloadConfigSuccess": { + "type": "boolean" + }, + "startTime": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + }, + "storageRetention": { + "type": "string" + } + }, + "description": "RuntimeInfo contains runtime information about Prometheus." + }, + "Target": { + "type": "object", + "properties": { + "DiscoveredLabels": { + "$ref": "#/components/schemas/DiscoveredLabels" + }, + "Labels": { + "$ref": "#/components/schemas/Labels" + }, + "ScrapePool": { + "type": "string" + }, + "ScrapeURL": { + "type": "string" + }, + "GlobalURL": { + "type": "string" + }, + "LastError": { + "type": "string" + }, + "LastScrape": { + "type": "string", + "format": "rfc3339 | unix_timestamp" + }, + "LastScrapeDuration": { + "type": "number", + "format": "float64" + }, + "Health": { + "$ref": "#/components/schemas/TargetHealth" + } + }, + "description": "Target has the information for one target." + }, + "TargetDiscovery": { + "type": "object", + "properties": { + "ActiveTargets": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Target" + } + }, + "DroppedTargets": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DroppedTarget" + } + } + }, + "description": "TargetDiscovery has all the active targets." + }, + "TargetHealth": { + "type": "string", + "description": "TargetHealth describes the health state of a target." + }, + "metadata": { + "type": "object", + "properties": { + "Help": { + "type": "string" + }, + "Type": { + "$ref": "#/components/schemas/MetricType" + }, + "Unit": { + "type": "string" + } + } + }, + "metricMetadata": { + "type": "object", + "properties": { + "Help": { + "type": "string" + }, + "Metric": { + "type": "string" + }, + "Target": { + "$ref": "#/components/schemas/Labels" + }, + "Type": { + "$ref": "#/components/schemas/MetricType" + }, + "Unit": { + "type": "string" + } + } + }, + "prometheusConfig": { + "type": "object", + "properties": { + "YAML": { + "type": "string" + } + }, + "description": "a dumped YAML file" + }, + "queryData": { + "type": "object", + "properties": { + "Result": { + "type": "object", + "properties": { + "metric": { + "type": "object", + "properties": { + "__name__": { + "type": "string" + }, + "job": { + "type": "string" + }, + "instance": { + "type": "string" + } + } + }, + "value": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "string", + "format": "unix_timestamp" + }, + { + "type": "string", + "format": "sample_value" + } + ] + } + } + } + }, + "ResultType": { + "type": "string", + "enum": [ + "matrix", + "vector", + "scalar", + "string" + ] + } + } + }, + "responseSeries": { + "type": "array", + "description": "a list of objects that contain the label name/value pairs which identify each series", + "items": { + "type": "object", + "properties": { + "__name__": { + "type": "string" + }, + "job": { + "type": "string" + }, + "instance": { + "type": "string" + } + } + } + }, + "responseSnapshot": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "responseQuery_exemplars": { + "type": "object", + "properties": { + "seriesLabels": { + "type": "object", + "properties": { + "__name__": { + "type": "string" + }, + "job": { + "type": "string" + }, + "instance": { + "type": "string" + }, + "service": { + "type": "string" + } + } + }, + "exemplars": { + "type": "object", + "properties": { + "labels": { + "type": "object", + "properties": { + "traceID": { + "type": "string" + } + } + }, + "values": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "unix_timestamp" + } + } + } + } + }, + "responseQuery_range": { + "type": "object", + "properties": { + "resultType": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "metric": { + "type": "object", + "properties": { + "__name__": { + "type": "string" + }, + "job": { + "type": "string" + }, + "instance": { + "type": "string" + } + } + }, + "values": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "string", + "format": "unix_timestamp" + }, + { + "type": "string", + "format": "sample_value" + } + ] + } + } + } + } + } + }, + "responseMetadata": { + "type": "object", + "properties": { + "metric name": { + "type": "string" + } + }, + "additionalProperties": { + "$ref": "#/components/schemas/metadata" + }, + "description": "a (key, object) map. `metric name`is an example key" + }, + "responseLabelValues": { + "type": "array", + "description": "a list of string label values", + "items": { + "type": "string" + } + }, + "responseLabelNames": { + "type": "array", + "description": "a list of string label names", + "items": { + "type": "string" + } + }, + "responseTargetMetadata": { + "type": "array", + "description": "A list of objects", + "items": { + "$ref": "#/components/schemas/metricMetadata" + } + }, + "rule": { + "type": "object" + }, + "stat": { + "type": "object", + "properties": { + "Name": { + "type": "string" + }, + "Value": { + "type": "integer", + "format": "uint64" + } + }, + "description": "stat holds the information about individual cardinality." + }, + "tsdbStatus": { + "type": "object", + "properties": { + "HeadStats": { + "$ref": "#/components/schemas/HeadStats" + }, + "LabelValueCountByLabelName": { + "type": "array", + "description": "This will provide a list of the label names and their value count.", + "items": { + "$ref": "#/components/schemas/stat" + } + }, + "MemoryInBytesByLabelName": { + "type": "array", + "description": "This will provide a list of the label names and memory used in bytes. Memory usage is calculated by adding the length of all values for a given label name.", + "items": { + "$ref": "#/components/schemas/stat" + } + }, + "SeriesCountByLabelValuePair": { + "type": "array", + "description": "This will provide a list of label value pairs and their series count.", + "items": { + "$ref": "#/components/schemas/stat" + } + }, + "SeriesCountByMetricName": { + "type": "array", + "description": "This will provide a list of metrics names and their series count.", + "items": { + "$ref": "#/components/schemas/stat" + } + } + }, + "description": "tsdbStatus has information of cardinality statistics from postings." + }, + "walReplayStatus": { + "type": "object", + "properties": { + "Current": { + "type": "integer", + "format": "int" + }, + "Max": { + "type": "integer", + "format": "int" + }, + "Min": { + "type": "integer", + "format": "int" + } + } + } + }, + "securitySchemes": { + "Basic": { + "type": "http", + "scheme": "basic" + } + } + } +} \ No newline at end of file diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.dockerignore b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.dockerignore new file mode 100644 index 00000000..a07814a3 --- /dev/null +++ b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.dockerignore @@ -0,0 +1 @@ +**/*.local diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.env b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.env new file mode 100644 index 00000000..e69de29b diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.gitignore b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.gitignore new file mode 100644 index 00000000..1f863c8a --- /dev/null +++ b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/.gitignore @@ -0,0 +1,15 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ +**/*.local +.DS_Store +.idea \ No newline at end of file diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/Dockerfile b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/Dockerfile new file mode 100644 index 00000000..59a15beb --- /dev/null +++ b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/Dockerfile @@ -0,0 +1,34 @@ +FROM devopsworks/golang-upx:1.18 AS builder + +ENV GO111MODULE=on +ENV GOPROXY=https://goproxy.cn,direct +ARG user +ENV HOST_USER=$user + +WORKDIR /repo + +# all the steps are cached +ADD go.mod . +ADD go.sum . +# if go.mod/go.sum not changed, this step is also cached +RUN go mod download + +ADD . ./ +RUN go mod vendor + +RUN export GDD_VER=$(go list -mod=vendor -m -f '{{ .Version }}' github.com/unionj-cloud/go-doudou/v2) && \ +CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -ldflags="-s -w -X 'github.com/unionj-cloud/go-doudou/v2/framework/buildinfo.BuildUser=$HOST_USER' -X 'github.com/unionj-cloud/go-doudou/v2/framework/buildinfo.BuildTime=$(date)' -X 'github.com/unionj-cloud/go-doudou/v2/framework/buildinfo.GddVer=$GDD_VER'" -mod vendor -o api cmd/main.go && \ +strip api && /usr/local/bin/upx api + +FROM alpine:3.14 + +COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai +ENV TZ="Asia/Shanghai" + +WORKDIR /repo + +COPY --from=builder /repo/api ./ + +COPY .env* ./ + +ENTRYPOINT ["/repo/api"] diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go new file mode 100644 index 00000000..e91d6f62 --- /dev/null +++ b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go @@ -0,0 +1,276 @@ +/** +* Generated by go-doudou v2.0.4. +* You can edit it as your need. + */ +package dto + +//go:generate go-doudou name --file $GOFILE +// Alert Alert has info for an alert. +type Alert struct { + ActiveAt *string + + Annotations *Labels + + Labels *Labels + + State *string + + Value *string +} + +// AlertmanagerDiscovery AlertmanagerDiscovery has all the active Alertmanagers. +type AlertmanagerDiscovery struct { + ActiveAlertmanagers []AlertmanagerTarget + + DroppedAlertmanagers []AlertmanagerTarget +} + +// AlertmanagerTarget AlertmanagerTarget has info on one AM. +type AlertmanagerTarget struct { + Url *string +} + +// DroppedTarget DroppedTarget has the information for one target that was dropped during relabelling. +type DroppedTarget struct { + DiscoveredLabels map[string][]string +} + +// HeadStats HeadStats has information about the TSDB head. +type HeadStats struct { + ChunkCount *int64 + + MaxTime *int64 + + MinTime *int64 + + NumLabelPairs *int64 + + NumSeries *int +} + +// Label Label is a key/value pair of strings. +type Label struct { + Name *string + + Value *string +} + +// Labels Labels is a sorted set of labels. Order has to be guaranteed upon +// instantiation. +type Labels struct { +} + +// MetricType MetricType represents metric type values. +type MetricType struct { +} + +// PrometheusVersion PrometheusVersion contains build information about Prometheus. +type PrometheusVersion struct { + Branch *string + + BuildDate *string + + BuildUser *string + + GoVersion *string + + Revision *string + + Version *string +} + +// RuleDiscovery RuleDiscovery has info for all rules +type RuleDiscovery struct { + RuleGroups []RuleGroup +} + +// RuleGroup RuleGroup has info for rules which are part of a group +type RuleGroup struct { + EvaluationTime *float64 + + File *string + + Interval *float64 + + LastEvaluation *string + + Name *string + // In order to preserve rule ordering, while exposing type (alerting or recording) + // specific properties, both alerting and recording rules are exposed in the + // same array. + Rules []Rule +} + +// RuntimeInfo RuntimeInfo contains runtime information about Prometheus. +type RuntimeInfo struct { + CWD *string + + GODEBUG *string + + GOGC *string + + GOMAXPROCS *int + + CorruptionCount *int64 + + GoroutineCount *int + + LastConfigTime *string + + ReloadConfigSuccess *bool + + StartTime *string + + StorageRetention *string +} + +// Target Target has the information for one target. +type Target struct { + DiscoveredLabels map[string][]string + + GlobalURL *string + + Health *TargetHealth + + Labels *Labels + + LastError *string + + LastScrape *string + + LastScrapeDuration *float64 + + ScrapePool *string + + ScrapeURL *string +} + +// TargetDiscovery TargetDiscovery has all the active targets. +type TargetDiscovery struct { + ActiveTargets []Target + + DroppedTargets []DroppedTarget +} + +// TargetHealth TargetHealth describes the health state of a target. +type TargetHealth struct { +} + +type Metadata struct { + Help *string + + Type *MetricType + + Unit *string +} + +type MetricMetadata struct { + Help *string + + Metric *string + + Target *Labels + + Type *MetricType + + Unit *string +} + +// PrometheusConfig a dumped YAML file +type PrometheusConfig struct { + YAML *string +} + +type QueryData struct { + Result *struct { + Metric *struct { + Name *string `json:"__name__" url:"__name__"` + Job *string `json:"job" url:"job"` + Instance *string `json:"instance" url:"instance"` + } `json:"metric" url:"metric"` + Value *[]interface{} `json:"value" url:"value"` + } + + ResultType *string +} + +// ResponseLabelNames a list of string label names +type ResponseLabelNames struct { +} + +// ResponseLabelValues a list of string label values +type ResponseLabelValues struct { +} + +type ResponseQueryExemplars struct { + Exemplars *struct { + Labels *struct { + TraceID *string `json:"traceID" url:"traceID"` + } `json:"labels" url:"labels"` + Values *string `json:"values" url:"values"` + Timestamp *string `json:"timestamp" url:"timestamp"` + } + + SeriesLabels *struct { + Service *string `json:"service" url:"service"` + Name *string `json:"__name__" url:"__name__"` + Job *string `json:"job" url:"job"` + Instance *string `json:"instance" url:"instance"` + } +} + +type ResponseQueryRange struct { + Result *struct { + Metric *struct { + Job *string `json:"job" url:"job"` + Instance *string `json:"instance" url:"instance"` + Name *string `json:"__name__" url:"__name__"` + } `json:"metric" url:"metric"` + Values *[]interface{} `json:"values" url:"values"` + } + + ResultType *string +} + +// ResponseSeries a list of objects that contain the label name/value pairs which identify each series +type ResponseSeries struct { +} + +type ResponseSnapshot struct { + Name *string +} + +// ResponseTargetMetadata A list of objects +type ResponseTargetMetadata struct { +} + +type Rule struct { +} + +// Stat stat holds the information about individual cardinality. +type Stat struct { + Name *string + + Value *int +} + +// TsdbStatus tsdbStatus has information of cardinality statistics from postings. +type TsdbStatus struct { + HeadStats *HeadStats + // This will provide a list of the label names and their value count. + LabelValueCountByLabelName []Stat + // This will provide a list of the label names and memory used in bytes. Memory usage is calculated by adding the length of all values for a given label name. + MemoryInBytesByLabelName []Stat + // This will provide a list of label value pairs and their series count. + SeriesCountByLabelValuePair []Stat + // This will provide a list of metrics names and their series count. + SeriesCountByMetricName []Stat +} + +type WalReplayStatus struct { + Current *int + + Max *int + + Min *int +} diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/go.mod b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/go.mod new file mode 100644 index 00000000..452409bf --- /dev/null +++ b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/go.mod @@ -0,0 +1,26 @@ +module testgensvcgo + +go 1.18 + +require ( + github.com/ascarter/requestid v0.0.0-20170313220838-5b76ab3d4aee + github.com/brianvoe/gofakeit/v6 v6.10.0 + github.com/go-resty/resty/v2 v2.6.0 + github.com/go-sql-driver/mysql v1.6.0 + github.com/gorilla/handlers v1.5.1 + github.com/iancoleman/strcase v0.1.3 + github.com/jmoiron/sqlx v1.3.1 + github.com/kelseyhightower/envconfig v1.4.0 + github.com/opentracing-contrib/go-stdlib v1.0.0 + github.com/opentracing/opentracing-go v1.2.0 + github.com/pkg/errors v0.9.1 + github.com/rs/zerolog v1.28.0 + github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 + github.com/grpc-ecosystem/go-grpc-middleware/providers/zerolog/v2 v2.0.0-rc.2 + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.2 + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 + github.com/prometheus/client_golang v1.11.0 + google.golang.org/grpc v1.38.0 + google.golang.org/protobuf v1.26.0 + github.com/unionj-cloud/go-doudou/v2 v2.0.4 +) \ No newline at end of file diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go new file mode 100644 index 00000000..5ecc0b78 --- /dev/null +++ b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go @@ -0,0 +1,623 @@ +/** +* Generated by go-doudou v2.0.4. +* You can edit it as your need. +*/ +package service + +import ( + "context" + "testgensvcgo/dto" + v3 "github.com/unionj-cloud/go-doudou/v2/toolkit/openapi/v3" +) + +//go:generate go-doudou svc http -c +//go:generate go-doudou svc grpc + + +// Testgensvcgo Prometheus HTTP API +// The current stable HTTP API is reachable under /api/v1 on a Prometheus server. Any non-breaking additions will be added under that endpoint. +// +// # Format overview +// The API response format is JSON. Every successful API request returns a ```2xx``` status code. +// +// Invalid requests that reach the API handlers return a JSON error object and one of the following HTTP response codes: +// +// ```400 Bad Request``` when parameters are missing or incorrect. +// ```422 Unprocessable Entity``` when an expression can't be executed ([RFC4918](https://datatracker.ietf.org/doc/html/rfc4918#page-78)). +// ```503 Service Unavailable``` when queries time out or abort. +// +// Other non-```2xx``` codes may be returned for errors occurring before the API endpoint is reached. +// +// An array of warnings may be returned if there are errors that do not inhibit the request execution. All of the data that was successfully collected will be returned in the data field. +// +// The JSON response envelope format is as follows: +// +// ``` +// { +// "status": "success" | "error", +// "data": , +// +// // Only set if status is "error". The data field may still hold +// // additional data. +// "errorType": "", +// "error": "", +// +// // Only if there were warnings while executing the request. +// // There will still be data in the data field. +// "warnings": [""] +// } +// ``` +// # Generic placeholders: +// +// ``````: Input timestamps may be provided either in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format or as a Unix timestamp in seconds, with optional decimal places for sub-second precision. Output timestamps are always represented as Unix timestamps in seconds. +// +// ``````: Prometheus [time series selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors) like ```http_requests_total``` or ```http_requests_total{method=~"(GET|POST)"}``` and need to be URL-encoded. +// +// ``````: [Prometheus duration strings](https://prometheus.io/docs/prometheus/latest/querying/basics/#time_durations). For example, ```5m``` refers to a duration of 5 minutes. +// +// ``````: boolean values (strings ```true``` and ```false```). +// +// **Note**: Names of query parameters that may be repeated end with ```[]```. +// +// +// v2 +type Testgensvcgo interface { + + // AdminTsdbSnapshot Creates Snapshot of current data + // Snapshot creates a snapshot of all current data into ```snapshots/-``` under the TSDB's data directory and returns the directory as response. It will optionally skip snapshotting data that is only present in the head block, and which has not yet been compacted to disk. + // + // New in v2.1 and supports PUT from v2.9 + // + AdminTsdbSnapshot(ctx context.Context, + // Skip data present in the head block. Optional. + // + skip_head *bool) ( + ret dto.ResponseSnapshot, err error) + + + // DeleteSeries Returns time series + // The following endpoint returns the list of time series that match a certain label set. + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits. + // + // The ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series. + // + // --- + // **NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future. + // + // --- + // + DeleteSeries(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided. + // + // Example: ```?' --data-urlencode 'match[]=up'``` + // + // required + match[] string) ( + ret dto.ResponseSeries, err error) + + + // GetAlertmanagers Returns current alertmanager discovery + // Returns an overview of the current state of the Prometheus alertmanager discovery + // + // Both the active and dropped Alertmanagers are part of the response. + // + GetAlertmanagers(ctx context.Context) ( + ret dto.AlertmanagerDiscovery, err error) + + + // GetAlerts Returns active alerts + // The /alerts endpoint returns a list of all active alerts. + // + // As the /alerts endpoint is fairly new, it does not have the same stability guarantees as the overarching API v1. + // + GetAlerts(ctx context.Context) ( + ret dto.Alert, err error) + + + // GetLabel_LabelnameValues Returns label values + // The following endpoint returns a list of label values for a provided label name + // + // The ```data``` section of the JSON response is a list of string label values. + // + // --- + // **NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future. + // + // --- + // + GetLabel_LabelnameValues(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series from which to read the label values. Optional. + // + match[] *string, + // Label name + // + // Example: ```/label/job/values``` + // + // required + label_name string) ( + ret dto.ResponseLabelValues, err error) + + + // GetLabels Returns label names + // The following endpoint returns a list of label names + // + // The ```data``` section of the JSON response is a list of string label names. + // + // --- + // **NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future. + // + // --- + // + GetLabels(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series from which to read the label values. Optional. + // + match[] *string) ( + ret dto.ResponseLabelNames, err error) + + + // GetMetadata Returns metric metadata + // It returns metadata about metrics currently scrapped from targets. However, it does not provide any target information. This is considered experimental and might change in the future. + // + // The data section of the query result consists of an object where each key is a metric name and each value is a list of unique metadata objects, as exposed for that metric name across all targets. + // + GetMetadata(ctx context.Context, + // Maximum number of metrics to return. + // + // Example: ```?limit=2``` + // + // required + limit float64, + // A metric name to filter metadata for. All metric metadata is retrieved if left empty. + // + // Example: ```?metric=http_requests_total``` + // + metric *string) ( + ret map[string]dto.Metadata, err error) + + + // GetQuery Evaluates instant query + // The following endpoint evaluates an instant query at a single point in time + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. + // + // The data section of the query result has the following format + // ``` + // { + // "resultType": "matrix" | "vector" | "scalar" | "string", + // "result": + // } + // ``` + // `````` refers to the query result data, which has varying formats depending on the ```resultType```. See the [expression query result formats](https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats). + // + GetQuery(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=up``` + // + // required + query string, + // Evaluation timestamp. Optional. + // + // The current server time is used if the ```time``` parameter is omitted. + // + // Example: ```?metric=http_requests_total``` + // + time *string, + // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. + // + // Example: ```?metric=http_requests_total``` + // + timeout *string) ( + ret dto.QueryData, err error) + + + // GetQueryexemplars Returns list of Exemplars + // This is experimental and might change in the future. The following endpoint returns a list of exemplars for a valid PromQL query for a specific time range + // + GetQueryexemplars(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=test_exemplar_metric_total``` + // + // required + query string, + // Start timestamp. + // + // Example: ```&start=2020-09-14T15:22:25.479Z``` + // + start *string, + // End timestamp. + // + // Example: ```&end=020-09-14T15:23:25.479Z``` + // + end *string) ( + ret dto.ResponseQueryExemplars, err error) + + + // GetQueryrange Evaluates query over range of time. + // The following endpoint evaluates an expression query over a range of time + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. + // + // The data section of the query result has the following format + // ``` + // { + // "resultType": "matrix", + // "result": + // } + // ``` + // For the format of the `````` placeholder, see the [range-vector result format](https://prometheus.io/docs/prometheus/latest/querying/api/#range-vectors). + // + GetQueryrange(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=up``` + // + // required + query string, + // Start timestamp. + // + // Example: ```&start=2015-07-01T20:10:30.781Z``` + // + start *string, + // End timestamp. + // + // Example: ```&end=2015-07-01T20:11:00.781Z``` + // + end *string, + // Query resolution step width in ```duration``` format or float number of seconds. + // + // Example: ```&step=15s``` + // + step *string, + // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. + // + // Example: ```?metric=http_requests_total``` + // + timeout *string) ( + ret dto.ResponseQueryRange, err error) + + + // GetRules Returns currently loaded rules + // The ```/rules``` API endpoint returns a list of alerting and recording rules that are currently loaded. In addition it returns the currently active alerts fired by the Prometheus instance of each alerting rule. + // + // As the ```/rules``` endpoint is fairly new, it does not have the same stability guarantees as the overarching API v1. + GetRules(ctx context.Context, + // Return only the alerting rules (e.g. ```type=alert```) or the recording rules (e.g. ```type=record```). When the parameter is absent or empty, no filtering is done. + // + type *string) ( + ret dto.RuleDiscovery, err error) + + + // GetSeries Returns time series + // The following endpoint returns the list of time series that match a certain label set. + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits. + // + // The ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series. + // + GetSeries(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided. + // + // Example: ```?' --data-urlencode 'match[]=up'``` + // + // required + match[] string) ( + ret dto.ResponseSeries, err error) + + + // GetStatusBuildinfo Returns build information + // The following endpoint returns various build information properties about the Prometheus server + // + // All values are of the result type ```string```. + // + // --- + // **NOTE:** The exact returned build properties may change without notice between Prometheus versions. + // + // --- + // + // New in v2.14 + // + GetStatusBuildinfo(ctx context.Context) ( + ret dto.PrometheusVersion, err error) + + + // GetStatusConfig Returns configuration file + // The following endpoint returns currently loaded configuration file + // + // The config is returned as dumped YAML file. Due to limitation of + // the YAML library, YAML comments are not included. + // + GetStatusConfig(ctx context.Context) ( + ret dto.PrometheusConfig, err error) + + + // GetStatusFlags Returns flag values + // The following endpoint returns flag values that Prometheus was configured with + // + // All values are of the result type ```string```. + // + // New in v2.2 + // + GetStatusFlags(ctx context.Context) ( + ret interface{}, err error) + + + // GetStatusRuntimeinfo Returns runtime info + // The following endpoint returns various runtime information properties about the Prometheus server + // + // The returned values are of different types, depending on the nature + // of the runtime property + // + // --- + // **NOTE:** The exact returned runtime properties may change without notice between Prometheus versions. + // + // --- + // + // New in v2.14 + // + GetStatusRuntimeinfo(ctx context.Context) ( + ret dto.RuntimeInfo, err error) + + + // GetStatusTsdb Returns statistics about TSBD + // The following endpoint returns various cardinality statistics about the Prometheus TSDB + // + // Response Data + // --- + // + // **headStats:** This provides the following data about the head block of the TSDB: + // >**numSeries:** The number of series. + // **chunkCount:** The number of chunks. + // **minTime:** The current minimum timestamp in milliseconds. + // **maxTime:** The current maximum timestamp in milliseconds. + // + // **seriesCountByMetricName:** This will provide a list of metrics names and their series count. + // **labelValueCountByLabelName:** This will provide a list of the label names and their value count. + // **memoryInBytesByLabelName:** This will provide a list of the label names and memory used in bytes. Memory usage is calculated by adding the length of all values for a given label name. + // **seriesCountByLabelPair:** This will provide a list of label value pairs and their series count. + // + GetStatusTsdb(ctx context.Context) ( + ret dto.TsdbStatus, err error) + + + // GetStatusWalreplay Returns info about WAL replay. + // The following endpoint returns information about the WAL replay + // + // Response Data + // --- + // + // **read:** The number of segments replayed so far. + // **total:** The total number segments needed to be replayed. + // **progress:** The progress of the replay (0 - 100%). + // **state:** The state of the replay. + // **Possible states:** + // - **waiting:** Waiting for the replay to start. + // - **in progress:** The replay is in progress. + // - **done:** The replay has finished. + // + // --- + // **NOTE:** This endpoint is available before the server has been marked ready and is updated in real time to facilitate monitoring the progress of the WAL replay. + // + // --- + // + // New in v2.28 + // + GetStatusWalreplay(ctx context.Context) ( + ret dto.WalReplayStatus, err error) + + + // GetTargets Returns current target discovery. + // Both the active and dropped targets are part of the response by default. ```labels``` represents the label set after relabelling has occurred. ```discoveredLabels``` represent the unmodified labels retrieved during service discovery before relabelling has occurred. + // + GetTargets(ctx context.Context, + // The ```state``` query parameter allows the caller to filter by active or dropped targets, (e.g., ```state=active```, ```state=dropped```, ```state=any```). + // + state *string) ( + ret dto.TargetDiscovery, err error) + + + // GetTargetsMetadata Returns target metadata + // The following endpoint returns metadata about metrics currently scraped from targets. This is experimental and might change in the future. + // + // The ```data``` section of the query result consists of a list of objects that contain metric metadata and the target label set. + GetTargetsMetadata(ctx context.Context, + // Label selectors that match targets by their label sets. All targets are selected if left empty. + // + // Example: ```match_target={job="prometheus"}``` + // + match_target *string, + // A metric name to retrieve metadata for. All metric metadata is retrieved if left empty. + // + // Example: ```metric=go_goroutines``` + // + metric *string, + // Maximum number of targets to match. + // + // Example: ```limit=2``` + // + limit *float64) ( + ret dto.ResponseTargetMetadata, err error) + + + // Labels Returns label names + // The following endpoint returns a list of label names + // + // The ```data``` section of the JSON response is a list of string label names. + // + Labels(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series from which to read the label values. Optional. + // + match[] *string) ( + ret dto.ResponseLabelNames, err error) + + + // PutAdminTsdbSnapshot Creates Snapshot of current data + // Snapshot creates a snapshot of all current data into ```snapshots/-``` under the TSDB's data directory and returns the directory as response. It will optionally skip snapshotting data that is only present in the head block, and which has not yet been compacted to disk. + // + // New in v2.1 and supports PUT from v2.9 + // + PutAdminTsdbSnapshot(ctx context.Context, + // Skip data present in the head block. Optional. + // + skip_head *bool) ( + ret dto.ResponseSnapshot, err error) + + + // Query Evaluates instant query + // The following endpoint evaluates an instant query at a single point in time + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. + // + // The data section of the query result has the following format + // ``` + // { + // "resultType": "matrix" | "vector" | "scalar" | "string", + // "result": + // } + // ``` + // `````` refers to the query result data, which has varying formats depending on the ```resultType```. See the [expression query result formats](https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats). + // + Query(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=up``` + // + // required + query string, + // Evaluation timestamp. Optional. + // + // The current server time is used if the ```time``` parameter is omitted. + // + // Example: ```?metric=http_requests_total``` + // + time *string, + // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. + // + // Example: ```?metric=http_requests_total``` + // + timeout *string) ( + ret dto.QueryData, err error) + + + // Queryexemplars Returns list of Exemplars + // This is experimental and might change in the future. The following endpoint returns a list of exemplars for a valid PromQL query for a specific time range + // + Queryexemplars(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=test_exemplar_metric_total``` + // + // required + query string, + // Start timestamp. + // + // Example: ```&start=2020-09-14T15:22:25.479Z``` + // + start *string, + // End timestamp. + // + // Example: ```&end=020-09-14T15:23:25.479Z``` + // + end *string) ( + ret dto.ResponseQueryExemplars, err error) + + + // Queryrange Evaluates query over range of time. + // The following endpoint evaluates an expression query over a range of time + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. + // + // The data section of the query result has the following format + // ``` + // { + // "resultType": "matrix", + // "result": + // } + // ``` + // For the format of the `````` placeholder, see the [range-vector result format](https://prometheus.io/docs/prometheus/latest/querying/api/#range-vectors). + // + Queryrange(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=up``` + // + // required + query string, + // Start timestamp. + // + // Example: ```&start=2015-07-01T20:10:30.781Z``` + // + start *string, + // End timestamp. + // + // Example: ```&end=2015-07-01T20:11:00.781Z``` + // + end *string, + // Query resolution step width in ```duration``` format or float number of seconds. + // + // Example: ```&step=15s``` + // + step *string, + // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. + // + // Example: ```?metric=http_requests_total``` + // + timeout *string) ( + ret dto.ResponseQueryRange, err error) + + + // Series Returns time series + // The following endpoint returns the list of time series that match a certain label set. + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits. + // + // The ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series. + // + Series(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided. + // + // Example: ```?' --data-urlencode 'match[]=up'``` + // + // required + match[] string) ( + ret dto.ResponseSeries, err error) + + +} \ No newline at end of file diff --git a/toolkit/openapi/v3/model.go b/toolkit/openapi/v3/model.go index 43f79ace..4c201687 100644 --- a/toolkit/openapi/v3/model.go +++ b/toolkit/openapi/v3/model.go @@ -364,3 +364,11 @@ var IEnumMethods = []string{ "func UnmarshalJSON(bytes []byte) error", "func MarshalJSON() ([]byte, error)", } + +type ExampleType int + +const ( + UNKNOWN_EXAMPLE ExampleType = iota + JSON_EXAMPLE + TEXT_EXAMPLE +) From b14dc0fd8e251f72fa1de899047e48f698338322 Mon Sep 17 00:00:00 2001 From: wubin1989 <328454505@qq.com> Date: Wed, 11 Jan 2023 12:33:44 +0800 Subject: [PATCH 2/7] ... --- .../openapi/v3/codegen/common_test.go | 7 +++++++ cmd/internal/openapi/v3/codegen/server.go | 2 +- cmd/internal/svc/codegen/httphandler.go | 21 ++++++++++++------- cmd/internal/svc/codegen/httphandler_test.go | 21 +++++++++++++++++++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/cmd/internal/openapi/v3/codegen/common_test.go b/cmd/internal/openapi/v3/codegen/common_test.go index d5d741f8..438e6313 100644 --- a/cmd/internal/openapi/v3/codegen/common_test.go +++ b/cmd/internal/openapi/v3/codegen/common_test.go @@ -33,6 +33,13 @@ func TestPattern2Method(t *testing.T) { }, want: "Goodfood_BigappleBooks_Mybird", }, + { + name: "", + args: args{ + pattern: "/api/v1/query_range", + }, + want: "ApiV1Query_range", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/cmd/internal/openapi/v3/codegen/server.go b/cmd/internal/openapi/v3/codegen/server.go index 4e9616ee..87e06fba 100644 --- a/cmd/internal/openapi/v3/codegen/server.go +++ b/cmd/internal/openapi/v3/codegen/server.go @@ -36,7 +36,7 @@ func Pattern2Method(pattern string) string { pattern = strings.TrimSuffix(strings.TrimPrefix(pattern, "/"), "/") partials := strings.Split(pattern, "/") var converted []string - nosymbolreg := regexp.MustCompile(`[^a-zA-Z0-9]`) + nosymbolreg := regexp.MustCompile(`[^a-zA-Z0-9_]`) for _, item := range partials { if strings.HasPrefix(item, "{") && strings.HasSuffix(item, "}") { item = strings.TrimSuffix(strings.TrimPrefix(item, "{"), "}") diff --git a/cmd/internal/svc/codegen/httphandler.go b/cmd/internal/svc/codegen/httphandler.go index e394ea8a..6a962dc4 100644 --- a/cmd/internal/svc/codegen/httphandler.go +++ b/cmd/internal/svc/codegen/httphandler.go @@ -3,10 +3,10 @@ package codegen import ( "bytes" "github.com/unionj-cloud/go-doudou/v2/toolkit/sliceutils" - "github.com/unionj-cloud/go-doudou/v2/toolkit/stringutils" "github.com/unionj-cloud/go-doudou/v2/version" "os" "path/filepath" + "regexp" "strings" "text/template" @@ -74,16 +74,23 @@ var RouteAnnotationStore = framework.AnnotationStore{ // /shelves/:shelf/books/:book func pattern(method string) string { httpMethods := []string{"GET", "POST", "PUT", "DELETE"} - snake := strcase.ToSnake(strings.ReplaceAll(method, "_", "_:")) - splits := strings.Split(snake, "_") + re1, err := regexp.Compile("_?[A-Z]") + if err != nil { + panic(err) + } + method = re1.ReplaceAllStringFunc(method, func(s string) string { + if strings.HasPrefix(s, "_") { + return "/:" + strings.ToLower(strings.TrimPrefix(s, "_")) + } else { + return "/" + strings.ToLower(s) + } + }) + splits := strings.Split(method, "/")[1:] head := strings.ToUpper(splits[0]) if sliceutils.StringContains(httpMethods, head) { splits = splits[1:] } - clean := sliceutils.StringFilter(splits, func(item string) bool { - return stringutils.IsNotEmpty(item) - }) - return strings.Join(clean, "/") + return strings.Join(splits, "/") } func noSplitPattern(method string) string { diff --git a/cmd/internal/svc/codegen/httphandler_test.go b/cmd/internal/svc/codegen/httphandler_test.go index 93ade8b2..3820361e 100644 --- a/cmd/internal/svc/codegen/httphandler_test.go +++ b/cmd/internal/svc/codegen/httphandler_test.go @@ -49,6 +49,27 @@ func Test_pattern(t *testing.T) { }, want: "goodfood/:bigapple/books/:mybird", }, + { + name: "", + args: args{ + method: "ApiV1Query_range", + }, + want: "api/v1/query_range", + }, + { + name: "", + args: args{ + method: "GetQuery_range", + }, + want: "query_range", + }, + { + name: "", + args: args{ + method: "GetQuery", + }, + want: "query", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From a328a081180b4f077e567bff0fb2c7369750d0a5 Mon Sep 17 00:00:00 2001 From: wubin1989 <328454505@qq.com> Date: Wed, 11 Jan 2023 14:59:49 +0800 Subject: [PATCH 3/7] ... --- .../codegen/testdata/testgensvcgo/dto/dto.go | 276 -------- .../v3/codegen/testdata/testgensvcgo/svc.go | 623 ------------------ cmd/internal/svc/codegen/httphandler.go | 27 +- cmd/internal/svc/codegen/httphandler_test.go | 73 -- toolkit/astutils/interfacecollector.go | 25 +- toolkit/astutils/interfacecollector_test.go | 73 ++ 6 files changed, 96 insertions(+), 1001 deletions(-) diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go index e91d6f62..e69de29b 100644 --- a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go +++ b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go @@ -1,276 +0,0 @@ -/** -* Generated by go-doudou v2.0.4. -* You can edit it as your need. - */ -package dto - -//go:generate go-doudou name --file $GOFILE -// Alert Alert has info for an alert. -type Alert struct { - ActiveAt *string - - Annotations *Labels - - Labels *Labels - - State *string - - Value *string -} - -// AlertmanagerDiscovery AlertmanagerDiscovery has all the active Alertmanagers. -type AlertmanagerDiscovery struct { - ActiveAlertmanagers []AlertmanagerTarget - - DroppedAlertmanagers []AlertmanagerTarget -} - -// AlertmanagerTarget AlertmanagerTarget has info on one AM. -type AlertmanagerTarget struct { - Url *string -} - -// DroppedTarget DroppedTarget has the information for one target that was dropped during relabelling. -type DroppedTarget struct { - DiscoveredLabels map[string][]string -} - -// HeadStats HeadStats has information about the TSDB head. -type HeadStats struct { - ChunkCount *int64 - - MaxTime *int64 - - MinTime *int64 - - NumLabelPairs *int64 - - NumSeries *int -} - -// Label Label is a key/value pair of strings. -type Label struct { - Name *string - - Value *string -} - -// Labels Labels is a sorted set of labels. Order has to be guaranteed upon -// instantiation. -type Labels struct { -} - -// MetricType MetricType represents metric type values. -type MetricType struct { -} - -// PrometheusVersion PrometheusVersion contains build information about Prometheus. -type PrometheusVersion struct { - Branch *string - - BuildDate *string - - BuildUser *string - - GoVersion *string - - Revision *string - - Version *string -} - -// RuleDiscovery RuleDiscovery has info for all rules -type RuleDiscovery struct { - RuleGroups []RuleGroup -} - -// RuleGroup RuleGroup has info for rules which are part of a group -type RuleGroup struct { - EvaluationTime *float64 - - File *string - - Interval *float64 - - LastEvaluation *string - - Name *string - // In order to preserve rule ordering, while exposing type (alerting or recording) - // specific properties, both alerting and recording rules are exposed in the - // same array. - Rules []Rule -} - -// RuntimeInfo RuntimeInfo contains runtime information about Prometheus. -type RuntimeInfo struct { - CWD *string - - GODEBUG *string - - GOGC *string - - GOMAXPROCS *int - - CorruptionCount *int64 - - GoroutineCount *int - - LastConfigTime *string - - ReloadConfigSuccess *bool - - StartTime *string - - StorageRetention *string -} - -// Target Target has the information for one target. -type Target struct { - DiscoveredLabels map[string][]string - - GlobalURL *string - - Health *TargetHealth - - Labels *Labels - - LastError *string - - LastScrape *string - - LastScrapeDuration *float64 - - ScrapePool *string - - ScrapeURL *string -} - -// TargetDiscovery TargetDiscovery has all the active targets. -type TargetDiscovery struct { - ActiveTargets []Target - - DroppedTargets []DroppedTarget -} - -// TargetHealth TargetHealth describes the health state of a target. -type TargetHealth struct { -} - -type Metadata struct { - Help *string - - Type *MetricType - - Unit *string -} - -type MetricMetadata struct { - Help *string - - Metric *string - - Target *Labels - - Type *MetricType - - Unit *string -} - -// PrometheusConfig a dumped YAML file -type PrometheusConfig struct { - YAML *string -} - -type QueryData struct { - Result *struct { - Metric *struct { - Name *string `json:"__name__" url:"__name__"` - Job *string `json:"job" url:"job"` - Instance *string `json:"instance" url:"instance"` - } `json:"metric" url:"metric"` - Value *[]interface{} `json:"value" url:"value"` - } - - ResultType *string -} - -// ResponseLabelNames a list of string label names -type ResponseLabelNames struct { -} - -// ResponseLabelValues a list of string label values -type ResponseLabelValues struct { -} - -type ResponseQueryExemplars struct { - Exemplars *struct { - Labels *struct { - TraceID *string `json:"traceID" url:"traceID"` - } `json:"labels" url:"labels"` - Values *string `json:"values" url:"values"` - Timestamp *string `json:"timestamp" url:"timestamp"` - } - - SeriesLabels *struct { - Service *string `json:"service" url:"service"` - Name *string `json:"__name__" url:"__name__"` - Job *string `json:"job" url:"job"` - Instance *string `json:"instance" url:"instance"` - } -} - -type ResponseQueryRange struct { - Result *struct { - Metric *struct { - Job *string `json:"job" url:"job"` - Instance *string `json:"instance" url:"instance"` - Name *string `json:"__name__" url:"__name__"` - } `json:"metric" url:"metric"` - Values *[]interface{} `json:"values" url:"values"` - } - - ResultType *string -} - -// ResponseSeries a list of objects that contain the label name/value pairs which identify each series -type ResponseSeries struct { -} - -type ResponseSnapshot struct { - Name *string -} - -// ResponseTargetMetadata A list of objects -type ResponseTargetMetadata struct { -} - -type Rule struct { -} - -// Stat stat holds the information about individual cardinality. -type Stat struct { - Name *string - - Value *int -} - -// TsdbStatus tsdbStatus has information of cardinality statistics from postings. -type TsdbStatus struct { - HeadStats *HeadStats - // This will provide a list of the label names and their value count. - LabelValueCountByLabelName []Stat - // This will provide a list of the label names and memory used in bytes. Memory usage is calculated by adding the length of all values for a given label name. - MemoryInBytesByLabelName []Stat - // This will provide a list of label value pairs and their series count. - SeriesCountByLabelValuePair []Stat - // This will provide a list of metrics names and their series count. - SeriesCountByMetricName []Stat -} - -type WalReplayStatus struct { - Current *int - - Max *int - - Min *int -} diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go index 5ecc0b78..e69de29b 100644 --- a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go +++ b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go @@ -1,623 +0,0 @@ -/** -* Generated by go-doudou v2.0.4. -* You can edit it as your need. -*/ -package service - -import ( - "context" - "testgensvcgo/dto" - v3 "github.com/unionj-cloud/go-doudou/v2/toolkit/openapi/v3" -) - -//go:generate go-doudou svc http -c -//go:generate go-doudou svc grpc - - -// Testgensvcgo Prometheus HTTP API -// The current stable HTTP API is reachable under /api/v1 on a Prometheus server. Any non-breaking additions will be added under that endpoint. -// -// # Format overview -// The API response format is JSON. Every successful API request returns a ```2xx``` status code. -// -// Invalid requests that reach the API handlers return a JSON error object and one of the following HTTP response codes: -// -// ```400 Bad Request``` when parameters are missing or incorrect. -// ```422 Unprocessable Entity``` when an expression can't be executed ([RFC4918](https://datatracker.ietf.org/doc/html/rfc4918#page-78)). -// ```503 Service Unavailable``` when queries time out or abort. -// -// Other non-```2xx``` codes may be returned for errors occurring before the API endpoint is reached. -// -// An array of warnings may be returned if there are errors that do not inhibit the request execution. All of the data that was successfully collected will be returned in the data field. -// -// The JSON response envelope format is as follows: -// -// ``` -// { -// "status": "success" | "error", -// "data": , -// -// // Only set if status is "error". The data field may still hold -// // additional data. -// "errorType": "", -// "error": "", -// -// // Only if there were warnings while executing the request. -// // There will still be data in the data field. -// "warnings": [""] -// } -// ``` -// # Generic placeholders: -// -// ``````: Input timestamps may be provided either in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format or as a Unix timestamp in seconds, with optional decimal places for sub-second precision. Output timestamps are always represented as Unix timestamps in seconds. -// -// ``````: Prometheus [time series selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors) like ```http_requests_total``` or ```http_requests_total{method=~"(GET|POST)"}``` and need to be URL-encoded. -// -// ``````: [Prometheus duration strings](https://prometheus.io/docs/prometheus/latest/querying/basics/#time_durations). For example, ```5m``` refers to a duration of 5 minutes. -// -// ``````: boolean values (strings ```true``` and ```false```). -// -// **Note**: Names of query parameters that may be repeated end with ```[]```. -// -// -// v2 -type Testgensvcgo interface { - - // AdminTsdbSnapshot Creates Snapshot of current data - // Snapshot creates a snapshot of all current data into ```snapshots/-``` under the TSDB's data directory and returns the directory as response. It will optionally skip snapshotting data that is only present in the head block, and which has not yet been compacted to disk. - // - // New in v2.1 and supports PUT from v2.9 - // - AdminTsdbSnapshot(ctx context.Context, - // Skip data present in the head block. Optional. - // - skip_head *bool) ( - ret dto.ResponseSnapshot, err error) - - - // DeleteSeries Returns time series - // The following endpoint returns the list of time series that match a certain label set. - // - // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits. - // - // The ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series. - // - // --- - // **NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future. - // - // --- - // - DeleteSeries(ctx context.Context, - // Start timestamp. Optional. - // - start *string, - // End timestamp. Optional. - // - end *string, - // Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided. - // - // Example: ```?' --data-urlencode 'match[]=up'``` - // - // required - match[] string) ( - ret dto.ResponseSeries, err error) - - - // GetAlertmanagers Returns current alertmanager discovery - // Returns an overview of the current state of the Prometheus alertmanager discovery - // - // Both the active and dropped Alertmanagers are part of the response. - // - GetAlertmanagers(ctx context.Context) ( - ret dto.AlertmanagerDiscovery, err error) - - - // GetAlerts Returns active alerts - // The /alerts endpoint returns a list of all active alerts. - // - // As the /alerts endpoint is fairly new, it does not have the same stability guarantees as the overarching API v1. - // - GetAlerts(ctx context.Context) ( - ret dto.Alert, err error) - - - // GetLabel_LabelnameValues Returns label values - // The following endpoint returns a list of label values for a provided label name - // - // The ```data``` section of the JSON response is a list of string label values. - // - // --- - // **NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future. - // - // --- - // - GetLabel_LabelnameValues(ctx context.Context, - // Start timestamp. Optional. - // - start *string, - // End timestamp. Optional. - // - end *string, - // Repeated series selector argument that selects the series from which to read the label values. Optional. - // - match[] *string, - // Label name - // - // Example: ```/label/job/values``` - // - // required - label_name string) ( - ret dto.ResponseLabelValues, err error) - - - // GetLabels Returns label names - // The following endpoint returns a list of label names - // - // The ```data``` section of the JSON response is a list of string label names. - // - // --- - // **NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future. - // - // --- - // - GetLabels(ctx context.Context, - // Start timestamp. Optional. - // - start *string, - // End timestamp. Optional. - // - end *string, - // Repeated series selector argument that selects the series from which to read the label values. Optional. - // - match[] *string) ( - ret dto.ResponseLabelNames, err error) - - - // GetMetadata Returns metric metadata - // It returns metadata about metrics currently scrapped from targets. However, it does not provide any target information. This is considered experimental and might change in the future. - // - // The data section of the query result consists of an object where each key is a metric name and each value is a list of unique metadata objects, as exposed for that metric name across all targets. - // - GetMetadata(ctx context.Context, - // Maximum number of metrics to return. - // - // Example: ```?limit=2``` - // - // required - limit float64, - // A metric name to filter metadata for. All metric metadata is retrieved if left empty. - // - // Example: ```?metric=http_requests_total``` - // - metric *string) ( - ret map[string]dto.Metadata, err error) - - - // GetQuery Evaluates instant query - // The following endpoint evaluates an instant query at a single point in time - // - // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. - // - // The data section of the query result has the following format - // ``` - // { - // "resultType": "matrix" | "vector" | "scalar" | "string", - // "result": - // } - // ``` - // `````` refers to the query result data, which has varying formats depending on the ```resultType```. See the [expression query result formats](https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats). - // - GetQuery(ctx context.Context, - // Prometheus expression query string. - // - // Example: ```?query=up``` - // - // required - query string, - // Evaluation timestamp. Optional. - // - // The current server time is used if the ```time``` parameter is omitted. - // - // Example: ```?metric=http_requests_total``` - // - time *string, - // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. - // - // Example: ```?metric=http_requests_total``` - // - timeout *string) ( - ret dto.QueryData, err error) - - - // GetQueryexemplars Returns list of Exemplars - // This is experimental and might change in the future. The following endpoint returns a list of exemplars for a valid PromQL query for a specific time range - // - GetQueryexemplars(ctx context.Context, - // Prometheus expression query string. - // - // Example: ```?query=test_exemplar_metric_total``` - // - // required - query string, - // Start timestamp. - // - // Example: ```&start=2020-09-14T15:22:25.479Z``` - // - start *string, - // End timestamp. - // - // Example: ```&end=020-09-14T15:23:25.479Z``` - // - end *string) ( - ret dto.ResponseQueryExemplars, err error) - - - // GetQueryrange Evaluates query over range of time. - // The following endpoint evaluates an expression query over a range of time - // - // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. - // - // The data section of the query result has the following format - // ``` - // { - // "resultType": "matrix", - // "result": - // } - // ``` - // For the format of the `````` placeholder, see the [range-vector result format](https://prometheus.io/docs/prometheus/latest/querying/api/#range-vectors). - // - GetQueryrange(ctx context.Context, - // Prometheus expression query string. - // - // Example: ```?query=up``` - // - // required - query string, - // Start timestamp. - // - // Example: ```&start=2015-07-01T20:10:30.781Z``` - // - start *string, - // End timestamp. - // - // Example: ```&end=2015-07-01T20:11:00.781Z``` - // - end *string, - // Query resolution step width in ```duration``` format or float number of seconds. - // - // Example: ```&step=15s``` - // - step *string, - // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. - // - // Example: ```?metric=http_requests_total``` - // - timeout *string) ( - ret dto.ResponseQueryRange, err error) - - - // GetRules Returns currently loaded rules - // The ```/rules``` API endpoint returns a list of alerting and recording rules that are currently loaded. In addition it returns the currently active alerts fired by the Prometheus instance of each alerting rule. - // - // As the ```/rules``` endpoint is fairly new, it does not have the same stability guarantees as the overarching API v1. - GetRules(ctx context.Context, - // Return only the alerting rules (e.g. ```type=alert```) or the recording rules (e.g. ```type=record```). When the parameter is absent or empty, no filtering is done. - // - type *string) ( - ret dto.RuleDiscovery, err error) - - - // GetSeries Returns time series - // The following endpoint returns the list of time series that match a certain label set. - // - // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits. - // - // The ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series. - // - GetSeries(ctx context.Context, - // Start timestamp. Optional. - // - start *string, - // End timestamp. Optional. - // - end *string, - // Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided. - // - // Example: ```?' --data-urlencode 'match[]=up'``` - // - // required - match[] string) ( - ret dto.ResponseSeries, err error) - - - // GetStatusBuildinfo Returns build information - // The following endpoint returns various build information properties about the Prometheus server - // - // All values are of the result type ```string```. - // - // --- - // **NOTE:** The exact returned build properties may change without notice between Prometheus versions. - // - // --- - // - // New in v2.14 - // - GetStatusBuildinfo(ctx context.Context) ( - ret dto.PrometheusVersion, err error) - - - // GetStatusConfig Returns configuration file - // The following endpoint returns currently loaded configuration file - // - // The config is returned as dumped YAML file. Due to limitation of - // the YAML library, YAML comments are not included. - // - GetStatusConfig(ctx context.Context) ( - ret dto.PrometheusConfig, err error) - - - // GetStatusFlags Returns flag values - // The following endpoint returns flag values that Prometheus was configured with - // - // All values are of the result type ```string```. - // - // New in v2.2 - // - GetStatusFlags(ctx context.Context) ( - ret interface{}, err error) - - - // GetStatusRuntimeinfo Returns runtime info - // The following endpoint returns various runtime information properties about the Prometheus server - // - // The returned values are of different types, depending on the nature - // of the runtime property - // - // --- - // **NOTE:** The exact returned runtime properties may change without notice between Prometheus versions. - // - // --- - // - // New in v2.14 - // - GetStatusRuntimeinfo(ctx context.Context) ( - ret dto.RuntimeInfo, err error) - - - // GetStatusTsdb Returns statistics about TSBD - // The following endpoint returns various cardinality statistics about the Prometheus TSDB - // - // Response Data - // --- - // - // **headStats:** This provides the following data about the head block of the TSDB: - // >**numSeries:** The number of series. - // **chunkCount:** The number of chunks. - // **minTime:** The current minimum timestamp in milliseconds. - // **maxTime:** The current maximum timestamp in milliseconds. - // - // **seriesCountByMetricName:** This will provide a list of metrics names and their series count. - // **labelValueCountByLabelName:** This will provide a list of the label names and their value count. - // **memoryInBytesByLabelName:** This will provide a list of the label names and memory used in bytes. Memory usage is calculated by adding the length of all values for a given label name. - // **seriesCountByLabelPair:** This will provide a list of label value pairs and their series count. - // - GetStatusTsdb(ctx context.Context) ( - ret dto.TsdbStatus, err error) - - - // GetStatusWalreplay Returns info about WAL replay. - // The following endpoint returns information about the WAL replay - // - // Response Data - // --- - // - // **read:** The number of segments replayed so far. - // **total:** The total number segments needed to be replayed. - // **progress:** The progress of the replay (0 - 100%). - // **state:** The state of the replay. - // **Possible states:** - // - **waiting:** Waiting for the replay to start. - // - **in progress:** The replay is in progress. - // - **done:** The replay has finished. - // - // --- - // **NOTE:** This endpoint is available before the server has been marked ready and is updated in real time to facilitate monitoring the progress of the WAL replay. - // - // --- - // - // New in v2.28 - // - GetStatusWalreplay(ctx context.Context) ( - ret dto.WalReplayStatus, err error) - - - // GetTargets Returns current target discovery. - // Both the active and dropped targets are part of the response by default. ```labels``` represents the label set after relabelling has occurred. ```discoveredLabels``` represent the unmodified labels retrieved during service discovery before relabelling has occurred. - // - GetTargets(ctx context.Context, - // The ```state``` query parameter allows the caller to filter by active or dropped targets, (e.g., ```state=active```, ```state=dropped```, ```state=any```). - // - state *string) ( - ret dto.TargetDiscovery, err error) - - - // GetTargetsMetadata Returns target metadata - // The following endpoint returns metadata about metrics currently scraped from targets. This is experimental and might change in the future. - // - // The ```data``` section of the query result consists of a list of objects that contain metric metadata and the target label set. - GetTargetsMetadata(ctx context.Context, - // Label selectors that match targets by their label sets. All targets are selected if left empty. - // - // Example: ```match_target={job="prometheus"}``` - // - match_target *string, - // A metric name to retrieve metadata for. All metric metadata is retrieved if left empty. - // - // Example: ```metric=go_goroutines``` - // - metric *string, - // Maximum number of targets to match. - // - // Example: ```limit=2``` - // - limit *float64) ( - ret dto.ResponseTargetMetadata, err error) - - - // Labels Returns label names - // The following endpoint returns a list of label names - // - // The ```data``` section of the JSON response is a list of string label names. - // - Labels(ctx context.Context, - // Start timestamp. Optional. - // - start *string, - // End timestamp. Optional. - // - end *string, - // Repeated series selector argument that selects the series from which to read the label values. Optional. - // - match[] *string) ( - ret dto.ResponseLabelNames, err error) - - - // PutAdminTsdbSnapshot Creates Snapshot of current data - // Snapshot creates a snapshot of all current data into ```snapshots/-``` under the TSDB's data directory and returns the directory as response. It will optionally skip snapshotting data that is only present in the head block, and which has not yet been compacted to disk. - // - // New in v2.1 and supports PUT from v2.9 - // - PutAdminTsdbSnapshot(ctx context.Context, - // Skip data present in the head block. Optional. - // - skip_head *bool) ( - ret dto.ResponseSnapshot, err error) - - - // Query Evaluates instant query - // The following endpoint evaluates an instant query at a single point in time - // - // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. - // - // The data section of the query result has the following format - // ``` - // { - // "resultType": "matrix" | "vector" | "scalar" | "string", - // "result": - // } - // ``` - // `````` refers to the query result data, which has varying formats depending on the ```resultType```. See the [expression query result formats](https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats). - // - Query(ctx context.Context, - // Prometheus expression query string. - // - // Example: ```?query=up``` - // - // required - query string, - // Evaluation timestamp. Optional. - // - // The current server time is used if the ```time``` parameter is omitted. - // - // Example: ```?metric=http_requests_total``` - // - time *string, - // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. - // - // Example: ```?metric=http_requests_total``` - // - timeout *string) ( - ret dto.QueryData, err error) - - - // Queryexemplars Returns list of Exemplars - // This is experimental and might change in the future. The following endpoint returns a list of exemplars for a valid PromQL query for a specific time range - // - Queryexemplars(ctx context.Context, - // Prometheus expression query string. - // - // Example: ```?query=test_exemplar_metric_total``` - // - // required - query string, - // Start timestamp. - // - // Example: ```&start=2020-09-14T15:22:25.479Z``` - // - start *string, - // End timestamp. - // - // Example: ```&end=020-09-14T15:23:25.479Z``` - // - end *string) ( - ret dto.ResponseQueryExemplars, err error) - - - // Queryrange Evaluates query over range of time. - // The following endpoint evaluates an expression query over a range of time - // - // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. - // - // The data section of the query result has the following format - // ``` - // { - // "resultType": "matrix", - // "result": - // } - // ``` - // For the format of the `````` placeholder, see the [range-vector result format](https://prometheus.io/docs/prometheus/latest/querying/api/#range-vectors). - // - Queryrange(ctx context.Context, - // Prometheus expression query string. - // - // Example: ```?query=up``` - // - // required - query string, - // Start timestamp. - // - // Example: ```&start=2015-07-01T20:10:30.781Z``` - // - start *string, - // End timestamp. - // - // Example: ```&end=2015-07-01T20:11:00.781Z``` - // - end *string, - // Query resolution step width in ```duration``` format or float number of seconds. - // - // Example: ```&step=15s``` - // - step *string, - // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. - // - // Example: ```?metric=http_requests_total``` - // - timeout *string) ( - ret dto.ResponseQueryRange, err error) - - - // Series Returns time series - // The following endpoint returns the list of time series that match a certain label set. - // - // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits. - // - // The ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series. - // - Series(ctx context.Context, - // Start timestamp. Optional. - // - start *string, - // End timestamp. Optional. - // - end *string, - // Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided. - // - // Example: ```?' --data-urlencode 'match[]=up'``` - // - // required - match[] string) ( - ret dto.ResponseSeries, err error) - - -} \ No newline at end of file diff --git a/cmd/internal/svc/codegen/httphandler.go b/cmd/internal/svc/codegen/httphandler.go index 6a962dc4..cb5c69fb 100644 --- a/cmd/internal/svc/codegen/httphandler.go +++ b/cmd/internal/svc/codegen/httphandler.go @@ -2,11 +2,9 @@ package codegen import ( "bytes" - "github.com/unionj-cloud/go-doudou/v2/toolkit/sliceutils" "github.com/unionj-cloud/go-doudou/v2/version" "os" "path/filepath" - "regexp" "strings" "text/template" @@ -70,29 +68,6 @@ var RouteAnnotationStore = framework.AnnotationStore{ } ` -// GetShelves_ShelfBooks_Book -// /shelves/:shelf/books/:book -func pattern(method string) string { - httpMethods := []string{"GET", "POST", "PUT", "DELETE"} - re1, err := regexp.Compile("_?[A-Z]") - if err != nil { - panic(err) - } - method = re1.ReplaceAllStringFunc(method, func(s string) string { - if strings.HasPrefix(s, "_") { - return "/:" + strings.ToLower(strings.TrimPrefix(s, "_")) - } else { - return "/" + strings.ToLower(s) - } - }) - splits := strings.Split(method, "/")[1:] - head := strings.ToUpper(splits[0]) - if sliceutils.StringContains(httpMethods, head) { - splits = splits[1:] - } - return strings.Join(splits, "/") -} - func noSplitPattern(method string) string { httpMethods := []string{"GET", "POST", "PUT", "DELETE"} snake := strcase.ToSnake(method) @@ -151,7 +126,7 @@ func GenHttpHandler(dir string, ic astutils.InterfaceCollector, routePatternStra funcMap := make(map[string]interface{}) funcMap["httpMethod"] = httpMethod - funcMap["pattern"] = pattern + funcMap["pattern"] = astutils.Pattern funcMap["noSplitPattern"] = noSplitPattern funcMap["lower"] = strings.ToLower if tpl, err = template.New("handler.go.tmpl").Funcs(funcMap).Parse(httpHandlerTmpl); err != nil { diff --git a/cmd/internal/svc/codegen/httphandler_test.go b/cmd/internal/svc/codegen/httphandler_test.go index 3820361e..4277b60c 100644 --- a/cmd/internal/svc/codegen/httphandler_test.go +++ b/cmd/internal/svc/codegen/httphandler_test.go @@ -5,79 +5,6 @@ import ( "testing" ) -func Test_pattern(t *testing.T) { - type args struct { - method string - } - tests := []struct { - name string - args args - want string - }{ - { - name: "1", - args: args{ - method: "GetBooks", - }, - want: "books", - }, - { - name: "2", - args: args{ - method: "PageUsers", - }, - want: "page/users", - }, - { - name: "", - args: args{ - method: "Get", - }, - want: "", - }, - { - name: "", - args: args{ - method: "GetShelves_ShelfBooks_Book", - }, - want: "shelves/:shelf/books/:book", - }, - { - name: "", - args: args{ - method: "Goodfood_BigappleBooks_Mybird", - }, - want: "goodfood/:bigapple/books/:mybird", - }, - { - name: "", - args: args{ - method: "ApiV1Query_range", - }, - want: "api/v1/query_range", - }, - { - name: "", - args: args{ - method: "GetQuery_range", - }, - want: "query_range", - }, - { - name: "", - args: args{ - method: "GetQuery", - }, - want: "query", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equalf(t, tt.want, pattern(tt.args.method), "pattern(%v)", tt.args.method) - }) - } -} - // Shelves_ShelfBooks_Book func Test_httpMethod(t *testing.T) { type args struct { diff --git a/toolkit/astutils/interfacecollector.go b/toolkit/astutils/interfacecollector.go index 68aac8ea..53e14f3c 100644 --- a/toolkit/astutils/interfacecollector.go +++ b/toolkit/astutils/interfacecollector.go @@ -9,6 +9,7 @@ import ( "go/ast" "go/parser" "go/token" + "regexp" "strings" ) @@ -55,14 +56,32 @@ func (ic *InterfaceCollector) Collect(n ast.Node) ast.Visitor { return nil } -func pathVariables(method string) (ret []string) { +// GetShelves_ShelfBooks_Book +// /shelves/:shelf/books/:book +func Pattern(method string) string { httpMethods := []string{"GET", "POST", "PUT", "DELETE"} - snake := strcase.ToSnake(strings.ReplaceAll(method, "_", "_:")) - splits := strings.Split(snake, "_") + re1, err := regexp.Compile("_?[A-Z]") + if err != nil { + panic(err) + } + method = re1.ReplaceAllStringFunc(method, func(s string) string { + if strings.HasPrefix(s, "_") { + return "/:" + strings.ToLower(strings.TrimPrefix(s, "_")) + } else { + return "/" + strings.ToLower(s) + } + }) + splits := strings.Split(method, "/")[1:] head := strings.ToUpper(splits[0]) if sliceutils.StringContains(httpMethods, head) { splits = splits[1:] } + return strings.Join(splits, "/") +} + +func pathVariables(method string) (ret []string) { + endpoint := Pattern(method) + splits := strings.Split(endpoint, "/") pvs := sliceutils.StringFilter(splits, func(item string) bool { return stringutils.IsNotEmpty(item) && strings.HasPrefix(item, ":") }) diff --git a/toolkit/astutils/interfacecollector_test.go b/toolkit/astutils/interfacecollector_test.go index 360fdd57..f06db3a2 100644 --- a/toolkit/astutils/interfacecollector_test.go +++ b/toolkit/astutils/interfacecollector_test.go @@ -29,3 +29,76 @@ func TestBuildInterfaceCollector(t *testing.T) { ic := BuildInterfaceCollector(file, ExprString) assert.NotNil(t, ic) } + +func Test_pattern(t *testing.T) { + type args struct { + method string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "1", + args: args{ + method: "GetBooks", + }, + want: "books", + }, + { + name: "2", + args: args{ + method: "PageUsers", + }, + want: "page/users", + }, + { + name: "", + args: args{ + method: "Get", + }, + want: "", + }, + { + name: "", + args: args{ + method: "GetShelves_ShelfBooks_Book", + }, + want: "shelves/:shelf/books/:book", + }, + { + name: "", + args: args{ + method: "Goodfood_BigappleBooks_Mybird", + }, + want: "goodfood/:bigapple/books/:mybird", + }, + { + name: "", + args: args{ + method: "ApiV1Query_range", + }, + want: "api/v1/query_range", + }, + { + name: "", + args: args{ + method: "GetQuery_range", + }, + want: "query_range", + }, + { + name: "", + args: args{ + method: "GetQuery", + }, + want: "query", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, Pattern(tt.args.method), "pattern(%v)", tt.args.method) + }) + } +} From d9d27a69a15bd6bc96e80f87e7c2f7c62b08dc1a Mon Sep 17 00:00:00 2001 From: wubin1989 <328454505@qq.com> Date: Fri, 13 Jan 2023 16:31:03 +0800 Subject: [PATCH 4/7] move executils package from internal to toolkit --- .../codegen/testdata/testgensvcgo/dto/dto.go | 276 ++++++++ .../v3/codegen/testdata/testgensvcgo/svc.go | 623 ++++++++++++++++++ toolkit/executils/executils.go | 38 ++ toolkit/executils/executils_test.go | 26 + 4 files changed, 963 insertions(+) create mode 100644 toolkit/executils/executils.go create mode 100644 toolkit/executils/executils_test.go diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go index e69de29b..e91d6f62 100644 --- a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go +++ b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/dto/dto.go @@ -0,0 +1,276 @@ +/** +* Generated by go-doudou v2.0.4. +* You can edit it as your need. + */ +package dto + +//go:generate go-doudou name --file $GOFILE +// Alert Alert has info for an alert. +type Alert struct { + ActiveAt *string + + Annotations *Labels + + Labels *Labels + + State *string + + Value *string +} + +// AlertmanagerDiscovery AlertmanagerDiscovery has all the active Alertmanagers. +type AlertmanagerDiscovery struct { + ActiveAlertmanagers []AlertmanagerTarget + + DroppedAlertmanagers []AlertmanagerTarget +} + +// AlertmanagerTarget AlertmanagerTarget has info on one AM. +type AlertmanagerTarget struct { + Url *string +} + +// DroppedTarget DroppedTarget has the information for one target that was dropped during relabelling. +type DroppedTarget struct { + DiscoveredLabels map[string][]string +} + +// HeadStats HeadStats has information about the TSDB head. +type HeadStats struct { + ChunkCount *int64 + + MaxTime *int64 + + MinTime *int64 + + NumLabelPairs *int64 + + NumSeries *int +} + +// Label Label is a key/value pair of strings. +type Label struct { + Name *string + + Value *string +} + +// Labels Labels is a sorted set of labels. Order has to be guaranteed upon +// instantiation. +type Labels struct { +} + +// MetricType MetricType represents metric type values. +type MetricType struct { +} + +// PrometheusVersion PrometheusVersion contains build information about Prometheus. +type PrometheusVersion struct { + Branch *string + + BuildDate *string + + BuildUser *string + + GoVersion *string + + Revision *string + + Version *string +} + +// RuleDiscovery RuleDiscovery has info for all rules +type RuleDiscovery struct { + RuleGroups []RuleGroup +} + +// RuleGroup RuleGroup has info for rules which are part of a group +type RuleGroup struct { + EvaluationTime *float64 + + File *string + + Interval *float64 + + LastEvaluation *string + + Name *string + // In order to preserve rule ordering, while exposing type (alerting or recording) + // specific properties, both alerting and recording rules are exposed in the + // same array. + Rules []Rule +} + +// RuntimeInfo RuntimeInfo contains runtime information about Prometheus. +type RuntimeInfo struct { + CWD *string + + GODEBUG *string + + GOGC *string + + GOMAXPROCS *int + + CorruptionCount *int64 + + GoroutineCount *int + + LastConfigTime *string + + ReloadConfigSuccess *bool + + StartTime *string + + StorageRetention *string +} + +// Target Target has the information for one target. +type Target struct { + DiscoveredLabels map[string][]string + + GlobalURL *string + + Health *TargetHealth + + Labels *Labels + + LastError *string + + LastScrape *string + + LastScrapeDuration *float64 + + ScrapePool *string + + ScrapeURL *string +} + +// TargetDiscovery TargetDiscovery has all the active targets. +type TargetDiscovery struct { + ActiveTargets []Target + + DroppedTargets []DroppedTarget +} + +// TargetHealth TargetHealth describes the health state of a target. +type TargetHealth struct { +} + +type Metadata struct { + Help *string + + Type *MetricType + + Unit *string +} + +type MetricMetadata struct { + Help *string + + Metric *string + + Target *Labels + + Type *MetricType + + Unit *string +} + +// PrometheusConfig a dumped YAML file +type PrometheusConfig struct { + YAML *string +} + +type QueryData struct { + Result *struct { + Metric *struct { + Name *string `json:"__name__" url:"__name__"` + Job *string `json:"job" url:"job"` + Instance *string `json:"instance" url:"instance"` + } `json:"metric" url:"metric"` + Value *[]interface{} `json:"value" url:"value"` + } + + ResultType *string +} + +// ResponseLabelNames a list of string label names +type ResponseLabelNames struct { +} + +// ResponseLabelValues a list of string label values +type ResponseLabelValues struct { +} + +type ResponseQueryExemplars struct { + Exemplars *struct { + Labels *struct { + TraceID *string `json:"traceID" url:"traceID"` + } `json:"labels" url:"labels"` + Values *string `json:"values" url:"values"` + Timestamp *string `json:"timestamp" url:"timestamp"` + } + + SeriesLabels *struct { + Service *string `json:"service" url:"service"` + Name *string `json:"__name__" url:"__name__"` + Job *string `json:"job" url:"job"` + Instance *string `json:"instance" url:"instance"` + } +} + +type ResponseQueryRange struct { + Result *struct { + Metric *struct { + Job *string `json:"job" url:"job"` + Instance *string `json:"instance" url:"instance"` + Name *string `json:"__name__" url:"__name__"` + } `json:"metric" url:"metric"` + Values *[]interface{} `json:"values" url:"values"` + } + + ResultType *string +} + +// ResponseSeries a list of objects that contain the label name/value pairs which identify each series +type ResponseSeries struct { +} + +type ResponseSnapshot struct { + Name *string +} + +// ResponseTargetMetadata A list of objects +type ResponseTargetMetadata struct { +} + +type Rule struct { +} + +// Stat stat holds the information about individual cardinality. +type Stat struct { + Name *string + + Value *int +} + +// TsdbStatus tsdbStatus has information of cardinality statistics from postings. +type TsdbStatus struct { + HeadStats *HeadStats + // This will provide a list of the label names and their value count. + LabelValueCountByLabelName []Stat + // This will provide a list of the label names and memory used in bytes. Memory usage is calculated by adding the length of all values for a given label name. + MemoryInBytesByLabelName []Stat + // This will provide a list of label value pairs and their series count. + SeriesCountByLabelValuePair []Stat + // This will provide a list of metrics names and their series count. + SeriesCountByMetricName []Stat +} + +type WalReplayStatus struct { + Current *int + + Max *int + + Min *int +} diff --git a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go index e69de29b..6fa911df 100644 --- a/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go +++ b/cmd/internal/openapi/v3/codegen/testdata/testgensvcgo/svc.go @@ -0,0 +1,623 @@ +/** +* Generated by go-doudou v2.0.4. +* You can edit it as your need. +*/ +package service + +import ( + "context" + "testgensvcgo/dto" + v3 "github.com/unionj-cloud/go-doudou/v2/toolkit/openapi/v3" +) + +//go:generate go-doudou svc http -c +//go:generate go-doudou svc grpc + + +// Testgensvcgo Prometheus HTTP API +// The current stable HTTP API is reachable under /api/v1 on a Prometheus server. Any non-breaking additions will be added under that endpoint. +// +// # Format overview +// The API response format is JSON. Every successful API request returns a ```2xx``` status code. +// +// Invalid requests that reach the API handlers return a JSON error object and one of the following HTTP response codes: +// +// ```400 Bad Request``` when parameters are missing or incorrect. +// ```422 Unprocessable Entity``` when an expression can't be executed ([RFC4918](https://datatracker.ietf.org/doc/html/rfc4918#page-78)). +// ```503 Service Unavailable``` when queries time out or abort. +// +// Other non-```2xx``` codes may be returned for errors occurring before the API endpoint is reached. +// +// An array of warnings may be returned if there are errors that do not inhibit the request execution. All of the data that was successfully collected will be returned in the data field. +// +// The JSON response envelope format is as follows: +// +// ``` +// { +// "status": "success" | "error", +// "data": , +// +// // Only set if status is "error". The data field may still hold +// // additional data. +// "errorType": "", +// "error": "", +// +// // Only if there were warnings while executing the request. +// // There will still be data in the data field. +// "warnings": [""] +// } +// ``` +// # Generic placeholders: +// +// ``````: Input timestamps may be provided either in [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) format or as a Unix timestamp in seconds, with optional decimal places for sub-second precision. Output timestamps are always represented as Unix timestamps in seconds. +// +// ``````: Prometheus [time series selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors) like ```http_requests_total``` or ```http_requests_total{method=~"(GET|POST)"}``` and need to be URL-encoded. +// +// ``````: [Prometheus duration strings](https://prometheus.io/docs/prometheus/latest/querying/basics/#time_durations). For example, ```5m``` refers to a duration of 5 minutes. +// +// ``````: boolean values (strings ```true``` and ```false```). +// +// **Note**: Names of query parameters that may be repeated end with ```[]```. +// +// +// v2 +type Testgensvcgo interface { + + // AdminTsdbSnapshot Creates Snapshot of current data + // Snapshot creates a snapshot of all current data into ```snapshots/-``` under the TSDB's data directory and returns the directory as response. It will optionally skip snapshotting data that is only present in the head block, and which has not yet been compacted to disk. + // + // New in v2.1 and supports PUT from v2.9 + // + AdminTsdbSnapshot(ctx context.Context, + // Skip data present in the head block. Optional. + // + skip_head *bool) ( + ret dto.ResponseSnapshot, err error) + + + // DeleteSeries Returns time series + // The following endpoint returns the list of time series that match a certain label set. + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits. + // + // The ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series. + // + // --- + // **NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future. + // + // --- + // + DeleteSeries(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided. + // + // Example: ```?' --data-urlencode 'match[]=up'``` + // + // required + match[] string) ( + ret dto.ResponseSeries, err error) + + + // GetAlertmanagers Returns current alertmanager discovery + // Returns an overview of the current state of the Prometheus alertmanager discovery + // + // Both the active and dropped Alertmanagers are part of the response. + // + GetAlertmanagers(ctx context.Context) ( + ret dto.AlertmanagerDiscovery, err error) + + + // GetAlerts Returns active alerts + // The /alerts endpoint returns a list of all active alerts. + // + // As the /alerts endpoint is fairly new, it does not have the same stability guarantees as the overarching API v1. + // + GetAlerts(ctx context.Context) ( + ret dto.Alert, err error) + + + // GetLabel_Label_nameValues Returns label values + // The following endpoint returns a list of label values for a provided label name + // + // The ```data``` section of the JSON response is a list of string label values. + // + // --- + // **NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future. + // + // --- + // + GetLabel_Label_nameValues(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series from which to read the label values. Optional. + // + match[] *string, + // Label name + // + // Example: ```/label/job/values``` + // + // required + label_name string) ( + ret dto.ResponseLabelValues, err error) + + + // GetLabels Returns label names + // The following endpoint returns a list of label names + // + // The ```data``` section of the JSON response is a list of string label names. + // + // --- + // **NOTE:** These API endpoints may return metadata for series for which there is no sample within the selected time range, and/or for series whose samples have been marked as deleted via the deletion API endpoint. The exact extent of additionally returned series metadata is an implementation detail that may change in the future. + // + // --- + // + GetLabels(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series from which to read the label values. Optional. + // + match[] *string) ( + ret dto.ResponseLabelNames, err error) + + + // GetMetadata Returns metric metadata + // It returns metadata about metrics currently scrapped from targets. However, it does not provide any target information. This is considered experimental and might change in the future. + // + // The data section of the query result consists of an object where each key is a metric name and each value is a list of unique metadata objects, as exposed for that metric name across all targets. + // + GetMetadata(ctx context.Context, + // Maximum number of metrics to return. + // + // Example: ```?limit=2``` + // + // required + limit float64, + // A metric name to filter metadata for. All metric metadata is retrieved if left empty. + // + // Example: ```?metric=http_requests_total``` + // + metric *string) ( + ret map[string]dto.Metadata, err error) + + + // GetQuery Evaluates instant query + // The following endpoint evaluates an instant query at a single point in time + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. + // + // The data section of the query result has the following format + // ``` + // { + // "resultType": "matrix" | "vector" | "scalar" | "string", + // "result": + // } + // ``` + // `````` refers to the query result data, which has varying formats depending on the ```resultType```. See the [expression query result formats](https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats). + // + GetQuery(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=up``` + // + // required + query string, + // Evaluation timestamp. Optional. + // + // The current server time is used if the ```time``` parameter is omitted. + // + // Example: ```?metric=http_requests_total``` + // + time *string, + // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. + // + // Example: ```?metric=http_requests_total``` + // + timeout *string) ( + ret dto.QueryData, err error) + + + // GetQuery_exemplars Returns list of Exemplars + // This is experimental and might change in the future. The following endpoint returns a list of exemplars for a valid PromQL query for a specific time range + // + GetQuery_exemplars(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=test_exemplar_metric_total``` + // + // required + query string, + // Start timestamp. + // + // Example: ```&start=2020-09-14T15:22:25.479Z``` + // + start *string, + // End timestamp. + // + // Example: ```&end=020-09-14T15:23:25.479Z``` + // + end *string) ( + ret dto.ResponseQueryExemplars, err error) + + + // GetQuery_range Evaluates query over range of time. + // The following endpoint evaluates an expression query over a range of time + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. + // + // The data section of the query result has the following format + // ``` + // { + // "resultType": "matrix", + // "result": + // } + // ``` + // For the format of the `````` placeholder, see the [range-vector result format](https://prometheus.io/docs/prometheus/latest/querying/api/#range-vectors). + // + GetQuery_range(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=up``` + // + // required + query string, + // Start timestamp. + // + // Example: ```&start=2015-07-01T20:10:30.781Z``` + // + start *string, + // End timestamp. + // + // Example: ```&end=2015-07-01T20:11:00.781Z``` + // + end *string, + // Query resolution step width in ```duration``` format or float number of seconds. + // + // Example: ```&step=15s``` + // + step *string, + // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. + // + // Example: ```?metric=http_requests_total``` + // + timeout *string) ( + ret dto.ResponseQueryRange, err error) + + + // GetRules Returns currently loaded rules + // The ```/rules``` API endpoint returns a list of alerting and recording rules that are currently loaded. In addition it returns the currently active alerts fired by the Prometheus instance of each alerting rule. + // + // As the ```/rules``` endpoint is fairly new, it does not have the same stability guarantees as the overarching API v1. + GetRules(ctx context.Context, + // Return only the alerting rules (e.g. ```type=alert```) or the recording rules (e.g. ```type=record```). When the parameter is absent or empty, no filtering is done. + // + type *string) ( + ret dto.RuleDiscovery, err error) + + + // GetSeries Returns time series + // The following endpoint returns the list of time series that match a certain label set. + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits. + // + // The ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series. + // + GetSeries(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided. + // + // Example: ```?' --data-urlencode 'match[]=up'``` + // + // required + match[] string) ( + ret dto.ResponseSeries, err error) + + + // GetStatusBuildinfo Returns build information + // The following endpoint returns various build information properties about the Prometheus server + // + // All values are of the result type ```string```. + // + // --- + // **NOTE:** The exact returned build properties may change without notice between Prometheus versions. + // + // --- + // + // New in v2.14 + // + GetStatusBuildinfo(ctx context.Context) ( + ret dto.PrometheusVersion, err error) + + + // GetStatusConfig Returns configuration file + // The following endpoint returns currently loaded configuration file + // + // The config is returned as dumped YAML file. Due to limitation of + // the YAML library, YAML comments are not included. + // + GetStatusConfig(ctx context.Context) ( + ret dto.PrometheusConfig, err error) + + + // GetStatusFlags Returns flag values + // The following endpoint returns flag values that Prometheus was configured with + // + // All values are of the result type ```string```. + // + // New in v2.2 + // + GetStatusFlags(ctx context.Context) ( + ret interface{}, err error) + + + // GetStatusRuntimeinfo Returns runtime info + // The following endpoint returns various runtime information properties about the Prometheus server + // + // The returned values are of different types, depending on the nature + // of the runtime property + // + // --- + // **NOTE:** The exact returned runtime properties may change without notice between Prometheus versions. + // + // --- + // + // New in v2.14 + // + GetStatusRuntimeinfo(ctx context.Context) ( + ret dto.RuntimeInfo, err error) + + + // GetStatusTsdb Returns statistics about TSBD + // The following endpoint returns various cardinality statistics about the Prometheus TSDB + // + // Response Data + // --- + // + // **headStats:** This provides the following data about the head block of the TSDB: + // >**numSeries:** The number of series. + // **chunkCount:** The number of chunks. + // **minTime:** The current minimum timestamp in milliseconds. + // **maxTime:** The current maximum timestamp in milliseconds. + // + // **seriesCountByMetricName:** This will provide a list of metrics names and their series count. + // **labelValueCountByLabelName:** This will provide a list of the label names and their value count. + // **memoryInBytesByLabelName:** This will provide a list of the label names and memory used in bytes. Memory usage is calculated by adding the length of all values for a given label name. + // **seriesCountByLabelPair:** This will provide a list of label value pairs and their series count. + // + GetStatusTsdb(ctx context.Context) ( + ret dto.TsdbStatus, err error) + + + // GetStatusWalreplay Returns info about WAL replay. + // The following endpoint returns information about the WAL replay + // + // Response Data + // --- + // + // **read:** The number of segments replayed so far. + // **total:** The total number segments needed to be replayed. + // **progress:** The progress of the replay (0 - 100%). + // **state:** The state of the replay. + // **Possible states:** + // - **waiting:** Waiting for the replay to start. + // - **in progress:** The replay is in progress. + // - **done:** The replay has finished. + // + // --- + // **NOTE:** This endpoint is available before the server has been marked ready and is updated in real time to facilitate monitoring the progress of the WAL replay. + // + // --- + // + // New in v2.28 + // + GetStatusWalreplay(ctx context.Context) ( + ret dto.WalReplayStatus, err error) + + + // GetTargets Returns current target discovery. + // Both the active and dropped targets are part of the response by default. ```labels``` represents the label set after relabelling has occurred. ```discoveredLabels``` represent the unmodified labels retrieved during service discovery before relabelling has occurred. + // + GetTargets(ctx context.Context, + // The ```state``` query parameter allows the caller to filter by active or dropped targets, (e.g., ```state=active```, ```state=dropped```, ```state=any```). + // + state *string) ( + ret dto.TargetDiscovery, err error) + + + // GetTargetsMetadata Returns target metadata + // The following endpoint returns metadata about metrics currently scraped from targets. This is experimental and might change in the future. + // + // The ```data``` section of the query result consists of a list of objects that contain metric metadata and the target label set. + GetTargetsMetadata(ctx context.Context, + // Label selectors that match targets by their label sets. All targets are selected if left empty. + // + // Example: ```match_target={job="prometheus"}``` + // + match_target *string, + // A metric name to retrieve metadata for. All metric metadata is retrieved if left empty. + // + // Example: ```metric=go_goroutines``` + // + metric *string, + // Maximum number of targets to match. + // + // Example: ```limit=2``` + // + limit *float64) ( + ret dto.ResponseTargetMetadata, err error) + + + // Labels Returns label names + // The following endpoint returns a list of label names + // + // The ```data``` section of the JSON response is a list of string label names. + // + Labels(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series from which to read the label values. Optional. + // + match[] *string) ( + ret dto.ResponseLabelNames, err error) + + + // PutAdminTsdbSnapshot Creates Snapshot of current data + // Snapshot creates a snapshot of all current data into ```snapshots/-``` under the TSDB's data directory and returns the directory as response. It will optionally skip snapshotting data that is only present in the head block, and which has not yet been compacted to disk. + // + // New in v2.1 and supports PUT from v2.9 + // + PutAdminTsdbSnapshot(ctx context.Context, + // Skip data present in the head block. Optional. + // + skip_head *bool) ( + ret dto.ResponseSnapshot, err error) + + + // Query Evaluates instant query + // The following endpoint evaluates an instant query at a single point in time + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. + // + // The data section of the query result has the following format + // ``` + // { + // "resultType": "matrix" | "vector" | "scalar" | "string", + // "result": + // } + // ``` + // `````` refers to the query result data, which has varying formats depending on the ```resultType```. See the [expression query result formats](https://prometheus.io/docs/prometheus/latest/querying/api/#expression-query-result-formats). + // + Query(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=up``` + // + // required + query string, + // Evaluation timestamp. Optional. + // + // The current server time is used if the ```time``` parameter is omitted. + // + // Example: ```?metric=http_requests_total``` + // + time *string, + // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. + // + // Example: ```?metric=http_requests_total``` + // + timeout *string) ( + ret dto.QueryData, err error) + + + // Query_exemplars Returns list of Exemplars + // This is experimental and might change in the future. The following endpoint returns a list of exemplars for a valid PromQL query for a specific time range + // + Query_exemplars(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=test_exemplar_metric_total``` + // + // required + query string, + // Start timestamp. + // + // Example: ```&start=2020-09-14T15:22:25.479Z``` + // + start *string, + // End timestamp. + // + // Example: ```&end=020-09-14T15:23:25.479Z``` + // + end *string) ( + ret dto.ResponseQueryExemplars, err error) + + + // Query_range Evaluates query over range of time. + // The following endpoint evaluates an expression query over a range of time + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large query that may breach server-side URL character limits. + // + // The data section of the query result has the following format + // ``` + // { + // "resultType": "matrix", + // "result": + // } + // ``` + // For the format of the `````` placeholder, see the [range-vector result format](https://prometheus.io/docs/prometheus/latest/querying/api/#range-vectors). + // + Query_range(ctx context.Context, + // Prometheus expression query string. + // + // Example: ```?query=up``` + // + // required + query string, + // Start timestamp. + // + // Example: ```&start=2015-07-01T20:10:30.781Z``` + // + start *string, + // End timestamp. + // + // Example: ```&end=2015-07-01T20:11:00.781Z``` + // + end *string, + // Query resolution step width in ```duration``` format or float number of seconds. + // + // Example: ```&step=15s``` + // + step *string, + // Evaluation timeout. Optional. Defaults to and is capped by the value of the ```-query.timeout``` flag. + // + // Example: ```?metric=http_requests_total``` + // + timeout *string) ( + ret dto.ResponseQueryRange, err error) + + + // Series Returns time series + // The following endpoint returns the list of time series that match a certain label set. + // + // You can URL-encode these parameters directly in the request body by using the ```POST``` method and ```Content-Type: application/x-www-form-urlencoded``` header. This is useful when specifying a large or dynamic number of series selectors that may breach server-side URL character limits. + // + // The ```data``` section of the query result consists of a list of objects that contain the label name/value pairs which identify each series. + // + Series(ctx context.Context, + // Start timestamp. Optional. + // + start *string, + // End timestamp. Optional. + // + end *string, + // Repeated series selector argument that selects the series to return. At least one ```match[]``` argument must be provided. + // + // Example: ```?' --data-urlencode 'match[]=up'``` + // + // required + match[] string) ( + ret dto.ResponseSeries, err error) + + +} \ No newline at end of file diff --git a/toolkit/executils/executils.go b/toolkit/executils/executils.go new file mode 100644 index 00000000..e0584b02 --- /dev/null +++ b/toolkit/executils/executils.go @@ -0,0 +1,38 @@ +package executils + +import ( + "os" + "os/exec" +) + +//go:generate mockgen -destination ../../mock/mock_executils_runner.go -package mock -source=./executils.go + +// Runner is mainly for executing shell command +type Runner interface { + Run(string, ...string) error + Start(string, ...string) (*exec.Cmd, error) + Output(string, ...string) ([]byte, error) +} + +// CmdRunner implements Runner interface +type CmdRunner struct{} + +func (r CmdRunner) Output(command string, args ...string) ([]byte, error) { + return exec.Command(command, args...).Output() +} + +// Run executes commands +func (r CmdRunner) Run(command string, args ...string) error { + cmd := exec.Command(command, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} + +// Start starts the specified command but does not wait for it to complete. +func (r CmdRunner) Start(command string, args ...string) (*exec.Cmd, error) { + cmd := exec.Command(command, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd, cmd.Start() +} diff --git a/toolkit/executils/executils_test.go b/toolkit/executils/executils_test.go new file mode 100644 index 00000000..b112daca --- /dev/null +++ b/toolkit/executils/executils_test.go @@ -0,0 +1,26 @@ +package executils + +import ( + "fmt" + "os" + "testing" +) + +func TestCmdRunner_Run(t *testing.T) { + var runner CmdRunner + cs := []string{"-test.run=TestHelperProcess", "--"} + runner.Run(os.Args[0], cs...) +} + +func TestCmdRunner_Start(t *testing.T) { + var runner CmdRunner + cs := []string{"-test.run=TestHelperProcess", "--"} + cmd, _ := runner.Start(os.Args[0], cs...) + if err := cmd.Wait(); err != nil { + panic(err) + } +} + +func TestHelperProcess(*testing.T) { + fmt.Println("testing helper process") +} From 5ef5b12445b04f8885af597d9cd6036977e1fbec Mon Sep 17 00:00:00 2001 From: wubin1989 <328454505@qq.com> Date: Tue, 17 Jan 2023 15:20:02 +0000 Subject: [PATCH 5/7] ... --- cmd/internal/protobuf/v3/message.go | 2 +- cmd/internal/svc/codegen/ast.go | 1 + cmd/internal/svc/codegen/doc_test.go | 12 +- cmd/internal/svc/codegen/testdata/dto/dto.go | 7 + cmd/internal/svc/codegen/testdata/svc.go | 3 +- .../svc/codegen/testdata/usersvc_openapi3.go | 2 +- .../codegen/testdata/usersvc_openapi3.json | 628 +++++++++++++++++- cmd/internal/svc/codegen/testdata/vo/vo.go | 5 +- toolkit/cast/string.go | 10 + toolkit/cast/string_test.go | 27 + toolkit/cast/stringslice.go | 22 + toolkit/cast/stringslice_test.go | 85 +++ toolkit/openapi/v3/helper.go | 70 +- toolkit/openapi/v3/model.go | 7 +- 14 files changed, 841 insertions(+), 40 deletions(-) create mode 100644 cmd/internal/svc/codegen/testdata/dto/dto.go diff --git a/cmd/internal/protobuf/v3/message.go b/cmd/internal/protobuf/v3/message.go index 62ee0c8f..2936fc85 100644 --- a/cmd/internal/protobuf/v3/message.go +++ b/cmd/internal/protobuf/v3/message.go @@ -212,7 +212,7 @@ func (receiver ProtoGenerator) MessageOf(ft string) ProtobufType { return Uint64 case "bool": return Bool - case "string", "error", "[]rune": + case "string", "error", "[]rune", "decimal.Decimal": return String case "[]byte", "v3.FileModel", "os.File": return Bytes diff --git a/cmd/internal/svc/codegen/ast.go b/cmd/internal/svc/codegen/ast.go index 3fa3ca39..2a0ef634 100644 --- a/cmd/internal/svc/codegen/ast.go +++ b/cmd/internal/svc/codegen/ast.go @@ -65,6 +65,7 @@ func parseSelectorExpr(expr *ast.SelectorExpr) string { result != "time.Time" && result != "v3.FileModel" && result != "multipart.FileHeader" && + result != "decimal.Decimal" && result != "os.File" { panic(fmt.Errorf("not support %s in svc.go file and vo, dto package", result)) } diff --git a/cmd/internal/svc/codegen/doc_test.go b/cmd/internal/svc/codegen/doc_test.go index e9fba36c..95ca8780 100644 --- a/cmd/internal/svc/codegen/doc_test.go +++ b/cmd/internal/svc/codegen/doc_test.go @@ -53,7 +53,7 @@ func TestGenDocUploadFile(t *testing.T) { } svcfile := filepath.Join(testDir, "svc.go") ic := astutils.BuildInterfaceCollector(svcfile, ExprStringP) - + ParseDto(testDir, "vo") tests := []struct { name string args args @@ -115,3 +115,13 @@ func TestParseVo(t *testing.T) { So(len(v3helper.Schemas), ShouldNotBeZeroValue) }) } + +func TestParseVo_Decimal(t *testing.T) { + Convey("Test Parse decimal.Decimal type", t, func() { + ParseDto(testDir, "dto") + schemas := v3helper.Schemas + laptopSchema := schemas["Laptop"] + priceSchema := laptopSchema.Properties["Price"] + So(priceSchema, ShouldResemble, v3helper.Decimal) + }) +} diff --git a/cmd/internal/svc/codegen/testdata/dto/dto.go b/cmd/internal/svc/codegen/testdata/dto/dto.go new file mode 100644 index 00000000..55ac8b34 --- /dev/null +++ b/cmd/internal/svc/codegen/testdata/dto/dto.go @@ -0,0 +1,7 @@ +package dto + +import "github.com/shopspring/decimal" + +type Laptop struct { + Price decimal.Decimal +} diff --git a/cmd/internal/svc/codegen/testdata/svc.go b/cmd/internal/svc/codegen/testdata/svc.go index 8d4b2350..4dd6cc13 100644 --- a/cmd/internal/svc/codegen/testdata/svc.go +++ b/cmd/internal/svc/codegen/testdata/svc.go @@ -2,6 +2,7 @@ package service import ( "context" + "github.com/shopspring/decimal" v3 "github.com/unionj-cloud/go-doudou/v2/toolkit/openapi/v3" "mime/multipart" "os" @@ -33,5 +34,5 @@ type Usersvc interface { UploadAvatar(context.Context, []v3.FileModel, string, v3.FileModel, *multipart.FileHeader, []*multipart.FileHeader) (int, interface{}, error) // comment5 - DownloadAvatar(ctx context.Context, userId interface{}, data []byte, userAttrs ...string) (*os.File, error) + DownloadAvatar(ctx context.Context, userId interface{}, data []byte, price decimal.Decimal, userAttrs ...string) (*os.File, error) } diff --git a/cmd/internal/svc/codegen/testdata/usersvc_openapi3.go b/cmd/internal/svc/codegen/testdata/usersvc_openapi3.go index 06e6280b..ea747e80 100755 --- a/cmd/internal/svc/codegen/testdata/usersvc_openapi3.go +++ b/cmd/internal/svc/codegen/testdata/usersvc_openapi3.go @@ -3,5 +3,5 @@ package service import "github.com/unionj-cloud/go-doudou/v2/framework/rest" func init() { - rest.Oas = `{"openapi":"3.0.2","info":{"title":"Usersvc","description":"用户服务接口\nv1版本","version":"v20221225"},"servers":[{"url":"http://localhost:6060"}],"paths":{"/usersvc/downloadavatar":{"post":{"description":"comment5","parameters":[{"name":"data","in":"query","required":true,"schema":{"type":"string"}},{"name":"userAttrs","in":"query","schema":{"type":"array","items":{"type":"string"}}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}}}}},"/usersvc/pageusers":{"post":{"description":"You can define your service methods as your need. Below is an example.@role(user)","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageUsersResp"}}}}}}},"/usersvc/signup":{"post":{"description":"comment3\n@permission(create,update)@role(admin)","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/SignUpReq"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignUpResp"}}}}}}},"/usersvc/uploadavatar":{"post":{"description":"comment4\n@role(user)","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UploadAvatarReq"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadAvatarResp"}}}}}}},"/usersvc/user":{"get":{"description":"comment1\ncomment2\n@role(admin)","parameters":[{"name":"userId","in":"query","description":"用户ID","required":true,"schema":{"type":"string","description":"用户ID"}},{"name":"photo","in":"query","description":"图片地址","required":true,"schema":{"type":"string","description":"图片地址"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetUserResp"}}}}}}}},"components":{"schemas":{"GetUserResp":{"title":"GetUserResp","type":"object","properties":{"code":{"type":"integer","format":"int32"},"data":{"type":"string"}},"required":["code","data"]},"PageUsersResp":{"title":"PageUsersResp","type":"object","properties":{"code":{"type":"integer","format":"int32"},"data":{"type":"object"}},"required":["code","data"]},"SignUpReq":{"title":"SignUpReq","type":"object","properties":{"actived":{"type":"boolean"},"password":{"type":"integer","format":"int32"},"score":{"type":"array","items":{"type":"integer","format":"int32"}},"username":{"type":"string"}},"required":["username","password","actived","score"]},"SignUpResp":{"title":"SignUpResp","type":"object","properties":{"code":{"type":"integer","format":"int32"},"data":{"type":"string"}},"required":["code","data"]},"UploadAvatarReq":{"title":"UploadAvatarReq","type":"object","properties":{"pf":{"type":"array","items":{"type":"string","format":"binary"}},"pf2":{"type":"string","format":"binary"},"pf3":{"type":"string","format":"binary"},"pf4":{"type":"array","items":{"type":"string","format":"binary"}},"ps":{"type":"string"}},"required":["pf","ps","pf2","pf4"]},"UploadAvatarResp":{"title":"UploadAvatarResp","type":"object","properties":{"ri":{"type":"integer","format":"int32"},"ri2":{"type":"object"}},"required":["ri","ri2"]}}}}` + rest.Oas = `{"openapi":"3.0.2","info":{"title":"Usersvc","description":"用户服务接口\nv1版本","version":"v20230117"},"servers":[{"url":"http://localhost:6060"}],"paths":{"/usersvc/downloadavatar":{"post":{"description":"comment5","parameters":[{"name":"data","in":"query","required":true,"schema":{"type":"string"}},{"name":"price","in":"query","required":true,"schema":{"type":"string","format":"decimal"}},{"name":"userAttrs","in":"query","schema":{"type":"array","items":{"type":"string"}}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}}}}},"/usersvc/pageusers":{"post":{"description":"You can define your service methods as your need. Below is an example.@role(user)","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageQuery"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageUsersResp"}}}}}}},"/usersvc/signup":{"post":{"description":"comment3\n@permission(create,update)@role(admin)","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/SignUpReq"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignUpResp"}}}}}}},"/usersvc/uploadavatar":{"post":{"description":"comment4\n@role(user)","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UploadAvatarReq"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadAvatarResp"}}}}}}},"/usersvc/user":{"get":{"description":"comment1\ncomment2\n@role(admin)","parameters":[{"name":"userId","in":"query","description":"用户ID","required":true,"schema":{"type":"string","description":"用户ID"}},{"name":"photo","in":"query","description":"图片地址","required":true,"schema":{"type":"string","description":"图片地址"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetUserResp"}}}}}}}},"components":{"schemas":{"Event":{"title":"Event","type":"object","properties":{"EventType":{"type":"integer","format":"int32"},"Name":{"type":"string"}},"required":["Name","EventType"]},"GetUserResp":{"title":"GetUserResp","type":"object","properties":{"code":{"type":"integer","format":"int32"},"data":{"type":"string"}},"required":["code","data"]},"Keyboard":{"title":"Keyboard","type":"object","properties":{"backlit":{"type":"boolean"},"layout":{"type":"string","default":"UNKNOWN","enum":["UNKNOWN","QWERTZ","AZERTY","QWERTY"]}},"required":["layout","backlit"]},"Order":{"title":"Order","type":"object","properties":{"Col":{"type":"string"},"Sort":{"type":"string"}},"description":"排序条件","required":["Col","Sort"]},"Page":{"title":"Page","type":"object","properties":{"Orders":{"type":"array","items":{"$ref":"#/components/schemas/Order"},"description":"排序规则"},"PageNo":{"type":"integer","format":"int32","description":"页码"},"Size":{"type":"integer","format":"int32","description":"每页行数"},"User":{"$ref":"#/components/schemas/UserVo"}},"required":["Orders","PageNo","Size","User"]},"PageFilter":{"title":"PageFilter","type":"object","properties":{"Dept":{"type":"integer","format":"int32","description":"所属部门ID"},"Name":{"type":"string","description":"真实姓名,前缀匹配"}},"description":"筛选条件","required":["Name","Dept"]},"PageQuery":{"title":"PageQuery","type":"object","properties":{"Filter":{"$ref":"#/components/schemas/PageFilter"},"Page":{"$ref":"#/components/schemas/Page"}},"description":"\n分页筛选条件","required":["Filter","Page"]},"PageRet":{"title":"PageRet","type":"object","properties":{"HasNext":{"type":"boolean"},"Items":{"type":"object"},"PageNo":{"type":"integer","format":"int32"},"PageSize":{"type":"integer","format":"int32"},"Price":{"type":"string","format":"decimal"},"Total":{"type":"integer","format":"int32"}},"description":"\n","required":["Items","PageNo","PageSize","Total","HasNext","Price"]},"PageUsersResp":{"title":"PageUsersResp","type":"object","properties":{"code":{"type":"integer","format":"int32"},"data":{"$ref":"#/components/schemas/PageRet"}},"required":["code","data"]},"SignUpReq":{"title":"SignUpReq","type":"object","properties":{"actived":{"type":"boolean"},"password":{"type":"integer","format":"int32"},"score":{"type":"array","items":{"type":"integer","format":"int32"}},"username":{"type":"string"}},"required":["username","password","actived","score"]},"SignUpResp":{"title":"SignUpResp","type":"object","properties":{"code":{"type":"integer","format":"int32"},"data":{"type":"string"}},"required":["code","data"]},"TestAlias":{"title":"TestAlias","type":"object","properties":{"Age":{"type":"object"},"School":{"type":"array","items":{"type":"object","properties":{"Addr":{"type":"object","properties":{"Block":{"type":"string"},"Full":{"type":"string"},"Zip":{"type":"string"}},"required":["Zip","Block","Full"]},"Name":{"type":"string"}},"required":["Name","Addr"]}}},"required":["Age","School"]},"TestExprStringP":{"title":"TestExprStringP","type":"object","properties":{"Age":{"type":"object"},"Data":{"type":"object","additionalProperties":{"type":"string"},"x-map-type":"map[string]string"},"Hobbies":{"type":"array","items":{"type":"string"}},"School":{"type":"array","items":{"type":"object","properties":{"Addr":{"type":"object","properties":{"Block":{"type":"string"},"Full":{"type":"string"},"Zip":{"type":"string"}},"required":["Zip","Block","Full"]},"Name":{"type":"string"}},"required":["Name","Addr"]}}},"required":["Age","Hobbies","Data","School"]},"UploadAvatarReq":{"title":"UploadAvatarReq","type":"object","properties":{"pf":{"type":"array","items":{"type":"string","format":"binary"}},"pf2":{"type":"string","format":"binary"},"pf3":{"type":"string","format":"binary"},"pf4":{"type":"array","items":{"type":"string","format":"binary"}},"ps":{"type":"string"}},"required":["pf","ps","pf2","pf4"]},"UploadAvatarResp":{"title":"UploadAvatarResp","type":"object","properties":{"ri":{"type":"integer","format":"int32"},"ri2":{"type":"object"}},"required":["ri","ri2"]},"UserVo":{"title":"UserVo","type":"object","properties":{"Dept":{"type":"string"},"Id":{"type":"integer","format":"int32"},"Name":{"type":"string"},"Phone":{"type":"string"}},"required":["Id","Name","Phone","Dept"]}}}}` } diff --git a/cmd/internal/svc/codegen/testdata/usersvc_openapi3.json b/cmd/internal/svc/codegen/testdata/usersvc_openapi3.json index c91eac4c..c3d44d6f 100755 --- a/cmd/internal/svc/codegen/testdata/usersvc_openapi3.json +++ b/cmd/internal/svc/codegen/testdata/usersvc_openapi3.json @@ -1 +1,627 @@ -{"openapi":"3.0.2","info":{"title":"Usersvc","description":"用户服务接口\nv1版本","version":"v20221225"},"servers":[{"url":"http://localhost:6060"}],"paths":{"/usersvc/downloadavatar":{"post":{"description":"comment5","parameters":[{"name":"data","in":"query","required":true,"schema":{"type":"string"}},{"name":"userAttrs","in":"query","schema":{"type":"array","items":{"type":"string"}}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}}}}},"/usersvc/pageusers":{"post":{"description":"You can define your service methods as your need. Below is an example.@role(user)","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageUsersResp"}}}}}}},"/usersvc/signup":{"post":{"description":"comment3\n@permission(create,update)@role(admin)","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/SignUpReq"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignUpResp"}}}}}}},"/usersvc/uploadavatar":{"post":{"description":"comment4\n@role(user)","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/UploadAvatarReq"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadAvatarResp"}}}}}}},"/usersvc/user":{"get":{"description":"comment1\ncomment2\n@role(admin)","parameters":[{"name":"userId","in":"query","description":"用户ID","required":true,"schema":{"type":"string","description":"用户ID"}},{"name":"photo","in":"query","description":"图片地址","required":true,"schema":{"type":"string","description":"图片地址"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetUserResp"}}}}}}}},"components":{"schemas":{"GetUserResp":{"title":"GetUserResp","type":"object","properties":{"code":{"type":"integer","format":"int32"},"data":{"type":"string"}},"required":["code","data"]},"PageUsersResp":{"title":"PageUsersResp","type":"object","properties":{"code":{"type":"integer","format":"int32"},"data":{"type":"object"}},"required":["code","data"]},"SignUpReq":{"title":"SignUpReq","type":"object","properties":{"actived":{"type":"boolean"},"password":{"type":"integer","format":"int32"},"score":{"type":"array","items":{"type":"integer","format":"int32"}},"username":{"type":"string"}},"required":["username","password","actived","score"]},"SignUpResp":{"title":"SignUpResp","type":"object","properties":{"code":{"type":"integer","format":"int32"},"data":{"type":"string"}},"required":["code","data"]},"UploadAvatarReq":{"title":"UploadAvatarReq","type":"object","properties":{"pf":{"type":"array","items":{"type":"string","format":"binary"}},"pf2":{"type":"string","format":"binary"},"pf3":{"type":"string","format":"binary"},"pf4":{"type":"array","items":{"type":"string","format":"binary"}},"ps":{"type":"string"}},"required":["pf","ps","pf2","pf4"]},"UploadAvatarResp":{"title":"UploadAvatarResp","type":"object","properties":{"ri":{"type":"integer","format":"int32"},"ri2":{"type":"object"}},"required":["ri","ri2"]}}}} \ No newline at end of file +{ + "openapi": "3.0.2", + "info": { + "title": "Usersvc", + "description": "用户服务接口\nv1版本", + "version": "v20230117" + }, + "servers": [ + { + "url": "http://localhost:6060" + } + ], + "paths": { + "/usersvc/downloadavatar": { + "post": { + "description": "comment5", + "parameters": [ + { + "name": "data", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "price", + "in": "query", + "required": true, + "schema": { + "type": "string", + "format": "decimal" + } + }, + { + "name": "userAttrs", + "in": "query", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + } + } + } + }, + "/usersvc/pageusers": { + "post": { + "description": "You can define your service methods as your need. Below is an example.@role(user)", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageQuery" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageUsersResp" + } + } + } + } + } + } + }, + "/usersvc/signup": { + "post": { + "description": "comment3\n@permission(create,update)@role(admin)", + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/SignUpReq" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignUpResp" + } + } + } + } + } + } + }, + "/usersvc/uploadavatar": { + "post": { + "description": "comment4\n@role(user)", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/UploadAvatarReq" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadAvatarResp" + } + } + } + } + } + } + }, + "/usersvc/user": { + "get": { + "description": "comment1\ncomment2\n@role(admin)", + "parameters": [ + { + "name": "userId", + "in": "query", + "description": "用户ID", + "required": true, + "schema": { + "type": "string", + "description": "用户ID" + } + }, + { + "name": "photo", + "in": "query", + "description": "图片地址", + "required": true, + "schema": { + "type": "string", + "description": "图片地址" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetUserResp" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Event": { + "title": "Event", + "type": "object", + "properties": { + "EventType": { + "type": "integer", + "format": "int32" + }, + "Name": { + "type": "string" + } + }, + "required": [ + "Name", + "EventType" + ] + }, + "GetUserResp": { + "title": "GetUserResp", + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "data": { + "type": "string" + } + }, + "required": [ + "code", + "data" + ] + }, + "Keyboard": { + "title": "Keyboard", + "type": "object", + "properties": { + "backlit": { + "type": "boolean" + }, + "layout": { + "type": "string", + "default": "UNKNOWN", + "enum": [ + "UNKNOWN", + "QWERTZ", + "AZERTY", + "QWERTY" + ] + } + }, + "required": [ + "layout", + "backlit" + ] + }, + "Order": { + "title": "Order", + "type": "object", + "properties": { + "Col": { + "type": "string" + }, + "Sort": { + "type": "string" + } + }, + "description": "排序条件", + "required": [ + "Col", + "Sort" + ] + }, + "Page": { + "title": "Page", + "type": "object", + "properties": { + "Orders": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Order" + }, + "description": "排序规则" + }, + "PageNo": { + "type": "integer", + "format": "int32", + "description": "页码" + }, + "Size": { + "type": "integer", + "format": "int32", + "description": "每页行数" + }, + "User": { + "$ref": "#/components/schemas/UserVo" + } + }, + "required": [ + "Orders", + "PageNo", + "Size", + "User" + ] + }, + "PageFilter": { + "title": "PageFilter", + "type": "object", + "properties": { + "Dept": { + "type": "integer", + "format": "int32", + "description": "所属部门ID" + }, + "Name": { + "type": "string", + "description": "真实姓名,前缀匹配" + } + }, + "description": "筛选条件", + "required": [ + "Name", + "Dept" + ] + }, + "PageQuery": { + "title": "PageQuery", + "type": "object", + "properties": { + "Filter": { + "$ref": "#/components/schemas/PageFilter" + }, + "Page": { + "$ref": "#/components/schemas/Page" + } + }, + "description": "\n分页筛选条件", + "required": [ + "Filter", + "Page" + ] + }, + "PageRet": { + "title": "PageRet", + "type": "object", + "properties": { + "HasNext": { + "type": "boolean" + }, + "Items": { + "type": "object" + }, + "PageNo": { + "type": "integer", + "format": "int32" + }, + "PageSize": { + "type": "integer", + "format": "int32" + }, + "Price": { + "type": "string", + "format": "decimal" + }, + "Total": { + "type": "integer", + "format": "int32" + } + }, + "description": "\n", + "required": [ + "Items", + "PageNo", + "PageSize", + "Total", + "HasNext", + "Price" + ] + }, + "PageUsersResp": { + "title": "PageUsersResp", + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "data": { + "$ref": "#/components/schemas/PageRet" + } + }, + "required": [ + "code", + "data" + ] + }, + "SignUpReq": { + "title": "SignUpReq", + "type": "object", + "properties": { + "actived": { + "type": "boolean" + }, + "password": { + "type": "integer", + "format": "int32" + }, + "score": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + }, + "username": { + "type": "string" + } + }, + "required": [ + "username", + "password", + "actived", + "score" + ] + }, + "SignUpResp": { + "title": "SignUpResp", + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "data": { + "type": "string" + } + }, + "required": [ + "code", + "data" + ] + }, + "TestAlias": { + "title": "TestAlias", + "type": "object", + "properties": { + "Age": { + "type": "object" + }, + "School": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Addr": { + "type": "object", + "properties": { + "Block": { + "type": "string" + }, + "Full": { + "type": "string" + }, + "Zip": { + "type": "string" + } + }, + "required": [ + "Zip", + "Block", + "Full" + ] + }, + "Name": { + "type": "string" + } + }, + "required": [ + "Name", + "Addr" + ] + } + } + }, + "required": [ + "Age", + "School" + ] + }, + "TestExprStringP": { + "title": "TestExprStringP", + "type": "object", + "properties": { + "Age": { + "type": "object" + }, + "Data": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-map-type": "map[string]string" + }, + "Hobbies": { + "type": "array", + "items": { + "type": "string" + } + }, + "School": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Addr": { + "type": "object", + "properties": { + "Block": { + "type": "string" + }, + "Full": { + "type": "string" + }, + "Zip": { + "type": "string" + } + }, + "required": [ + "Zip", + "Block", + "Full" + ] + }, + "Name": { + "type": "string" + } + }, + "required": [ + "Name", + "Addr" + ] + } + } + }, + "required": [ + "Age", + "Hobbies", + "Data", + "School" + ] + }, + "UploadAvatarReq": { + "title": "UploadAvatarReq", + "type": "object", + "properties": { + "pf": { + "type": "array", + "items": { + "type": "string", + "format": "binary" + } + }, + "pf2": { + "type": "string", + "format": "binary" + }, + "pf3": { + "type": "string", + "format": "binary" + }, + "pf4": { + "type": "array", + "items": { + "type": "string", + "format": "binary" + } + }, + "ps": { + "type": "string" + } + }, + "required": [ + "pf", + "ps", + "pf2", + "pf4" + ] + }, + "UploadAvatarResp": { + "title": "UploadAvatarResp", + "type": "object", + "properties": { + "ri": { + "type": "integer", + "format": "int32" + }, + "ri2": { + "type": "object" + } + }, + "required": [ + "ri", + "ri2" + ] + }, + "UserVo": { + "title": "UserVo", + "type": "object", + "properties": { + "Dept": { + "type": "string" + }, + "Id": { + "type": "integer", + "format": "int32" + }, + "Name": { + "type": "string" + }, + "Phone": { + "type": "string" + } + }, + "required": [ + "Id", + "Name", + "Phone", + "Dept" + ] + } + } + } +} \ No newline at end of file diff --git a/cmd/internal/svc/codegen/testdata/vo/vo.go b/cmd/internal/svc/codegen/testdata/vo/vo.go index 1affe5bc..7ee8bbe9 100644 --- a/cmd/internal/svc/codegen/testdata/vo/vo.go +++ b/cmd/internal/svc/codegen/testdata/vo/vo.go @@ -1,5 +1,7 @@ package vo +import "github.com/shopspring/decimal" + //go:generate go-doudou name --file $GOFILE -o // 筛选条件 @@ -38,6 +40,7 @@ type PageRet struct { PageSize int Total int HasNext bool + Price decimal.Decimal } type UserVo struct { @@ -45,4 +48,4 @@ type UserVo struct { Name string Phone string Dept string -} \ No newline at end of file +} diff --git a/toolkit/cast/string.go b/toolkit/cast/string.go index 776a81a5..ef3de2be 100644 --- a/toolkit/cast/string.go +++ b/toolkit/cast/string.go @@ -3,6 +3,7 @@ package cast import ( "fmt" "github.com/pkg/errors" + "github.com/shopspring/decimal" "strconv" ) @@ -145,3 +146,12 @@ func ToRuneSliceE(s string) ([]rune, error) { func ToByteSliceE(s string) ([]byte, error) { return []byte(s), nil } + +func ToDecimal(s string) decimal.Decimal { + ret, _ := decimal.NewFromString(s) + return ret +} + +func ToDecimalE(s string) (decimal.Decimal, error) { + return decimal.NewFromString(s) +} diff --git a/toolkit/cast/string_test.go b/toolkit/cast/string_test.go index f725c45f..5c385435 100644 --- a/toolkit/cast/string_test.go +++ b/toolkit/cast/string_test.go @@ -1,6 +1,7 @@ package cast import ( + "github.com/shopspring/decimal" "reflect" "testing" ) @@ -854,3 +855,29 @@ func TestToIntOrDefault(t *testing.T) { }) } } + +func TestToDecimal(t *testing.T) { + type args struct { + s string + } + tests := []struct { + name string + args args + want decimal.Decimal + }{ + { + name: "", + args: args{ + s: "2.43", + }, + want: decimal.NewFromFloat(2.43), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ToDecimal(tt.args.s); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ToDecimal() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/toolkit/cast/stringslice.go b/toolkit/cast/stringslice.go index f423276f..b7efc65f 100644 --- a/toolkit/cast/stringslice.go +++ b/toolkit/cast/stringslice.go @@ -2,6 +2,7 @@ package cast import ( "fmt" + "github.com/shopspring/decimal" ) func ToIntSliceE(s []string) ([]int, error) { @@ -275,3 +276,24 @@ func ToInterfaceSliceE(s []string) ([]interface{}, error) { } return ret, nil } + +func ToDecimalSlice(s []string) []decimal.Decimal { + var ret []decimal.Decimal + for _, item := range s { + d, _ := decimal.NewFromString(item) + ret = append(ret, d) + } + return ret +} + +func ToDecimalSliceE(s []string) ([]decimal.Decimal, error) { + var ret []decimal.Decimal + for _, item := range s { + d, err := ToDecimalE(item) + if err != nil { + return nil, fmt.Errorf("unable to cast string slice %#v to []decimal.Decimal because of error %s", s, err) + } + ret = append(ret, d) + } + return ret, nil +} diff --git a/toolkit/cast/stringslice_test.go b/toolkit/cast/stringslice_test.go index 72f3f73b..0cce4e6d 100644 --- a/toolkit/cast/stringslice_test.go +++ b/toolkit/cast/stringslice_test.go @@ -2,6 +2,7 @@ package cast import ( "fmt" + "github.com/shopspring/decimal" "reflect" "testing" ) @@ -888,3 +889,87 @@ func TestToErrorSliceE(t *testing.T) { }) } } + +func TestToDecimalSlice(t *testing.T) { + type args struct { + s []string + } + tests := []struct { + name string + args args + want []decimal.Decimal + }{ + { + name: "", + args: args{ + s: []string{ + "2.43", + "17.89", + }, + }, + want: []decimal.Decimal{ + decimal.NewFromFloat(2.43), + decimal.NewFromFloat(17.89), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ToDecimalSlice(tt.args.s); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ToDecimalSlice() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestToDecimalSliceE(t *testing.T) { + type args struct { + s []string + } + tests := []struct { + name string + args args + want []decimal.Decimal + wantErr bool + }{ + { + name: "", + args: args{ + s: []string{ + "2.43", + "17.89", + }, + }, + want: []decimal.Decimal{ + decimal.NewFromFloat(2.43), + decimal.NewFromFloat(17.89), + }, + wantErr: false, + }, + { + name: "", + args: args{ + s: []string{ + "2.43", + "17d.89", + }, + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ToDecimalSliceE(tt.args.s) + if (err != nil) != tt.wantErr { + t.Errorf("ToDecimalSliceE() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != nil { + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ToDecimalSliceE() got = %v, want %v", got, tt.want) + } + } + }) + } +} diff --git a/toolkit/openapi/v3/helper.go b/toolkit/openapi/v3/helper.go index 9c5b0187..882b9cca 100644 --- a/toolkit/openapi/v3/helper.go +++ b/toolkit/openapi/v3/helper.go @@ -71,6 +71,8 @@ func SchemaOf(field astutils.FieldMeta) *Schema { return File case "time.Time": return Time + case "decimal.Decimal": + return Decimal default: return handleDefaultCase(ft) } @@ -134,39 +136,41 @@ func handleDefaultCase(ft string) *Schema { } var castFuncMap = map[string]string{ - "bool": "ToBool", - "float64": "ToFloat64", - "float32": "ToFloat32", - "int64": "ToInt64", - "int32": "ToInt32", - "int16": "ToInt16", - "int8": "ToInt8", - "int": "ToInt", - "uint": "ToUint", - "uint8": "ToUint8", - "uint16": "ToUint16", - "uint32": "ToUint32", - "uint64": "ToUint64", - "error": "ToError", - "[]byte": "ToByteSlice", - "[]rune": "ToRuneSlice", - "[]interface{}": "ToInterfaceSlice", - "[]bool": "ToBoolSlice", - "[]int": "ToIntSlice", - "[]float64": "ToFloat64Slice", - "[]float32": "ToFloat32Slice", - "[]int64": "ToInt64Slice", - "[]int32": "ToInt32Slice", - "[]int16": "ToInt16Slice", - "[]int8": "ToInt8Slice", - "[]uint": "ToUintSlice", - "[]uint8": "ToUint8Slice", - "[]uint16": "ToUint16Slice", - "[]uint32": "ToUint32Slice", - "[]uint64": "ToUint64Slice", - "[]error": "ToErrorSlice", - "[][]byte": "ToByteSliceSlice", - "[][]rune": "ToRuneSliceSlice", + "bool": "ToBool", + "float64": "ToFloat64", + "float32": "ToFloat32", + "int64": "ToInt64", + "int32": "ToInt32", + "int16": "ToInt16", + "int8": "ToInt8", + "int": "ToInt", + "uint": "ToUint", + "uint8": "ToUint8", + "uint16": "ToUint16", + "uint32": "ToUint32", + "uint64": "ToUint64", + "error": "ToError", + "decimal.Decimal": "ToDecimal", + "[]byte": "ToByteSlice", + "[]rune": "ToRuneSlice", + "[]interface{}": "ToInterfaceSlice", + "[]bool": "ToBoolSlice", + "[]int": "ToIntSlice", + "[]float64": "ToFloat64Slice", + "[]float32": "ToFloat32Slice", + "[]int64": "ToInt64Slice", + "[]int32": "ToInt32Slice", + "[]int16": "ToInt16Slice", + "[]int8": "ToInt8Slice", + "[]uint": "ToUintSlice", + "[]uint8": "ToUint8Slice", + "[]uint16": "ToUint16Slice", + "[]uint32": "ToUint32Slice", + "[]uint64": "ToUint64Slice", + "[]error": "ToErrorSlice", + "[]decimal.Decimal": "ToDecimalSlice", + "[][]byte": "ToByteSliceSlice", + "[][]rune": "ToRuneSliceSlice", } func IsSupport(t string) bool { diff --git a/toolkit/openapi/v3/model.go b/toolkit/openapi/v3/model.go index 4c201687..d6c9045b 100644 --- a/toolkit/openapi/v3/model.go +++ b/toolkit/openapi/v3/model.go @@ -289,7 +289,8 @@ const ( // DateTimeF date-time DateTimeF Format = "date-time" // BinaryF binary - BinaryF Format = "binary" + BinaryF Format = "binary" + DecimalF Format = "decimal" ) var ( @@ -340,6 +341,10 @@ var ( Type: ArrayT, Items: File, } + Decimal = &Schema{ + Type: StringT, + Format: DecimalF, + } ) type FileModel struct { From cd871f18da3ea490cd58c4c91a450e332896b570 Mon Sep 17 00:00:00 2001 From: wubin1989 <328454505@qq.com> Date: Tue, 17 Jan 2023 15:21:34 +0000 Subject: [PATCH 6/7] fix #17 --- toolkit/openapi/v3/helper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolkit/openapi/v3/helper.go b/toolkit/openapi/v3/helper.go index 882b9cca..42f3f49c 100644 --- a/toolkit/openapi/v3/helper.go +++ b/toolkit/openapi/v3/helper.go @@ -71,7 +71,7 @@ func SchemaOf(field astutils.FieldMeta) *Schema { return File case "time.Time": return Time - case "decimal.Decimal": + case "decimal.Decimal": // simple treat decimal.Decimal as string return Decimal default: return handleDefaultCase(ft) From 9d222a2d3b096a68efeeb4d3d58b14f6532debae Mon Sep 17 00:00:00 2001 From: wubin1989 <328454505@qq.com> Date: Tue, 17 Jan 2023 15:58:36 +0000 Subject: [PATCH 7/7] fix unit test --- cmd/internal/openapi/v3/codegen/common.go | 2 +- cmd/version_test.go | 19 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/cmd/internal/openapi/v3/codegen/common.go b/cmd/internal/openapi/v3/codegen/common.go index ebc88c90..89cda8e7 100644 --- a/cmd/internal/openapi/v3/codegen/common.go +++ b/cmd/internal/openapi/v3/codegen/common.go @@ -320,7 +320,7 @@ func (receiver *OpenAPICodeGenerator) responseBody(endpoint, httpMethod string, } else if content.TextPlain != nil { results = append(results, *receiver.schema2Field(content.TextPlain.Schema, "ret", content.TextPlain.Example, v3.TEXT_EXAMPLE)) } else if content.Default != nil { - results = append(results, *receiver.schema2Field(content.Default.Schema, "ret", content.TextPlain.Example, v3.TEXT_EXAMPLE)) + results = append(results, *receiver.schema2Field(content.Default.Schema, "ret", content.Default.Example, v3.TEXT_EXAMPLE)) } else { return nil, errors.Errorf("200 response content definition not support yet in api %s %s", httpMethod, endpoint) } diff --git a/cmd/version_test.go b/cmd/version_test.go index 8e1d31ca..7a0e75d4 100644 --- a/cmd/version_test.go +++ b/cmd/version_test.go @@ -10,25 +10,6 @@ import ( "testing" ) -func Test_versionCmd_No(t *testing.T) { - Convey("Should not panic and stop to upgrade when run version command", t, func() { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - prompt := mock.NewMockISelect(ctrl) - prompt. - EXPECT(). - Run(). - AnyTimes(). - Return(0, "No", nil) - - cmd.Prompt = prompt - - So(func() { - ExecuteCommandC(cmd.GetRootCmd(), []string{"version"}...) - }, ShouldNotPanic) - }) -} - func Test_versionCmd_Yes(t *testing.T) { Convey("Should not panic and succeed to upgrade when run version command", t, func() { ctrl := gomock.NewController(t)