Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: proper processing of routing headers #1160

Merged
merged 3 commits into from
Jul 20, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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
104 changes: 76 additions & 28 deletions baselines/routingtest/src/v1/test_service_client.ts.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -342,14 +342,22 @@ export class TestServiceClient {
options = options || {};
options.otherArgs = options.otherArgs || {};
options.otherArgs.headers = options.otherArgs.headers || {};let routingParameter = {};
if ((typeof request.name !== "undefined") && RegExp('(?<database>projects)/[^/]+/databases/[^/]+/documents').test(request.name!)){
Object.assign(routingParameter, { database: request.name!.match(RegExp('(?<database>projects/[^/]+/databases/[^/]+)'))![0]})}

options.otherArgs.headers[
'x-goog-request-params'
] = gax.routingHeader.fromParams(
routingParameter
);
{
const fieldValue = request.name;
if (fieldValue !== undefined && fieldValue !== null) {
const match = fieldValue.toString().match(RegExp('(?<database>projects/[^/]+/databases/[^/]+)/documents'));
if (match) {
const parameterValue = match.groups?.['database'] ?? fieldValue;
Object.assign(routingParameter, { database: parameterValue });
}
}
}

options.otherArgs.headers[
'x-goog-request-params'
] = gax.routingHeader.fromParams(
routingParameter
);
this.initialize();
return this.innerApiCalls.fastFibonacci(request, options, callback);
}
Expand Down Expand Up @@ -422,17 +430,33 @@ export class TestServiceClient {
options = options || {};
options.otherArgs = options.otherArgs || {};
options.otherArgs.headers = options.otherArgs.headers || {};let routingParameter = {};
if ((typeof request.name !== "undefined") && RegExp('[^/]+').test(request.name!)){
Object.assign(routingParameter, { name: request.name!.match(RegExp('[^/]+'))![0]})}
{
const fieldValue = request.name;
if (fieldValue !== undefined && fieldValue !== null) {
const match = fieldValue.toString().match(RegExp('(?<name>.*)'));
if (match) {
const parameterValue = match.groups?.['name'] ?? fieldValue;
alexander-fenster marked this conversation as resolved.
Show resolved Hide resolved
Object.assign(routingParameter, { name: parameterValue });
}
}
}

if ((typeof request.name !== "undefined") && RegExp('(?<routing_id>(?:/.*)?)').test(request.name!)){
Object.assign(routingParameter, { routing_id: request.name!.match(RegExp('(?<routing_id>.*)'))![0]})}
{
const fieldValue = request.name;
if (fieldValue !== undefined && fieldValue !== null) {
const match = fieldValue.toString().match(RegExp('(?<routing_id>(?:.*)?)'));
if (match) {
const parameterValue = match.groups?.['routing_id'] ?? fieldValue;
Object.assign(routingParameter, { routing_id: parameterValue });
}
}
}

options.otherArgs.headers[
'x-goog-request-params'
] = gax.routingHeader.fromParams(
routingParameter
);
options.otherArgs.headers[
'x-goog-request-params'
] = gax.routingHeader.fromParams(
routingParameter
);
this.initialize();
return this.innerApiCalls.randomFibonacci(request, options, callback);
}
Expand Down Expand Up @@ -505,20 +529,44 @@ export class TestServiceClient {
options = options || {};
options.otherArgs = options.otherArgs || {};
options.otherArgs.headers = options.otherArgs.headers || {};let routingParameter = {};
if ((typeof request.parentId !== "undefined") && RegExp('(?<database>projects)/[^/]+').test(request.parentId!)){
Object.assign(routingParameter, { database: request.parentId!.match(RegExp('(?<database>projects/[^/]+)'))![0]})}
{
const fieldValue = request.parentId;
if (fieldValue !== undefined && fieldValue !== null) {
const match = fieldValue.toString().match(RegExp('(?<database>projects/[^/]+)'));
if (match) {
const parameterValue = match.groups?.['database'] ?? fieldValue;
Object.assign(routingParameter, { database: parameterValue });
}
}
}

if ((typeof request.nest1?.nest2?.nameId !== "undefined") && RegExp('(?<database>projects)/[^/]+/databases/[^/]+/documents').test(request.nest1?.nest2?.nameId!)){
Object.assign(routingParameter, { database: request.nest1?.nest2?.nameId!.match(RegExp('(?<database>projects/[^/]+/databases/[^/]+)'))![0]})}
{
const fieldValue = request.nest1?.nest2?.nameId;
if (fieldValue !== undefined && fieldValue !== null) {
const match = fieldValue.toString().match(RegExp('(?<database>projects/[^/]+/databases/[^/]+)/documents'));
if (match) {
const parameterValue = match.groups?.['database'] ?? fieldValue;
Object.assign(routingParameter, { database: parameterValue });
}
}
}

if ((typeof request.anotherParentId !== "undefined") && RegExp('(?<routing_id>projects)/[^/]+/databases/[^/]+/documents').test(request.anotherParentId!)){
Object.assign(routingParameter, { routing_id: request.anotherParentId!.match(RegExp('(?<routing_id>projects/[^/]+)'))![0]})}
{
const fieldValue = request.anotherParentId;
if (fieldValue !== undefined && fieldValue !== null) {
const match = fieldValue.toString().match(RegExp('(?<routing_id>projects/[^/]+)/databases/[^/]+/documents'));
if (match) {
const parameterValue = match.groups?.['routing_id'] ?? fieldValue;
Object.assign(routingParameter, { routing_id: parameterValue });
}
}
}

options.otherArgs.headers[
'x-goog-request-params'
] = gax.routingHeader.fromParams(
routingParameter
);
options.otherArgs.headers[
'x-goog-request-params'
] = gax.routingHeader.fromParams(
routingParameter
);
this.initialize();
return this.innerApiCalls.slowFibonacci(request, options, callback);
}
Expand Down
22 changes: 15 additions & 7 deletions templates/typescript_gapic/_util.njk
Original file line number Diff line number Diff line change
Expand Up @@ -266,15 +266,23 @@ request.{{ oneComment.paramName.toCamelCase() }}
let routingParameter = {};
{%- for paramArray in method.dynamicRoutingRequestParams %}
{%- for param in paramArray %}
if ((typeof request.{{ param.fieldRetrieve.join('?.') }} !== "undefined") && RegExp('{{ param.messageRegex | safe }}').test(request.{{ param.fieldRetrieve.join('?.') }}!)){
Object.assign(routingParameter, { {{ param.fieldSend }}: request.{{ param.fieldRetrieve.join('?.') }}!.match(RegExp('{{ param.namedSegment | safe }}'))![0]})}
{
const fieldValue = request.{{ param.fieldRetrieve.join('?.') }};
if (fieldValue !== undefined && fieldValue !== null) {
const match = fieldValue.toString().match(RegExp('{{ param.messageRegex | safe }}'));
if (match) {
const parameterValue = match.groups?.['{{ param.fieldSend }}'] ?? fieldValue;
Object.assign(routingParameter, { {{ param.fieldSend }}: parameterValue });
}
}
}
{% endfor -%}
{%- endfor %}
options.otherArgs.headers[
'x-goog-request-params'
] = gax.routingHeader.fromParams(
routingParameter
);
options.otherArgs.headers[
'x-goog-request-params'
] = gax.routingHeader.fromParams(
routingParameter
);
{%- endif %}
{%- if method.headerRequestParams.length > 0 %}
options.otherArgs.headers[
Expand Down
29 changes: 14 additions & 15 deletions typescript/src/schema/proto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import * as protos from '../../../protos';
import {CommentsMap, Comment} from './comments';
import {convertTemplateToRegex, getNamedSegment, milliseconds} from '../util';
import {processPathTemplate, milliseconds} from '../util';
import {ResourceDescriptor, ResourceDatabase} from './resource-database';
import {
RetryableCodeMap,
Expand Down Expand Up @@ -661,15 +661,14 @@ export function getDynamicHeaderRequestParams(
return params;
}

// This is what each routing annotation is translated into. fieldRetrive is the name of the
// field the header should retrieve from the message. fieldSend is the name of the field the header should send.
// messageRegex is the regex of the path template that the message field should match.
// namedSegment is the regex capture of the named value of the field.
// This is what each routing annotation is translated into.
export interface DynamicRoutingParameters {
// The name of request field to apply the rules to
fieldRetrieve: string[];
// The name of the field to send in the header
fieldSend: string;
// The regex to extract the value to send in the header
messageRegex: string;
namedSegment: string;
}

// The field to be retrieved needs to be converted into camelCase
Expand All @@ -693,7 +692,6 @@ export function getSingleRoutingHeaderParam(
fieldRetrieve: [],
fieldSend: '',
messageRegex: '',
namedSegment: '',
};
// If routing parameters are empty, then return empty interface
if (!rule.field) {
Expand All @@ -703,19 +701,20 @@ export function getSingleRoutingHeaderParam(
dynamicRoutingRule = {
fieldRetrieve: convertFieldToCamelCase(rule.field),
fieldSend: rule.field,
messageRegex: '[^/]+',
namedSegment: '[^/]+',
messageRegex: `(?<${rule.field}>.*)`,
};
}
// If the annotation is malformed, then return empty interface
else if (getNamedSegment(rule.pathTemplate).length < 1) {
return dynamicRoutingRule;
} else {
else {
alexander-fenster marked this conversation as resolved.
Show resolved Hide resolved
const processedPathTemplate = processPathTemplate(rule.pathTemplate);
if (!processedPathTemplate) {
return dynamicRoutingRule;
}
const {fieldSend, messageRegex} = processedPathTemplate;
dynamicRoutingRule = {
fieldRetrieve: convertFieldToCamelCase(rule.field),
fieldSend: getNamedSegment(rule.pathTemplate)[1],
messageRegex: convertTemplateToRegex(rule.pathTemplate),
namedSegment: getNamedSegment(rule.pathTemplate)[3],
fieldSend,
messageRegex,
};
}
return dynamicRoutingRule;
Expand Down
Loading