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

Feature 399 did gateway extensions #400

Merged
merged 8 commits into from
Dec 14, 2023
23 changes: 23 additions & 0 deletions src/lib/core/dto/did-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,27 @@ export interface DIDRulesDTO extends Omit<DIDRules, 'subscription'>, BaseDTO {
*/
export interface CreateDIDSampleDTO extends BaseDTO {
created: boolean
}

/**
* Data Transfer Object for AddDIDEndpoint
*/
export interface AddDIDDTO extends BaseDTO {
created: boolean
}

/**
* Data Transfer Object for AttachDIDEndpoint
*/
export interface AttachDIDDTO extends BaseDTO {
created: boolean
}

/**
* Data Transfer Object for SetDIDStatus (open/closed) endpoint
*/
export interface SetDIDStatusDTO extends BaseDTO {
scope: string
name: string
open: boolean
}
62 changes: 45 additions & 17 deletions src/lib/core/port/secondary/did-gateway-output-port.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,49 @@
import { ListDIDDTO, DIDExtendedDTO, DIDMetaDTO, ListDIDRulesDTO, DIDKeyValuePairsDTO, CreateDIDSampleDTO } from "../../dto/did-dto";
import { DIDType } from "../../entity/rucio";
import { ListDIDDTO, DIDExtendedDTO, DIDMetaDTO, ListDIDRulesDTO, DIDKeyValuePairsDTO, CreateDIDSampleDTO, AddDIDDTO, AttachDIDDTO as AttachDIDsDTO, SetDIDStatusDTO } from "../../dto/did-dto";
import { DID, DIDType } from "../../entity/rucio";


/**
* Output port for the DID Gateway, responsible for defining the methods that the Gateway will use to interact with the Rucio Server.
*/
export default interface DIDGatewayOutputPort {
/**
* Sends a request to create a sample DID to the Rucio Server.
* @param rucioAuthToken A valid Rucio auth token.
* @param inputScope The scope of the input DID.
* @param inputName The name of the input DID.
* @param outputScope The scope of the output DID.
* @param outputName The name of the output DID.
* @param nbFiles The number of files.
* @returns A Promise that resolves to a {@link CreateDIDSampleDTO} object.
*/
createDIDSample(
rucioAuthToken: string,
inputScope: string,
inputName: string,
outputScope: string,
outputName: string,
nbFiles: number
): Promise<CreateDIDSampleDTO>


/**
* Creates a new DID on the Rucio Server.
* @param rucioAuthToken A valid Rucio auth token.
* @param scope The scope of the DID
* @param name The name of the DID
* @param didType The DIDType of the DID
*/
addDID(rucioAuthToken: string, scope: string, name: string, didType: DIDType): Promise<AddDIDDTO>

/**
* Attaches a list of DIDs to a parent DID.
* @param rucioAuthToken A valid Rucio auth token.
* @param scope The scope of the parent DID
* @param name The name of the parent DID
* @param dids A list of DIDs to attach to the parent DID
*/
attachDIDs(rucioAuthToken: string, scope: string, name: string, dids: DID[]): Promise<AttachDIDsDTO>

/**
* Retrieves a DID from the Rucio Server.
* @param rucioAuthToken A valid Rucio auth token.
Expand Down Expand Up @@ -79,21 +117,11 @@ export default interface DIDGatewayOutputPort {
listDIDContents(rucioAuthToken: string, scope: string, name: string): Promise<ListDIDDTO>

/**
* Sends a request to create a sample DID to the Rucio Server.
* Sets a DID status to open or closed.
* @param rucioAuthToken A valid Rucio auth token.
* @param inputScope The scope of the input DID.
* @param inputName The name of the input DID.
* @param outputScope The scope of the output DID.
* @param outputName The name of the output DID.
* @param nbFiles The number of files.
* @returns A Promise that resolves to a {@link CreateDIDSampleDTO} object.
* @param scope The scope of the DID whose status is to be changed.
* @param name The name of the DID whose status is to be changed.
* @param open A boolean value indicating whether the DID should be open or closed.
*/
createDIDSample(
rucioAuthToken: string,
inputScope: string,
inputName: string,
outputScope: string,
outputName: string,
nbFiles: number
): Promise<CreateDIDSampleDTO>
setDIDStatus(rucioAuthToken: string, scope: string, name: string, open: boolean): Promise<SetDIDStatusDTO>
}
90 changes: 75 additions & 15 deletions src/lib/infrastructure/gateway/did-gateway/did-gateway.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DIDExtendedDTO, DIDMetaDTO, ListDIDDTO, ListDIDRulesDTO, DIDKeyValuePairsDTO, CreateDIDSampleDTO } from '@/lib/core/dto/did-dto'
import { DIDAvailability, DIDType } from '@/lib/core/entity/rucio'
import { DIDExtendedDTO, DIDMetaDTO, ListDIDDTO, ListDIDRulesDTO, DIDKeyValuePairsDTO, CreateDIDSampleDTO, AddDIDDTO, AttachDIDDTO, SetDIDStatusDTO } from '@/lib/core/dto/did-dto'
import { DID, DIDAvailability, DIDType } from '@/lib/core/entity/rucio'
import DIDGatewayOutputPort from '@/lib/core/port/secondary/did-gateway-output-port'
import { injectable } from 'inversify'
import GetDIDEndpoint from './endpoints/get-did-endpoint'
Expand All @@ -10,9 +10,74 @@ import GetDIDKeyValuePairsEndpoint from './endpoints/get-did-keyvaluepairs-endpo
import ListDIDParentsEndpoint from './endpoints/list-did-parents-endpoint'
import ListDIDContentsEndpoint from './endpoints/list-did-contents-endpoint'
import CreateDIDSampleEndpoint from './endpoints/create-did-sample-endpoint'
import AddDIDEndpoint from './endpoints/add-did-endpoint'
import AttachDIDsEndpoint from './endpoints/attach-dids-endpoint'
import SetDIDStatusEndpoint from './endpoints/set-did-status-endpoints'

@injectable()
export default class RucioDIDGateway implements DIDGatewayOutputPort {
async addDID(rucioAuthToken: string, scope: string, name: string, didType: DIDType): Promise<AddDIDDTO> {
try {
const endpoint = new AddDIDEndpoint(rucioAuthToken, scope, name, didType)
const dto = await endpoint.fetch()
return dto
} catch(error) {
const errorDTO: AddDIDDTO = {
status: 'error',
created: false,
errorName: 'An exception occurred while creating the DID.',
errorType: 'gateway_endpoint_error',
errorCode: 500,
errorMessage: error?.toString(),
}
return Promise.resolve(errorDTO)
}
}


async attachDIDs(rucioAuthToken: string, scope: string, name: string, dids: DID[]): Promise<AttachDIDDTO> {
try {
const endpoint = new AttachDIDsEndpoint(rucioAuthToken, scope, name, dids)
const dto = endpoint.fetch()
return dto
}catch (error) {
const errorDTO: AttachDIDDTO = {
status: 'error',
created: false,
errorName: 'An exception occurred while attaching the DIDs.',
errorType: 'gateway_endpoint_error',
errorCode: 500,
errorMessage: error?.toString(),
}
return Promise.resolve(errorDTO)
}
}

async createDIDSample(
rucioAuthToken: string,
inputScope: string,
inputName: string,
outputScope: string,
outputName: string,
nbFiles: number
): Promise<CreateDIDSampleDTO> {
try {
const endpoint = new CreateDIDSampleEndpoint(rucioAuthToken, inputScope, inputName, outputScope, outputName, nbFiles);
const dto = await endpoint.fetch()
return dto;
} catch(error) {
const errorDTO: CreateDIDSampleDTO = {
status: 'error',
created: false,
errorName: 'An exception occurred while creating the sample DID.',
errorType: 'gateway_endpoint_error',
errorCode: 500,
errorMessage: error?.toString(),
}
return Promise.resolve(errorDTO)
}
}


async getDID(
rucioAuthToken: string,
Expand Down Expand Up @@ -174,23 +239,18 @@ export default class RucioDIDGateway implements DIDGatewayOutputPort {
}
}

async createDIDSample(
rucioAuthToken: string,
inputScope: string,
inputName: string,
outputScope: string,
outputName: string,
nbFiles: number
): Promise<CreateDIDSampleDTO> {
async setDIDStatus(rucioAuthToken: string, scope: string, name: string, open: boolean): Promise<SetDIDStatusDTO> {
try {
const endpoint = new CreateDIDSampleEndpoint(rucioAuthToken, inputScope, inputName, outputScope, outputName, nbFiles);
const endpoint = new SetDIDStatusEndpoint(rucioAuthToken, scope, name, open)
const dto = await endpoint.fetch()
return dto;
return dto
} catch(error) {
const errorDTO: CreateDIDSampleDTO = {
const errorDTO: SetDIDStatusDTO = {
status: 'error',
created: false,
errorName: 'An exception occurred while creating the sample DID.',
scope: scope,
name: name,
open: open,
errorName: 'Unknown Error',
errorType: 'gateway_endpoint_error',
errorCode: 500,
errorMessage: error?.toString(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { AddDIDDTO } from "@/lib/core/dto/did-dto";
import { DIDType } from "@/lib/core/entity/rucio";
import { BaseEndpoint, extractErrorMessage } from "@/lib/sdk/gateway-endpoints";
import { HTTPRequest } from "@/lib/sdk/http";
import { Response } from "node-fetch";


export default class AddDIDEndpoint extends BaseEndpoint<AddDIDDTO> {
constructor(
private readonly rucioAuthToken: string,
private readonly scope: string,
private readonly name: string,
private readonly didType: DIDType,

){
super(true)
}

async initialize(): Promise<void> {
await super.initialize()
const rucioHost = await this.envConfigGateway.rucioHost()
const endpoint = `${rucioHost}/dids/${this.scope}/${this.name}`
const request: HTTPRequest = {
method: 'POST',
url: endpoint,
headers: {
'X-Rucio-Auth-Token': this.rucioAuthToken,
'Content-Type': 'application/json',
},
body: {
scope: this.scope,
name: this.name,
type: this.didType.toUpperCase(),
},
}
this.request = request
this.initialized = true
}

async reportErrors(statusCode: number, response: Response): Promise<AddDIDDTO | undefined> {
const errorDTO: AddDIDDTO = {
status: 'error',
created: false,
errorMessage: 'Unknown Exception while making the request to Rucio Server or parsing the response from Rucio Server',
errorCode: statusCode,
errorName: 'Unknown Error',
errorType: 'gateway-endpoint-error',
}
if(statusCode === 409) {
errorDTO.errorMessage = `DID ${this.scope}:${this.name} Already Exists`
errorDTO.errorName = 'DID Already Attached'
return errorDTO
}
const error = await extractErrorMessage(response)
errorDTO.errorMessage = error
errorDTO.errorName = 'Rucio Server Error'
return errorDTO
}

createDTO(data: string): AddDIDDTO {
const dto: AddDIDDTO = {
status: 'success',
created: data.toLowerCase() === "created" ? true : false,
}
return dto
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { AttachDIDDTO } from "@/lib/core/dto/did-dto";
import { DID } from "@/lib/core/entity/rucio";
import { BaseEndpoint, extractErrorMessage } from "@/lib/sdk/gateway-endpoints";
import { HTTPRequest } from "@/lib/sdk/http";
import { Response } from "node-fetch";


export default class AttachDIDsEndpoint extends BaseEndpoint<AttachDIDDTO> {
constructor(
private readonly rucioAuthToken: string,
private readonly scope: string,
private readonly name: string,
private readonly dids: DID[],
){
super(true)
}

async initialize(): Promise<void> {
await super.initialize()
const rucioHost = await this.envConfigGateway.rucioHost()
const endpoint = `${rucioHost}/dids/${this.scope}/${this.name}/dids`
const request: HTTPRequest = {
method: 'POST',
url: endpoint,
headers: {
'X-Rucio-Auth-Token': this.rucioAuthToken,
'Content-Type': 'application/json',
},
body: {
scope: this.scope,
name: this.name,
dids: this.dids.map(did => {
return {
scope: did.scope,
name: did.name,
}
})
},
}
this.request = request
this.initialized = true
}

async reportErrors(statusCode: number, response: Response): Promise<AttachDIDDTO | undefined> {
const errorDTO: AttachDIDDTO = {
status: 'error',
created: false,
errorMessage: 'Unknown Exception from Rucio Server',
errorCode: statusCode,
errorName: 'Unknown Error',
errorType: 'gateway-endpoint-error',
}
if(statusCode === 409) {
errorDTO.errorMessage = `Already Attached`
errorDTO.errorName = 'DID Already Attached'
return errorDTO
}
const error = await extractErrorMessage(response)
errorDTO.errorMessage = error
return errorDTO
}

createDTO(data: string): AttachDIDDTO {
const dto: AttachDIDDTO = {
status: 'success',
created: data.toLowerCase() === "created" ? true : false,
}
return dto
}
}
Loading
Loading