mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Implement a first draft of the RoutingResourceStore
This commit is contained in:
committed by
Joachim Van Herwegen
parent
dee4eef131
commit
86de805daa
35
src/storage/routing/PathRouterRule.ts
Normal file
35
src/storage/routing/PathRouterRule.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { Representation } from '../../ldp/representation/Representation';
|
||||
import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier';
|
||||
import { NotFoundHttpError } from '../../util/errors/NotFoundHttpError';
|
||||
import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError';
|
||||
import type { ResourceStore } from '../ResourceStore';
|
||||
import type { RouterRule } from './RouterRule';
|
||||
|
||||
// TODO:
|
||||
export class PathRouterRule implements RouterRule {
|
||||
private readonly pathMap: { [path: string]: ResourceStore };
|
||||
|
||||
public constructor(pathMap: { [path: string]: ResourceStore }) {
|
||||
this.pathMap = pathMap;
|
||||
}
|
||||
|
||||
public async getMatchingResourceStore(identifier: ResourceIdentifier, representation?: Representation):
|
||||
Promise<ResourceStore> {
|
||||
const paths = Object.keys(this.pathMap);
|
||||
const matches = paths.filter((path): boolean => identifier.path.includes(path));
|
||||
if (matches.length !== 1) {
|
||||
// Incoming data, need to reject
|
||||
if (representation) {
|
||||
throw new UnsupportedHttpError(
|
||||
`Identifiers need to have exactly 1 of the following in them: [${paths.join(', ')}]`,
|
||||
);
|
||||
|
||||
// Because of the above requirement, we know this will always be a 404 for requests
|
||||
} else {
|
||||
throw new NotFoundHttpError();
|
||||
}
|
||||
}
|
||||
|
||||
return this.pathMap[matches[0]];
|
||||
}
|
||||
}
|
||||
42
src/storage/routing/RdfConvertingRouterRule.ts
Normal file
42
src/storage/routing/RdfConvertingRouterRule.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import type { Representation } from '../../ldp/representation/Representation';
|
||||
import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier';
|
||||
import { INTERNAL_QUADS } from '../../util/ContentTypes';
|
||||
import type { RepresentationConverter } from '../conversion/RepresentationConverter';
|
||||
import type { ResourceStore } from '../ResourceStore';
|
||||
import type { RouterRule } from './RouterRule';
|
||||
|
||||
// TODO:
|
||||
export class RdfConvertingRouterRule implements RouterRule {
|
||||
private readonly rdfStore: ResourceStore;
|
||||
private readonly binaryStore: ResourceStore;
|
||||
private readonly converter: RepresentationConverter;
|
||||
|
||||
public constructor(rdfStore: ResourceStore, binaryStore: ResourceStore, converter: RepresentationConverter) {
|
||||
this.rdfStore = rdfStore;
|
||||
this.binaryStore = binaryStore;
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
public async getMatchingResourceStore(identifier: ResourceIdentifier, representation?: Representation):
|
||||
Promise<ResourceStore> {
|
||||
if (representation) {
|
||||
try {
|
||||
const preferences = { type: [{ value: INTERNAL_QUADS, weight: 1 }]};
|
||||
await this.converter.canHandle({ identifier, representation, preferences });
|
||||
return this.rdfStore;
|
||||
} catch {
|
||||
return this.binaryStore;
|
||||
}
|
||||
} else {
|
||||
// No content-type given so we can only check if one of the stores has data for the identifier
|
||||
// Any of the two stores can be used. Using the binary one here since that one would be faster in current cases.
|
||||
try {
|
||||
const response = await this.binaryStore.getRepresentation(identifier, {});
|
||||
response.data.destroy();
|
||||
return this.binaryStore;
|
||||
} catch {
|
||||
return this.rdfStore;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/storage/routing/RouterRule.ts
Normal file
20
src/storage/routing/RouterRule.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { Representation } from '../../ldp/representation/Representation';
|
||||
import type { ResourceIdentifier } from '../../ldp/representation/ResourceIdentifier';
|
||||
import type { ResourceStore } from '../ResourceStore';
|
||||
|
||||
/**
|
||||
* A RouterRule represents a rule that decides which instance of a
|
||||
* ResourceStore should be used to handle the incoming request.
|
||||
*/
|
||||
export interface RouterRule {
|
||||
|
||||
/**
|
||||
* Find the appropriate ResourceStore to which the request should be routed based on the incoming parameters.
|
||||
* @param identifier - Incoming ResourceIdentifier.
|
||||
* @param representation - Optional incoming Representation.
|
||||
*/
|
||||
getMatchingResourceStore: (
|
||||
identifier: ResourceIdentifier,
|
||||
representation?: Representation,
|
||||
) => Promise<ResourceStore>;
|
||||
}
|
||||
Reference in New Issue
Block a user