aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/http-interceptors/caching-interceptor.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/http-interceptors/caching-interceptor.ts')
-rw-r--r--src/app/http-interceptors/caching-interceptor.ts94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/app/http-interceptors/caching-interceptor.ts b/src/app/http-interceptors/caching-interceptor.ts
new file mode 100644
index 0000000..df13376
--- /dev/null
+++ b/src/app/http-interceptors/caching-interceptor.ts
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2022. Deutsche Telekom AG
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Observable, of } from 'rxjs';
+import { startWith, tap } from 'rxjs/operators';
+
+import { RequestCache } from '../services/cacheservice/request-cache.service';
+import { urlTileApi } from '../services/tileservice/tiles.service';
+
+/**
+ * Interceptor that returns HttpResponses from cache and updates cache if outdated
+ * This applies to GET requests from specified urls (specified in this class)
+ */
+@Injectable()
+// https://angular.io/guide/http#using-interceptors-for-caching
+// https://github.com/angular/angular/blob/master/aio/content/examples/http/src/app/http-interceptors/caching-interceptor.ts
+export class CachingInterceptor implements HttpInterceptor {
+ private cachedUrls: Array<string> = [
+ urlTileApi,
+ window.location.origin + '/keycloak/auth/realms/ONAP/protocol/openid-connect/userinfo',
+ ];
+
+ // cache is the cache service that supports get() and put()
+ constructor(private cache: RequestCache) {}
+
+ intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
+ // continue if not cacheable.
+ if (!this.isCacheable(request)) {
+ return next.handle(request);
+ }
+
+ const cachedResponse = this.cache.get(request);
+
+ // when a custom 'x-refresh' header is set, refresh the cash
+ // (see https://github.com/angular/angular/blob/master/aio/content/examples/http/src/app/package-search/package-search.service.ts)
+ if (request.headers.get('x-refresh')) {
+ const results$ = this.getUpdatedResponse(request, next, this.cache);
+ return cachedResponse ? results$.pipe(startWith(cachedResponse)) : results$;
+ }
+ // cache-or-fetch
+ return cachedResponse ? of(cachedResponse) : this.getUpdatedResponse(request, next, this.cache);
+ }
+
+ /**
+ * Checks if the request is cacheable.
+ * This is true if the request is a http GET and the url is defined in this method
+ * (-> urlTileApi)
+ */
+ private isCacheable(req: HttpRequest<any>): boolean {
+ // Only GET requests are cacheable
+ return (
+ req.method === 'GET' &&
+ // Only the tile api is cacheable in this app
+ -1 < this.cachedUrls.indexOf(req.url)
+ );
+ }
+
+ /**
+ * Get server response observable by sending request to `next()`.
+ * Will add the response to the cache on the way out.
+ */
+ private getUpdatedResponse(
+ req: HttpRequest<any>,
+ next: HttpHandler,
+ cache: RequestCache,
+ ): Observable<HttpEvent<any>> {
+ return next.handle(req.clone()).pipe(
+ tap(event => {
+ // There may be other events besides the response.
+ if (event instanceof HttpResponse) {
+ cache.put(req, event); // Update the cache.
+ }
+ }),
+ );
+ }
+}