move the correlation id to the ngrx store

This commit is contained in:
Art Lowel
2021-12-16 14:17:28 +01:00
committed by Yura Bondarenko
parent ba268d4f28
commit 2fe5587e02
8 changed files with 125 additions and 35 deletions

View File

@@ -156,21 +156,6 @@ const PROVIDERS = [
useClass: LogInterceptor,
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,
useValue: ValidateEmailErrorStateMatcher

View File

@@ -49,6 +49,7 @@ import {
import { sidebarReducer, SidebarState } from './shared/sidebar/sidebar.reducer';
import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer';
import { ThemeState, themeReducer } from './shared/theme-support/theme.reducer';
import { correlationIdReducer } from './correlation-id/correlation-id.reducer';
export interface AppState {
router: fromRouter.RouterReducerState;
@@ -69,6 +70,7 @@ export interface AppState {
communityList: CommunityListState;
epeopleRegistry: EPeopleRegistryState;
groupRegistry: GroupRegistryState;
correlationId: string;
}
export const appReducers: ActionReducerMap<AppState> = {
@@ -90,6 +92,7 @@ export const appReducers: ActionReducerMap<AppState> = {
communityList: CommunityListReducer,
epeopleRegistry: ePeopleRegistryReducer,
groupRegistry: groupRegistryReducer,
correlationId: correlationIdReducer
};
export const routerStateSelector = (state: AppState) => state.router;

View File

@@ -3,9 +3,8 @@ import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/c
import { Router } from '@angular/router';
import { Observable } from 'rxjs';
import { CookieService } from '../services/cookie.service';
import { hasValue } from '../../shared/empty.util';
import { CorrelationIdService } from '../../correlation-id/correlation-id.service';
/**
* Log Interceptor intercepting Http Requests & Responses to
@@ -15,12 +14,12 @@ import { hasValue } from '../../shared/empty.util';
@Injectable()
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>> {
// Get Unique id of the user from the cookies
const correlationId = this.cookieService.get('CORRELATION-ID');
// Get the correlation id for the user from the store
const correlationId = this.cidService.getCorrelationId();
// Add headers from the intercepted request
let headers = request.headers;

View 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;

View 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;
}
}
};

View 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;
}
}

View File

@@ -36,6 +36,7 @@ import { BrowserAuthRequestService } from '../../app/core/auth/browser-auth-requ
import { AppConfig, APP_CONFIG_STATE } from '../../config/app-config.interface';
import { DefaultAppConfig } from '../../config/default-app-config';
import { extendEnvironmentWithAppConfig } from '../../config/config.util';
import { CorrelationIdService } from '../../app/correlation-id/correlation-id.service';
import { environment } from '../../environments/environment';
@@ -81,16 +82,21 @@ export function getRequest(transferState: TransferState): any {
providers: [
{
provide: APP_INITIALIZER,
useFactory: (transferState: TransferState) => {
useFactory: (
transferState: TransferState,
dspaceTransferState: DSpaceTransferState,
correlationIdService: CorrelationIdService
) => {
if (transferState.hasKey<AppConfig>(APP_CONFIG_STATE)) {
const appConfig = transferState.get<AppConfig>(APP_CONFIG_STATE, new DefaultAppConfig());
// extend environment with app config for browser
extendEnvironmentWithAppConfig(environment, appConfig);
}
dspaceTransferState.transfer();
correlationIdService.initCorrelationId();
return () => true;
},
deps: [TransferState],
deps: [TransferState, DSpaceTransferState, CorrelationIdService],
multi: true
},
{
@@ -137,9 +143,4 @@ export function getRequest(transferState: TransferState): any {
]
})
export class BrowserAppModule {
constructor(
private transferState: DSpaceTransferState,
) {
this.transferState.transfer();
}
}

View File

@@ -32,6 +32,7 @@ import { ServerHardRedirectService } from '../../app/core/services/server-hard-r
import { Angulartics2Mock } from '../../app/shared/mocks/angulartics2.service.mock';
import { AuthRequestService } from '../../app/core/auth/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 { environment } from '../../environments/environment';
@@ -65,11 +66,17 @@ export function createTranslateLoader() {
// Initialize app config and extend environment
{
provide: APP_INITIALIZER,
useFactory: (transferState: TransferState) => {
useFactory: (
transferState: TransferState,
dspaceTransferState: DSpaceTransferState,
correlationIdService: CorrelationIdService,
) => {
transferState.set<AppConfig>(APP_CONFIG_STATE, environment as AppConfig);
dspaceTransferState.transfer();
correlationIdService.initCorrelationId();
return () => true;
},
deps: [TransferState],
deps: [TransferState, DSpaceTransferState, CorrelationIdService],
multi: true
},
{
@@ -117,9 +124,4 @@ export function createTranslateLoader() {
]
})
export class ServerAppModule {
constructor(
private transferState: DSpaceTransferState,
) {
this.transferState.transfer();
}
}