Skip to content

Commit

Permalink
api: add list-did feature with multicall post processing pipeline #226
Browse files Browse the repository at this point in the history
  • Loading branch information
maany committed Jul 14, 2023
1 parent 92cca03 commit 5eda5a4
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 93 deletions.
6 changes: 6 additions & 0 deletions src/lib/core/dto/did-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ export interface ListDIDDTO extends BaseStreamableDTO {
| 'Unknown Error'
}

/**
* Represents the individual data items in the stream
*/
export type ListDIDsStreamData = string

/**
* Data Transfer Object for GetDIDEndpoint
*/
Expand All @@ -24,6 +29,7 @@ export interface DIDDTO extends DID {
| 'Scope Not Found'
| 'Unknown Error'
| null
message?: string
account: string
open: boolean
monotonic: boolean
Expand Down
3 changes: 2 additions & 1 deletion src/lib/core/port/primary/list-dids-ports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { BaseAuthenticatedInputPort } from "@/lib/sdk/primary-ports";
import { ListDIDsRequest } from "@/lib/core/usecase-models/list-dids-usecase-models";
import { BaseStreamingOutputPort } from "@/lib/sdk/primary-ports";
import { ListDIDsError, ListDIDsResponse } from "@/lib/core/usecase-models/list-dids-usecase-models";
import { ListDIDsViewModel } from "@/lib/infrastructure/data/view-model/list-did";

/**
* @interface ListDIDsInputPort to fetch a list of DIDs from the backend.
Expand All @@ -11,4 +12,4 @@ export interface ListDIDsInputPort extends BaseAuthenticatedInputPort<ListDIDsRe
/**
* @interface ListDIDsOutputPort to stream a list of DIDs to the frontend.
*/
export interface ListDIDsOutputPort extends BaseStreamingOutputPort<ListDIDsResponse, ListDIDsError> {}
export interface ListDIDsOutputPort extends BaseStreamingOutputPort<ListDIDsResponse, ListDIDsError, ListDIDsViewModel> {}
5 changes: 3 additions & 2 deletions src/lib/core/use-case/list-dids-usecase.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { injectable } from "inversify";
import type { ListDIDsInputPort, ListDIDsOutputPort } from "@/lib/core/port/primary/list-dids-ports";
import type DIDGatewayOutputPort from "@/lib/core/port/secondary/did-gateway-output-port";
import { ListDIDDTO } from "../dto/did-dto";
import { ListDIDDTO, ListDIDsStreamData } from "../dto/did-dto";
import { ListDIDsError, ListDIDsRequest, ListDIDsResponse } from "../usecase-models/list-dids-usecase-models";
import { parseDIDString } from "@/lib/common/did-utils";
import { DID } from "../entity/rucio";
import { BaseStreamingUseCase } from "@/lib/sdk/usecase";
import { AuthenticatedRequestModel } from "@/lib/sdk/usecase-models";
import { ListDIDsViewModel } from "@/lib/infrastructure/data/view-model/list-did";

@injectable()
class ListDIDsUseCase extends BaseStreamingUseCase<ListDIDsRequest, ListDIDsResponse, ListDIDsError, ListDIDDTO, DID> implements ListDIDsInputPort {
class ListDIDsUseCase extends BaseStreamingUseCase<ListDIDsRequest, ListDIDsResponse, ListDIDsError, ListDIDDTO, ListDIDsStreamData, ListDIDsViewModel> implements ListDIDsInputPort {
constructor(
protected presenter: ListDIDsOutputPort,
private didGateway: DIDGatewayOutputPort,
Expand Down
77 changes: 0 additions & 77 deletions src/lib/core/use-case/list-dids-usecase2.ts

This file was deleted.

105 changes: 105 additions & 0 deletions src/lib/core/use-case/list-dids/list-dids-usecase2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { injectable } from "inversify";
import type { ListDIDsInputPort, ListDIDsOutputPort } from "@/lib/core/port/primary/list-dids-ports";
import type DIDGatewayOutputPort from "@/lib/core/port/secondary/did-gateway-output-port";
import { DIDDTO, ListDIDDTO, ListDIDsStreamData } from "../../dto/did-dto";
import { ListDIDsError, ListDIDsRequest, ListDIDsResponse } from "../../usecase-models/list-dids-usecase-models";
import { parseDIDString } from "@/lib/common/did-utils";
import { BaseMultiCallStreamableUseCase, BaseStreamingUseCase } from "@/lib/sdk/usecase";
import { AuthenticatedRequestModel } from "@/lib/sdk/usecase-models";
import { ListDIDsViewModel } from "@/lib/infrastructure/data/view-model/list-did";
import GetDIDsPipelineElement from "./pipeline-element-get-did";

@injectable()
class ListDIDsUseCase extends BaseMultiCallStreamableUseCase<ListDIDsRequest, ListDIDsResponse, ListDIDsError, ListDIDDTO, ListDIDsStreamData, DIDDTO, ListDIDsViewModel> implements ListDIDsInputPort {

constructor(
protected presenter: ListDIDsOutputPort,
private didGateway: DIDGatewayOutputPort,
) {
const getDIDPipelineElement = new GetDIDsPipelineElement(didGateway);
super(presenter, [getDIDPipelineElement])
this.didGateway = didGateway;
}

validateRequestModel(requestModel: AuthenticatedRequestModel<ListDIDsRequest>): ListDIDsError | undefined {
let scope: string;
let name: string;
try{
let didComponents = parseDIDString(requestModel.query);
scope = didComponents.scope;
name = didComponents.name;
} catch (error: any) {
return {
status: 'error',
error: 'Invalid DID Query',
message: (error as Error).message,
} as ListDIDsError
}
}

async makeGatewayRequest(requestModel: AuthenticatedRequestModel<ListDIDsRequest>): Promise<ListDIDDTO> {
const { scope, name } = parseDIDString(requestModel.query);
const listDIDDTO: ListDIDDTO = await this.didGateway.listDIDs(requestModel.rucioAuthToken, scope, name, requestModel.type);
return listDIDDTO;
}

handleGatewayError(error: ListDIDDTO): ListDIDsError {
let errorType = 'Unknown Error'
if(error.error === 'Invalid Auth Token') {
errorType = 'Invalid Request'
}
else if(error.error !== 'Unknown Error') {
errorType = 'Invalid DID Query'
}

return {
error: errorType,
message: `${error.error}: ${error.message}`,
} as ListDIDsError
}

streamDataToStreamDTO(streamedChunk: ListDIDsStreamData, requestModel: ListDIDsRequest): DIDDTO {
const { scope, name } = parseDIDString(streamedChunk);
return {
name: name,
scope: scope,
did_type: requestModel.type,
} as DIDDTO
}

processStreamedData(dto: DIDDTO): { data: ListDIDsResponse | ListDIDsError; status: "success" | "error"; } {
const responseModel: ListDIDsResponse = {
status: 'success',
name: dto.name,
scope: dto.scope,
did_type: dto.did_type,
length: 0,
bytes: 0,
}
return {
data: responseModel,
status: 'success',
}
}

handleStreamError(error: ListDIDsError): void {
this.emit('error', error)
}

validateFinalResponseModel(responseModel: ListDIDsResponse): { isValid: boolean; errorModel?: ListDIDsError | undefined; } {
return {
isValid: true,
}
}









}

export default ListDIDsUseCase;
91 changes: 91 additions & 0 deletions src/lib/core/use-case/list-dids/pipeline-element-get-did.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { parseDIDString } from "@/lib/common/did-utils";
import { BaseStreamingPostProcessingPipelineElement } from "@/lib/sdk/postprocessing-pipeline-elements";
import { AuthenticatedRequestModel } from "@/lib/sdk/usecase-models";
import { inject } from "inversify";
import { DIDDTO } from "../../dto/did-dto";
import DIDGatewayOutputPort from "../../port/secondary/did-gateway-output-port";
import { ListDIDsError, ListDIDsRequest, ListDIDsResponse } from "../../usecase-models/list-dids-usecase-models";

export default class GetDIDsPipelineElement extends BaseStreamingPostProcessingPipelineElement<ListDIDsRequest, ListDIDsResponse, ListDIDsError, DIDDTO>{
constructor(private didGateway: DIDGatewayOutputPort) {
super();
}
async makeGatewayRequest(requestModel: AuthenticatedRequestModel<ListDIDsRequest>, responseModel: ListDIDsResponse): Promise<DIDDTO> {
let scope: string = '';
let name: string = '';
try {
const parsedDID = parseDIDString(requestModel.query);
scope = parsedDID.scope;
name = parsedDID.name;
const dto: DIDDTO = await this.didGateway.getDID(requestModel.rucioAuthToken, scope, name);
return dto;
} catch (error: any) {
const errorDTO: DIDDTO = {
status: 'error',
error: 'Invalid Parameters',
message: (error as Error).message,
name: requestModel.query,
scope: requestModel.query,
did_type: requestModel.type,
account: '',
open: false,
monotonic: false,
expired_at: '',
bytes: 0,
length: 0
}
return errorDTO;
}
}

handleGatewayError(dto: DIDDTO): ListDIDsError {
let error: 'Unknown Error' | 'Invalid DID Query' | 'Invalid Request' = 'Unknown Error';
switch(dto.error) {
case 'Invalid Auth Token':
error = 'Invalid Request';
break;
case 'Data Identifier Not Found':
error = 'Invalid DID Query';
break;
case 'Invalid Parameters':
error = 'Invalid Request';
break;
case 'Scope Not Found':
error = 'Invalid DID Query';
break;
case 'Unknown Error':
error = 'Unknown Error';
break;
default:
error = 'Unknown Error';
break;
}

const errorModel: ListDIDsError = {
status: 'error',
name: dto.name,
error: error,
message: dto.error + ': ' + dto.message + ' for DID ' + dto.scope + ':' + dto.name,
}
return errorModel;
}

validateDTO(dto: DIDDTO): { status: "success" | "error" | "critical"; data: ListDIDsError | DIDDTO; } {
if(dto.expired_at === '') {
dto.expired_at = 'Never';
}

return {
status: 'success',
data: dto
}
}


transformResponseModel(responseModel: ListDIDsResponse, dto: DIDDTO): ListDIDsResponse {
responseModel.bytes = dto.bytes;
responseModel.length = dto.length;
return responseModel;
}

}
3 changes: 2 additions & 1 deletion src/lib/infrastructure/ioc/features/list-dids-feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import INPUT_PORT from '@/lib/infrastructure/ioc/ioc-symbols-input-port'
import USECASE_FACTORY from '@/lib/infrastructure/ioc/ioc-symbols-usecase-factory'
import { Container } from 'inversify'
import ListDIDsController from '@/lib/infrastructure/controller/list-dids-controller'
import ListDIDsUseCase from '@/lib/core/use-case/list-dids-usecase'
// import ListDIDsUseCase from '@/lib/core/use-case/list-dids-usecase'
import ListDIDsUseCase from '@/lib/core/use-case/list-dids/list-dids-usecase2'
import ListDIDsPresenter from '../../presenter/list-dids-presenter'

export default class ListDidsFeature extends BaseStreamableFeature<
Expand Down
2 changes: 1 addition & 1 deletion src/lib/infrastructure/presenter/list-dids-presenter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { BaseStreamingPresenter } from '@/lib/sdk/presenter'
import { DIDType } from '@/lib/core/entity/rucio'
import { ListDIDsOutputPort } from '@/lib/core/port/primary/list-dids-ports'

export default class ListDIDsPresenter extends BaseStreamingPresenter<ListDIDsResponse, ListDIDsViewModel, ListDIDsError> implements ListDIDsOutputPort {
export default class ListDIDsPresenter extends BaseStreamingPresenter<ListDIDsResponse, ListDIDsError, ListDIDsViewModel> implements ListDIDsOutputPort {
response: NextApiResponse<any>

constructor(response: NextApiResponse) {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/sdk/gateway-endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export abstract class BaseEndpoint<TDTO extends BaseDTO> {
*/
protected initialized: boolean = false;
protected request: HTTPRequest | undefined;
protected rucioHost: string = 'http://rucio-host.com';
protected rucioHost: string = 'https://rucio-host.com';
protected envConfigGateway: EnvConfigGatewayOutputPort;

constructor(
Expand Down
Loading

0 comments on commit 5eda5a4

Please sign in to comment.