mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 10:34:15 +00:00
Finished patch support
This commit is contained in:
@@ -9,10 +9,10 @@ import { of as observableOf } from 'rxjs';
|
||||
import { AuthInterceptor } from './auth.interceptor';
|
||||
import { AuthService } from './auth.service';
|
||||
import { DSpaceRESTv2Service } from '../dspace-rest-v2/dspace-rest-v2.service';
|
||||
import { RestRequestMethod } from '../data/request.models';
|
||||
import { RouterStub } from '../../shared/testing/router-stub';
|
||||
import { TruncatablesState } from '../../shared/truncatable/truncatable.reducer';
|
||||
import { AuthServiceStub } from '../../shared/testing/auth-service-stub';
|
||||
import { RestRequestMethod } from '../data//rest-request-method';
|
||||
|
||||
describe(`AuthInterceptor`, () => {
|
||||
let service: DSpaceRESTv2Service;
|
||||
@@ -49,7 +49,7 @@ describe(`AuthInterceptor`, () => {
|
||||
describe('when has a valid token', () => {
|
||||
|
||||
it('should not add an Authorization header when we’re sending a HTTP request to \'authn\' endpoint', () => {
|
||||
service.request(RestRequestMethod.Post, 'dspace-spring-rest/api/authn/login', 'password=password&user=user').subscribe((response) => {
|
||||
service.request(RestRequestMethod.POST, 'dspace-spring-rest/api/authn/login', 'password=password&user=user').subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
@@ -60,7 +60,7 @@ describe(`AuthInterceptor`, () => {
|
||||
});
|
||||
|
||||
it('should add an Authorization header when we’re sending a HTTP request to \'authn\' endpoint', () => {
|
||||
service.request(RestRequestMethod.Post, 'dspace-spring-rest/api/submission/workspaceitems', 'test').subscribe((response) => {
|
||||
service.request(RestRequestMethod.POST, 'dspace-spring-rest/api/submission/workspaceitems', 'test').subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
@@ -85,11 +85,11 @@ describe(`AuthInterceptor`, () => {
|
||||
|
||||
it('should redirect to login', () => {
|
||||
|
||||
service.request(RestRequestMethod.Post, 'dspace-spring-rest/api/submission/workspaceitems', 'password=password&user=user').subscribe((response) => {
|
||||
service.request(RestRequestMethod.POST, 'dspace-spring-rest/api/submission/workspaceitems', 'password=password&user=user').subscribe((response) => {
|
||||
expect(response).toBeTruthy();
|
||||
});
|
||||
|
||||
service.request(RestRequestMethod.Post, 'dspace-spring-rest/api/submission/workspaceitems', 'password=password&user=user');
|
||||
service.request(RestRequestMethod.POST, 'dspace-spring-rest/api/submission/workspaceitems', 'password=password&user=user');
|
||||
|
||||
httpMock.expectNone('dspace-spring-rest/api/submission/workspaceitems');
|
||||
});
|
||||
|
11
src/app/core/cache/object-cache.service.ts
vendored
11
src/app/core/cache/object-cache.service.ts
vendored
@@ -1,6 +1,6 @@
|
||||
import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
||||
|
||||
import { distinctUntilChanged, filter, first, map, mergeMap, take, tap } from 'rxjs/operators';
|
||||
import { distinctUntilChanged, filter, first, map, mergeMap } from 'rxjs/operators';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MemoizedSelector, select, Store } from '@ngrx/store';
|
||||
import { IndexName } from '../index/index.reducer';
|
||||
@@ -8,7 +8,8 @@ import { IndexName } from '../index/index.reducer';
|
||||
import { CacheableObject, ObjectCacheEntry } from './object-cache.reducer';
|
||||
import {
|
||||
AddPatchObjectCacheAction,
|
||||
AddToObjectCacheAction, ApplyPatchObjectCacheAction,
|
||||
AddToObjectCacheAction,
|
||||
ApplyPatchObjectCacheAction,
|
||||
RemoveFromObjectCacheAction
|
||||
} from './object-cache.actions';
|
||||
import { hasNoValue, isNotEmpty } from '../../shared/empty.util';
|
||||
@@ -18,8 +19,8 @@ import { pathSelector } from '../shared/selectors';
|
||||
import { NormalizedObjectFactory } from './models/normalized-object-factory';
|
||||
import { NormalizedObject } from './models/normalized-object.model';
|
||||
import { applyPatch, Operation } from 'fast-json-patch';
|
||||
import { RestRequestMethod } from '../data/request.models';
|
||||
import { AddToSSBAction } from './server-sync-buffer.actions';
|
||||
import { RestRequestMethod } from '../data//rest-request-method';
|
||||
|
||||
function selfLinkFromUuidSelector(uuid: string): MemoizedSelector<CoreState, string> {
|
||||
return pathSelector<CoreState, string>(coreSelector, 'index', IndexName.OBJECT, uuid);
|
||||
@@ -209,6 +210,8 @@ export class ObjectCacheService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add operations to the existing list of operations for an ObjectCacheEntry
|
||||
* Makes sure the ServerSyncBuffer for this ObjectCacheEntry is updated
|
||||
@@ -219,7 +222,7 @@ export class ObjectCacheService {
|
||||
*/
|
||||
public addPatch(uuid: string, patch: Operation[]) {
|
||||
this.store.dispatch(new AddPatchObjectCacheAction(uuid, patch));
|
||||
this.store.dispatch(new AddToSSBAction(uuid, RestRequestMethod.Patch));
|
||||
this.store.dispatch(new AddToSSBAction(uuid, RestRequestMethod.PATCH));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,9 +1,7 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
import { type } from '../../shared/ngrx/type';
|
||||
import { CacheableObject } from './object-cache.reducer';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { RestRequest, RestRequestMethod } from '../data/request.models';
|
||||
import { RestRequestMethod } from '../data//rest-request-method';
|
||||
|
||||
/**
|
||||
* The list of ServerSyncBufferAction type definitions
|
||||
@@ -33,7 +31,7 @@ export class AddToSSBAction implements Action {
|
||||
* the unique href of the cached object entry that should be updated
|
||||
*/
|
||||
constructor(href: string, method: RestRequestMethod) {
|
||||
this.payload = { href, method };
|
||||
this.payload = { href, method: undefined };
|
||||
}
|
||||
}
|
||||
|
||||
|
12
src/app/core/cache/server-sync-buffer.effects.ts
vendored
12
src/app/core/cache/server-sync-buffer.effects.ts
vendored
@@ -14,22 +14,24 @@ import { Action, select, Store } from '@ngrx/store';
|
||||
import { ServerSyncBufferEntry, ServerSyncBufferState } from './server-sync-buffer.reducer';
|
||||
import { of as observableOf, combineLatest as observableCombineLatest } from 'rxjs';
|
||||
import { RequestService } from '../data/request.service';
|
||||
import { PutRequest, RestRequestMethod } from '../data/request.models';
|
||||
import { PutRequest } from '../data/request.models';
|
||||
import { ObjectCacheService } from './object-cache.service';
|
||||
import { ApplyPatchObjectCacheAction } from './object-cache.actions';
|
||||
import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer';
|
||||
import { GenericConstructor } from '../shared/generic-constructor';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RestRequestMethod } from '../data//rest-request-method';
|
||||
|
||||
@Injectable()
|
||||
export class ObjectCacheEffects {
|
||||
export class ServerSyncBufferEffects {
|
||||
@Effect() setTimeoutForServerSync = this.actions$
|
||||
.pipe(
|
||||
ofType(ServerSyncBufferActionTypes.ADD),
|
||||
exhaustMap((action: AddToSSBAction) => {
|
||||
const autoSyncConfig = this.EnvConfig.cache.autoSync;
|
||||
const timeoutInSeconds = autoSyncConfig.timePerMethod[action.type] || autoSyncConfig.defaultTime;
|
||||
// const autoSyncConfig = this.EnvConfig.cache.autoSync;
|
||||
// const timeoutInSeconds = autoSyncConfig.timePerMethod[action.type] || autoSyncConfig.defaultTime;
|
||||
const timeoutInSeconds = 0;
|
||||
return observableOf(new CommitSSBAction(action.payload.method)).pipe(delay(timeoutInSeconds * 1000))
|
||||
})
|
||||
);
|
||||
@@ -51,7 +53,7 @@ export class ObjectCacheEffects {
|
||||
return true;
|
||||
})
|
||||
.map((entry: ServerSyncBufferEntry) => {
|
||||
if (entry.method === RestRequestMethod.Patch) {
|
||||
if (entry.method === RestRequestMethod.PATCH) {
|
||||
return this.applyPatch(entry.href);
|
||||
} else {
|
||||
/* TODO other request stuff */
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import { RestRequestMethod } from '../data/request.models';
|
||||
import { hasNoValue, hasValue } from '../../shared/empty.util';
|
||||
import {
|
||||
AddToSSBAction,
|
||||
@@ -6,6 +5,7 @@ import {
|
||||
ServerSyncBufferAction,
|
||||
ServerSyncBufferActionTypes
|
||||
} from './server-sync-buffer.actions';
|
||||
import { RestRequestMethod } from '../data//rest-request-method';
|
||||
|
||||
/**
|
||||
* An entry in the ServerSyncBufferState
|
||||
|
@@ -4,11 +4,13 @@ import { ResponseCacheEffects } from './cache/response-cache.effects';
|
||||
import { UUIDIndexEffects } from './index/index.effects';
|
||||
import { RequestEffects } from './data/request.effects';
|
||||
import { AuthEffects } from './auth/auth.effects';
|
||||
import { ServerSyncBufferEffects } from './cache/server-sync-buffer.effects';
|
||||
|
||||
export const coreEffects = [
|
||||
ResponseCacheEffects,
|
||||
RequestEffects,
|
||||
ObjectCacheEffects,
|
||||
UUIDIndexEffects,
|
||||
AuthEffects
|
||||
AuthEffects,
|
||||
ServerSyncBufferEffects
|
||||
];
|
||||
|
@@ -121,7 +121,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain>
|
||||
// .filter((href: string) => hasValue(href))
|
||||
// .take(1)
|
||||
// .subscribe((href: string) => {
|
||||
// const request = new RestRequest(this.requestService.generateRequestId(), href, RestRequestMethod.Post, dso);
|
||||
// const request = new RestRequest(this.requestService.generateRequestId(), href, RestRequestMethod.POST, dso);
|
||||
// this.requestService.configure(request);
|
||||
// });
|
||||
//
|
||||
|
@@ -1,7 +1,5 @@
|
||||
import { SortOptions } from '../cache/models/sort-options.model';
|
||||
import { GenericConstructor } from '../shared/generic-constructor';
|
||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
||||
import { RESTURLCombiner } from '../url-combiner/rest-url-combiner';
|
||||
import { BrowseEntriesResponseParsingService } from './browse-entries-response-parsing.service';
|
||||
import { DSOResponseParsingService } from './dso-response-parsing.service';
|
||||
import { ResponseParsingService } from './parsing.service';
|
||||
@@ -10,35 +8,17 @@ import { BrowseResponseParsingService } from './browse-response-parsing.service'
|
||||
import { ConfigResponseParsingService } from './config-response-parsing.service';
|
||||
import { AuthResponseParsingService } from '../auth/auth-response-parsing.service';
|
||||
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
|
||||
import { HttpHeaders } from '@angular/common/http';
|
||||
import { IntegrationResponseParsingService } from '../integration/integration-response-parsing.service';
|
||||
import { RestRequestMethod } from './/rest-request-method';
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
|
||||
/**
|
||||
* Represents a Request Method.
|
||||
*
|
||||
* I didn't reuse the RequestMethod enum in @angular/http because
|
||||
* it uses numbers. The string values here are more clear when
|
||||
* debugging.
|
||||
*
|
||||
* The ones commented out are still unsupported in the rest of the codebase
|
||||
*/
|
||||
export enum RestRequestMethod {
|
||||
Get = 'GET',
|
||||
Post = 'POST',
|
||||
Put = 'PUT',
|
||||
Delete = 'DELETE',
|
||||
Options = 'OPTIONS',
|
||||
Head = 'HEAD',
|
||||
Patch = 'PATCH'
|
||||
}
|
||||
|
||||
export abstract class RestRequest {
|
||||
constructor(
|
||||
public uuid: string,
|
||||
public href: string,
|
||||
public method: RestRequestMethod = RestRequestMethod.Get,
|
||||
public method: RestRequestMethod = RestRequestMethod.GET,
|
||||
public body?: any,
|
||||
public options?: HttpOptions
|
||||
) {
|
||||
@@ -56,7 +36,7 @@ export class GetRequest extends RestRequest {
|
||||
public body?: any,
|
||||
public options?: HttpOptions
|
||||
) {
|
||||
super(uuid, href, RestRequestMethod.Get, body)
|
||||
super(uuid, href, RestRequestMethod.GET, body)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +47,7 @@ export class PostRequest extends RestRequest {
|
||||
public body?: any,
|
||||
public options?: HttpOptions
|
||||
) {
|
||||
super(uuid, href, RestRequestMethod.Post, body)
|
||||
super(uuid, href, RestRequestMethod.POST, body)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +58,7 @@ export class PutRequest extends RestRequest {
|
||||
public body?: any,
|
||||
public options?: HttpOptions
|
||||
) {
|
||||
super(uuid, href, RestRequestMethod.Put, body)
|
||||
super(uuid, href, RestRequestMethod.PUT, body)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +69,7 @@ export class DeleteRequest extends RestRequest {
|
||||
public body?: any,
|
||||
public options?: HttpOptions
|
||||
) {
|
||||
super(uuid, href, RestRequestMethod.Delete, body)
|
||||
super(uuid, href, RestRequestMethod.DELETE, body)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +80,7 @@ export class OptionsRequest extends RestRequest {
|
||||
public body?: any,
|
||||
public options?: HttpOptions
|
||||
) {
|
||||
super(uuid, href, RestRequestMethod.Options, body)
|
||||
super(uuid, href, RestRequestMethod.OPTIONS, body)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +91,7 @@ export class HeadRequest extends RestRequest {
|
||||
public body?: any,
|
||||
public options?: HttpOptions
|
||||
) {
|
||||
super(uuid, href, RestRequestMethod.Head, body)
|
||||
super(uuid, href, RestRequestMethod.HEAD, body)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +102,7 @@ export class PatchRequest extends RestRequest {
|
||||
public body?: any,
|
||||
public options?: HttpOptions
|
||||
) {
|
||||
super(uuid, href, RestRequestMethod.Patch, body)
|
||||
super(uuid, href, RestRequestMethod.PATCH, body)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -14,10 +14,11 @@ import { IndexName } from '../index/index.reducer';
|
||||
import { pathSelector } from '../shared/selectors';
|
||||
import { UUIDService } from '../shared/uuid.service';
|
||||
import { RequestConfigureAction, RequestExecuteAction } from './request.actions';
|
||||
import { GetRequest, RestRequest, RestRequestMethod } from './request.models';
|
||||
import { GetRequest, RestRequest } from './request.models';
|
||||
|
||||
import { RequestEntry } from './request.reducer';
|
||||
import { CommitSSBAction } from '../cache/server-sync-buffer.actions';
|
||||
import { RestRequestMethod } from './/rest-request-method';
|
||||
|
||||
@Injectable()
|
||||
export class RequestService {
|
||||
@@ -71,7 +72,7 @@ export class RequestService {
|
||||
|
||||
// TODO to review "overrideRequest" param when https://github.com/DSpace/dspace-angular/issues/217 will be fixed
|
||||
configure<T extends CacheableObject>(request: RestRequest, forceBypassCache: boolean = false): void {
|
||||
const isGetRequest = request.method === RestRequestMethod.Get;
|
||||
const isGetRequest = request.method === RestRequestMethod.GET;
|
||||
if (!isGetRequest || !this.isCachedOrPending(request) || forceBypassCache) {
|
||||
this.dispatchRequest(request);
|
||||
if (isGetRequest && !forceBypassCache) {
|
||||
|
18
src/app/core/data/rest-request-method.ts
Normal file
18
src/app/core/data/rest-request-method.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Represents a Request Method.
|
||||
*
|
||||
* I didn't reuse the RequestMethod enum in @angular/http because
|
||||
* it uses numbers. The string values here are more clear when
|
||||
* debugging.
|
||||
*
|
||||
* The ones commented out are still unsupported in the rest of the codebase
|
||||
*/
|
||||
export enum RestRequestMethod {
|
||||
GET = 'GET',
|
||||
POST = 'POST',
|
||||
PUT = 'PUT',
|
||||
DELETE = 'DELETE',
|
||||
OPTIONS = 'OPTIONS',
|
||||
HEAD = 'HEAD',
|
||||
PATCH = 'PATCH'
|
||||
}
|
@@ -3,10 +3,10 @@ import {catchError, map} from 'rxjs/operators';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Request } from '@angular/http';
|
||||
import { HttpClient, HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http'
|
||||
import { RestRequestMethod } from '../data/request.models';
|
||||
|
||||
import { DSpaceRESTV2Response } from './dspace-rest-v2-response.model';
|
||||
import { HttpObserve } from '@angular/common/http/src/client';
|
||||
import { RestRequestMethod } from '../data//rest-request-method';
|
||||
|
||||
export interface HttpOptions {
|
||||
body?: any;
|
||||
|
@@ -7,10 +7,10 @@ import {
|
||||
RemoveFromObjectCacheAction
|
||||
} from '../cache/object-cache.actions';
|
||||
import { RequestActionTypes, RequestConfigureAction } from '../data/request.actions';
|
||||
import { RestRequestMethod } from '../data/request.models';
|
||||
import { AddToIndexAction, RemoveFromIndexByValueAction } from './index.actions';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { IndexName } from './index.reducer';
|
||||
import { RestRequestMethod } from '../data//rest-request-method';
|
||||
|
||||
@Injectable()
|
||||
export class UUIDIndexEffects {
|
||||
@@ -42,7 +42,7 @@ export class UUIDIndexEffects {
|
||||
@Effect() addRequest$ = this.actions$
|
||||
.pipe(
|
||||
ofType(RequestActionTypes.CONFIGURE),
|
||||
filter((action: RequestConfigureAction) => action.payload.method === RestRequestMethod.Get),
|
||||
filter((action: RequestConfigureAction) => action.payload.method === RestRequestMethod.GET),
|
||||
map((action: RequestConfigureAction) => {
|
||||
return new AddToIndexAction(
|
||||
IndexName.REQUEST,
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { RestRequestMethod } from '../app/core/data/request.models';
|
||||
import { RestRequestMethod } from '../app/core/data//rest-request-method';
|
||||
|
||||
/* enum indices */
|
||||
type TimePerMethod = {
|
||||
[method in RestRequestMethod]: number;
|
||||
};
|
||||
|
@@ -4,5 +4,5 @@ import { AutoSyncConfig } from './auto-sync-config.interface';
|
||||
export interface CacheConfig extends Config {
|
||||
msToLive: number,
|
||||
control: string,
|
||||
autoSync: AutoSyncConfig
|
||||
// autoSync: AutoSyncConfig
|
||||
}
|
||||
|
Reference in New Issue
Block a user