Skip to content
Snippets Groups Projects
Commit 4cabf89d authored by Ulf Seltmann's avatar Ulf Seltmann
Browse files

mainly paths are now relative

parent b52b303f
No related merge requests found
Showing with 384 additions and 855 deletions
*
\ No newline at end of file
......@@ -2,4 +2,5 @@
/dist
/public
/data
/site
\ No newline at end of file
/site
/coverage
\ No newline at end of file
FROM library/node:8-alpine
MAINTAINER Ulf Seltmann <ulf.seltmann@uni-leipzig.de>
VOLUME ["/data"]
EXPOSE 3000
ENV npm_config_registry=https://docker.ub.intern.uni-leipzig.de/npm \
data_dir=/data
RUN npm install -g dacap
CMD chown node:node -R ${data_dir} && su node -c dacap
\ No newline at end of file
......@@ -16,7 +16,17 @@ const defaultObjectValueSize = parseInt(process.env.object_value_size) || 80;
const autosaveInterval = parseInt(process.env.autosave_interval) || 60;
const registerName = process.env.register_name || 'api-cache';
const server = new Server(storagePath, proxyPath, proxyUrl, defaultTtl, defaultCheckPeriod, defaultArrayValueSize, defaultObjectValueSize, autosaveInterval, registerName);
const server = new Server({
storagePath: storagePath,
proxyPath: proxyPath,
proxyUrl: proxyUrl,
defaultTtl: defaultTtl,
defaultCheckPeriod: defaultCheckPeriod,
defaultArrayValueSize: defaultArrayValueSize,
defaultObjectValueSize: defaultObjectValueSize,
autosaveInterval: autosaveInterval,
registerName: registerName
});
server.listen(proxyPort, () => {
debug('server up and running');
......
......@@ -20,7 +20,7 @@ services:
- APP_TMP_DIR=/tmp
- DEBUG=*
command:
- npm run inspect
- npm run inspect-watch
hostname: api.ub.uni-leipzig.de
volumes:
......
This diff is collapsed.
{
"name": "dacap",
"version": "1.0.0",
"version": "1.0.1",
"description": "proxies,compresses and caches api-requests",
"main": "bin/dacap",
"bin": {
......@@ -13,26 +13,27 @@
"webpack-watch": "webpack --config webpack.dev.js --watch",
"start": "node bin/dacap",
"tsc": "tsc",
"inspect-watch": "tsc-watch --sourceMap --onSuccess 'node --inspect=0.0.0.0:9229 bin/dacap'",
"inspect-watch": "tsc-watch --onSuccess 'node --inspect=0.0.0.0:9229 bin/dacap'",
"inspect-brk-watch": "tsc-watch --onSuccess 'node --inspect-brk=0.0.0.0:9229 bin/dacap'",
"test": "ts-mocha --recursive test/*",
"test": "mocha",
"ci": "istanbul cover _mocha -- --no-colors --timeout 10000 --reporter mocha-jenkins-reporter",
"build": "rm -rf dist public && tsc --declaration && webpack --config webpack.prod.js"
},
"author": "Ulf Seltmann <ulf.seltmann@uni-leipzig.de>",
"license": "GPL-2.0",
"dependencies": {
"@angular/common": "^4.3.5",
"@angular/compiler": "^4.3.5",
"@angular/core": "^4.3.5",
"@angular/forms": "^4.3.5",
"@angular/http": "^4.3.5",
"@angular/platform-browser": "^4.3.5",
"@angular/platform-browser-dynamic": "^4.3.5",
"@angular/router": "^4.3.5",
"@angular/common": "^4.3.6",
"@angular/compiler": "^4.3.6",
"@angular/core": "^4.3.6",
"@angular/forms": "^4.3.6",
"@angular/http": "^4.3.6",
"@angular/platform-browser": "^4.3.6",
"@angular/platform-browser-dynamic": "^4.3.6",
"@angular/router": "^4.3.6",
"body-parser": "^1.17.2",
"compression": "^1.7.0",
"core-js": "^2.5.0",
"debug": "^3.0.0",
"debug": "^3.0.1",
"express": "^4.15.4",
"node-cache": "^4.1.5",
"q": "^1.5.0",
......@@ -41,37 +42,37 @@
"react-proxy-loader": "^0.3.5",
"request": "^2.81.0",
"rxjs": "^5.4.3",
"zone.js": "^0.8.16"
"zone.js": "^0.8.17"
},
"devDependencies": {
"@types/body-parser": "^1.16.5",
"@types/compression": "0.0.33",
"@types/debug": "0.0.30",
"@types/express": "^4.0.36",
"@types/express": "^4.0.37",
"@types/mocha": "^2.2.42",
"@types/node": "^8.0.20",
"@types/node": "^8.0.25",
"@types/node-cache": "^4.1.0",
"@types/react": "^16.0.2",
"@types/react-dom": "^15.5.3",
"@types/request": "^2.0.1",
"@types/react": "^16.0.5",
"@types/react-dom": "^15.5.4",
"@types/request": "^2.0.3",
"@types/should": "^11.2.0",
"angular2-template-loader": "^0.6.2",
"awesome-typescript-loader": "^3.2.3",
"bootstrap": "^3.3.7",
"css-loader": "^0.28.5",
"eslint": "^4.4.1",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.2",
"html-loader": "^0.5.1",
"html-webpack-plugin": "^2.30.1",
"istanbul": "^0.4.5",
"jquery": "^3.2.1",
"mocha": "^3.5.0",
"mocha-jenkins-reporter": "^0.3.9",
"should": "^11.2.1",
"source-map-loader": "^0.2.1",
"style-loader": "^0.18.2",
"ts-mocha": "^1.0.3",
"tsc-watch": "^1.0.7",
"typescript": "^2.4.2",
"typescript": "^2.5.1",
"webpack": "^3.5.5",
"webpack-merge": "^4.1.0"
}
......
import { Component, Output, EventEmitter } from '@angular/core';
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { CacheService } from './cache.service';
import { Cache } from './cache';
......@@ -10,7 +10,7 @@ import { Cache } from './cache';
export class AddCacheComponent {
name: string;
apiEndPoint: string;
proxyUrl: string;
@Input () proxyUrl: string;
@Output() onAdd: EventEmitter<Cache> = new EventEmitter();
constructor(private cacheService: CacheService) { }
......
......@@ -4,7 +4,7 @@
<p>shows all cache caches available.</p>
</div>
</div>
<add-cache (onAdd)="addCache($event)"></add-cache>
<add-cache [proxyUrl]="config.proxyUrl + config.proxyPath" (onAdd)="addCache($event)"></add-cache>
<div class="container">
<cache *ngFor="let item of caches" [data]="item" (onDelete)="removeCache($event)"></cache>
<cache *ngFor="let item of caches" [data]="item" [proxyUrl]="config.proxyUrl + config.proxyPath" (onDelete)="removeCache($event)"></cache>
</div>
\ No newline at end of file
import { Component, OnInit, enableProdMode } from '@angular/core';
import { Cache } from './cache';
import { Cache, Config } from './cache';
import { CacheService } from './cache.service';
@Component({
......@@ -12,6 +12,7 @@ import { CacheService } from './cache.service';
export class AppComponent implements OnInit {
caches: Cache[];
config: Config = new Config();
constructor(private cacheService: CacheService) { }
......@@ -20,6 +21,10 @@ export class AppComponent implements OnInit {
this.caches = result;
})
this.cacheService.getConfig().then((result) => {
this.config = result;
})
}
addCache(cache: Cache) {
......
......@@ -18,7 +18,7 @@
</div>
<div class="col-md-6">
<label>Proxy-Endpoint:</label>
<pre>{{data.proxyEndPoint}}</pre>
<pre>{{proxyUrl}}{{data.name}}/</pre>
</div>
</div>
<div class="row">
......@@ -31,7 +31,7 @@
</div>
<div class="row">
<div class="col-md-12">
<cache-details [cache]="data.cache" [proxyEndPoint]="data.proxyEndPoint" [name]="data.name"></cache-details>
<cache-details [cache]="data.cache" [proxyEndPoint]="proxyUrl + data.name + '/'" [name]="data.name"></cache-details>
</div>
</div>
</div>
......
......@@ -11,6 +11,7 @@ import { Cache } from './cache';
export class CacheComponent {
@Input() data: Cache;
@Input() proxyUrl: string
@Output() onDelete: EventEmitter<string> = new EventEmitter();
constructor(private cacheService: CacheService, private appComponent: AppComponent) { }
......
import { Component, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Cache } from './cache';
import { CacheDetails } from './cache';
import { CacheDetails, Cache, Config } from './cache';
@Injectable()
export class CacheService {
constructor(private http: HttpClient) { }
getConfig(): Promise<Config> {
return new Promise<Config>((resolve, reject) => {
this.http.get('api/config').subscribe(resolve.bind(this));
});
}
getCaches(): Promise<Cache[]> {
return new Promise<Cache[]>((resolve, reject) => {
this.http.get('/api/list/cache').subscribe(resolve.bind(this));
this.http.get('api/list/cache').subscribe(resolve.bind(this));
});
}
addCache(name: string, params: { apiEndPoint: string, cacheOptions: { [key: string]: string } }): Promise<Cache> {
return new Promise<Cache>((resolve, reject) => {
this.http.post(`/api/add/cache/${name}`, params).subscribe(resolve.bind(this));
this.http.post(`api/add/cache/${name}`, params).subscribe(resolve.bind(this));
})
}
deleteCache(name: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
this.http.get(`/api/delete/cache/${name}`).subscribe(resolve.bind(this));
this.http.get(`api/delete/cache/${name}`).subscribe(resolve.bind(this));
});
}
flushCache(name: string): Promise<Cache> {
return new Promise<Cache>((resolve, reject) => {
this.http.get(`/api/flush/cache/${name}`).subscribe(resolve.bind(this));
this.http.get(`api/flush/cache/${name}`).subscribe(resolve.bind(this));
});
}
deleteValue(name: string, hash: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
this.http.get(`/api/delete/cache/${name}/key/${hash}`).subscribe(resolve.bind(this));
this.http.get(`api/delete/cache/${name}/key/${hash}`).subscribe(resolve.bind(this));
});
}
refreshValue(name: string, hash: string): Promise<CacheDetails> {
return new Promise<CacheDetails>((resolve, reject) => {
this.http.get(`/api/refresh/cache/${name}/key/${hash}`).subscribe(resolve.bind(this));
this.http.get(`api/refresh/cache/${name}/key/${hash}`).subscribe(resolve.bind(this));
});
}
}
\ No newline at end of file
......@@ -33,4 +33,16 @@ export class CacheDetails {
uriPath: string;
contentType: string;
size: number;
}
export class Config {
storagePath: string;
proxyPath: string;
proxyUrl: string;
defaultTtl: number;
defaultCheckPeriod: number;
defaultArrayValueSize: number;
defaultObjectValueSize: number;
autosaveInterval: number;
registerName: string;
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>Angular Tour of Heroes</title>
<title>dacap :: Dynamic And Caching Api Proxy</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
......
......@@ -40,7 +40,6 @@ export interface CacheDetails {
export interface CacheInfo {
name: string,
apiEndPoint: string,
proxyEndPoint: string,
cacheOptions: NodeCache.Options,
cacheStats: NodeCache.Stats,
cache: CacheDetails[],
......@@ -107,17 +106,16 @@ export class Register {
delete this.cacheRegister[name];
}
getInfo = (proxyUrl: string, name?: string): CacheInfo|CacheInfo[] => {
return (name) ? this._getInfo(proxyUrl, name) : Object.keys(this.cacheRegister).map((key): CacheInfo => {
return this._getInfo(proxyUrl, key);
getInfo = (name?: string): CacheInfo|CacheInfo[] => {
return (name) ? this._getInfo(name) : Object.keys(this.cacheRegister).map((key): CacheInfo => {
return this._getInfo(key);
});
}
private _getInfo(proxyUrl: string, name: string): CacheInfo {
private _getInfo(name: string): CacheInfo {
return {
name: name,
apiEndPoint: this.cacheRegister[name].getEndpoint().toString(),
proxyEndPoint: proxyUrl + name + '/',
cacheOptions: this.cacheRegister[name].getCache().options,
cacheStats: this.cacheRegister[name].getCache().getStats(),
cache: <CacheDetails[]>this.cacheRegister[name].getDetails()
......
......@@ -11,23 +11,24 @@ export class Server {
private register: cache.Register;
private expressApp: express.Application;
constructor(private storagePath: string,
private proxyPath: string,
private proxyUrl: string,
private defaultTtl: number,
private defaultCheckPeriod: number,
private defaultArrayValueSize: number,
private defaultObjectValueSize: number,
private autosaveInterval: number,
private registerName: string) {
constructor(private config: {
storagePath: string,
proxyPath: string,
proxyUrl: string,
defaultTtl: number,
defaultCheckPeriod: number,
defaultArrayValueSize: number,
defaultObjectValueSize: number,
autosaveInterval: number,
registerName: string
}) {
this._init();
}
private _init() {
this.register = new cache.Register(this.storagePath, this.registerName);
this.register = new cache.Register(this.config.storagePath, this.config.registerName);
this.register.restore();
setTimeout(this.register.save, this.autosaveInterval * 1000);
setTimeout(this.register.save, this.config.autosaveInterval * 1000);
this.expressApp = express();
this.expressApp.get(/favicon.ico/, (req, res, next) => {
......@@ -37,27 +38,31 @@ export class Server {
this.expressApp.use(compression());
this.expressApp.use(bodyparser.json());
this.expressApp.post('/api/add/cache/:name', (req, res, next) => {
this.expressApp.get('/admin/api/config', (req, res, next) => {
return res.json(this.config);
});
this.expressApp.post('/admin/api/add/cache/:name', (req, res, next) => {
if (!req.body || !req.body.apiEndPoint) return res.status(400).send(`you need to specify at least an url`);
if (this.register.has(req.body.name)) return res.send(`already registered endpoint "${req.params.name}"`);
this.register.add(req.params.name, req.body.apiEndPoint, {
stdTTL: req.body.cacheOptions.ttl || this.defaultTtl,
checkperiod: req.body.cacheOptions.checkPeriod || this.defaultCheckPeriod,
objectValueSize: req.body.cacheOptions.objectValueSize || this.defaultObjectValueSize,
arrayValueSize: req.body.cacheOptions.arrayValueSize || this.defaultArrayValueSize
stdTTL: req.body.cacheOptions.ttl || this.config.defaultTtl,
checkperiod: req.body.cacheOptions.checkPeriod || this.config.defaultCheckPeriod,
objectValueSize: req.body.cacheOptions.objectValueSize || this.config.defaultObjectValueSize,
arrayValueSize: req.body.cacheOptions.arrayValueSize || this.config.defaultArrayValueSize
});
res.json(this.register.getInfo(this.proxyUrl + this.proxyPath, req.params.name));
res.json(this.register.getInfo(req.params.name));
});
this.expressApp.get('/api/list/cache', async (req, res, next) => {
this.expressApp.get('/admin/api/list/cache', async (req, res, next) => {
try {
res.json(this.register.getInfo(this.proxyUrl + this.proxyPath));
res.json(this.register.getInfo());
} catch (err) {
next(err);
}
});
this.expressApp.get('/api/delete/cache/:name', (req, res, next) => {
this.expressApp.get('/admin/api/delete/cache/:name', (req, res, next) => {
try {
this.register.delete(req.params.name);
res.json({});
......@@ -66,17 +71,17 @@ export class Server {
}
})
this.expressApp.get('/api/flush/cache/:name', (req, res, next) => {
this.expressApp.get('/admin/api/flush/cache/:name', (req, res, next) => {
try {
const cache = this.register.get(req.params.name)
cache.flush();
res.json(this.register.getInfo(this.proxyUrl + this.proxyPath, req.params.name));
res.json(this.register.getInfo(req.params.name));
} catch (err) {
next(err);
}
});
this.expressApp.get('/api/delete/cache/:name/key/:hash', (req, res, next) => {
this.expressApp.get('/admin/api/delete/cache/:name/key/:hash', (req, res, next) => {
try {
const cache = this.register.get(req.params.name)
cache.del(req.params.hash);
......@@ -86,7 +91,7 @@ export class Server {
}
})
this.expressApp.get('/api/refresh/cache/:name/key/:hash', async (req, res, next) => {
this.expressApp.get('/admin/api/refresh/cache/:name/key/:hash', async (req, res, next) => {
try {
const cache = this.register.get(req.params.name);
const value = cache.getCache().get(req.params.hash);
......@@ -99,10 +104,10 @@ export class Server {
this.expressApp.use('/admin/', express.static(path.resolve(__dirname, '..', 'public')));
this.expressApp.use(this.proxyPath, cache.Middleware(this.register));
this.expressApp.use(this.config.proxyPath, cache.Middleware(this.register));
}
listen(port: number, cb) {
return this.expressApp.listen(port, cb);
this.expressApp.listen(port, cb);
}
}
\ No newline at end of file
const path = require('path');
const Middleware = require('../dist/cache').Middleware;
const Register = require('../dist/cache').Register;
const Cache = require('../dist/cache').Cache;
describe('Middleware', () => {
it('should be a function', (done) => {
done();
});
})
\ No newline at end of file
import {Register, Cache, Middleware} from '../src/cache';
import * as path from 'path';
import 'should';
describe('register', () => {
it('should create an instance', (done) => {
new Register(path.resolve(__dirname, '..', '.tmp'), 'foobar');
done();
})
});
describe('cache', () => {
it('should create an instance', (done) => {
new Cache();
done();
});
})
\ No newline at end of file
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"noImplicitAny": false,
"outDir": "dist"
"module": "commonjs",
"target": "es6",
"noImplicitAny": false,
"outDir": "dist"
},
"include":[ "src/*"],
"include": ["src/*"],
"exclude": [
"admin"
]
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment