mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 11:33:04 +00:00
move the correlation id to the ngrx store
This commit is contained in:

committed by
Yura Bondarenko

parent
ba268d4f28
commit
2fe5587e02
@@ -156,21 +156,6 @@ const PROVIDERS = [
|
|||||||
useClass: LogInterceptor,
|
useClass: LogInterceptor,
|
||||||
multi: true
|
multi: true
|
||||||
},
|
},
|
||||||
// insert the unique id of the user that is using the application utilizing cookies
|
|
||||||
{
|
|
||||||
provide: APP_INITIALIZER,
|
|
||||||
useFactory: (cookieService: CookieService, uuidService: UUIDService) => {
|
|
||||||
const correlationId = cookieService.get('CORRELATION-ID');
|
|
||||||
|
|
||||||
// Check if cookie exists, if don't, set it with unique id
|
|
||||||
if (!correlationId) {
|
|
||||||
cookieService.set('CORRELATION-ID', uuidService.generate());
|
|
||||||
}
|
|
||||||
return () => true;
|
|
||||||
},
|
|
||||||
multi: true,
|
|
||||||
deps: [CookieService, UUIDService]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
provide: DYNAMIC_ERROR_MESSAGES_MATCHER,
|
provide: DYNAMIC_ERROR_MESSAGES_MATCHER,
|
||||||
useValue: ValidateEmailErrorStateMatcher
|
useValue: ValidateEmailErrorStateMatcher
|
||||||
|
@@ -49,6 +49,7 @@ import {
|
|||||||
import { sidebarReducer, SidebarState } from './shared/sidebar/sidebar.reducer';
|
import { sidebarReducer, SidebarState } from './shared/sidebar/sidebar.reducer';
|
||||||
import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer';
|
import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer';
|
||||||
import { ThemeState, themeReducer } from './shared/theme-support/theme.reducer';
|
import { ThemeState, themeReducer } from './shared/theme-support/theme.reducer';
|
||||||
|
import { correlationIdReducer } from './correlation-id/correlation-id.reducer';
|
||||||
|
|
||||||
export interface AppState {
|
export interface AppState {
|
||||||
router: fromRouter.RouterReducerState;
|
router: fromRouter.RouterReducerState;
|
||||||
@@ -69,6 +70,7 @@ export interface AppState {
|
|||||||
communityList: CommunityListState;
|
communityList: CommunityListState;
|
||||||
epeopleRegistry: EPeopleRegistryState;
|
epeopleRegistry: EPeopleRegistryState;
|
||||||
groupRegistry: GroupRegistryState;
|
groupRegistry: GroupRegistryState;
|
||||||
|
correlationId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const appReducers: ActionReducerMap<AppState> = {
|
export const appReducers: ActionReducerMap<AppState> = {
|
||||||
@@ -90,6 +92,7 @@ export const appReducers: ActionReducerMap<AppState> = {
|
|||||||
communityList: CommunityListReducer,
|
communityList: CommunityListReducer,
|
||||||
epeopleRegistry: ePeopleRegistryReducer,
|
epeopleRegistry: ePeopleRegistryReducer,
|
||||||
groupRegistry: groupRegistryReducer,
|
groupRegistry: groupRegistryReducer,
|
||||||
|
correlationId: correlationIdReducer
|
||||||
};
|
};
|
||||||
|
|
||||||
export const routerStateSelector = (state: AppState) => state.router;
|
export const routerStateSelector = (state: AppState) => state.router;
|
||||||
|
@@ -3,9 +3,8 @@ import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/c
|
|||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
import { CookieService } from '../services/cookie.service';
|
|
||||||
import { hasValue } from '../../shared/empty.util';
|
import { hasValue } from '../../shared/empty.util';
|
||||||
|
import { CorrelationIdService } from '../../correlation-id/correlation-id.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log Interceptor intercepting Http Requests & Responses to
|
* Log Interceptor intercepting Http Requests & Responses to
|
||||||
@@ -15,12 +14,12 @@ import { hasValue } from '../../shared/empty.util';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class LogInterceptor implements HttpInterceptor {
|
export class LogInterceptor implements HttpInterceptor {
|
||||||
|
|
||||||
constructor(private cookieService: CookieService, private router: Router) {}
|
constructor(private cidService: CorrelationIdService, private router: Router) {}
|
||||||
|
|
||||||
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
|
|
||||||
// Get Unique id of the user from the cookies
|
// Get the correlation id for the user from the store
|
||||||
const correlationId = this.cookieService.get('CORRELATION-ID');
|
const correlationId = this.cidService.getCorrelationId();
|
||||||
|
|
||||||
// Add headers from the intercepted request
|
// Add headers from the intercepted request
|
||||||
let headers = request.headers;
|
let headers = request.headers;
|
||||||
|
15
src/app/correlation-id/correlation-id.actions.ts
Normal file
15
src/app/correlation-id/correlation-id.actions.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { type } from '../shared/ngrx/type';
|
||||||
|
import { Action } from '@ngrx/store';
|
||||||
|
|
||||||
|
export const CorrelationIDActionTypes = {
|
||||||
|
SET: type('dspace/core/correlationId/SET')
|
||||||
|
};
|
||||||
|
|
||||||
|
export class SetCorrelationIdAction implements Action {
|
||||||
|
type = CorrelationIDActionTypes.SET;
|
||||||
|
|
||||||
|
constructor(public payload: string) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CorrelationIdAction = SetCorrelationIdAction;
|
21
src/app/correlation-id/correlation-id.reducer.ts
Normal file
21
src/app/correlation-id/correlation-id.reducer.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import {
|
||||||
|
CorrelationIdAction,
|
||||||
|
CorrelationIDActionTypes,
|
||||||
|
SetCorrelationIdAction
|
||||||
|
} from './correlation-id.actions';
|
||||||
|
import { AppState } from '../app.reducer';
|
||||||
|
|
||||||
|
const initialState = null;
|
||||||
|
|
||||||
|
export const correlationIdSelector = (state: AppState) => state.correlationId;
|
||||||
|
|
||||||
|
export const correlationIdReducer = (state = initialState, action: CorrelationIdAction): string => {
|
||||||
|
switch (action.type) {
|
||||||
|
case CorrelationIDActionTypes.SET: {
|
||||||
|
return (action as SetCorrelationIdAction).payload;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
64
src/app/correlation-id/correlation-id.service.ts
Normal file
64
src/app/correlation-id/correlation-id.service.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { CookieService } from '../core/services/cookie.service';
|
||||||
|
import { UUIDService } from '../core/shared/uuid.service';
|
||||||
|
import { Store, select } from '@ngrx/store';
|
||||||
|
import { AppState } from '../app.reducer';
|
||||||
|
import { isEmpty } from '../shared/empty.util';
|
||||||
|
import { correlationIdSelector } from './correlation-id.reducer';
|
||||||
|
import { take } from 'rxjs/operators';
|
||||||
|
import { SetCorrelationIdAction } from './correlation-id.actions';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service to manage the correlation id, an id used to give context to server side logs
|
||||||
|
*/
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class CorrelationIdService {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected cookieService: CookieService,
|
||||||
|
protected uuidService: UUIDService,
|
||||||
|
protected store: Store<AppState>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the correlation id based on the cookie or the ngrx store
|
||||||
|
*/
|
||||||
|
initCorrelationId(): void {
|
||||||
|
// first see of there's a cookie with a correlation-id
|
||||||
|
let correlationId = this.cookieService.get('CORRELATION-ID');
|
||||||
|
|
||||||
|
// if there isn't see if there's an ID in the store
|
||||||
|
if (isEmpty(correlationId)) {
|
||||||
|
correlationId = this.getCorrelationId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no id was found, create a new id
|
||||||
|
if (isEmpty(correlationId)) {
|
||||||
|
correlationId = this.uuidService.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the correct id both in the store and as a cookie to ensure they're in sync
|
||||||
|
this.store.dispatch(new SetCorrelationIdAction(correlationId));
|
||||||
|
this.cookieService.set('CORRELATION-ID', correlationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the correlation id from the store
|
||||||
|
*/
|
||||||
|
getCorrelationId(): string {
|
||||||
|
let correlationId;
|
||||||
|
|
||||||
|
this.store.pipe(
|
||||||
|
select(correlationIdSelector),
|
||||||
|
take(1)
|
||||||
|
).subscribe((storeId: string) => {
|
||||||
|
// we can do this because ngrx selects are synchronous
|
||||||
|
correlationId = storeId;
|
||||||
|
});
|
||||||
|
|
||||||
|
return correlationId;
|
||||||
|
}
|
||||||
|
}
|
@@ -36,6 +36,7 @@ import { BrowserAuthRequestService } from '../../app/core/auth/browser-auth-requ
|
|||||||
import { AppConfig, APP_CONFIG_STATE } from '../../config/app-config.interface';
|
import { AppConfig, APP_CONFIG_STATE } from '../../config/app-config.interface';
|
||||||
import { DefaultAppConfig } from '../../config/default-app-config';
|
import { DefaultAppConfig } from '../../config/default-app-config';
|
||||||
import { extendEnvironmentWithAppConfig } from '../../config/config.util';
|
import { extendEnvironmentWithAppConfig } from '../../config/config.util';
|
||||||
|
import { CorrelationIdService } from '../../app/correlation-id/correlation-id.service';
|
||||||
|
|
||||||
import { environment } from '../../environments/environment';
|
import { environment } from '../../environments/environment';
|
||||||
|
|
||||||
@@ -81,16 +82,21 @@ export function getRequest(transferState: TransferState): any {
|
|||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
useFactory: (transferState: TransferState) => {
|
useFactory: (
|
||||||
|
transferState: TransferState,
|
||||||
|
dspaceTransferState: DSpaceTransferState,
|
||||||
|
correlationIdService: CorrelationIdService
|
||||||
|
) => {
|
||||||
if (transferState.hasKey<AppConfig>(APP_CONFIG_STATE)) {
|
if (transferState.hasKey<AppConfig>(APP_CONFIG_STATE)) {
|
||||||
const appConfig = transferState.get<AppConfig>(APP_CONFIG_STATE, new DefaultAppConfig());
|
const appConfig = transferState.get<AppConfig>(APP_CONFIG_STATE, new DefaultAppConfig());
|
||||||
// extend environment with app config for browser
|
// extend environment with app config for browser
|
||||||
extendEnvironmentWithAppConfig(environment, appConfig);
|
extendEnvironmentWithAppConfig(environment, appConfig);
|
||||||
}
|
}
|
||||||
|
dspaceTransferState.transfer();
|
||||||
|
correlationIdService.initCorrelationId();
|
||||||
return () => true;
|
return () => true;
|
||||||
},
|
},
|
||||||
deps: [TransferState],
|
deps: [TransferState, DSpaceTransferState, CorrelationIdService],
|
||||||
multi: true
|
multi: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -137,9 +143,4 @@ export function getRequest(transferState: TransferState): any {
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class BrowserAppModule {
|
export class BrowserAppModule {
|
||||||
constructor(
|
|
||||||
private transferState: DSpaceTransferState,
|
|
||||||
) {
|
|
||||||
this.transferState.transfer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,7 @@ import { ServerHardRedirectService } from '../../app/core/services/server-hard-r
|
|||||||
import { Angulartics2Mock } from '../../app/shared/mocks/angulartics2.service.mock';
|
import { Angulartics2Mock } from '../../app/shared/mocks/angulartics2.service.mock';
|
||||||
import { AuthRequestService } from '../../app/core/auth/auth-request.service';
|
import { AuthRequestService } from '../../app/core/auth/auth-request.service';
|
||||||
import { ServerAuthRequestService } from '../../app/core/auth/server-auth-request.service';
|
import { ServerAuthRequestService } from '../../app/core/auth/server-auth-request.service';
|
||||||
|
import { CorrelationIdService } from '../../app/correlation-id/correlation-id.service';
|
||||||
import { AppConfig, APP_CONFIG_STATE } from '../../config/app-config.interface';
|
import { AppConfig, APP_CONFIG_STATE } from '../../config/app-config.interface';
|
||||||
|
|
||||||
import { environment } from '../../environments/environment';
|
import { environment } from '../../environments/environment';
|
||||||
@@ -65,11 +66,17 @@ export function createTranslateLoader() {
|
|||||||
// Initialize app config and extend environment
|
// Initialize app config and extend environment
|
||||||
{
|
{
|
||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
useFactory: (transferState: TransferState) => {
|
useFactory: (
|
||||||
|
transferState: TransferState,
|
||||||
|
dspaceTransferState: DSpaceTransferState,
|
||||||
|
correlationIdService: CorrelationIdService,
|
||||||
|
) => {
|
||||||
transferState.set<AppConfig>(APP_CONFIG_STATE, environment as AppConfig);
|
transferState.set<AppConfig>(APP_CONFIG_STATE, environment as AppConfig);
|
||||||
|
dspaceTransferState.transfer();
|
||||||
|
correlationIdService.initCorrelationId();
|
||||||
return () => true;
|
return () => true;
|
||||||
},
|
},
|
||||||
deps: [TransferState],
|
deps: [TransferState, DSpaceTransferState, CorrelationIdService],
|
||||||
multi: true
|
multi: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -117,9 +124,4 @@ export function createTranslateLoader() {
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ServerAppModule {
|
export class ServerAppModule {
|
||||||
constructor(
|
|
||||||
private transferState: DSpaceTransferState,
|
|
||||||
) {
|
|
||||||
this.transferState.transfer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user