Skip to content
Merged
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
1 change: 0 additions & 1 deletion packages/lambda-tiler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ handler.router.hook('request', (req) => {

handler.router.hook('response', (req, res) => {
req.set('fetchCount', FsaLog.count);
req.set('fetches', FsaLog.requests);
req.set('cacheSize', FsaCache.size);
// Force access-control-allow-origin to everything
res.header('access-control-allow-origin', '*');
Expand Down
27 changes: 7 additions & 20 deletions packages/lambda-tiler/src/routes/__tests__/health.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,17 @@ import assert from 'node:assert';
import { afterEach, before, beforeEach, describe, it } from 'node:test';

import { ConfigProviderMemory } from '@basemaps/config';
import { LogConfig } from '@basemaps/shared';
import { LambdaAlbRequest, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
import { LambdaHttpResponse } from '@linzjs/lambda';
import { VectorTile, VectorTileFeature, VectorTileLayer } from '@mapbox/vector-tile';
import { ALBEventRequestContext, Context } from 'aws-lambda';
import sinon from 'sinon';

import { FakeData } from '../../__tests__/config.data.js';
import { mockRequest } from '../../__tests__/xyz.util.js';
import { ConfigLoader } from '../../util/config.loader.js';
import { getTestBuffer, healthGet, TestFeature, TestTiles, VectorTileProvider } from '../health.js';
import { TileXyzRaster } from '../tile.xyz.raster.js';
import { tileXyzVector } from '../tile.xyz.vector.js';

const ctx: LambdaHttpRequest = new LambdaAlbRequest(
{
requestContext: null as unknown as ALBEventRequestContext,
httpMethod: 'get',
path: '/v1/tiles/health',
body: null,
isBase64Encoded: false,
},
{} as Context,
LogConfig.get(),
);

// Function to create a vector tile with specific properties for testing
function createTestTile(testFeatures: TestFeature[]): VectorTile {
const layers: Record<string, VectorTileLayer> = {};
Expand Down Expand Up @@ -65,14 +52,14 @@ describe('/v1/health', () => {
sandbox.restore();
});

it('Should return bad response', () => {
it('Should return bad response', async () => {
// Given ... a bad get tile response
const BadResponse = new LambdaHttpResponse(500, 'Can not get Tile Set.');
sandbox.stub(TileXyzRaster, 'tile').resolves(BadResponse);
sandbox.stub(tileXyzVector, 'tile').resolves(BadResponse);

// When ...Then ...
assert.rejects(() => healthGet(ctx), BadResponse);
await assert.rejects(() => healthGet(mockRequest('/v1/tiles/health')), BadResponse);
});

const Response1 = new LambdaHttpResponse(200, 'ok');
Expand All @@ -99,20 +86,20 @@ describe('/v1/health', () => {
callbackVectorTile.onCall(1).resolves(testVectorTile2);

// When ...
const res = await healthGet(ctx);
const res = await healthGet(mockRequest('/v1/tiles/health'));

// Then ...
assert.equal(res.status, 200);
assert.equal(res.statusDescription, 'ok');
});

it('Should return mis-match tile response', () => {
it('Should return mis-match tile response', async () => {
// Given ... a bad get tile response for second get tile
const callback = sandbox.stub(TileXyzRaster, 'tile');
callback.onCall(0).resolves(Response2);

// When ... Then ...
const BadResponse = new LambdaHttpResponse(500, 'TileSet does not match.');
assert.rejects(() => healthGet(ctx), BadResponse);
await assert.rejects(() => healthGet(mockRequest('/v1/tiles/health')), BadResponse);
});
});
20 changes: 13 additions & 7 deletions packages/lambda-tiler/src/util/config.loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ export class ConfigLoader {
const cb = await config.ConfigBundle.get('cb_latest');
if (cb == null) return config;

req?.timer.start('config:load');
const configUrl = fsa.toUrl(cb.path);
return CachedConfig.get(configUrl).then((cfg) => {
req?.set('config', configUrl.href);

return CachedConfig.get(fsa.toUrl(cb.path)).then((cfg) => {
req?.timer.end('config:load');
if (cfg == null) throw new LambdaHttpResponse(500, 'Unable to find latest configuration');
if (cfg.assets == null) cfg.assets = cb.assets;
return cfg;
Expand All @@ -44,8 +44,15 @@ export class ConfigLoader {
}

static async load(req: LambdaHttpRequest): Promise<BasemapsConfigProvider> {
req.timer.start('config:load');
const config = await this._load(req);
req.timer.end('config:load');
return config;
}

static async _load(req: LambdaHttpRequest): Promise<BasemapsConfigProvider> {
const rawLocation = req.query.get('config');
if (rawLocation == null) return this.getDefaultConfig();
if (rawLocation == null) return this.getDefaultConfig(req);

const configLocation = isBase58(rawLocation) ? Buffer.from(base58.decode(rawLocation)).toString() : rawLocation;
const configUrl = fsa.toUrl(configLocation);
Expand All @@ -58,10 +65,9 @@ export class ConfigLoader {
throw new LambdaHttpResponse(400, `Bucket: "${configUrl.hostname}" is not a allowed bucket location`);
}

req.set('config', configUrl.href);
req.timer.start('config:load');
return CachedConfig.get(configUrl).then((f) => {
req.timer.end('config:load');
req.set('config', configUrl.href);

if (f == null) throw new LambdaHttpResponse(400, `Invalid config location at ${configLocation}`);
return f;
});
Expand Down
Loading