Skip to content

Commit

Permalink
feat(cmd-api-server): swagger.json endpoints
Browse files Browse the repository at this point in the history
fixes: #1877
Signed-off-by: adrianbatuto <[email protected]>
  • Loading branch information
adrianbatuto committed May 30, 2023
1 parent e54842d commit 5a5d78f
Show file tree
Hide file tree
Showing 10 changed files with 383 additions and 2 deletions.
31 changes: 30 additions & 1 deletion packages/cactus-cmd-api-server/src/main/json/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
"PrometheusExporterMetricsResponse": {
"type": "string",
"nullable": false
},
"GetOpenApiSpecV1EndpointResponse": {
"type": "string",
"nullable": false
}
}
},
Expand Down Expand Up @@ -128,6 +132,31 @@
}
}
}
},
"/api/v1/api-server/get-open-api-spec-v1-endpoint": {
"post": {
"description": "Returns the openapi.json document of specific plugin.",
"x-hyperledger-cactus": {
"http": {
"verbLowerCase": "get",
"path": "/api/v1/api-server/get-open-api-spec-v1-endpoint"
}
},
"operationId": "getOpenApiSpecV1Endpoint",
"parameters": [],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GetOpenApiSpecV1EndpointResponse"
}
}
}
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ All URIs are relative to *http://localhost*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
*DefaultApi* | [**getHealthCheckV1**](docs/DefaultApi.md#gethealthcheckv1) | **GET** /api/v1/api-server/healthcheck | Can be used to verify liveness of an API server instance
*DefaultApi* | [**getOpenApiSpecV1Endpoint**](docs/DefaultApi.md#getopenapispecv1endpoint) | **POST** /api/v1/api-server/get-open-api-spec-v1-endpoint |
*DefaultApi* | [**getPrometheusMetricsV1**](docs/DefaultApi.md#getprometheusmetricsv1) | **GET** /api/v1/api-server/get-prometheus-exporter-metrics | Get the Prometheus Metrics


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,57 @@ class DefaultApi(basePath: kotlin.String = defaultBasePath) : ApiClient(basePath
)
}

/**
*
* Returns the openapi.json document of specific plugin.
* @return kotlin.String
* @throws UnsupportedOperationException If the API returns an informational or redirection response
* @throws ClientException If the API returns a client error response
* @throws ServerException If the API returns a server error response
*/
@Suppress("UNCHECKED_CAST")
@Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
fun getOpenApiSpecV1Endpoint() : kotlin.String {
val localVariableConfig = getOpenApiSpecV1EndpointRequestConfig()

val localVarResponse = request<Unit, kotlin.String>(
localVariableConfig
)

return when (localVarResponse.responseType) {
ResponseType.Success -> (localVarResponse as Success<*>).data as kotlin.String
ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.")
ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.")
ResponseType.ClientError -> {
val localVarError = localVarResponse as ClientError<*>
throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse)
}
ResponseType.ServerError -> {
val localVarError = localVarResponse as ServerError<*>
throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse)
}
}
}

/**
* To obtain the request config of the operation getOpenApiSpecV1Endpoint
*
* @return RequestConfig
*/
fun getOpenApiSpecV1EndpointRequestConfig() : RequestConfig<Unit> {
val localVariableBody = null
val localVariableQuery: MultiValueMap = mutableMapOf()
val localVariableHeaders: MutableMap<String, String> = mutableMapOf()

return RequestConfig(
method = RequestMethod.POST,
path = "/api/v1/api-server/get-open-api-spec-v1-endpoint",
query = localVariableQuery,
headers = localVariableHeaders,
body = localVariableBody
)
}

/**
* Get the Prometheus Metrics
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@ import "models/health_check_response_pb.proto";
service DefaultService {
rpc GetHealthCheckV1 (google.protobuf.Empty) returns (HealthCheckResponsePB);

rpc GetOpenApiSpecV1Endpoint (google.protobuf.Empty) returns (GetOpenApiSpecV1EndpointResponse);

rpc GetPrometheusMetricsV1 (google.protobuf.Empty) returns (GetPrometheusMetricsV1Response);

}

message GetOpenApiSpecV1EndpointResponse {
string data = 1;
}

message GetPrometheusMetricsV1Response {
string data = 1;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import {

import { ICactusApiServerOptions } from "./config/config-service";
import OAS from "../json/openapi.json";
// import { OpenAPIV3 } from "express-openapi-validator/dist/framework/types";

import { PrometheusExporter } from "./prometheus-exporter/prometheus-exporter";
import { AuthorizerFactory } from "./authzn/authorizer-factory";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,35 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati



setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};

return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
* Returns the openapi.json document of specific plugin.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getOpenApiSpecV1Endpoint: async (options: any = {}): Promise<RequestArgs> => {
const localVarPath = `/api/v1/api-server/get-open-api-spec-v1-endpoint`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}

const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;



setSearchParams(localVarUrlObj, localVarQueryParameter, options.query);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
Expand Down Expand Up @@ -184,6 +213,15 @@ export const DefaultApiFp = function(configuration?: Configuration) {
const localVarAxiosArgs = await localVarAxiosParamCreator.getHealthCheckV1(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
* Returns the openapi.json document of specific plugin.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async getOpenApiSpecV1Endpoint(options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<string>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.getOpenApiSpecV1Endpoint(options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @summary Get the Prometheus Metrics
Expand Down Expand Up @@ -213,6 +251,14 @@ export const DefaultApiFactory = function (configuration?: Configuration, basePa
getHealthCheckV1(options?: any): AxiosPromise<HealthCheckResponse> {
return localVarFp.getHealthCheckV1(options).then((request) => request(axios, basePath));
},
/**
* Returns the openapi.json document of specific plugin.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getOpenApiSpecV1Endpoint(options?: any): AxiosPromise<string> {
return localVarFp.getOpenApiSpecV1Endpoint(options).then((request) => request(axios, basePath));
},
/**
*
* @summary Get the Prometheus Metrics
Expand Down Expand Up @@ -243,6 +289,16 @@ export class DefaultApi extends BaseAPI {
return DefaultApiFp(this.configuration).getHealthCheckV1(options).then((request) => request(this.axios, this.basePath));
}

/**
* Returns the openapi.json document of specific plugin.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof DefaultApi
*/
public getOpenApiSpecV1Endpoint(options?: any) {
return DefaultApiFp(this.configuration).getOpenApiSpecV1Endpoint(options).then((request) => request(this.axios, this.basePath));
}

/**
*
* @summary Get the Prometheus Metrics
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,72 @@ import * as dependency_2 from "./../models/health_check_response_pb";
import * as pb_1 from "google-protobuf";
import * as grpc_1 from "@grpc/grpc-js";
export namespace org.hyperledger.cactus.cmd_api_server {
export class GetOpenApiSpecV1EndpointResponse extends pb_1.Message {
constructor(data?: any[] | {
data?: string;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], []);
if (!Array.isArray(data) && typeof data == "object") {
if ("data" in data && data.data != undefined) {
this.data = data.data;
}
}
}
get data() {
return pb_1.Message.getField(this, 1) as string;
}
set data(value: string) {
pb_1.Message.setField(this, 1, value);
}
static fromObject(data: {
data?: string;
}) {
const message = new GetOpenApiSpecV1EndpointResponse({});
if (data.data != null) {
message.data = data.data;
}
return message;
}
toObject() {
const data: {
data?: string;
} = {};
if (this.data != null) {
data.data = this.data;
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (typeof this.data === "string" && this.data.length)
writer.writeString(1, this.data);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): GetOpenApiSpecV1EndpointResponse {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new GetOpenApiSpecV1EndpointResponse();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
message.data = reader.readString();
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): GetOpenApiSpecV1EndpointResponse {
return GetOpenApiSpecV1EndpointResponse.deserialize(bytes);
}
}
export class GetPrometheusMetricsV1Response extends pb_1.Message {
constructor(data?: any[] | {
data?: string;
Expand Down Expand Up @@ -87,6 +153,15 @@ export namespace org.hyperledger.cactus.cmd_api_server {
responseSerialize: (message: dependency_2.org.hyperledger.cactus.cmd_api_server.HealthCheckResponsePB) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => dependency_2.org.hyperledger.cactus.cmd_api_server.HealthCheckResponsePB.deserialize(new Uint8Array(bytes))
},
GetOpenApiSpecV1Endpoint: {
path: "/org.hyperledger.cactus.cmd_api_server.DefaultService/GetOpenApiSpecV1Endpoint",
requestStream: false,
responseStream: false,
requestSerialize: (message: dependency_1.google.protobuf.Empty) => Buffer.from(message.serialize()),
requestDeserialize: (bytes: Buffer) => dependency_1.google.protobuf.Empty.deserialize(new Uint8Array(bytes)),
responseSerialize: (message: GetOpenApiSpecV1EndpointResponse) => Buffer.from(message.serialize()),
responseDeserialize: (bytes: Buffer) => GetOpenApiSpecV1EndpointResponse.deserialize(new Uint8Array(bytes))
},
GetPrometheusMetricsV1: {
path: "/org.hyperledger.cactus.cmd_api_server.DefaultService/GetPrometheusMetricsV1",
requestStream: false,
Expand All @@ -99,6 +174,7 @@ export namespace org.hyperledger.cactus.cmd_api_server {
};
[method: string]: grpc_1.UntypedHandleCall;
abstract GetHealthCheckV1(call: grpc_1.ServerUnaryCall<dependency_1.google.protobuf.Empty, dependency_2.org.hyperledger.cactus.cmd_api_server.HealthCheckResponsePB>, callback: grpc_1.requestCallback<dependency_2.org.hyperledger.cactus.cmd_api_server.HealthCheckResponsePB>): void;
abstract GetOpenApiSpecV1Endpoint(call: grpc_1.ServerUnaryCall<dependency_1.google.protobuf.Empty, GetOpenApiSpecV1EndpointResponse>, callback: grpc_1.requestCallback<GetOpenApiSpecV1EndpointResponse>): void;
abstract GetPrometheusMetricsV1(call: grpc_1.ServerUnaryCall<dependency_1.google.protobuf.Empty, GetPrometheusMetricsV1Response>, callback: grpc_1.requestCallback<GetPrometheusMetricsV1Response>): void;
}
export class DefaultServiceClient extends grpc_1.makeGenericClientConstructor(UnimplementedDefaultServiceService.definition, "DefaultService", {}) {
Expand All @@ -112,6 +188,13 @@ export namespace org.hyperledger.cactus.cmd_api_server {
GetHealthCheckV1(message: dependency_1.google.protobuf.Empty, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<dependency_2.org.hyperledger.cactus.cmd_api_server.HealthCheckResponsePB>, options?: grpc_1.CallOptions | grpc_1.requestCallback<dependency_2.org.hyperledger.cactus.cmd_api_server.HealthCheckResponsePB>, callback?: grpc_1.requestCallback<dependency_2.org.hyperledger.cactus.cmd_api_server.HealthCheckResponsePB>): grpc_1.ClientUnaryCall {
return super.GetHealthCheckV1(message, metadata, options, callback);
}
GetOpenApiSpecV1Endpoint(message: dependency_1.google.protobuf.Empty, metadata: grpc_1.Metadata, options: grpc_1.CallOptions, callback: grpc_1.requestCallback<GetOpenApiSpecV1EndpointResponse>): grpc_1.ClientUnaryCall;
GetOpenApiSpecV1Endpoint(message: dependency_1.google.protobuf.Empty, metadata: grpc_1.Metadata, callback: grpc_1.requestCallback<GetOpenApiSpecV1EndpointResponse>): grpc_1.ClientUnaryCall;
GetOpenApiSpecV1Endpoint(message: dependency_1.google.protobuf.Empty, options: grpc_1.CallOptions, callback: grpc_1.requestCallback<GetOpenApiSpecV1EndpointResponse>): grpc_1.ClientUnaryCall;
GetOpenApiSpecV1Endpoint(message: dependency_1.google.protobuf.Empty, callback: grpc_1.requestCallback<GetOpenApiSpecV1EndpointResponse>): grpc_1.ClientUnaryCall;
GetOpenApiSpecV1Endpoint(message: dependency_1.google.protobuf.Empty, metadata: grpc_1.Metadata | grpc_1.CallOptions | grpc_1.requestCallback<GetOpenApiSpecV1EndpointResponse>, options?: grpc_1.CallOptions | grpc_1.requestCallback<GetOpenApiSpecV1EndpointResponse>, callback?: grpc_1.requestCallback<GetOpenApiSpecV1EndpointResponse>): grpc_1.ClientUnaryCall {
return super.GetOpenApiSpecV1Endpoint(message, metadata, options, callback);
}
GetPrometheusMetricsV1(message: dependency_1.google.protobuf.Empty, metadata: grpc_1.Metadata, options: grpc_1.CallOptions, callback: grpc_1.requestCallback<GetPrometheusMetricsV1Response>): grpc_1.ClientUnaryCall;
GetPrometheusMetricsV1(message: dependency_1.google.protobuf.Empty, metadata: grpc_1.Metadata, callback: grpc_1.requestCallback<GetPrometheusMetricsV1Response>): grpc_1.ClientUnaryCall;
GetPrometheusMetricsV1(message: dependency_1.google.protobuf.Empty, options: grpc_1.CallOptions, callback: grpc_1.requestCallback<GetPrometheusMetricsV1Response>): grpc_1.ClientUnaryCall;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Checks } from "@hyperledger/cactus-common";
import { PluginRegistry } from "@hyperledger/cactus-core";
import {
ICactusPlugin,
IPluginWebService,
isIPluginWebService,
} from "@hyperledger/cactus-core-api";
import type { OpenAPIV3 } from "express-openapi-validator/dist/framework/types";

export async function getOpenApiSpec(
pluginRegistry: PluginRegistry,
): Promise<OpenAPIV3.Document[]> {
Checks.truthy(
pluginRegistry,
`openApiSpec()
pluginRegistry (PluginRegistry)`,
);

const openApiJsonSpecsPromises = pluginRegistry
.getPlugins()
.filter((pluginInstance) => isIPluginWebService(pluginInstance))
.map(async (plugin: ICactusPlugin) => {
const webPlugin = plugin as IPluginWebService;
const openApiSpec = (await webPlugin.getOpenApiSpec()) as OpenAPIV3.Document;
return openApiSpec;
});

const openApiJsonSpecs = await Promise.all(openApiJsonSpecsPromises);
return openApiJsonSpecs;
}
Loading

0 comments on commit 5a5d78f

Please sign in to comment.