add georouter creator injection
This commit is contained in:
parent
4c3195390e
commit
ca03d1769a
|
@ -10,6 +10,7 @@ import { Match } from '../../domain/entities/match';
|
|||
import { MatchQuery } from '../../queries/match.query';
|
||||
import { MatchPresenter } from '../secondaries/match.presenter';
|
||||
import { DefaultParamsProvider } from '../secondaries/default-params.provider';
|
||||
import { GeorouterCreator } from '../secondaries/georouter-creator';
|
||||
|
||||
@UsePipes(
|
||||
new RpcValidationPipe({
|
||||
|
@ -23,13 +24,18 @@ export class MatcherController {
|
|||
private readonly _queryBus: QueryBus,
|
||||
private readonly _defaultParamsProvider: DefaultParamsProvider,
|
||||
@InjectMapper() private readonly _mapper: Mapper,
|
||||
private readonly _georouterCreator: GeorouterCreator,
|
||||
) {}
|
||||
|
||||
@GrpcMethod('MatcherService', 'Match')
|
||||
async match(data: MatchRequest): Promise<ICollection<Match>> {
|
||||
try {
|
||||
const matchCollection = await this._queryBus.execute(
|
||||
new MatchQuery(data, this._defaultParamsProvider.getParams()),
|
||||
new MatchQuery(
|
||||
data,
|
||||
this._defaultParamsProvider.getParams(),
|
||||
this._georouterCreator,
|
||||
),
|
||||
);
|
||||
return Promise.resolve({
|
||||
data: matchCollection.data.map((match: Match) =>
|
||||
|
|
|
@ -25,8 +25,8 @@ message MatchRequest {
|
|||
int32 proportion = 16;
|
||||
bool useAzimuth = 17;
|
||||
int32 azimuthMargin = 18;
|
||||
int32 maxDetourDistanceRatio = 19;
|
||||
int32 maxDetourDurationRatio = 20;
|
||||
float maxDetourDistanceRatio = 19;
|
||||
float maxDetourDurationRatio = 20;
|
||||
repeated int32 exclusions = 21;
|
||||
int32 identifier = 22;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { Georouter } from '../../domain/interfaces/georouter.interface';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ICreateGeorouter } from '../../domain/interfaces/georouter-creator.interface';
|
||||
import { IGeorouter } from '../../domain/interfaces/georouter.interface';
|
||||
import { GraphhopperGeorouter } from './graphhopper-georouter';
|
||||
|
||||
export class GeorouterCreator {
|
||||
create(type: string, url: string): Georouter {
|
||||
@Injectable()
|
||||
export class GeorouterCreator implements ICreateGeorouter {
|
||||
create(type: string, url: string): IGeorouter {
|
||||
switch (type) {
|
||||
case 'graphhopper':
|
||||
return new GraphhopperGeorouter(url);
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
import { Route } from '../../domain/entities/route';
|
||||
import { Georouter } from '../../domain/interfaces/georouter.interface';
|
||||
import { IGeorouter } from '../../domain/interfaces/georouter.interface';
|
||||
import { GeorouterSettings } from '../../domain/types/georouter-settings.type';
|
||||
|
||||
export class GraphhopperGeorouter implements Georouter {
|
||||
export class GraphhopperGeorouter implements IGeorouter {
|
||||
_url: string;
|
||||
|
||||
constructor(url: string) {
|
||||
this._url = url + '/route?';
|
||||
}
|
||||
|
||||
route(
|
||||
routesRequested: [],
|
||||
withPoints: boolean,
|
||||
withTime: boolean,
|
||||
withDistance: boolean,
|
||||
): Route[] {
|
||||
route(routesRequested: [], settings: GeorouterSettings): Route[] {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ import { IRequestAlgorithmSettings } from '../interfaces/algorithm-settings-requ
|
|||
import { DefaultAlgorithmSettings } from '../types/default-algorithm-settings.type';
|
||||
import { Algorithm } from '../types/algorithm.enum';
|
||||
import { TimingFrequency } from '../types/timing';
|
||||
import { ICreateGeorouter } from '../interfaces/georouter-creator.interface';
|
||||
import { IGeorouter } from '../interfaces/georouter.interface';
|
||||
|
||||
export class AlgorithmSettings {
|
||||
_algorithmSettingsRequest: IRequestAlgorithmSettings;
|
||||
|
@ -15,13 +17,13 @@ export class AlgorithmSettings {
|
|||
azimuthMargin: number;
|
||||
maxDetourDurationRatio: number;
|
||||
maxDetourDistanceRatio: number;
|
||||
georouterType: string;
|
||||
georouterUrl: string;
|
||||
georouter: IGeorouter;
|
||||
|
||||
constructor(
|
||||
algorithmSettingsRequest: IRequestAlgorithmSettings,
|
||||
defaultAlgorithmSettings: DefaultAlgorithmSettings,
|
||||
frequency: TimingFrequency,
|
||||
georouterCreator: ICreateGeorouter,
|
||||
) {
|
||||
this._algorithmSettingsRequest = algorithmSettingsRequest;
|
||||
this.algorithm =
|
||||
|
@ -49,8 +51,10 @@ export class AlgorithmSettings {
|
|||
this.maxDetourDurationRatio =
|
||||
algorithmSettingsRequest.maxDetourDurationRatio ??
|
||||
defaultAlgorithmSettings.maxDetourDurationRatio;
|
||||
this.georouterType = defaultAlgorithmSettings.georouterType;
|
||||
this.georouterUrl = defaultAlgorithmSettings.georouterUrl;
|
||||
this.georouter = georouterCreator.create(
|
||||
defaultAlgorithmSettings.georouterType,
|
||||
defaultAlgorithmSettings.georouterUrl,
|
||||
);
|
||||
if (this._strict) {
|
||||
this.restrict = frequency;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import { IGeorouter } from './georouter.interface';
|
||||
|
||||
export interface ICreateGeorouter {
|
||||
create(type: string, url: string): IGeorouter;
|
||||
}
|
|
@ -1,10 +1,6 @@
|
|||
import { Route } from '../entities/route';
|
||||
import { GeorouterSettings } from '../types/georouter-settings.type';
|
||||
|
||||
export interface Georouter {
|
||||
route(
|
||||
routesRequested: [],
|
||||
withPoints: boolean,
|
||||
withTime: boolean,
|
||||
withDistance: boolean,
|
||||
): Array<Route>;
|
||||
export interface IGeorouter {
|
||||
route(routesRequested: [], settings: GeorouterSettings): Array<Route>;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
export type GeorouterSettings = {
|
||||
withPoints: boolean;
|
||||
withTime: boolean;
|
||||
withDistance: boolean;
|
||||
};
|
|
@ -12,6 +12,7 @@ import { CacheModule } from '@nestjs/cache-manager';
|
|||
import { RedisClientOptions } from '@liaoliaots/nestjs-redis';
|
||||
import { redisStore } from 'cache-manager-ioredis-yet';
|
||||
import { DefaultParamsProvider } from './adapters/secondaries/default-params.provider';
|
||||
import { GeorouterCreator } from './adapters/secondaries/georouter-creator';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
|
@ -51,6 +52,7 @@ import { DefaultParamsProvider } from './adapters/secondaries/default-params.pro
|
|||
Messager,
|
||||
DefaultParamsProvider,
|
||||
MatchUseCase,
|
||||
GeorouterCreator,
|
||||
],
|
||||
exports: [],
|
||||
})
|
||||
|
|
|
@ -6,10 +6,13 @@ import { Role } from '../domain/types/role.enum';
|
|||
import { AlgorithmSettings } from '../domain/entities/algorithm-settings';
|
||||
import { Time } from '../domain/entities/time';
|
||||
import { IDefaultParams } from '../domain/types/default-params.type';
|
||||
import { IGeorouter } from '../domain/interfaces/georouter.interface';
|
||||
import { ICreateGeorouter } from '../domain/interfaces/georouter-creator.interface';
|
||||
|
||||
export class MatchQuery {
|
||||
private readonly _matchRequest: MatchRequest;
|
||||
private readonly _defaultParams: IDefaultParams;
|
||||
private readonly _georouterCreator: ICreateGeorouter;
|
||||
person: Person;
|
||||
roles: Array<Role>;
|
||||
time: Time;
|
||||
|
@ -17,10 +20,16 @@ export class MatchQuery {
|
|||
exclusions: Array<number>;
|
||||
requirement: Requirement;
|
||||
algorithmSettings: AlgorithmSettings;
|
||||
georouter: IGeorouter;
|
||||
|
||||
constructor(matchRequest: MatchRequest, defaultParams: IDefaultParams) {
|
||||
constructor(
|
||||
matchRequest: MatchRequest,
|
||||
defaultParams: IDefaultParams,
|
||||
georouterCreator: ICreateGeorouter,
|
||||
) {
|
||||
this._matchRequest = matchRequest;
|
||||
this._defaultParams = defaultParams;
|
||||
this._georouterCreator = georouterCreator;
|
||||
this._setPerson();
|
||||
this._setRoles();
|
||||
this._setTime();
|
||||
|
@ -75,6 +84,7 @@ export class MatchQuery {
|
|||
this._matchRequest,
|
||||
this._defaultParams.DEFAULT_ALGORITHM_SETTINGS,
|
||||
this.time.frequency,
|
||||
this._georouterCreator,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,12 @@ describe('Graphhopper Georouter', () => {
|
|||
const graphhopperGeorouter: GraphhopperGeorouter = new GraphhopperGeorouter(
|
||||
'http://localhost',
|
||||
);
|
||||
expect(() => graphhopperGeorouter.route([], false, false, false)).toThrow();
|
||||
expect(() =>
|
||||
graphhopperGeorouter.route([], {
|
||||
withDistance: false,
|
||||
withPoints: false,
|
||||
withTime: false,
|
||||
}),
|
||||
).toThrow();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,6 +26,10 @@ const defaultParams: IDefaultParams = {
|
|||
},
|
||||
};
|
||||
|
||||
const mockGeorouterCreator = {
|
||||
create: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
describe('Match query', () => {
|
||||
it('should be defined', () => {
|
||||
const matchRequest: MatchRequest = new MatchRequest();
|
||||
|
@ -40,7 +44,11 @@ describe('Match query', () => {
|
|||
lon: 3.045432,
|
||||
},
|
||||
];
|
||||
const matchQuery: MatchQuery = new MatchQuery(matchRequest, defaultParams);
|
||||
const matchQuery: MatchQuery = new MatchQuery(
|
||||
matchRequest,
|
||||
defaultParams,
|
||||
mockGeorouterCreator,
|
||||
);
|
||||
expect(matchQuery).toBeDefined();
|
||||
});
|
||||
|
||||
|
@ -59,7 +67,11 @@ describe('Match query', () => {
|
|||
];
|
||||
matchRequest.identifier = 125;
|
||||
matchRequest.exclusions = [126, 127, 128];
|
||||
const matchQuery: MatchQuery = new MatchQuery(matchRequest, defaultParams);
|
||||
const matchQuery: MatchQuery = new MatchQuery(
|
||||
matchRequest,
|
||||
defaultParams,
|
||||
mockGeorouterCreator,
|
||||
);
|
||||
expect(matchQuery.exclusions.length).toBe(4);
|
||||
});
|
||||
|
||||
|
@ -77,7 +89,11 @@ describe('Match query', () => {
|
|||
},
|
||||
];
|
||||
matchRequest.driver = true;
|
||||
const matchQuery: MatchQuery = new MatchQuery(matchRequest, defaultParams);
|
||||
const matchQuery: MatchQuery = new MatchQuery(
|
||||
matchRequest,
|
||||
defaultParams,
|
||||
mockGeorouterCreator,
|
||||
);
|
||||
expect(matchQuery.roles).toEqual([Role.DRIVER]);
|
||||
});
|
||||
|
||||
|
@ -95,7 +111,11 @@ describe('Match query', () => {
|
|||
},
|
||||
];
|
||||
matchRequest.passenger = true;
|
||||
const matchQuery: MatchQuery = new MatchQuery(matchRequest, defaultParams);
|
||||
const matchQuery: MatchQuery = new MatchQuery(
|
||||
matchRequest,
|
||||
defaultParams,
|
||||
mockGeorouterCreator,
|
||||
);
|
||||
expect(matchQuery.roles).toEqual([Role.PASSENGER]);
|
||||
});
|
||||
|
||||
|
@ -114,7 +134,11 @@ describe('Match query', () => {
|
|||
];
|
||||
matchRequest.passenger = true;
|
||||
matchRequest.driver = true;
|
||||
const matchQuery: MatchQuery = new MatchQuery(matchRequest, defaultParams);
|
||||
const matchQuery: MatchQuery = new MatchQuery(
|
||||
matchRequest,
|
||||
defaultParams,
|
||||
mockGeorouterCreator,
|
||||
);
|
||||
expect(matchQuery.roles.length).toBe(2);
|
||||
expect(matchQuery.roles).toContain(Role.PASSENGER);
|
||||
expect(matchQuery.roles).toContain(Role.DRIVER);
|
||||
|
@ -135,7 +159,11 @@ describe('Match query', () => {
|
|||
];
|
||||
matchRequest.seatsDriver = 1;
|
||||
matchRequest.seatsPassenger = 2;
|
||||
const matchQuery: MatchQuery = new MatchQuery(matchRequest, defaultParams);
|
||||
const matchQuery: MatchQuery = new MatchQuery(
|
||||
matchRequest,
|
||||
defaultParams,
|
||||
mockGeorouterCreator,
|
||||
);
|
||||
expect(matchQuery.requirement.seatsDriver).toBe(1);
|
||||
expect(matchQuery.requirement.seatsPassenger).toBe(2);
|
||||
});
|
||||
|
@ -162,7 +190,11 @@ describe('Match query', () => {
|
|||
matchRequest.remoteness = 20000;
|
||||
matchRequest.maxDetourDistanceRatio = 0.41;
|
||||
matchRequest.maxDetourDurationRatio = 0.42;
|
||||
const matchQuery: MatchQuery = new MatchQuery(matchRequest, defaultParams);
|
||||
const matchQuery: MatchQuery = new MatchQuery(
|
||||
matchRequest,
|
||||
defaultParams,
|
||||
mockGeorouterCreator,
|
||||
);
|
||||
expect(matchQuery.algorithmSettings.algorithm).toBe(Algorithm.CLASSIC);
|
||||
expect(matchQuery.algorithmSettings.restrict).toBe(
|
||||
TimingFrequency.FREQUENCY_PUNCTUAL,
|
||||
|
|
|
@ -15,6 +15,10 @@ const mockMessager = {
|
|||
publish: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
const mockGeorouterCreator = {
|
||||
create: jest.fn().mockImplementation(),
|
||||
};
|
||||
|
||||
const defaultParams: IDefaultParams = {
|
||||
DEFAULT_IDENTIFIER: 0,
|
||||
MARGIN_DURATION: 900,
|
||||
|
@ -77,7 +81,7 @@ describe('MatchUseCase', () => {
|
|||
];
|
||||
matchRequest.departure = '2023-04-01 12:23:00';
|
||||
const matches = await matchUseCase.execute(
|
||||
new MatchQuery(matchRequest, defaultParams),
|
||||
new MatchQuery(matchRequest, defaultParams, mockGeorouterCreator),
|
||||
);
|
||||
expect(matches.total).toBe(1);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue