From 99f936ff45c4edfefa2d13d6f18c3836cc4d12a2 Mon Sep 17 00:00:00 2001 From: William Welling Date: Fri, 24 Mar 2017 16:15:01 -0500 Subject: [PATCH] Providing global config as an opaque token. --- config/environment.default.js | 2 +- src/app/app.component.ts | 7 +++-- .../data-services/collection-data.effects.ts | 7 +++-- src/app/core/data-services/data.effects.ts | 15 +++++---- .../core/data-services/item-data.effects.ts | 7 +++-- .../dspace-rest-v2/dspace-rest-v2.service.ts | 8 +++-- .../core/url-combiner/rest-url-combiner.ts | 9 +++--- src/config.ts | 31 +++++++++++++++++-- src/platform/modules/browser.module.ts | 11 ++++--- src/platform/modules/node.module.ts | 4 +++ 10 files changed, 74 insertions(+), 27 deletions(-) diff --git a/config/environment.default.js b/config/environment.default.js index 47c4213436..47159c2797 100644 --- a/config/environment.default.js +++ b/config/environment.default.js @@ -13,7 +13,7 @@ module.exports = { }, "cache": { // how long should objects be cached for by default - "msToLive": 15 * 60 * 1000, //15 minutes + "msToLive": 15 * 60 * 1000, //15 minutes }, "universal": { //on the client: start with the state on the server diff --git a/src/app/app.component.ts b/src/app/app.component.ts index a5e6f50579..8586679931 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,6 +1,7 @@ import { Component, ChangeDetectionStrategy, + Inject, ViewEncapsulation, OnDestroy, OnInit, HostListener @@ -9,7 +10,8 @@ import { TranslateService } from "ng2-translate"; import { HostWindowState } from "./shared/host-window.reducer"; import { Store } from "@ngrx/store"; import { HostWindowResizeAction } from "./shared/host-window.actions"; -import { GlobalConfig } from "../config"; + +import { GLOBAL_CONFIG, GlobalConfig, globalConfig } from '../config'; @Component({ changeDetection: ChangeDetectionStrategy.Default, @@ -28,13 +30,14 @@ export class AppComponent implements OnDestroy, OnInit { recipient: 'World' }; - env: string = GlobalConfig.production; + env: string = this.config.production; styles = { color: 'red' }; constructor( + @Inject(GLOBAL_CONFIG) private config: GlobalConfig, private translate: TranslateService, private store: Store ) { diff --git a/src/app/core/data-services/collection-data.effects.ts b/src/app/core/data-services/collection-data.effects.ts index 676d71659c..3d979e2c56 100644 --- a/src/app/core/data-services/collection-data.effects.ts +++ b/src/app/core/data-services/collection-data.effects.ts @@ -1,4 +1,4 @@ -import { Injectable } from "@angular/core"; +import { Inject, Injectable } from "@angular/core"; import { DataEffects } from "./data.effects"; import { Serializer } from "../serializer"; import { Collection } from "../shared/collection.model"; @@ -9,15 +9,18 @@ import { Actions, Effect } from "@ngrx/effects"; import { RequestCacheFindAllAction, RequestCacheFindByIDAction } from "../cache/request-cache.actions"; import { CollectionDataService } from "./collection-data.service"; +import { GLOBAL_CONFIG, GlobalConfig, globalConfig } from '../../../config'; + @Injectable() export class CollectionDataEffects extends DataEffects { constructor( + @Inject(GLOBAL_CONFIG) config: GlobalConfig, actions$: Actions, restApi: DSpaceRESTv2Service, cache: ObjectCacheService, dataService: CollectionDataService ) { - super(actions$, restApi, cache, dataService); + super(config, actions$, restApi, cache, dataService); } protected getFindAllEndpoint(action: RequestCacheFindAllAction): string { diff --git a/src/app/core/data-services/data.effects.ts b/src/app/core/data-services/data.effects.ts index a68f7f2899..162d588981 100644 --- a/src/app/core/data-services/data.effects.ts +++ b/src/app/core/data-services/data.effects.ts @@ -1,9 +1,9 @@ +import { Inject } from "@angular/core"; import { Actions } from "@ngrx/effects"; import { Observable } from "rxjs"; import { DSpaceRESTV2Response } from "../dspace-rest-v2/dspace-rest-v2-response.model"; import { DSpaceRESTv2Service } from "../dspace-rest-v2/dspace-rest-v2.service"; import { ObjectCacheService } from "../cache/object-cache.service"; -import { GlobalConfig } from "../../../config"; import { CacheableObject } from "../cache/object-cache.reducer"; import { Serializer } from "../serializer"; import { @@ -13,17 +13,20 @@ import { import { DataService } from "./data.service"; import { hasNoValue } from "../../shared/empty.util"; +import { GlobalConfig } from '../../../config'; + export abstract class DataEffects { protected abstract getFindAllEndpoint(action: RequestCacheFindAllAction): string; protected abstract getFindByIdEndpoint(action: RequestCacheFindByIDAction): string; protected abstract getSerializer(): Serializer; constructor( + private config: GlobalConfig, private actions$: Actions, private restApi: DSpaceRESTv2Service, private objectCache: ObjectCacheService, private dataService: DataService - ) {} + ) { } // TODO, results of a findall aren't retrieved from cache yet protected findAll = this.actions$ @@ -38,11 +41,11 @@ export abstract class DataEffects { if (hasNoValue(t) || hasNoValue(t.uuid)) { throw new Error('The server returned an invalid object'); } - this.objectCache.add(t, GlobalConfig.cache.msToLive); + this.objectCache.add(t, this.config.cache.msToLive); }); }) .map((ts: Array) => ts.map(t => t.uuid)) - .map((ids: Array) => new RequestCacheSuccessAction(action.payload.key, ids, new Date().getTime(), GlobalConfig.cache.msToLive)) + .map((ids: Array) => new RequestCacheSuccessAction(action.payload.key, ids, new Date().getTime(), this.config.cache.msToLive)) .catch((error: Error) => Observable.of(new RequestCacheErrorAction(action.payload.key, error.message))); }); @@ -56,9 +59,9 @@ export abstract class DataEffects { if (hasNoValue(t) || hasNoValue(t.uuid)) { throw new Error('The server returned an invalid object'); } - this.objectCache.add(t, GlobalConfig.cache.msToLive); + this.objectCache.add(t, this.config.cache.msToLive); }) - .map((t: T) => new RequestCacheSuccessAction(action.payload.key, [t.uuid], new Date().getTime(), GlobalConfig.cache.msToLive)) + .map((t: T) => new RequestCacheSuccessAction(action.payload.key, [t.uuid], new Date().getTime(), this.config.cache.msToLive)) .catch((error: Error) => Observable.of(new RequestCacheErrorAction(action.payload.key, error.message))); }); diff --git a/src/app/core/data-services/item-data.effects.ts b/src/app/core/data-services/item-data.effects.ts index d6bce6e8da..d3d9f5ebfc 100644 --- a/src/app/core/data-services/item-data.effects.ts +++ b/src/app/core/data-services/item-data.effects.ts @@ -1,4 +1,4 @@ -import { Injectable } from "@angular/core"; +import { Inject, Injectable } from "@angular/core"; import { DataEffects } from "./data.effects"; import { Serializer } from "../serializer"; import { Item } from "../shared/item.model"; @@ -9,15 +9,18 @@ import { Actions, Effect } from "@ngrx/effects"; import { RequestCacheFindAllAction, RequestCacheFindByIDAction } from "../cache/request-cache.actions"; import { ItemDataService } from "./item-data.service"; +import { GLOBAL_CONFIG, GlobalConfig, globalConfig } from '../../../config'; + @Injectable() export class ItemDataEffects extends DataEffects { constructor( + @Inject(GLOBAL_CONFIG) config: GlobalConfig, actions$: Actions, restApi: DSpaceRESTv2Service, cache: ObjectCacheService, dataService: ItemDataService ) { - super(actions$, restApi, cache, dataService); + super(config, actions$, restApi, cache, dataService); } protected getFindAllEndpoint(action: RequestCacheFindAllAction): string { diff --git a/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts b/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts index e4261ba9f2..97c7b4a782 100644 --- a/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts +++ b/src/app/core/dspace-rest-v2/dspace-rest-v2.service.ts @@ -1,14 +1,16 @@ -import { Injectable } from '@angular/core'; +import { Inject, Injectable } from '@angular/core'; import { Http, RequestOptionsArgs } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import { RESTURLCombiner } from "../url-combiner/rest-url-combiner"; +import { GLOBAL_CONFIG, GlobalConfig, globalConfig } from '../../../config'; + /** * Service to access DSpace's REST API */ @Injectable() export class DSpaceRESTv2Service { - constructor(public _http: Http) { + constructor(private http: Http, @Inject(GLOBAL_CONFIG) private config: GlobalConfig) { } @@ -23,7 +25,7 @@ export class DSpaceRESTv2Service { * An Observablse containing the response from the server */ get(relativeURL: string, options?: RequestOptionsArgs): Observable { - return this._http.get(new RESTURLCombiner(relativeURL).toString(), options) + return this.http.get(new RESTURLCombiner(this.config, relativeURL).toString(), options) .map(res => res.json()) .catch(err => { console.log('Error: ', err); diff --git a/src/app/core/url-combiner/rest-url-combiner.ts b/src/app/core/url-combiner/rest-url-combiner.ts index c1da441631..16775af6b6 100644 --- a/src/app/core/url-combiner/rest-url-combiner.ts +++ b/src/app/core/url-combiner/rest-url-combiner.ts @@ -1,5 +1,6 @@ import { URLCombiner } from "./url-combiner"; -import { GlobalConfig } from "../../../config"; + +import { GlobalConfig } from '../../../config'; /** * Combines a variable number of strings representing parts @@ -7,8 +8,8 @@ import { GlobalConfig } from "../../../config"; * * TODO write tests once GlobalConfig becomes injectable */ -export class RESTURLCombiner extends URLCombiner{ - constructor(...parts:Array) { - super(GlobalConfig.rest.baseURL, GlobalConfig.rest.nameSpace, ...parts); +export class RESTURLCombiner extends URLCombiner { + constructor(config: GlobalConfig, ...parts: Array) { + super(config.rest.baseURL, config.rest.nameSpace, ...parts); } } diff --git a/src/config.ts b/src/config.ts index e3b0781324..7ae16bdf11 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,8 +1,10 @@ // Look in ./config folder for config +import { OpaqueToken } from '@angular/core'; -const path = require('path'); +import path from 'path'; let configContext = require.context("../config", false, /js$/); + let EnvConfig: any = {}; let EnvConfigFile: string; let DefaultConfig: any = {}; @@ -29,6 +31,29 @@ try { EnvConfig = {}; } -const GlobalConfig = Object.assign(DefaultConfig, EnvConfig); +const GLOBAL_CONFIG = new OpaqueToken('config'); -export {GlobalConfig} +interface GlobalConfig { + "production": string, + "rest": { + "nameSpace": string, + "baseURL": string + }, + "ui": { + "nameSpace": string, + "baseURL": string + }, + "cache": { + "msToLive": number, + }, + "universal": { + "shouldRehydrate": boolean + } +} + +const globalConfig = { + provide: GLOBAL_CONFIG, + useValue: Object.assign(DefaultConfig, EnvConfig) +}; + +export { GLOBAL_CONFIG, GlobalConfig, globalConfig} diff --git a/src/platform/modules/browser.module.ts b/src/platform/modules/browser.module.ts index 7edd9549ab..33b1df9410 100755 --- a/src/platform/modules/browser.module.ts +++ b/src/platform/modules/browser.module.ts @@ -1,4 +1,4 @@ -import { NgModule } from '@angular/core'; +import { Inject, NgModule } from '@angular/core'; import { Http } from '@angular/http'; import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; @@ -22,7 +22,8 @@ import { effects } from '../../app/app.effects'; // see https://github.com/angular/angular/pull/12322 import { Meta } from '../angular2-meta'; import { RehydrateStoreAction } from "../../app/store.actions"; -import { GlobalConfig } from "../../config"; + +import { GLOBAL_CONFIG, GlobalConfig, globalConfig } from '../../config'; // import * as LRU from 'modern-lru'; @@ -82,17 +83,19 @@ export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE'; Meta, + globalConfig + // { provide: AUTO_PREBOOT, useValue: false } // turn off auto preboot complete ] }) export class MainModule { - constructor(public store: Store) { + constructor(public store: Store, @Inject(GLOBAL_CONFIG) private config: GlobalConfig, ) { // TODO(gdi2290): refactor into a lifecycle hook this.doRehydrate(); } doRehydrate() { - if (GlobalConfig.universal.shouldRehydrate) { + if (this.config.universal.shouldRehydrate) { let defaultValue = {}; let serverCache = this._getCacheValue(NGRX_CACHE_KEY, defaultValue); this.store.dispatch(new RehydrateStoreAction(serverCache)); diff --git a/src/platform/modules/node.module.ts b/src/platform/modules/node.module.ts index 008f8bc3ce..073d5c1c66 100755 --- a/src/platform/modules/node.module.ts +++ b/src/platform/modules/node.module.ts @@ -21,6 +21,8 @@ import { effects } from '../../app/app.effects'; // see https://github.com/angular/angular/pull/12322 import { Meta } from '../angular2-meta'; +import { globalConfig } from '../../config'; + export function createTranslateLoader(http: Http) { return new TranslateStaticLoader(http, './assets/i18n', '.json'); } @@ -70,6 +72,8 @@ export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE'; { provide: 'LRU', useFactory: getLRU, deps: [] }, Meta, + + globalConfig ] }) export class MainModule {