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

feat: implementing Startable and propagating stop() #309

Open
wants to merge 1 commit 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: 8 additions & 1 deletion src/domain/buildingBlocks/Pluto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,18 @@ export namespace Pluto {
* preferred underlying storage technology, most appropriate for your use case.
*/
export interface Pluto {
// TODO extend Startable.Controller (changes the interface)

/**
* Pluto initialise function
* Handle startup.
*/
start(): Promise<void>;

/**
* Handle teardown.
*/
stop?(): Promise<void>;

/**
* create a Backup object from the stored data
*/
Expand Down
19 changes: 9 additions & 10 deletions src/domain/buildingBlocks/Pollux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export type CredentialOfferJWTBasePayload = {
options: {
challenge: string;
domain: string;
}
}
};
};

export type CredentialOfferPayloads = {
[CredentialType.AnonCreds]: Anoncreds.CredentialOfferType;
Expand Down Expand Up @@ -48,9 +48,8 @@ export type ProcessedCredentialOfferPayloads = {
* handle Credential related tasks
*/
export interface Pollux {

revealCredentialFields: (credential: Credential, fields: string[], linkSecret: string) => Promise<{
[name: string]: any
[name: string]: any;
}>;

isCredentialRevoked: (credential: Credential) => Promise<boolean>;
Expand All @@ -71,12 +70,12 @@ export interface Pollux {
presentationDefinition: PresentationDefinitionRequest<CredentialType.JWT>,
credential: Credential,
privateKey: PrivateKey
): Promise<PresentationSubmission<CredentialType.JWT>>
): Promise<PresentationSubmission<CredentialType.JWT>>;
createPresentationSubmission(
presentationDefinition: PresentationDefinitionRequest<CredentialType.AnonCreds>,
credential: Credential,
privateKey: LinkSecret
): Promise<PresentationSubmission<CredentialType.AnonCreds>>
): Promise<PresentationSubmission<CredentialType.AnonCreds>>;

/**
* Process a PresentationSubmission, resolve the issuer did and verify the credential and the holder signature
Expand All @@ -88,15 +87,15 @@ export interface Pollux {
verifyPresentationSubmission(
presentationSubmission: PresentationSubmission<CredentialType.JWT>,
options?: Pollux.verifyPresentationSubmission.options.JWT
): Promise<boolean>
): Promise<boolean>;
verifyPresentationSubmission(
presentationSubmission: PresentationSubmission<CredentialType.AnonCreds>,
options?: Pollux.verifyPresentationSubmission.options.Anoncreds
): Promise<boolean>
): Promise<boolean>;
verifyPresentationSubmission(
presentationSubmission: PresentationSubmission,
options?: Pollux.verifyPresentationSubmission.options.JWT | Pollux.verifyPresentationSubmission.options.Anoncreds
): Promise<boolean>
): Promise<boolean>;

/**
* Creates a PresentationDefinitionRequest object for oob Verifications
Expand All @@ -108,7 +107,7 @@ export interface Pollux {
type: T,
claims: PresentationClaims<T>,
options: PresentationOptions
): Promise<PresentationDefinitionRequest<T>>
): Promise<PresentationDefinitionRequest<T>>;



Expand Down
41 changes: 17 additions & 24 deletions src/edge-agent/Agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@ import { SignWithDID } from "./didFunctions/Sign";
import { CreatePrismDID } from "./didFunctions/CreatePrismDID";
import { FetchApi } from "./helpers/FetchApi";
import { Task } from "../utils/tasks";

enum AgentState {
STOPPED = "stopped",
STARTING = "starting",
RUNNING = "running",
STOPPING = "stopping",
}
import { Startable } from "../utils/startable";
import { notNil } from "../utils";

/**
* Edge agent implementation
Expand All @@ -22,14 +17,14 @@ enum AgentState {
* @class Agent
* @typedef {Agent}
*/
export default class Agent {
export default class Agent implements Startable.Controller {
/**
* Agent state
*
* @public
* @type {AgentState}
* @type {Startable.State}
*/
public state: AgentState = AgentState.STOPPED;
public state = Startable.State.STOPPED;
public backup: AgentBackup;
public readonly pollux: Pollux;

Expand Down Expand Up @@ -86,30 +81,28 @@ export default class Agent {
/**
* Asyncronously start the agent
*
* @async
* @returns {Promise<AgentState>}
*/
async start(): Promise<AgentState> {
if (this.state === AgentState.STOPPED) {
this.state = AgentState.STARTING;
start(): Promise<Startable.State> {
return Startable.start(this, async () => {
await this.pluto.start();
await this.pollux.start();
}

return this.state;
});
}

/**
* Asyncronously stop the agent and any side task that is running
*
* @async
* @returns {Promise<void>}
* @returns {Promise<Startable.State>}
*/
async stop(): Promise<void> {
if (this.state !== AgentState.RUNNING) {
return;
}
this.state = AgentState.STOPPED;
stop(): Promise<Startable.State> {
return Startable.stop(this, async () => {
await this.pollux.stop();

if (notNil(this.pluto.stop)) {
await this.pluto.stop();
}
});
}

/**
Expand Down
110 changes: 45 additions & 65 deletions src/edge-agent/didcomm/Agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,8 @@
import { ParsePrismInvitation } from "./ParsePrismInvitation";
import { ParseInvitation } from "./ParseInvitation";
import { HandleOOBInvitation } from "./HandleOOBInvitation";

enum AgentState {
STOPPED = "stopped",
STARTING = "starting",
RUNNING = "running",
STOPPING = "stopping",
}
import { Startable } from "../../utils/startable";
import { notNil } from "../../utils";

/**
* Edge agent implementation
Expand All @@ -52,14 +47,8 @@
* @class Agent
* @typedef {Agent}
*/
export default class DIDCommAgent {
/**
* Agent state
*
* @public
* @type {AgentState}
*/
public state: AgentState = AgentState.STOPPED;
export default class DIDCommAgent implements Startable.Controller {
public state = Startable.State.STOPPED;
public backup: AgentBackup;
public readonly pollux: Pollux;

Expand All @@ -80,7 +69,7 @@
public readonly connectionManager: ConnectionsManager,
public readonly seed: Domain.Seed = apollo.createRandomSeed().seed,
public readonly api: Domain.Api = new FetchApi(),
options?: AgentOptions

Check warning on line 72 in src/edge-agent/didcomm/Agent.ts

View workflow job for this annotation

GitHub Actions / Build and test

'options' is defined but never used. Allowed unused args must match /^_/u
) {
this.pollux = new Pollux(apollo, castor);
this.backup = new AgentBackup(this);
Expand Down Expand Up @@ -148,64 +137,55 @@
return agent;
}

start(): Promise<Startable.State> {
return Startable.start(this, async () => {
try {
this.state = Startable.State.STARTING;
await this.pluto.start();
await this.pollux.start();
await this.connectionManager.startMediator();
}
catch (e) {
if (e instanceof Domain.AgentError.NoMediatorAvailableError) {
const hostDID = await this.createNewPeerDID([], false);
await this.connectionManager.registerMediator(hostDID);
}
else {
throw e;
}
}

/**
* Asyncronously start the agent
*
* @async
* @returns {Promise<AgentState>}
*/
async start(): Promise<AgentState> {
if (this.state !== AgentState.STOPPED) {
return this.state;
}

try {
this.state = AgentState.STARTING;
await this.pluto.start();
await this.pollux.start();
await this.connectionManager.startMediator();
} catch (e) {
if (e instanceof Domain.AgentError.NoMediatorAvailableError) {
const hostDID = await this.createNewPeerDID([], false);

await this.connectionManager.registerMediator(hostDID);

} else throw e;
}

if (this.connectionManager.mediationHandler.mediator !== undefined) {
await this.connectionManager.startFetchingMessages(5);
this.state = AgentState.RUNNING;
} else {
throw new Domain.AgentError.MediationRequestFailedError("Mediation failed");
}

const storedLinkSecret = await this.pluto.getLinkSecret();
if (storedLinkSecret == null) {
const secret = this.pollux.anoncreds.createLinksecret();
const linkSecret = new Domain.LinkSecret(secret);
await this.pluto.storeLinkSecret(linkSecret);
}
if (this.connectionManager.mediationHandler.mediator !== undefined) {
await this.connectionManager.startFetchingMessages(5);
}
else {
throw new Domain.AgentError.MediationRequestFailedError("Mediation failed");
}

return this.state;
const storedLinkSecret = await this.pluto.getLinkSecret();
if (storedLinkSecret == null) {
const secret = this.pollux.anoncreds.createLinksecret();
const linkSecret = new Domain.LinkSecret(secret);
await this.pluto.storeLinkSecret(linkSecret);
}
});
}

/**
* Asyncronously stop the agent and any side task that is running
* Asyncronously stop the agent and dependencies
*
* @async
* @returns {Promise<void>}
*/
async stop(): Promise<void> {
if (this.state !== AgentState.RUNNING) {
return;
}
this.state = AgentState.STOPPING;
await this.connectionManager.stopAllEvents();
await this.connectionManager.stopFetchingMessages();
// await this.agent.stop();
this.state = AgentState.STOPPED;
stop(): Promise<Startable.State> {
return Startable.stop(this, async () => {
await this.connectionManager.stopAllEvents();
await this.connectionManager.stopFetchingMessages();
await this.pollux.stop();

if (notNil(this.pluto.stop)) {
await this.pluto.stop();
}
});
}

/**
Expand Down
36 changes: 16 additions & 20 deletions src/edge-agent/oidc/Agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { Task } from "../../utils/tasks";
import * as DIDfns from "../didFunctions";
import * as Tasks from "./tasks";
import * as Errors from "./errors";
import { JsonObj, expect } from "../../utils";
import { JsonObj, expect, notNil } from "../../utils";
import { Startable } from "../../utils/startable";

/**
* https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html
Expand All @@ -24,20 +25,12 @@ class Connection {
public readonly issuerMeta: OIDC.IssuerMetadata,
public readonly scopes: string[],
public readonly tokenResponse: TokenResponse,
) { }
) {}
}

// TODO make startable interface
enum AgentState {
STOPPED = "stopped",
STARTING = "starting",
RUNNING = "running",
STOPPING = "stopping",
}

export class OIDCAgent {
export class OIDCAgent implements Startable.Controller {
private connections: Connection[] = [];
public state = AgentState.STOPPED;
public state = Startable.State.STOPPED;
public readonly pollux: Pollux;

constructor(
Expand Down Expand Up @@ -81,18 +74,21 @@ export class OIDCAgent {
return agent;
}

async start() {
if (this.state === AgentState.STOPPED) {
this.state = AgentState.STARTING;
start(): Promise<Startable.State> {
return Startable.start(this, async () => {
await this.pluto.start();
await this.pollux.start();
this.state = AgentState.RUNNING;
}
return this.state;
});
}

async stop(): Promise<void> {
this.state = AgentState.STOPPED
async stop(): Promise<Startable.State> {
return Startable.stop(this, async () => {
await this.pollux.stop();

if (notNil(this.pluto.stop)) {
await this.pluto.stop();
}
});
}

private runTask<T>(task: Task<T>): Promise<T> {
Expand Down
Loading
Loading