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

[ADLS Gen2] Swagger + generated code #2393

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,11 @@
"docker:publish-manifest-latest": "cross-var docker manifest push xstoreazurite.azurecr.io/public/azure-storage/azurite:latest",
"prepare": "npm run build",
"build": "tsc",
"build:autorest:debug": "autorest ./swagger/blob.md --typescript --typescript.debugger --use=S:/GitHub/XiaoningLiu/autorest.typescript.server",
"build:autorest:blob": "autorest ./swagger/blob.md --typescript --use=S:/GitHub/XiaoningLiu/autorest.typescript.server",
"build:autorest:queue": "autorest ./swagger/queue.md --typescript --use=S:/GitHub/XiaoningLiu/autorest.typescript.server",
"build:autorest:table": "autorest ./swagger/table.md --typescript --use=S:/GitHub/XiaoningLiu/autorest.typescript.server",
"build:autorest:debug": "autorest ./swagger/blob.md --typescript --typescript.debugger --use=../autorest.typescript.server",
"build:autorest:blob": "autorest ./swagger/blob.md --typescript --use=../autorest.typescript.server",
"build:autorest:queue": "autorest ./swagger/queue.md --typescript --use=../autorest.typescript.server",
"build:autorest:table": "autorest ./swagger/table.md --typescript --use=../autorest.typescript.server",
"build:autorest:dfs": "autorest ./swagger/dfs.md --typescript --use=../autorest.typescript.server",
"build:exe": "node ./scripts/buildExe.js",
"build:linux": "node ./scripts/buildLinux.js",
"watch": "tsc -watch -p ./",
Expand Down
143 changes: 143 additions & 0 deletions src/dfs/generated/Context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import Operation from './artifacts/operation';
import IRequest from './IRequest';
import IResponse from './IResponse';

export interface IHandlerParameters {
[key: string]: any;
}

/**
* Context holds generated server context information.
* Every incoming HTTP request will initialize a new context.
*
* @export
* @class Context
*/
export default class Context {
public readonly context: any;
public readonly path: string;

/**
* Creates an instance of Context.
* Context holds generated server context information.
* Every incoming HTTP request will initialize a new context.
*
* @param {Context} context An existing Context
* @memberof Context
*/
public constructor(context: Context);

/**
* Creates an instance of Context.
* Context holds generated server context information.
* Every incoming HTTP request will initialize a new context.
*
* @param {Object} holder Holder is an Object which used to keep context information
* @param {string} [path="context"] holder[path] is used as context object by default
* @param {IRequest} [req]
* @param {IResponse} [res]
* @memberof Context
*/
public constructor(
holder: object,
path: string,
req?: IRequest,
res?: IResponse
);

public constructor(
holderOrContext: object | Context,
path: string = "context",
req?: IRequest,
res?: IResponse
) {
if (holderOrContext instanceof Context) {
this.context = holderOrContext.context;
this.path = holderOrContext.path;
} else {
const context = holderOrContext as any;
this.path = path;

if (context[this.path] === undefined) {
context[this.path] = {};
}

if (typeof context[this.path] !== "object") {
throw new TypeError(
`Initialize Context error because holder.${this.path} is not an object.`
);
}

this.context = context[this.path];

this.request = req;
this.response = res;
}
}

public get operation(): Operation | undefined {
return this.context.operation;
}

public set operation(operation: Operation | undefined) {
this.context.operation = operation;
}

public set request(request: IRequest | undefined) {
this.context.request = request;
}

public get request(): IRequest | undefined {
return this.context.request;
}

public get dispatchPattern(): string | undefined {
return this.context.dispatchPattern;
}

public set dispatchPattern(path: string | undefined) {
this.context.dispatchPattern = path;
}

public set response(response: IResponse | undefined) {
this.context.response = response;
}

public get response(): IResponse | undefined {
return this.context.response;
}

public get handlerParameters(): IHandlerParameters | undefined {
return this.context.handlerParameters;
}

public set handlerParameters(
handlerParameters: IHandlerParameters | undefined
) {
this.context.handlerParameters = handlerParameters;
}

public get handlerResponses(): any {
return this.context.handlerResponses;
}

public set handlerResponses(handlerResponses: any) {
this.context.handlerResponses = handlerResponses;
}

public get contextId(): string | undefined {
return this.context.contextID;
}

public set contextId(contextID: string | undefined) {
this.context.contextID = contextID;
}

public set startTime(startTime: Date | undefined) {
this.context.startTime = startTime;
}

public get startTime(): Date | undefined {
return this.context.startTime;
}
}
162 changes: 162 additions & 0 deletions src/dfs/generated/ExpressMiddlewareFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import { ErrorRequestHandler, NextFunction, Request, RequestHandler, Response } from 'express';

import Context from './Context';
import ExpressRequestAdapter from './ExpressRequestAdapter';
import ExpressResponseAdapter from './ExpressResponseAdapter';
import IHandlers from './handlers/IHandlers';
import deserializerMiddleware from './middleware/deserializer.middleware';
import dispatchMiddleware from './middleware/dispatch.middleware';
import endMiddleware from './middleware/end.middleware';
import errorMiddleware from './middleware/error.middleware';
import HandlerMiddlewareFactory from './middleware/HandlerMiddlewareFactory';
import serializerMiddleware from './middleware/serializer.middleware';
import MiddlewareFactory from './MiddlewareFactory';
import ILogger from './utils/ILogger';

/**
* ExpressMiddlewareFactory will generate Express compatible middleware according to swagger definitions.
* Generated middleware MUST be used by strict order:
* * dispatchMiddleware
* * DeserializerMiddleware
* * HandlerMiddleware
* * SerializerMiddleware
* * ErrorMiddleware
* * EndMiddleware
*
* @export
* @class MiddlewareFactory
*/
export default class ExpressMiddlewareFactory extends MiddlewareFactory {
/**
* Creates an instance of MiddlewareFactory.
*
* @param {ILogger} logger A valid logger
* @param {string} [contextPath="default_context"] Optional. res.locals[contextPath] will be used to hold context
* @memberof MiddlewareFactory
*/
public constructor(
logger: ILogger,
private readonly contextPath: string = "default_context"
) {
super(logger);
}

/**
* DispatchMiddleware is the 1s middleware should be used among other generated middleware.
*
* @returns {RequestHandler}
* @memberof MiddlewareFactory
*/
public createDispatchMiddleware(): RequestHandler {
return (req: Request, res: Response, next: NextFunction) => {
req.baseUrl
const request = new ExpressRequestAdapter(req);
const response = new ExpressResponseAdapter(res);
dispatchMiddleware(
new Context(res.locals, this.contextPath, request, response),
request,
next,
this.logger
);
};
}

/**
* DeserializerMiddleware is the 2nd middleware should be used among other generated middleware.
*
* @returns {RequestHandler}
* @memberof MiddlewareFactory
*/
public createDeserializerMiddleware(): RequestHandler {
return (req: Request, res: Response, next: NextFunction) => {
const request = new ExpressRequestAdapter(req);
const response = new ExpressResponseAdapter(res);
deserializerMiddleware(
new Context(res.locals, this.contextPath, request, response),
request,
next,
this.logger
);
};
}

/**
* HandlerMiddleware is the 3rd middleware should be used among other generated middleware.
*
* @param {IHandlers} handlers
* @returns {RequestHandler}
* @memberof MiddlewareFactory
*/
public createHandlerMiddleware(handlers: IHandlers): RequestHandler {
const handlerMiddlewareFactory = new HandlerMiddlewareFactory(
handlers,
this.logger
);
return (req: Request, res: Response, next: NextFunction) => {
const request = new ExpressRequestAdapter(req);
const response = new ExpressResponseAdapter(res);
handlerMiddlewareFactory.createHandlerMiddleware()(
new Context(res.locals, this.contextPath, request, response),
next
);
};
}

/**
* SerializerMiddleware is the 4st middleware should be used among other generated middleware.
*
* @returns {RequestHandler}
* @memberof MiddlewareFactory
*/
public createSerializerMiddleware(): RequestHandler {
return (req: Request, res: Response, next: NextFunction) => {
const request = new ExpressRequestAdapter(req);
const response = new ExpressResponseAdapter(res);
serializerMiddleware(
new Context(res.locals, this.contextPath, request, response),
new ExpressResponseAdapter(res),
next,
this.logger
);
};
}

/**
* ErrorMiddleware is the 5st middleware should be used among other generated middleware.
*
* @returns {ErrorRequestHandler}
* @memberof MiddlewareFactory
*/
public createErrorMiddleware(): ErrorRequestHandler {
return (err: Error, req: Request, res: Response, next: NextFunction) => {
const request = new ExpressRequestAdapter(req);
const response = new ExpressResponseAdapter(res);
errorMiddleware(
new Context(res.locals, this.contextPath, request, response),
err,
new ExpressRequestAdapter(req),
new ExpressResponseAdapter(res),
next,
this.logger
);
};
}

/**
* EndMiddleware is the 6st middleware should be used among other generated middleware.
*
* @returns {RequestHandler}
* @memberof MiddlewareFactory
*/
public createEndMiddleware(): RequestHandler {
return (req: Request, res: Response) => {
const request = new ExpressRequestAdapter(req);
const response = new ExpressResponseAdapter(res);
endMiddleware(
new Context(res.locals, this.contextPath, request, response),
new ExpressResponseAdapter(res),
this.logger
);
};
}
}
57 changes: 57 additions & 0 deletions src/dfs/generated/ExpressRequestAdapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Request } from 'express';

import IRequest, { HttpMethod } from './IRequest';

export default class ExpressRequestAdapter implements IRequest {
public constructor(private readonly req: Request) {}

public getMethod(): HttpMethod {
return this.req.method.toUpperCase() as HttpMethod;
}

public getUrl(): string {
return this.req.url;
}

public getEndpoint(): string {
return `${this.req.protocol}://${this.getHeader("host") ||
this.req.hostname}`;
}

public getPath(): string {
return this.req.path;
}

public getBodyStream(): NodeJS.ReadableStream {
return this.req;
}

public getBody(): string | undefined {
return this.req.body;
}

public setBody(body: string | undefined): ExpressRequestAdapter {
this.req.body = body;
return this;
}

public getHeader(field: string): string | undefined {
return this.req.header(field);
}

public getHeaders(): { [header: string]: string | string[] | undefined } {
return this.req.headers;
}

public getRawHeaders(): string[] {
return this.req.rawHeaders;
}

public getQuery(key: string): string | undefined {
return this.req.query[key];
}

public getProtocol(): string {
return this.req.protocol;
}
}
Loading