Merge pull request #1255 from 4Science/#1248

Improve logging Angular implementation
This commit is contained in:
Tim Donohue
2021-07-20 11:03:30 -05:00
committed by GitHub
3 changed files with 135 additions and 1 deletions

View File

@@ -1,5 +1,5 @@
import { APP_BASE_HREF, CommonModule } from '@angular/common';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
@@ -38,6 +38,7 @@ import { ForbiddenComponent } from './forbidden/forbidden.component';
import { AuthInterceptor } from './core/auth/auth.interceptor';
import { LocaleInterceptor } from './core/locale/locale.interceptor';
import { XsrfInterceptor } from './core/xsrf/xsrf.interceptor';
import { LogInterceptor } from './core/log/log.interceptor';
import { RootComponent } from './root/root.component';
import { ThemedRootComponent } from './root/themed-root.component';
import { ThemedEntryComponentModule } from '../themes/themed-entry-component.module';
@@ -49,6 +50,9 @@ import { ThemedBreadcrumbsComponent } from './breadcrumbs/themed-breadcrumbs.com
import { ThemedHeaderNavbarWrapperComponent } from './header-nav-wrapper/themed-header-navbar-wrapper.component';
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
import { UUIDService } from './core/shared/uuid.service';
import { CookieService } from './core/services/cookie.service';
export function getBase() {
return environment.ui.nameSpace;
}
@@ -121,6 +125,27 @@ const PROVIDERS = [
useClass: XsrfInterceptor,
multi: true
},
// register LogInterceptor as HttpInterceptor
{
provide: HTTP_INTERCEPTORS,
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 ]
},
...DYNAMIC_MATCHER_PROVIDERS,
];

View File

@@ -0,0 +1,76 @@
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { Router } from '@angular/router';
import { LogInterceptor } from './log.interceptor';
import { DspaceRestService } from '../dspace-rest/dspace-rest.service';
import { RestRequestMethod } from '../data/rest-request-method';
import { CookieService } from '../services/cookie.service';
import { CookieServiceMock } from '../../shared/mocks/cookie.service.mock';
import { RouterStub } from '../../shared/testing/router.stub';
describe('LogInterceptor', () => {
let service: DspaceRestService;
let httpMock: HttpTestingController;
let cookieService: CookieService;
const router = Object.assign(new RouterStub(),{url : '/statistics'});
// Mock payload/statuses are dummy content as we are not testing the results
// of any below requests. We are only testing for X-XSRF-TOKEN header.
const mockPayload = {
id: 1
};
const mockStatusCode = 200;
const mockStatusText = 'SUCCESS';
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
DspaceRestService,
// LogInterceptor,
{
provide: HTTP_INTERCEPTORS,
useClass: LogInterceptor,
multi: true,
},
{ provide: CookieService, useValue: new CookieServiceMock() },
{ provide: Router, useValue: router },
],
});
service = TestBed.get(DspaceRestService);
httpMock = TestBed.get(HttpTestingController);
cookieService = TestBed.get(CookieService);
cookieService.set('CORRELATION-ID','123455');
});
it('headers should be set', (done) => {
service.request(RestRequestMethod.POST, 'server/api/core/items', 'test', { withCredentials: false }).subscribe((response) => {
expect(response).toBeTruthy();
done();
});
const httpRequest = httpMock.expectOne('server/api/core/items');
httpRequest.flush(mockPayload, { status: mockStatusCode, statusText: mockStatusText });
expect(httpRequest.request.headers.has('X-CORRELATION-ID')).toBeTrue();
expect(httpRequest.request.headers.has('X-REFERRER')).toBeTrue();
});
it('headers should have the right values', (done) => {
service.request(RestRequestMethod.POST, 'server/api/core/items', 'test', { withCredentials: false }).subscribe((response) => {
expect(response).toBeTruthy();
done();
});
const httpRequest = httpMock.expectOne('server/api/core/items');
httpRequest.flush(mockPayload, { status: mockStatusCode, statusText: mockStatusText });
expect(httpRequest.request.headers.get('X-CORRELATION-ID')).toEqual('123455');
expect(httpRequest.request.headers.get('X-REFERRER')).toEqual('/statistics');
});
});

View File

@@ -0,0 +1,33 @@
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Router } from '@angular/router';
import { Observable } from 'rxjs';
import { CookieService } from '../services/cookie.service';
/**
* Log Interceptor intercepting Http Requests & Responses to
* exchange add headers of the user using the application utilizing unique id in cookies.
* Add header for users current page path.
*/
@Injectable()
export class LogInterceptor implements HttpInterceptor {
constructor(private cookieService: CookieService, 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');
// Add headers from the intercepted request
let headers = request.headers;
headers = headers.append('X-CORRELATION-ID', correlationId);
headers = headers.append('X-REFERRER', this.router.url);
// Add new headers to the intercepted request
request = request.clone({ withCredentials: true, headers: headers });
return next.handle(request);
}
}