Finished patch support

This commit is contained in:
lotte
2018-09-19 15:32:14 +02:00
parent e959542e2d
commit c6f55e424b
14 changed files with 61 additions and 58 deletions

View File

@@ -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 were 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 were 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');
});

View File

@@ -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));
}
/**

View File

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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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
];

View File

@@ -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);
// });
//

View File

@@ -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)
}
}

View File

@@ -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) {

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

View File

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

View File

@@ -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,

View File

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

View File

@@ -4,5 +4,5 @@ import { AutoSyncConfig } from './auto-sync-config.interface';
export interface CacheConfig extends Config {
msToLive: number,
control: string,
autoSync: AutoSyncConfig
// autoSync: AutoSyncConfig
}