Skip to content

Commit

Permalink
feat: create peer connection storage
Browse files Browse the repository at this point in the history
  • Loading branch information
Sotatek-HocNguyena committed May 6, 2024
1 parent 35a2cee commit 532b7d0
Show file tree
Hide file tree
Showing 19 changed files with 495 additions and 21 deletions.
18 changes: 18 additions & 0 deletions src/core/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ConnectionService,
CredentialService,
IdentifierService,
PeerConnectionService,
} from "./services";
import { SignifyNotificationService } from "./services/signifyNotificationService";
import { AgentServicesProps } from "./agent.types";
Expand All @@ -21,6 +22,8 @@ import {
CredentialStorage,
IdentifierMetadataRecord,
IdentifierStorage,
PeerConnectionMetadataRecord,
PeerConnectionStorage,
} from "./records";
import { KeyStoreKeys, SecureStorage } from "../storage";
import { MultiSigService } from "./services/multiSigService";
Expand Down Expand Up @@ -54,6 +57,7 @@ class Agent {

private connectionService!: ConnectionService;
private credentialService!: CredentialService;
private peerConnectionService!: PeerConnectionService;
private signifyNotificationService!: SignifyNotificationService;

get identifiers() {
Expand Down Expand Up @@ -93,6 +97,15 @@ class Agent {
return this.credentialService;
}

get peerConnections() {
if (!this.peerConnectionService) {
this.peerConnectionService = new PeerConnectionService(
this.agentServicesProps
);
}
return this.peerConnectionService;
}

get basicStorage() {
return this.basicStorageService;
}
Expand Down Expand Up @@ -150,6 +163,11 @@ class Agent {
credentialStorage: new CredentialStorage(
this.getStorageService<CredentialMetadataRecord>(this.storageSession)
),
peerConnectionStorage: new PeerConnectionStorage(
this.getStorageService<PeerConnectionMetadataRecord>(
this.storageSession
)
),
};
Agent.ready = true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/agent/agent.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { IdentifierStorage } from "./records/identifierStorage";
import { CredentialStorage } from "./records/credentialStorage";
import { BasicStorage } from "./records/basicStorage";
import { ConnectionHistoryType } from "./services/connection.types";
import { PeerConnectionStorage } from "./records";

enum ConnectionStatus {
CONFIRMED = "confirmed",
Expand Down Expand Up @@ -101,6 +102,7 @@ interface AgentServicesProps {
eventService: EventService;
identifierStorage: IdentifierStorage;
credentialStorage: CredentialStorage;
peerConnectionStorage: PeerConnectionStorage;
}

interface CreateIdentifierResult {
Expand Down
2 changes: 2 additions & 0 deletions src/core/agent/records/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export * from "./credentialMetadataRecord";
export * from "./identifierMetadataRecord";
export * from "./peerConnectionMetadataRecord";
export * from "./basicRecord";
export * from "./credentialStorage";
export * from "./identifierStorage";
export * from "./peerConnectionStorage";
export * from "./basicStorage";
34 changes: 34 additions & 0 deletions src/core/agent/records/peerConnectionMetadataRecord.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
PeerConnectionMetadataRecord,
PeerConnectionMetadataRecordProps,
} from "./peerConnectionMetadataRecord";

const mockData: PeerConnectionMetadataRecordProps = {
id: "id",
name: "name",
url: "url",
iconB64: "icon",
selectedAid: "aid",
isPending: false,
};

describe("Peer Connection Record", () => {
test("should fill the record based on supplied props", () => {
const createdAt = new Date();
const settingsRecord = new PeerConnectionMetadataRecord({
...mockData,
createdAt: createdAt,
});
settingsRecord.getTags();
expect(settingsRecord.type).toBe(PeerConnectionMetadataRecord.type);
expect(settingsRecord.id).toBe(mockData.id);
expect(settingsRecord.name).toBe(mockData.name);
expect(settingsRecord.url).toBe(mockData.url);
expect(settingsRecord.selectedAid).toBe(mockData.selectedAid);
expect(settingsRecord.iconB64).toBe(mockData.iconB64);
expect(settingsRecord.getTags()).toMatchObject({
isPending: mockData.isPending,
});
expect(settingsRecord.createdAt).toBe(createdAt);
});
});
34 changes: 13 additions & 21 deletions src/core/agent/records/peerConnectionMetadataRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,20 @@ import { BaseRecord } from "../../storage/storage.types";

interface PeerConnectionMetadataRecordProps {
id: string;
name: string;
url: string;
name?: string;
url?: string;
createdAt?: Date;
isArchived?: boolean;
isDeleted?: boolean;
isPending?: boolean;
iconB64: string;
selectedAid: string;
iconB64?: string;
selectedAid?: string;
}

class PeerConnectionMetadataRecord extends BaseRecord {
name!: string;
isArchived?: boolean;
isDeleted?: boolean;
name?: string;
isPending?: boolean;
url!: string;
iconB64!: string;
selectedAid!: string;
url?: string;
iconB64?: string;
selectedAid?: string;

static readonly type = "PeerConnectionMetadataRecord";
readonly type = PeerConnectionMetadataRecord.type;
Expand All @@ -29,22 +25,18 @@ class PeerConnectionMetadataRecord extends BaseRecord {

if (props) {
this.id = props.id;
this.name = props.name;
this.url = props.url;
this.isArchived = props.isArchived ?? false;
this.isDeleted = props.isDeleted ?? false;
this.isPending = props.isPending ?? false;
this.selectedAid = props.selectedAid;
this.name = props.name ?? "";
this.url = props.url ?? "";
this.isPending = props.isPending ?? true;
this.selectedAid = props.selectedAid ?? "";
this.createdAt = props.createdAt ?? new Date();
this.iconB64 = props.iconB64;
this.iconB64 = props.iconB64 ?? "";
}
}

getTags() {
return {
...this._tags,
isArchived: this.isArchived,
isDeleted: this.isDeleted,
isPending: this.isPending,
};
}
Expand Down
88 changes: 88 additions & 0 deletions src/core/agent/records/peerConnectionStorage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { PeerConnectionMetadataRecord } from "./peerConnectionMetadataRecord";
import { PeerConnectionStorage } from "./peerConnectionStorage";

const storageService = jest.mocked({
save: jest.fn(),
delete: jest.fn(),
deleteById: jest.fn(),
update: jest.fn(),
findById: jest.fn(),
findAllByQuery: jest.fn(),
getAll: jest.fn(),
});

const peerConnectionStorage = new PeerConnectionStorage(storageService as any);

const peerConnectionMetadataRecordProps = {
id: "id",
name: "name",
url: "url",
iconB64: "icon",
selectedAid: "aid",
isPending: true,
createdAt: new Date(),
};

const peerConnectionMetadataRecord = new PeerConnectionMetadataRecord({
...peerConnectionMetadataRecordProps,
});

const peerConnectionMetadataRecord2 = new PeerConnectionMetadataRecord({
...peerConnectionMetadataRecordProps,
id: "id2",
});

describe("Connection service of agent", () => {
beforeEach(() => {
jest.resetAllMocks();
});

test("Should get all credentials", async () => {
storageService.findAllByQuery.mockResolvedValue([
peerConnectionMetadataRecord,
peerConnectionMetadataRecord2,
]);
expect(await peerConnectionStorage.getAllPeerConnectionMetadata()).toEqual([
peerConnectionMetadataRecord,
peerConnectionMetadataRecord2,
]);
});

test("Should get credential metadata", async () => {
storageService.findById.mockResolvedValue(peerConnectionMetadataRecord);
expect(
await peerConnectionStorage.getPeerConnectionMetadata(
peerConnectionMetadataRecord.id
)
).toEqual(peerConnectionMetadataRecord);
});

test("Should throw if peerConnection metadata record is missing", async () => {
storageService.findById.mockResolvedValue(null);
await expect(
peerConnectionStorage.getPeerConnectionMetadata(
peerConnectionMetadataRecord.id
)
).rejects.toThrowError(
PeerConnectionStorage.PEER_CONNECTION_METADATA_RECORD_MISSING
);
});

test("Should save peerConnection metadata record", async () => {
await peerConnectionStorage.createPeerConnectionMetadataRecord(
peerConnectionMetadataRecordProps
);
expect(storageService.save).toBeCalledWith(peerConnectionMetadataRecord);
});

test("Should update credential metadata record", async () => {
storageService.findById.mockResolvedValue(peerConnectionMetadataRecord);
await peerConnectionStorage.updatePeerConnectionMetadata(
peerConnectionMetadataRecord.id,
{
isPending: false,
}
);
expect(storageService.update).toBeCalled();
});
});
76 changes: 76 additions & 0 deletions src/core/agent/records/peerConnectionStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { StorageService } from "../../storage/storage.types";
import {
PeerConnectionMetadataRecord,
PeerConnectionMetadataRecordProps,
} from "./peerConnectionMetadataRecord";

class PeerConnectionStorage {
static readonly PEER_CONNECTION_METADATA_RECORD_MISSING =
"Peer connection metadata record does not exist";
private storageService: StorageService<PeerConnectionMetadataRecord>;

constructor(storageService: StorageService<PeerConnectionMetadataRecord>) {
this.storageService = storageService;
}

async getPeerConnectionMetadata(
id: string
): Promise<PeerConnectionMetadataRecord> {
const metadata = await this.storageService.findById(
id,
PeerConnectionMetadataRecord
);
if (!metadata) {
throw new Error(
PeerConnectionStorage.PEER_CONNECTION_METADATA_RECORD_MISSING
);
}
return metadata;
}

async getAllPeerConnectionMetadata(): Promise<
PeerConnectionMetadataRecord[]
> {
const records = await this.storageService.findAllByQuery(
{},
PeerConnectionMetadataRecord
);
return records;
}

async updatePeerConnectionMetadata(
id: string,
metadata: Partial<
Pick<
PeerConnectionMetadataRecord,
"name" | "url" | "iconB64" | "selectedAid" | "isPending"
>
>
): Promise<void> {
const identifierMetadataRecord = await this.getPeerConnectionMetadata(id);
if (metadata.name !== undefined)
identifierMetadataRecord.name = metadata.name;
if (metadata.url !== undefined) identifierMetadataRecord.url = metadata.url;
if (metadata.iconB64 !== undefined)
identifierMetadataRecord.iconB64 = metadata.iconB64;
if (metadata.selectedAid !== undefined)
identifierMetadataRecord.selectedAid = metadata.selectedAid;
if (metadata.isPending !== undefined)
identifierMetadataRecord.isPending = metadata.isPending;
await this.storageService.update(identifierMetadataRecord);
}

async createPeerConnectionMetadataRecord(
data: PeerConnectionMetadataRecordProps
): Promise<void> {
const record = new PeerConnectionMetadataRecord(data);
await this.storageService.save(record);
}

async deletePeerConnectionMetadataRecord(id: string): Promise<void> {
const record = await this.getPeerConnectionMetadata(id);
await this.storageService.delete(record);
}
}

export { PeerConnectionStorage };
3 changes: 3 additions & 0 deletions src/core/agent/services/agentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,23 @@ import { EventService } from "./eventService";
import { IdentifierStorage } from "../records/identifierStorage";
import { CredentialStorage } from "../records/credentialStorage";
import { AgentServicesProps } from "../agent.types";
import { PeerConnectionStorage } from "../records";

abstract class AgentService {
protected readonly basicStorage: StorageApi;
protected readonly signifyClient: SignifyClient;
protected readonly eventService: EventService;
protected readonly identifierStorage: IdentifierStorage;
protected readonly credentialStorage: CredentialStorage;
protected readonly peerConnectionStorage: PeerConnectionStorage;

constructor(agentServicesProps: AgentServicesProps) {
this.basicStorage = agentServicesProps.basicStorage;
this.signifyClient = agentServicesProps.signifyClient;
this.eventService = agentServicesProps.eventService;
this.identifierStorage = agentServicesProps.identifierStorage;
this.credentialStorage = agentServicesProps.credentialStorage;
this.peerConnectionStorage = agentServicesProps.peerConnectionStorage;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/core/agent/services/connectionService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ const agentServicesProps = {
eventService: new EventService(),
identifierStorage: new IdentifierStorage(session as any),
credentialStorage: new CredentialStorage(session as any),
peerConnectionStorage: {} as any,
};

const connectionService = new ConnectionService(agentServicesProps);
Expand Down
1 change: 1 addition & 0 deletions src/core/agent/services/credentialService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const agentServicesProps = {
eventService: new EventService(),
identifierStorage: identifierStorage as any,
credentialStorage: credentialStorage as any,
peerConnectionStorage: {} as any,
};

const credentialService = new CredentialService(agentServicesProps);
Expand Down
1 change: 1 addition & 0 deletions src/core/agent/services/delegationService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const agentServicesProps = {
eventService: new EventService(),
identifierStorage: identifierStorage as any,
credentialStorage: {} as any,
peerConnectionStorage: {} as any,
};

const delegationService = new DelegationService(agentServicesProps);
Expand Down
1 change: 1 addition & 0 deletions src/core/agent/services/identifierService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ const agentServicesProps = {
eventService: new EventService(),
identifierStorage: identifierStorage as any,
credentialStorage: credentialStorage as any,
peerConnectionStorage: {} as any,
};

const identifierService = new IdentifierService(agentServicesProps);
Expand Down

0 comments on commit 532b7d0

Please sign in to comment.