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
140 changes: 138 additions & 2 deletions src/handlers/StackHandler.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,140 @@
import { ServerRequestHandler } from 'vscode-languageserver';
import { ResponseError, ErrorCodes, RequestHandler } from 'vscode-languageserver';
import { TopLevelSection } from '../context/ContextType';
import { getEntityMap } from '../context/SectionContextBuilder';
import { Parameter } from '../context/semantic/Entity';
import { parseIdentifiable } from '../protocol/LspParser';
import { Identifiable } from '../protocol/LspTypes';
import { ServerComponents } from '../server/ServerComponents';
import { analyzeCapabilities } from '../stacks/actions/CapabilityAnalyzer';
import { parseStackActionParams, parseTemplateUriParams } from '../stacks/actions/StackActionParser';
import {
GetCapabilitiesResult,
TemplateUri,
GetParametersResult,
CreateStackActionParams,
CreateStackActionResult,
GetStackActionStatusResult,
} from '../stacks/actions/StackActionRequestType';
import { ListStacksParams, ListStacksResult } from '../stacks/StackRequestType';
import { LoggerFactory } from '../telemetry/LoggerFactory';
import { extractErrorMessage } from '../utils/Errors';
import { parseWithPrettyError } from '../utils/ZodErrorWrapper';

const log = LoggerFactory.getLogger('StackHandler');

export function getParametersHandler(
components: ServerComponents,
): RequestHandler<TemplateUri, GetParametersResult, void> {
return (rawParams) => {
log.debug({ Handler: 'getParametersHandler', rawParams });

try {
const params = parseWithPrettyError(parseTemplateUriParams, rawParams);
const syntaxTree = components.syntaxTreeManager.getSyntaxTree(params);
if (syntaxTree) {
const parametersMap = getEntityMap(syntaxTree, TopLevelSection.Parameters);
if (parametersMap) {
const parameters = [...parametersMap.values()].map((context) => context.entity as Parameter);
return {
parameters,
};
}
}

return {
parameters: [],
};
} catch (error) {
handleStackActionError(error, 'Failed to get parameters');
}
};
}

export function createValidationHandler(
components: ServerComponents,
): RequestHandler<CreateStackActionParams, CreateStackActionResult, void> {
return async (rawParams) => {
log.debug({ Handler: 'createValidationHandler', rawParams });

try {
const params = parseWithPrettyError(parseStackActionParams, rawParams);
return await components.validationWorkflowService.start(params);
} catch (error) {
handleStackActionError(error, 'Failed to start validation workflow');
}
};
}

export function createDeploymentHandler(
components: ServerComponents,
): RequestHandler<CreateStackActionParams, CreateStackActionResult, void> {
return async (rawParams) => {
log.debug({ Handler: 'createDeploymentHandler', rawParams });

try {
const params = parseWithPrettyError(parseStackActionParams, rawParams);
return await components.deploymentWorkflowService.start(params);
} catch (error) {
handleStackActionError(error, 'Failed to start deployment workflow');
}
};
}

export function getValidationStatusHandler(
components: ServerComponents,
): RequestHandler<Identifiable, GetStackActionStatusResult, void> {
return (rawParams) => {
log.debug({ Handler: 'getValidationStatusHandler', rawParams });

try {
const params = parseWithPrettyError(parseIdentifiable, rawParams);
return components.validationWorkflowService.getStatus(params);
} catch (error) {
handleStackActionError(error, 'Failed to get validation status');
}
};
}

export function getDeploymentStatusHandler(
components: ServerComponents,
): RequestHandler<Identifiable, GetStackActionStatusResult, void> {
return (rawParams) => {
log.debug({ Handler: 'getDeploymentStatusHandler', rawParams });

try {
const params = parseWithPrettyError(parseIdentifiable, rawParams);
return components.deploymentWorkflowService.getStatus(params);
} catch (error) {
handleStackActionError(error, 'Failed to get deployment status');
}
};
}

export function getCapabilitiesHandler(
components: ServerComponents,
): RequestHandler<TemplateUri, GetCapabilitiesResult, void> {
return async (rawParams) => {
log.debug({ Handler: 'getCapabilitiesHandler', rawParams });

try {
const params = parseWithPrettyError(parseTemplateUriParams, rawParams);
const document = components.documentManager.get(params);
if (!document) {
throw new ResponseError(ErrorCodes.InvalidRequest, 'Template body document not available');
}

const capabilities = await analyzeCapabilities(document, components.cfnService);

return { capabilities };
} catch (error) {
handleStackActionError(error, 'Failed to analyze template capabilities');
}
};
}

export function listStacksHandler(
components: ServerComponents,
): ServerRequestHandler<ListStacksParams, ListStacksResult, never, void> {
): RequestHandler<ListStacksParams, ListStacksResult, void> {
return async (params: ListStacksParams): Promise<ListStacksResult> => {
try {
if (params.statusToInclude?.length && params.statusToExclude?.length) {
Expand All @@ -21,3 +147,13 @@ export function listStacksHandler(
}
};
}

function handleStackActionError(error: unknown, contextMessage: string): never {
if (error instanceof ResponseError) {
throw error;
}
if (error instanceof TypeError) {
throw new ResponseError(ErrorCodes.InvalidParams, error.message);
}
throw new ResponseError(ErrorCodes.InternalError, `${contextMessage}: ${extractErrorMessage(error)}`);
}
142 changes: 0 additions & 142 deletions src/handlers/TemplateHandler.ts

This file was deleted.

5 changes: 0 additions & 5 deletions src/protocol/LspConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { LspDocuments } from './LspDocuments';
import { LspHandlers } from './LspHandlers';
import { LspResourceHandlers } from './LspResourceHandlers';
import { LspStackHandlers } from './LspStackHandlers';
import { LspTemplateHandlers } from './LspTemplateHandlers';
import { LspWorkspace } from './LspWorkspace';

type LspConnectionHandlers = {
Expand All @@ -32,7 +31,6 @@ export type LspFeatures = {
communication: LspCommunication;
handlers: LspHandlers;
authHandlers: LspAuthHandlers;
templateHandlers: LspTemplateHandlers;
stackHandlers: LspStackHandlers;
resourceHandlers: LspResourceHandlers;
};
Expand All @@ -44,7 +42,6 @@ export class LspConnection {
private readonly communication: LspCommunication;
private readonly handlers: LspHandlers;
private readonly authHandlers: LspAuthHandlers;
private readonly templateHandlers: LspTemplateHandlers;
private readonly stackHandlers: LspStackHandlers;
private readonly resourceHandlers: LspResourceHandlers;

Expand All @@ -67,7 +64,6 @@ export class LspConnection {
this.communication = new LspCommunication(this.connection);
this.handlers = new LspHandlers(this.connection);
this.authHandlers = new LspAuthHandlers(this.connection);
this.templateHandlers = new LspTemplateHandlers(this.connection);
this.stackHandlers = new LspStackHandlers(this.connection);
this.resourceHandlers = new LspResourceHandlers(this.connection);

Expand Down Expand Up @@ -104,7 +100,6 @@ export class LspConnection {
communication: this.communication,
handlers: this.handlers,
authHandlers: this.authHandlers,
templateHandlers: this.templateHandlers,
stackHandlers: this.stackHandlers,
resourceHandlers: this.resourceHandlers,
};
Expand Down
47 changes: 44 additions & 3 deletions src/protocol/LspStackHandlers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,51 @@
import { Connection, ServerRequestHandler } from 'vscode-languageserver';
import { ListStacksParams, ListStacksResult, ListStacksRequest } from '../stacks/StackRequestType';
import { Connection, RequestHandler } from 'vscode-languageserver';
import {
CreateValidationRequest,
CreateDeploymentRequest,
GetDeploymentStatusRequest,
GetValidationStatusRequest,
GetCapabilitiesRequest,
GetParametersRequest,
} from '../stacks/actions/StackActionProtocol';
import {
TemplateUri,
CreateStackActionParams,
CreateStackActionResult,
GetStackActionStatusResult,
GetParametersResult,
GetCapabilitiesResult,
} from '../stacks/actions/StackActionRequestType';
import { ListStacksParams, ListStacksRequest, ListStacksResult } from '../stacks/StackRequestType';
import { Identifiable } from './LspTypes';

export class LspStackHandlers {
constructor(private readonly connection: Connection) {}

onListStacks(handler: ServerRequestHandler<ListStacksParams, ListStacksResult, never, void>) {
onCreateValidation(handler: RequestHandler<CreateStackActionParams, CreateStackActionResult, void>) {
this.connection.onRequest(CreateValidationRequest.method, handler);
}

onCreateDeployment(handler: RequestHandler<CreateStackActionParams, CreateStackActionResult, void>) {
this.connection.onRequest(CreateDeploymentRequest.method, handler);
}

onGetValidationStatus(handler: RequestHandler<Identifiable, GetStackActionStatusResult, void>) {
this.connection.onRequest(GetValidationStatusRequest.method, handler);
}

onGetDeploymentStatus(handler: RequestHandler<Identifiable, GetStackActionStatusResult, void>) {
this.connection.onRequest(GetDeploymentStatusRequest.method, handler);
}

onGetParameters(handler: RequestHandler<TemplateUri, GetParametersResult, void>) {
this.connection.onRequest(GetParametersRequest.method, handler);
}

onGetCapabilities(handler: RequestHandler<TemplateUri, GetCapabilitiesResult, void>) {
this.connection.onRequest(GetCapabilitiesRequest.method, handler);
}

onListStacks(handler: RequestHandler<ListStacksParams, ListStacksResult, void>) {
this.connection.onRequest(ListStacksRequest.method, handler);
}
}
Loading
Loading