chore: Use consistent strategy naming.

This commit is contained in:
Ruben Verborgh 2021-07-21 23:37:23 +02:00
parent 449a5a6e42
commit 6495d650c2
9 changed files with 36 additions and 35 deletions

View File

@ -13,7 +13,7 @@
"comment": "This authorizer makes sure that for auxiliary resources, the main authorizer gets called with the associated identifier.", "comment": "This authorizer makes sure that for auxiliary resources, the main authorizer gets called with the associated identifier.",
"@type": "AuxiliaryAuthorizer", "@type": "AuxiliaryAuthorizer",
"resourceAuthorizer": { "@id": "urn:solid-server:default:WebAclAuthorizer" }, "resourceAuthorizer": { "@id": "urn:solid-server:default:WebAclAuthorizer" },
"auxStrategy": { "@id": "urn:solid-server:default:AuxiliaryStrategy" } "auxiliaryStrategy": { "@id": "urn:solid-server:default:AuxiliaryStrategy" }
}, },
{ "@id": "urn:solid-server:default:WebAclAuthorizer" } { "@id": "urn:solid-server:default:WebAclAuthorizer" }
] ]

View File

@ -5,7 +5,7 @@
"comment": "Stores data in memory.", "comment": "Stores data in memory.",
"@id": "urn:solid-server:default:MemoryDataAccessor", "@id": "urn:solid-server:default:MemoryDataAccessor",
"@type": "InMemoryDataAccessor", "@type": "InMemoryDataAccessor",
"strategy": { "@id": "urn:solid-server:default:IdentifierStrategy" } "identifierStrategy": { "@id": "urn:solid-server:default:IdentifierStrategy" }
} }
] ]
} }

View File

@ -6,7 +6,7 @@
"@id": "urn:solid-server:default:ResourceStore_Locking", "@id": "urn:solid-server:default:ResourceStore_Locking",
"@type": "LockingResourceStore", "@type": "LockingResourceStore",
"locks": { "@id": "urn:solid-server:default:ResourceLocker" }, "locks": { "@id": "urn:solid-server:default:ResourceLocker" },
"strategy": { "@id": "urn:solid-server:default:AuxiliaryStrategy" } "auxiliaryStrategy": { "@id": "urn:solid-server:default:AuxiliaryStrategy" }
} }
] ]
} }

View File

@ -14,12 +14,12 @@ export class AuxiliaryAuthorizer extends Authorizer {
protected readonly logger = getLoggerFor(this); protected readonly logger = getLoggerFor(this);
private readonly resourceAuthorizer: Authorizer; private readonly resourceAuthorizer: Authorizer;
private readonly auxStrategy: AuxiliaryIdentifierStrategy; private readonly auxiliaryStrategy: AuxiliaryIdentifierStrategy;
public constructor(resourceAuthorizer: Authorizer, auxStrategy: AuxiliaryIdentifierStrategy) { public constructor(resourceAuthorizer: Authorizer, auxiliaryStrategy: AuxiliaryIdentifierStrategy) {
super(); super();
this.resourceAuthorizer = resourceAuthorizer; this.resourceAuthorizer = resourceAuthorizer;
this.auxStrategy = auxStrategy; this.auxiliaryStrategy = auxiliaryStrategy;
} }
public async canHandle(auxiliaryAuth: AuthorizerArgs): Promise<void> { public async canHandle(auxiliaryAuth: AuthorizerArgs): Promise<void> {
@ -40,12 +40,12 @@ export class AuxiliaryAuthorizer extends Authorizer {
} }
private getRequiredAuthorization(auxiliaryAuth: AuthorizerArgs): AuthorizerArgs { private getRequiredAuthorization(auxiliaryAuth: AuthorizerArgs): AuthorizerArgs {
if (!this.auxStrategy.isAuxiliaryIdentifier(auxiliaryAuth.identifier)) { if (!this.auxiliaryStrategy.isAuxiliaryIdentifier(auxiliaryAuth.identifier)) {
throw new NotImplementedHttpError('AuxiliaryAuthorizer only supports auxiliary resources.'); throw new NotImplementedHttpError('AuxiliaryAuthorizer only supports auxiliary resources.');
} }
return { return {
...auxiliaryAuth, ...auxiliaryAuth,
identifier: this.auxStrategy.getAssociatedIdentifier(auxiliaryAuth.identifier), identifier: this.auxiliaryStrategy.getAssociatedIdentifier(auxiliaryAuth.identifier),
}; };
} }
} }

View File

@ -27,12 +27,13 @@ export class LockingResourceStore implements AtomicResourceStore {
private readonly source: ResourceStore; private readonly source: ResourceStore;
private readonly locks: ExpiringReadWriteLocker; private readonly locks: ExpiringReadWriteLocker;
private readonly strategy: AuxiliaryIdentifierStrategy; private readonly auxiliaryStrategy: AuxiliaryIdentifierStrategy;
public constructor(source: ResourceStore, locks: ExpiringReadWriteLocker, strategy: AuxiliaryIdentifierStrategy) { public constructor(source: ResourceStore, locks: ExpiringReadWriteLocker,
auxiliaryStrategy: AuxiliaryIdentifierStrategy) {
this.source = source; this.source = source;
this.locks = locks; this.locks = locks;
this.strategy = strategy; this.auxiliaryStrategy = auxiliaryStrategy;
} }
public async resourceExists(identifier: ResourceIdentifier, conditions?: Conditions): Promise<boolean> { public async resourceExists(identifier: ResourceIdentifier, conditions?: Conditions): Promise<boolean> {
@ -75,8 +76,8 @@ export class LockingResourceStore implements AtomicResourceStore {
* For auxiliary resources this means the associated identifier. * For auxiliary resources this means the associated identifier.
*/ */
protected getLockIdentifier(identifier: ResourceIdentifier): ResourceIdentifier { protected getLockIdentifier(identifier: ResourceIdentifier): ResourceIdentifier {
return this.strategy.isAuxiliaryIdentifier(identifier) ? return this.auxiliaryStrategy.isAuxiliaryIdentifier(identifier) ?
this.strategy.getAssociatedIdentifier(identifier) : this.auxiliaryStrategy.getAssociatedIdentifier(identifier) :
identifier; identifier;
} }

View File

@ -20,12 +20,12 @@ interface ContainerEntry {
type CacheEntry = DataEntry | ContainerEntry; type CacheEntry = DataEntry | ContainerEntry;
export class InMemoryDataAccessor implements DataAccessor { export class InMemoryDataAccessor implements DataAccessor {
private readonly strategy: IdentifierStrategy; private readonly identifierStrategy: IdentifierStrategy;
// A dummy container where every entry corresponds to a root container // A dummy container where every entry corresponds to a root container
private readonly store: { entries: Record<string, ContainerEntry> }; private readonly store: { entries: Record<string, ContainerEntry> };
public constructor(strategy: IdentifierStrategy) { public constructor(identifierStrategy: IdentifierStrategy) {
this.strategy = strategy; this.identifierStrategy = identifierStrategy;
this.store = { entries: { }}; this.store = { entries: { }};
} }
@ -102,10 +102,10 @@ export class InMemoryDataAccessor implements DataAccessor {
* This does not verify if these identifiers actually exist. * This does not verify if these identifiers actually exist.
*/ */
private getHierarchy(identifier: ResourceIdentifier): ResourceIdentifier[] { private getHierarchy(identifier: ResourceIdentifier): ResourceIdentifier[] {
if (this.strategy.isRootContainer(identifier)) { if (this.identifierStrategy.isRootContainer(identifier)) {
return [ identifier ]; return [ identifier ];
} }
const hierarchy = this.getHierarchy(this.strategy.getParentContainer(identifier)); const hierarchy = this.getHierarchy(this.identifierStrategy.getParentContainer(identifier));
hierarchy.push(identifier); hierarchy.push(identifier);
return hierarchy; return hierarchy;
} }
@ -117,11 +117,11 @@ export class InMemoryDataAccessor implements DataAccessor {
private getParentEntry(identifier: ResourceIdentifier): ContainerEntry { private getParentEntry(identifier: ResourceIdentifier): ContainerEntry {
// Casting is fine here as the parent should never be used as a real container // Casting is fine here as the parent should never be used as a real container
let parent: CacheEntry = this.store as ContainerEntry; let parent: CacheEntry = this.store as ContainerEntry;
if (this.strategy.isRootContainer(identifier)) { if (this.identifierStrategy.isRootContainer(identifier)) {
return parent; return parent;
} }
const hierarchy = this.getHierarchy(this.strategy.getParentContainer(identifier)); const hierarchy = this.getHierarchy(this.identifierStrategy.getParentContainer(identifier));
for (const entry of hierarchy) { for (const entry of hierarchy) {
parent = parent.entries[entry.path]; parent = parent.entries[entry.path];
if (!parent) { if (!parent) {

View File

@ -11,7 +11,7 @@
{ {
"@id": "urn:solid-server:template:DataAccessor", "@id": "urn:solid-server:template:DataAccessor",
"@type": "InMemoryDataAccessor", "@type": "InMemoryDataAccessor",
"strategy": { "identifierStrategy": {
"@id": "urn:solid-server:template:IdentifierStrategy" "@id": "urn:solid-server:template:IdentifierStrategy"
} }
} }

View File

@ -121,7 +121,7 @@ describe('A DataAccessorBasedStore', (): void => {
let accessor: SimpleDataAccessor; let accessor: SimpleDataAccessor;
const root = 'http://test.com/'; const root = 'http://test.com/';
const identifierStrategy = new SingleRootIdentifierStrategy(root); const identifierStrategy = new SingleRootIdentifierStrategy(root);
let auxStrategy: AuxiliaryStrategy; let auxiliaryStrategy: AuxiliaryStrategy;
let containerMetadata: RepresentationMetadata; let containerMetadata: RepresentationMetadata;
let representation: Representation; let representation: Representation;
const resourceData = 'text'; const resourceData = 'text';
@ -129,8 +129,8 @@ describe('A DataAccessorBasedStore', (): void => {
beforeEach(async(): Promise<void> => { beforeEach(async(): Promise<void> => {
accessor = new SimpleDataAccessor(); accessor = new SimpleDataAccessor();
auxStrategy = new SimpleSuffixStrategy('.dummy'); auxiliaryStrategy = new SimpleSuffixStrategy('.dummy');
store = new DataAccessorBasedStore(accessor, identifierStrategy, auxStrategy); store = new DataAccessorBasedStore(accessor, identifierStrategy, auxiliaryStrategy);
containerMetadata = new RepresentationMetadata( containerMetadata = new RepresentationMetadata(
{ [RDF.type]: [ { [RDF.type]: [
@ -165,7 +165,7 @@ describe('A DataAccessorBasedStore', (): void => {
expect(result).toMatchObject({ binary: true }); expect(result).toMatchObject({ binary: true });
expect(await arrayifyStream(result.data)).toEqual([ resourceData ]); expect(await arrayifyStream(result.data)).toEqual([ resourceData ]);
expect(result.metadata.contentType).toEqual('text/plain'); expect(result.metadata.contentType).toEqual('text/plain');
expect(result.metadata.get('AUXILIARY')?.value).toBe(auxStrategy.getAuxiliaryIdentifier(resourceID).path); expect(result.metadata.get('AUXILIARY')?.value).toBe(auxiliaryStrategy.getAuxiliaryIdentifier(resourceID).path);
}); });
it('will return a data stream that matches the metadata for containers.', async(): Promise<void> => { it('will return a data stream that matches the metadata for containers.', async(): Promise<void> => {
@ -173,12 +173,12 @@ describe('A DataAccessorBasedStore', (): void => {
containerMetadata.identifier = namedNode(resourceID.path); containerMetadata.identifier = namedNode(resourceID.path);
accessor.data[resourceID.path] = { metadata: containerMetadata } as Representation; accessor.data[resourceID.path] = { metadata: containerMetadata } as Representation;
const metaMirror = new RepresentationMetadata(containerMetadata); const metaMirror = new RepresentationMetadata(containerMetadata);
await auxStrategy.addMetadata(metaMirror); await auxiliaryStrategy.addMetadata(metaMirror);
const result = await store.getRepresentation(resourceID); const result = await store.getRepresentation(resourceID);
expect(result).toMatchObject({ binary: false }); expect(result).toMatchObject({ binary: false });
expect(await arrayifyStream(result.data)).toBeRdfIsomorphic(metaMirror.quads()); expect(await arrayifyStream(result.data)).toBeRdfIsomorphic(metaMirror.quads());
expect(result.metadata.contentType).toEqual(INTERNAL_QUADS); expect(result.metadata.contentType).toEqual(INTERNAL_QUADS);
expect(result.metadata.get('AUXILIARY')?.value).toBe(auxStrategy.getAuxiliaryIdentifier(resourceID).path); expect(result.metadata.get('AUXILIARY')?.value).toBe(auxiliaryStrategy.getAuxiliaryIdentifier(resourceID).path);
}); });
it('will remove containment triples referencing auxiliary resources.', async(): Promise<void> => { it('will remove containment triples referencing auxiliary resources.', async(): Promise<void> => {
@ -371,7 +371,7 @@ describe('A DataAccessorBasedStore', (): void => {
it('errors when trying to create an auxiliary resource with invalid data.', async(): Promise<void> => { it('errors when trying to create an auxiliary resource with invalid data.', async(): Promise<void> => {
const resourceID = { path: `${root}resource.dummy` }; const resourceID = { path: `${root}resource.dummy` };
auxStrategy.validate = jest.fn().mockRejectedValue(new Error('bad data!')); auxiliaryStrategy.validate = jest.fn().mockRejectedValue(new Error('bad data!'));
await expect(store.setRepresentation(resourceID, representation)).rejects.toThrow('bad data!'); await expect(store.setRepresentation(resourceID, representation)).rejects.toThrow('bad data!');
}); });
@ -520,7 +520,7 @@ describe('A DataAccessorBasedStore', (): void => {
storageMetadata.add(RDF.type, PIM.terms.Storage); storageMetadata.add(RDF.type, PIM.terms.Storage);
accessor.data[`${root}container/`] = new BasicRepresentation(representation.data, storageMetadata); accessor.data[`${root}container/`] = new BasicRepresentation(representation.data, storageMetadata);
accessor.data[`${root}container/.dummy`] = representation; accessor.data[`${root}container/.dummy`] = representation;
auxStrategy.isRootRequired = jest.fn().mockReturnValue(true); auxiliaryStrategy.isRootRequired = jest.fn().mockReturnValue(true);
const result = store.deleteResource({ path: `${root}container/.dummy` }); const result = store.deleteResource({ path: `${root}container/.dummy` });
await expect(result).rejects.toThrow(MethodNotAllowedHttpError); await expect(result).rejects.toThrow(MethodNotAllowedHttpError);
await expect(result).rejects.toThrow( await expect(result).rejects.toThrow(
@ -548,7 +548,7 @@ describe('A DataAccessorBasedStore', (): void => {
const storageMetadata = new RepresentationMetadata(representation.metadata); const storageMetadata = new RepresentationMetadata(representation.metadata);
accessor.data[`${root}container/`] = new BasicRepresentation(representation.data, storageMetadata); accessor.data[`${root}container/`] = new BasicRepresentation(representation.data, storageMetadata);
accessor.data[`${root}container/.dummy`] = representation; accessor.data[`${root}container/.dummy`] = representation;
auxStrategy.isRootRequired = jest.fn().mockReturnValue(true); auxiliaryStrategy.isRootRequired = jest.fn().mockReturnValue(true);
await expect(store.deleteResource({ path: `${root}container/.dummy` })).resolves.toEqual([ await expect(store.deleteResource({ path: `${root}container/.dummy` })).resolves.toEqual([
{ path: `${root}container/.dummy` }, { path: `${root}container/.dummy` },
]); ]);
@ -571,7 +571,7 @@ describe('A DataAccessorBasedStore', (): void => {
accessor.data[`${root}resource.dummy`] = representation; accessor.data[`${root}resource.dummy`] = representation;
const deleteFn = accessor.deleteResource; const deleteFn = accessor.deleteResource;
accessor.deleteResource = jest.fn(async(identifier: ResourceIdentifier): Promise<void> => { accessor.deleteResource = jest.fn(async(identifier: ResourceIdentifier): Promise<void> => {
if (auxStrategy.isAuxiliaryIdentifier(identifier)) { if (auxiliaryStrategy.isAuxiliaryIdentifier(identifier)) {
throw new Error('auxiliary error!'); throw new Error('auxiliary error!');
} }
await deleteFn.call(accessor, identifier); await deleteFn.call(accessor, identifier);
@ -594,7 +594,7 @@ describe('A DataAccessorBasedStore', (): void => {
accessor.data[`${root}resource.dummy`] = representation; accessor.data[`${root}resource.dummy`] = representation;
const deleteFn = accessor.deleteResource; const deleteFn = accessor.deleteResource;
accessor.deleteResource = jest.fn(async(identifier: ResourceIdentifier): Promise<void> => { accessor.deleteResource = jest.fn(async(identifier: ResourceIdentifier): Promise<void> => {
if (auxStrategy.isAuxiliaryIdentifier(identifier)) { if (auxiliaryStrategy.isAuxiliaryIdentifier(identifier)) {
throw 'auxiliary error!'; throw 'auxiliary error!';
} }
await deleteFn.call(accessor, identifier); await deleteFn.call(accessor, identifier);

View File

@ -19,7 +19,7 @@ describe('A LockingResourceStore', (): void => {
let store: LockingResourceStore; let store: LockingResourceStore;
let locker: ExpiringReadWriteLocker; let locker: ExpiringReadWriteLocker;
let source: ResourceStore; let source: ResourceStore;
let strategy: AuxiliaryIdentifierStrategy; let auxiliaryStrategy: AuxiliaryIdentifierStrategy;
let order: string[]; let order: string[];
let timeoutTrigger: EventEmitter; let timeoutTrigger: EventEmitter;
@ -70,12 +70,12 @@ describe('A LockingResourceStore', (): void => {
}), }),
}; };
strategy = { auxiliaryStrategy = {
isAuxiliaryIdentifier: jest.fn((id: ResourceIdentifier): any => id.path.endsWith('.dummy')), isAuxiliaryIdentifier: jest.fn((id: ResourceIdentifier): any => id.path.endsWith('.dummy')),
getAssociatedIdentifier: jest.fn((id: ResourceIdentifier): any => ({ path: id.path.slice(0, -6) })), getAssociatedIdentifier: jest.fn((id: ResourceIdentifier): any => ({ path: id.path.slice(0, -6) })),
} as any; } as any;
store = new LockingResourceStore(source, locker, strategy); store = new LockingResourceStore(source, locker, auxiliaryStrategy);
}); });
function registerEventOrder(eventSource: EventEmitter, event: string): void { function registerEventOrder(eventSource: EventEmitter, event: string): void {