Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Support importing without proto file name knowledge in Python generated protobuf code ([#275](https://github.com/opensearch-project/opensearch-protobufs/pull/275))
- Preprocessing - Add filter to not convert additionalProperties when only one key allowed ([#292](https://github.com/opensearch-project/opensearch-protobufs/pull/292))
- Add HybridQuery protos ([#294](https://github.com/opensearch-project/opensearch-protobufs/pull/294))
- Preprocessing - Consolidate global parameters into GlobalParams schema ([#295](https://github.com/opensearch-project/opensearch-protobufs/pull/295))

### Changed
- Update preprocessing for x-protobuf-excluded ([#266](https://github.com/opensearch-project/opensearch-protobufs/pull/266))
- Fix aggregations protos ([#270](https://github.com/opensearch-project/opensearch-protobufs/pull/270))
Expand Down
129 changes: 129 additions & 0 deletions tools/proto-convert/src/GlobalParamWrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { OpenAPIV3 } from 'openapi-types';

export class GlobalParameterConsolidator {
private root: OpenAPIV3.Document;
private readonly GLOBAL_PARAM_PREFIX = '_global___query';

constructor(root: OpenAPIV3.Document) {
this.root = root;
}

/**
* Consolidates global query parameters into a single globalParams object.
*
*/
consolidate(): OpenAPIV3.Document {
this.createGlobalParamsSchema();
this.createGlobalParamsParameter();
this.replaceGlobalParamsInPaths();
return this.root;
}

private createGlobalParamsSchema(): void {
const parameters = this.root.components?.parameters;
if (!parameters) {
return;
}

if (!this.root.components) {
this.root.components = {};
}
if (!this.root.components.schemas) {
this.root.components.schemas = {};
}

const properties: Record<string, any> = {};
const addedParams = new Set<string>();

for (const [paramKey, paramDef] of Object.entries(parameters)) {
if (!paramDef) continue;

// Check if parameter key starts with _global___query
if (paramKey.startsWith(this.GLOBAL_PARAM_PREFIX)) {
const param = paramDef as any;
const paramName = param.name || paramKey;

if (!addedParams.has(paramName)) {
const propertyObj: any = {
...param
};

properties[paramName] = propertyObj;
addedParams.add(paramName);
console.log(`Found global parameter: ${paramKey}`);
}
}
}

const globalParamsSchema: OpenAPIV3.SchemaObject = {
type: 'object',
description: 'Global query parameters that apply to all operations',
properties,
};

(this.root.components.schemas as any).GlobalParams = globalParamsSchema;
}

private createGlobalParamsParameter(): void {
if (!this.root.components) {
this.root.components = {};
}
if (!this.root.components.parameters) {
this.root.components.parameters = {};
}

const globalParamsParam: any = {
name: 'globalParams',
in: 'query',
description: 'Global query parameters',
schema: {
$ref: '#/components/schemas/GlobalParams',
}
};

(this.root.components.parameters as any).globalParams = globalParamsParam;
}

private replaceGlobalParamsInPaths(): void {
if (!this.root.paths) {
return;
}

for (const pathKey in this.root.paths) {
const pathItem = this.root.paths[pathKey];
if (!pathItem) continue;

const methods = ['get', 'post', 'put', 'delete'];
for (const method of methods) {
const operation = (pathItem as any)[method] as OpenAPIV3.OperationObject | undefined;
if (!operation) continue;

this.replaceGlobalParamsInOperation(operation);
}
}
}

private replaceGlobalParamsInOperation(operation: OpenAPIV3.OperationObject): void {
if (!operation.parameters) {
return;
}

let hasGlobalParams = false;

for (let i = operation.parameters.length - 1; i >= 0; i--) {
const param = operation.parameters[i];
const paramRef = (param as any).$ref;

if (paramRef && paramRef.includes(`/${this.GLOBAL_PARAM_PREFIX}`)) {
operation.parameters.splice(i, 1);
hasGlobalParams = true;
}
}

if (hasGlobalParams) {
operation.parameters.push({
$ref: '#/components/parameters/globalParams',
} as OpenAPIV3.ReferenceObject);
}
}
}
4 changes: 3 additions & 1 deletion tools/proto-convert/src/PreProcessing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Logger from './utils/logger';
import * as path from 'path';
import {SchemaModifier} from "./SchemaModifier";
import {VendorExtensionProcessor} from "./VendorExtensionProcessor";
import {GlobalParameterConsolidator} from "./GlobalParamWrapper";
import type {OpenAPIV3} from "openapi-types";

let config_filtered_path: string[] | undefined;
Expand Down Expand Up @@ -49,7 +50,8 @@ try {
const original_spec = read_yaml(opts.input)
const filtered_spec = new Filter().filter_spec(original_spec, opts.filtered_path);
const sanitized_spec = new Sanitizer().sanitize(filtered_spec);
const vendor_processed_spec = new VendorExtensionProcessor(sanitized_spec, logger).process();
const consolidated_spec = new GlobalParameterConsolidator(sanitized_spec).consolidate();
const vendor_processed_spec = new VendorExtensionProcessor(consolidated_spec, logger).process();
const schema_modified_spec = new SchemaModifier(vendor_processed_spec, logger).modify();
write_yaml(opts.output, schema_modified_spec);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ inputSpec: build/processed-opensearch-openapi.yaml
templateDir: tools/proto-convert/src/config/protobuf-schema-template/
additionalProperties:
packageName: org.opensearch.protobufs
addJsonNameAnnotation: true
addJsonNameAnnotation: false
flattenComplexType: true
numberedFieldNumberList: true
startEnumsWithUnspecified: true
Expand Down