mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
OPS-182: Support wachter API, refactor & remove unused thrift (#142)
This commit is contained in:
parent
11cc97ecf6
commit
dceaf7b920
@ -1,21 +1,27 @@
|
||||
require('dotenv').config({ path: ['.env', process.env.NODE_ENV].filter(Boolean).join('.') });
|
||||
|
||||
const THRIFT_PROXY_CONFIG = {
|
||||
context: [
|
||||
'/v1',
|
||||
'/v3',
|
||||
'/stat',
|
||||
'/fistful',
|
||||
'/file_storage',
|
||||
'/deanonimus',
|
||||
'/payout/management',
|
||||
],
|
||||
target: process.env.PROXY_TARGET,
|
||||
secure: false,
|
||||
logLevel: 'debug',
|
||||
changeOrigin: true,
|
||||
};
|
||||
const { PROXY_TARGET } = process.env;
|
||||
const REQUIRED_ENV = [PROXY_TARGET];
|
||||
|
||||
if (!THRIFT_PROXY_CONFIG.target) throw new Error('proxy.conf.js - set the thrift proxy target!');
|
||||
if (REQUIRED_ENV.findIndex((e) => !e) !== -1) {
|
||||
throw new Error('[proxy.conf.js] Set required environment variables!');
|
||||
}
|
||||
|
||||
module.exports = [THRIFT_PROXY_CONFIG];
|
||||
module.exports = [
|
||||
{
|
||||
context: [
|
||||
'/v1',
|
||||
'/v3',
|
||||
'/stat',
|
||||
'/fistful',
|
||||
'/file_storage',
|
||||
'/deanonimus',
|
||||
'/payout/management',
|
||||
'/wachter',
|
||||
],
|
||||
target: PROXY_TARGET,
|
||||
secure: false,
|
||||
logLevel: 'debug',
|
||||
changeOrigin: true,
|
||||
},
|
||||
];
|
||||
|
@ -3,10 +3,14 @@ import { Observable } from 'rxjs';
|
||||
import { ThriftApi } from './thrift-api';
|
||||
import { ThriftApiArgs } from './types/thrift-api-args';
|
||||
|
||||
export function createThriftApi<T extends Record<PropertyKey, any>>() {
|
||||
return ThriftApi as unknown as new (...args: ThriftApiArgs) => {
|
||||
[N in keyof T]: (
|
||||
...args: Parameters<T[N]>
|
||||
) => ReturnType<T[N]> extends Promise<infer R> ? Observable<R> : never;
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type WrappedThriftApi<T extends Record<PropertyKey, any>> = new (...args: ThriftApiArgs) => {
|
||||
[N in keyof T]: (
|
||||
...args: Parameters<T[N]>
|
||||
) => ReturnType<T[N]> extends Promise<infer R> ? Observable<R> : never;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function createThriftApi<T extends Record<PropertyKey, any>>(): WrappedThriftApi<T> {
|
||||
return ThriftApi as never;
|
||||
}
|
||||
|
@ -1,58 +1,88 @@
|
||||
import { from } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { ConnectOptions } from '@vality/woody/src/connect-options';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import pick from 'lodash-es/pick';
|
||||
import { combineLatest, from } from 'rxjs';
|
||||
import { first, map, shareReplay, switchMap } from 'rxjs/operators';
|
||||
|
||||
import { ThriftConnector } from '../thrift-connector';
|
||||
import { createThriftInstance, thriftInstanceToObject } from '../thrift-instance';
|
||||
import { KeycloakTokenInfoService } from '../../../shared/services';
|
||||
import { ThriftAstMetadata } from '../thrift-instance';
|
||||
import { ThriftApiArgs } from './types/thrift-api-args';
|
||||
import {
|
||||
callThriftServiceMethodWithConvert,
|
||||
createAuthorizationHeaders,
|
||||
createDeprecatedUserIdentityHeaders,
|
||||
createUserIdentityHeaders,
|
||||
createWachterHeaders,
|
||||
ThriftClientMainOptions,
|
||||
UserIdentityHeaderParams,
|
||||
} from './utils';
|
||||
|
||||
export class ThriftApi extends ThriftConnector {
|
||||
constructor(...[injector, options]: ThriftApiArgs) {
|
||||
super(injector, options);
|
||||
export class ThriftApi {
|
||||
private connectOptions$ = combineLatest([
|
||||
this.injector.get(KeycloakTokenInfoService).decoded$,
|
||||
this.injector.get(KeycloakService).getToken(),
|
||||
]).pipe(
|
||||
map(([{ email, sub: id, preferred_username: username }, token]) =>
|
||||
this.getConnectOptions({ email, id, username }, token)
|
||||
),
|
||||
shareReplay({ refCount: true, bufferSize: 1 })
|
||||
);
|
||||
private methodOptions$ = from(this.options.metadata()).pipe(
|
||||
map((metadata) => ({
|
||||
metadata: metadata as ThriftAstMetadata[],
|
||||
namespaceName: this.options.name,
|
||||
...pick(this.options, 'serviceName', 'context'),
|
||||
})),
|
||||
shareReplay({ refCount: true, bufferSize: 1 })
|
||||
);
|
||||
|
||||
constructor(private injector: ThriftApiArgs[0], private options: ThriftApiArgs[1]) {
|
||||
this.initServiceMethods();
|
||||
}
|
||||
|
||||
private initServiceMethods() {
|
||||
Object.assign(
|
||||
this,
|
||||
Object.fromEntries(
|
||||
options.functions.map((methodName) => [
|
||||
this.options.functions.map((methodName) => [
|
||||
methodName,
|
||||
(...methodArgs) =>
|
||||
from(options.metadata()).pipe(
|
||||
switchMap((metadata) =>
|
||||
this.callThriftServiceMethodWithConvert(
|
||||
options.name,
|
||||
options.serviceName,
|
||||
methodName,
|
||||
methodArgs,
|
||||
metadata,
|
||||
options.context
|
||||
)
|
||||
)
|
||||
),
|
||||
this.createMethod(methodName),
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private callThriftServiceMethodWithConvert(
|
||||
namespaceName: string,
|
||||
serviceName: string,
|
||||
methodName: string,
|
||||
methodArgs: any[],
|
||||
metadata: any,
|
||||
context: any
|
||||
) {
|
||||
const methodMetadata = metadata.find((m) => m.name === namespaceName).ast.service[
|
||||
serviceName
|
||||
].functions[methodName];
|
||||
const methodThriftArgs = methodArgs.map((arg, idx) =>
|
||||
createThriftInstance(
|
||||
metadata,
|
||||
context,
|
||||
namespaceName,
|
||||
methodMetadata.args[idx].type,
|
||||
arg
|
||||
)
|
||||
);
|
||||
return this.callThriftServiceMethod(methodName, ...methodThriftArgs).pipe(
|
||||
map((v) => thriftInstanceToObject(metadata, namespaceName, methodMetadata.type, v))
|
||||
);
|
||||
private createMethod(methodName: string) {
|
||||
return (...methodArgs) =>
|
||||
combineLatest([this.connectOptions$, this.methodOptions$]).pipe(
|
||||
first(),
|
||||
switchMap(([connectOptions, methodOptions]) =>
|
||||
callThriftServiceMethodWithConvert(
|
||||
connectOptions,
|
||||
methodOptions,
|
||||
methodName,
|
||||
methodArgs
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private getConnectOptions(
|
||||
userIdentityHeaderParams: Partial<UserIdentityHeaderParams>,
|
||||
token: string
|
||||
): ThriftClientMainOptions & ConnectOptions {
|
||||
return {
|
||||
...pick(this.options, 'hostname', 'port', 'service', 'deprecatedHeaders'),
|
||||
path: this.options.wachterServiceName ? '/wachter' : this.options.path,
|
||||
headers: Object.assign(
|
||||
createUserIdentityHeaders(userIdentityHeaderParams),
|
||||
this.options.deprecatedHeaders &&
|
||||
createDeprecatedUserIdentityHeaders(userIdentityHeaderParams),
|
||||
this.options.wachterServiceName && {
|
||||
...createWachterHeaders(this.options.wachterServiceName),
|
||||
...createAuthorizationHeaders(token),
|
||||
}
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,15 @@
|
||||
export interface ThriftApiOptions {
|
||||
import { Overwrite } from 'utility-types';
|
||||
|
||||
import { ThriftInstanceContext } from '../../thrift-instance';
|
||||
import { ThriftClientMainOptions } from '../utils';
|
||||
|
||||
export interface ThriftApiOptions extends Overwrite<ThriftClientMainOptions, { path?: string }> {
|
||||
name: string;
|
||||
service: object;
|
||||
serviceName: string;
|
||||
path: string;
|
||||
hostname?: string;
|
||||
port?: string;
|
||||
metadata: () => Promise<any>;
|
||||
context: any;
|
||||
// https://github.com/valitydev/wachter/blob/master/src/main/resources/application.yml
|
||||
wachterServiceName?: string;
|
||||
metadata: () => Promise<unknown>;
|
||||
context: ThriftInstanceContext;
|
||||
functions: string[];
|
||||
deprecatedHeaders?: boolean;
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
import { ConnectOptions } from '@vality/woody/src/connect-options';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
createThriftInstance,
|
||||
ThriftAstMetadata,
|
||||
ThriftInstanceContext,
|
||||
thriftInstanceToObject,
|
||||
} from '../../thrift-instance';
|
||||
import { callThriftServiceMethod, ThriftClientMainOptions } from './call-thrift-service-method';
|
||||
|
||||
interface ThriftServiceMethodOptions {
|
||||
namespaceName: string;
|
||||
serviceName: string;
|
||||
metadata: ThriftAstMetadata[];
|
||||
context: ThriftInstanceContext;
|
||||
}
|
||||
|
||||
export function callThriftServiceMethodWithConvert<T>(
|
||||
connectOptions: ThriftClientMainOptions & ConnectOptions,
|
||||
{ namespaceName, serviceName, metadata, context }: ThriftServiceMethodOptions,
|
||||
methodName: string,
|
||||
methodArgs: unknown[]
|
||||
): Observable<T> {
|
||||
const methodMetadata = metadata.find((m) => m.name === namespaceName).ast.service[serviceName]
|
||||
.functions[methodName];
|
||||
const methodThriftArgs = methodArgs.map((arg, idx) =>
|
||||
createThriftInstance(metadata, context, namespaceName, methodMetadata.args[idx].type, arg)
|
||||
);
|
||||
return callThriftServiceMethod<T>(connectOptions, methodName, methodThriftArgs).pipe(
|
||||
map((v) => thriftInstanceToObject(metadata, namespaceName, methodMetadata.type, v))
|
||||
);
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
import connectClient from '@vality/woody';
|
||||
import { ConnectOptions } from '@vality/woody/src/connect-options';
|
||||
import isNil from 'lodash-es/isNil';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export interface ThriftClientMainOptions {
|
||||
path: string;
|
||||
service: object;
|
||||
hostname?: string;
|
||||
port?: string;
|
||||
}
|
||||
|
||||
const DEFAULT_CONNECT_OPTIONS: ConnectOptions = {
|
||||
deadlineConfig: {
|
||||
amount: 3,
|
||||
unitOfTime: 'm',
|
||||
},
|
||||
};
|
||||
|
||||
export function callThriftServiceMethod<T>(
|
||||
{ hostname, port, path, service, ...options }: ThriftClientMainOptions & ConnectOptions,
|
||||
serviceMethodName: string,
|
||||
serviceMethodArgs: unknown[] = []
|
||||
): Observable<T> {
|
||||
return new Observable<T>((observer) => {
|
||||
try {
|
||||
/**
|
||||
* Connection errors come with HTTP errors (!= 200) and should be handled with errors from the service.
|
||||
* You need to have 1 free connection per request. Otherwise, the error cannot be caught or identified.
|
||||
* TODO: Optimization option: add a connection pool.
|
||||
*/
|
||||
const connection = connectClient(
|
||||
hostname ?? location.hostname,
|
||||
port ?? location.port,
|
||||
path,
|
||||
service,
|
||||
{ ...DEFAULT_CONNECT_OPTIONS, ...options },
|
||||
(err) => {
|
||||
observer.error(err);
|
||||
observer.complete();
|
||||
}
|
||||
);
|
||||
const serviceMethod = connection[serviceMethodName] as (...args: unknown[]) => unknown;
|
||||
if (isNil(serviceMethod)) {
|
||||
observer.error(
|
||||
`Service method: "${serviceMethodName}" is not found in thrift client`
|
||||
);
|
||||
observer.complete();
|
||||
} else {
|
||||
serviceMethod.call(connection, ...serviceMethodArgs, (err, result: T) => {
|
||||
if (err) observer.error(err);
|
||||
else observer.next(result);
|
||||
observer.complete();
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
observer.error(err);
|
||||
observer.complete();
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
const createPrefixedHeaders = (params: Record<string, string>, prefix: string) =>
|
||||
Object.fromEntries(Object.entries(params).map(([k, v]) => [prefix + k, v]));
|
||||
|
||||
export type UserIdentityHeaderParams = Record<'email' | 'username' | 'id' | 'realm', string>;
|
||||
|
||||
const DEFAULT_USER_IDENTITY_HEADER_PARAMS: Partial<UserIdentityHeaderParams> = {
|
||||
realm: 'internal',
|
||||
};
|
||||
|
||||
export const createUserIdentityHeaders = (params: Partial<UserIdentityHeaderParams>) =>
|
||||
createPrefixedHeaders(
|
||||
{ ...DEFAULT_USER_IDENTITY_HEADER_PARAMS, ...params },
|
||||
'woody.meta.user-identity.'
|
||||
);
|
||||
|
||||
export const createDeprecatedUserIdentityHeaders = (params: Partial<UserIdentityHeaderParams>) =>
|
||||
createPrefixedHeaders(
|
||||
{ ...DEFAULT_USER_IDENTITY_HEADER_PARAMS, ...params },
|
||||
'x-rbk-meta-user-identity.'
|
||||
);
|
||||
|
||||
export const createAuthorizationHeaders = (token: string) => ({
|
||||
authorization: `Bearer ${token}`,
|
||||
});
|
||||
|
||||
export const createWachterHeaders = (serviceName: string) => ({
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
Service: serviceName,
|
||||
});
|
3
src/app/api/utils/create-thrift-api/utils/index.ts
Normal file
3
src/app/api/utils/create-thrift-api/utils/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './create-connect-options';
|
||||
export * from './call-thrift-service-method';
|
||||
export * from './call-thrift-service-method-with-convert';
|
@ -1,3 +1,2 @@
|
||||
export * from './create-thrift-api';
|
||||
export * from './thrift-connector';
|
||||
export * from './thrift-instance';
|
||||
|
@ -1 +0,0 @@
|
||||
export * from './thrift-connector';
|
@ -1,68 +0,0 @@
|
||||
import connectClient from '@vality/woody';
|
||||
import isNil from 'lodash-es/isNil';
|
||||
import { Observable } from 'rxjs';
|
||||
import { switchMap, first } from 'rxjs/operators';
|
||||
|
||||
import { KeycloakTokenInfoService } from '@cc/app/shared/services';
|
||||
|
||||
import { ThriftApiArgs } from '../create-thrift-api/types/thrift-api-args';
|
||||
import { ThriftApiOptions } from '../create-thrift-api/types/thrift-api-options';
|
||||
import { toConnectOptions } from './utils';
|
||||
|
||||
export class ThriftConnector {
|
||||
keycloakTokenInfoService: KeycloakTokenInfoService;
|
||||
options: ThriftApiOptions;
|
||||
|
||||
constructor(...[injector, options]: ThriftApiArgs) {
|
||||
this.keycloakTokenInfoService = injector.get(KeycloakTokenInfoService);
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
protected callThriftServiceMethod<T>(
|
||||
serviceMethodName: string,
|
||||
...args: unknown[]
|
||||
): Observable<T> {
|
||||
return this.keycloakTokenInfoService.decoded$.pipe(
|
||||
first(),
|
||||
switchMap(
|
||||
(token) =>
|
||||
new Observable<T>((observer) => {
|
||||
try {
|
||||
/**
|
||||
* Connection errors come with HTTP errors (!= 200) and should be handled with errors from the service.
|
||||
* You need to have 1 free connection per request. Otherwise, the error cannot be caught or identified.
|
||||
* TODO: Optimization option: add a connection pool.
|
||||
*/
|
||||
const connection = connectClient(
|
||||
this.options.hostname || location.hostname,
|
||||
this.options.port || location.port,
|
||||
this.options.path,
|
||||
this.options.service,
|
||||
toConnectOptions(token, this.options.deprecatedHeaders),
|
||||
(err) => {
|
||||
observer.error(err);
|
||||
observer.complete();
|
||||
}
|
||||
);
|
||||
const serviceMethod = connection[serviceMethodName];
|
||||
if (isNil(serviceMethod)) {
|
||||
observer.error(
|
||||
`Service method: "${serviceMethodName}" is not found in thrift client`
|
||||
);
|
||||
observer.complete();
|
||||
} else {
|
||||
serviceMethod.bind(connection)(...args, (err, result) => {
|
||||
if (err) observer.error(err);
|
||||
else observer.next(result);
|
||||
observer.complete();
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
observer.error(err);
|
||||
observer.complete();
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './to-connect-options';
|
@ -1,35 +0,0 @@
|
||||
import { ConnectOptions } from '@vality/woody/src/connect-options';
|
||||
|
||||
import { KeycloakToken } from '@cc/app/shared/services';
|
||||
|
||||
const toDepricatedHeaders = (email: string, username: string, partyID: string, realm: string) => ({
|
||||
'x-rbk-meta-user-identity.email': email,
|
||||
'x-rbk-meta-user-identity.realm': realm,
|
||||
'x-rbk-meta-user-identity.username': username,
|
||||
'x-rbk-meta-user-identity.id': partyID,
|
||||
});
|
||||
|
||||
const toHeaders = (email: string, username: string, partyID: string, realm: string) => ({
|
||||
'woody.meta.user-identity.email': email,
|
||||
'woody.meta.user-identity.realm': realm,
|
||||
'woody.meta.user-identity.username': username,
|
||||
'woody.meta.user-identity.id': partyID,
|
||||
});
|
||||
|
||||
export const toConnectOptions = (
|
||||
{ email, sub, preferred_username }: KeycloakToken,
|
||||
deprecatedHeaders = false,
|
||||
realm = 'internal'
|
||||
): ConnectOptions => ({
|
||||
headers: {
|
||||
...toHeaders(email, preferred_username, sub, realm),
|
||||
...(deprecatedHeaders
|
||||
? toDepricatedHeaders(email, preferred_username, sub, realm)
|
||||
: undefined),
|
||||
},
|
||||
deadlineConfig: {
|
||||
amount: 3,
|
||||
unitOfTime: 'm',
|
||||
},
|
||||
deprecatedHeaders,
|
||||
});
|
@ -22,7 +22,6 @@ import { ApiModelPipesModule, ThriftPipesModule } from '@cc/app/shared/pipes';
|
||||
import { EmptySearchResultModule } from '@cc/components/empty-search-result';
|
||||
import { TableModule } from '@cc/components/table';
|
||||
|
||||
import { ClaimManagementService } from '../../thrift-services/damsel/claim-management.service';
|
||||
import { CreateClaimDialogComponent } from './components/create-claim-dialog/create-claim-dialog.component';
|
||||
import { SearchClaimsComponentRouting } from './search-claims-routing.module';
|
||||
import { SearchClaimsComponent } from './search-claims.component';
|
||||
@ -63,6 +62,6 @@ import { SearchTableComponent } from './search-table/search-table.component';
|
||||
ClaimMailPipePipe,
|
||||
CreateClaimDialogComponent,
|
||||
],
|
||||
providers: [SearchClaimsService, ClaimManagementService],
|
||||
providers: [SearchClaimsService],
|
||||
})
|
||||
export class SearchClaimsModule {}
|
||||
|
@ -6,7 +6,7 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
|
||||
import { BaseDialogSuperclass, BaseDialogModule, BaseDialogService } from '@vality/ng-core';
|
||||
import { BaseDialogSuperclass, BaseDialogModule } from '@vality/ng-core';
|
||||
import { from, BehaviorSubject, Observable } from 'rxjs';
|
||||
|
||||
import { InvoicingService } from '@cc/app/api/payment-processing';
|
||||
@ -64,7 +64,6 @@ export class ChangeChargebackStatusDialogComponent
|
||||
constructor(
|
||||
injector: Injector,
|
||||
private invoicingService: InvoicingService,
|
||||
private baseDialogService: BaseDialogService,
|
||||
private notificationService: NotificationService,
|
||||
private errorService: ErrorService,
|
||||
private domainMetadataFormExtensionsService: DomainMetadataFormExtensionsService
|
||||
|
@ -1,88 +0,0 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import {
|
||||
Claim,
|
||||
ClaimID,
|
||||
ClaimSearchQuery,
|
||||
ClaimSearchResponse,
|
||||
Modification,
|
||||
} from '@vality/domain-proto/lib/claim_management';
|
||||
import {
|
||||
ClaimSearchQuery as ClaimSearchQueryType,
|
||||
Modification as ModificationType,
|
||||
} from '@vality/domain-proto/lib/claim_management/gen-nodejs/claim_management_types';
|
||||
import * as ClaimManagement from '@vality/domain-proto/lib/claim_management/gen-nodejs/ClaimManagement';
|
||||
import { Observable } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
|
||||
@Injectable()
|
||||
/**
|
||||
* @deprecated use api/ClaimManagement service
|
||||
*/
|
||||
export class ClaimManagementService extends ThriftService {
|
||||
constructor(zone: NgZone, keycloakTokenInfoService: KeycloakTokenInfoService) {
|
||||
super(zone, keycloakTokenInfoService, '/v1/cm', ClaimManagement);
|
||||
}
|
||||
|
||||
createClaim = (partyID: string, changeset: Modification[]): Observable<Claim> =>
|
||||
this.toObservableAction('CreateClaim')(partyID, changeset);
|
||||
|
||||
searchClaims = (query: ClaimSearchQuery): Observable<ClaimSearchResponse> =>
|
||||
this.toObservableAction('SearchClaims')(new ClaimSearchQueryType(query));
|
||||
|
||||
getClaim = (partyID: string, claimID: ClaimID): Observable<Claim> =>
|
||||
this.toObservableAction('GetClaim')(partyID, claimID);
|
||||
|
||||
acceptClaim = (partyID: string, claimID: ClaimID): Observable<void> =>
|
||||
this.getClaim(partyID, claimID).pipe(
|
||||
switchMap((claim) =>
|
||||
this.toObservableAction('AcceptClaim')(partyID, claimID, claim.revision)
|
||||
)
|
||||
);
|
||||
|
||||
requestClaimReview = (partyID: string, claimID: ClaimID): Observable<void> =>
|
||||
this.getClaim(partyID, claimID).pipe(
|
||||
switchMap((claim) =>
|
||||
this.toObservableAction('RequestClaimReview')(partyID, claimID, claim.revision)
|
||||
)
|
||||
);
|
||||
|
||||
requestClaimChanges = (partyID: string, claimID: ClaimID): Observable<void> =>
|
||||
this.getClaim(partyID, claimID).pipe(
|
||||
switchMap((claim) =>
|
||||
this.toObservableAction('RequestClaimChanges')(partyID, claimID, claim.revision)
|
||||
)
|
||||
);
|
||||
|
||||
denyClaim = (partyID: string, claimID: ClaimID, reason: string): Observable<void> =>
|
||||
this.getClaim(partyID, claimID).pipe(
|
||||
switchMap((claim) =>
|
||||
this.toObservableAction('DenyClaim')(partyID, claimID, claim.revision, reason)
|
||||
)
|
||||
);
|
||||
|
||||
revokeClaim = (partyID: string, claimID: ClaimID, reason: string): Observable<void> =>
|
||||
this.getClaim(partyID, claimID).pipe(
|
||||
switchMap((claim) =>
|
||||
this.toObservableAction('RevokeClaim')(partyID, claimID, claim.revision, reason)
|
||||
)
|
||||
);
|
||||
|
||||
updateClaim = (
|
||||
partyID: string,
|
||||
claimID: ClaimID,
|
||||
changeset: Modification[]
|
||||
): Observable<void> =>
|
||||
this.getClaim(partyID, claimID).pipe(
|
||||
switchMap((claim) =>
|
||||
this.toObservableAction('UpdateClaim')(
|
||||
claim.party_id,
|
||||
claim.id,
|
||||
claim.revision,
|
||||
changeset.map((m) => new ModificationType(m))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
@ -1,13 +1,12 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ClaimManagementService } from './claim-management.service';
|
||||
import { DomainStoreService } from './domain-store.service';
|
||||
import { PaymentProcessingService } from './payment-processing.service';
|
||||
import { RoutingRulesModule } from './routing-rules';
|
||||
|
||||
@NgModule({
|
||||
imports: [RoutingRulesModule],
|
||||
providers: [PaymentProcessingService, DomainStoreService, ClaimManagementService],
|
||||
providers: [PaymentProcessingService, DomainStoreService],
|
||||
})
|
||||
/**
|
||||
* @deprecated
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
InvoicePaymentAdjustmentParams as InvoicePaymentAdjustmentParamsObject,
|
||||
InvoiceRepairScenario as InvoiceRepairScenarioObject,
|
||||
} from '@vality/domain-proto/lib/payment_processing/gen-nodejs/payment_processing_types';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { Observable, timer } from 'rxjs';
|
||||
import { first, map, share, switchMap } from 'rxjs/operators';
|
||||
|
||||
@ -28,8 +29,18 @@ import { createDamselInstance, damselInstanceToObject } from './utils/create-dam
|
||||
* @deprecated
|
||||
*/
|
||||
export class PaymentProcessingService extends ThriftService {
|
||||
constructor(zone: NgZone, keycloakTokenInfoService: KeycloakTokenInfoService) {
|
||||
super(zone, keycloakTokenInfoService, '/v1/processing/invoicing', Invoicing);
|
||||
constructor(
|
||||
zone: NgZone,
|
||||
keycloakTokenInfoService: KeycloakTokenInfoService,
|
||||
keycloakService: KeycloakService
|
||||
) {
|
||||
super(
|
||||
zone,
|
||||
keycloakTokenInfoService,
|
||||
keycloakService,
|
||||
'/v1/processing/invoicing',
|
||||
Invoicing
|
||||
);
|
||||
}
|
||||
|
||||
getPaymentAdjustment = (
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { SearchHit } from '@vality/deanonimus-proto';
|
||||
import * as Deanonimus from '@vality/deanonimus-proto/lib/deanonimus/gen-nodejs/Deanonimus';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
@ -8,8 +9,12 @@ import { ThriftService } from '../services/thrift/thrift-service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class DeanonimusService extends ThriftService {
|
||||
constructor(zone: NgZone, keycloakTokenInfoService: KeycloakTokenInfoService) {
|
||||
super(zone, keycloakTokenInfoService, '/deanonimus', Deanonimus);
|
||||
constructor(
|
||||
zone: NgZone,
|
||||
keycloakTokenInfoService: KeycloakTokenInfoService,
|
||||
keycloakService: KeycloakService
|
||||
) {
|
||||
super(zone, keycloakTokenInfoService, keycloakService, '/deanonimus', Deanonimus);
|
||||
}
|
||||
|
||||
searchParty = (text: string): Observable<SearchHit[]> =>
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
} from '@vality/file-storage-proto';
|
||||
import { Timestamp } from '@vality/file-storage-proto/lib/base';
|
||||
import * as FileStorage from '@vality/file-storage-proto/lib/file_storage/gen-nodejs/FileStorage';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
@ -16,8 +17,12 @@ import { ThriftService } from '../services/thrift/thrift-service';
|
||||
|
||||
@Injectable()
|
||||
export class FileStorageService extends ThriftService {
|
||||
constructor(zone: NgZone, keycloakTokenInfoService: KeycloakTokenInfoService) {
|
||||
super(zone, keycloakTokenInfoService, '/file_storage', FileStorage);
|
||||
constructor(
|
||||
zone: NgZone,
|
||||
keycloakTokenInfoService: KeycloakTokenInfoService,
|
||||
keycloakService: KeycloakService
|
||||
) {
|
||||
super(zone, keycloakTokenInfoService, keycloakService, '/file_storage', FileStorage);
|
||||
}
|
||||
|
||||
createNewFile = (metadata: Metadata, expiresAt: Timestamp): Observable<NewFileResult> =>
|
||||
|
@ -1,20 +0,0 @@
|
||||
import { CategoryRef, ProviderObject } from '@vality/domain-proto/lib/domain';
|
||||
import get from 'lodash-es/get';
|
||||
|
||||
export const filterProvidersByCategories = (
|
||||
objects: ProviderObject[],
|
||||
shopCategories: number[]
|
||||
): ProviderObject[] =>
|
||||
objects.filter((obj) => {
|
||||
const predicate = (category: CategoryRef) =>
|
||||
!!shopCategories.find((shopCategory) => shopCategory === category.id);
|
||||
const paymentCats = get(obj, 'data.payment_terms.categories.value');
|
||||
const recurrentCats = get(obj, 'data.recurrent_paytool_terms.categories.value');
|
||||
if (paymentCats) {
|
||||
return !!Array.from(paymentCats.values()).find(predicate);
|
||||
}
|
||||
if (recurrentCats) {
|
||||
return !!Array.from(recurrentCats.values()).find(predicate);
|
||||
}
|
||||
return null;
|
||||
});
|
@ -1,14 +0,0 @@
|
||||
import { ProviderObject } from '@vality/domain-proto/lib/domain';
|
||||
import get from 'lodash-es/get';
|
||||
|
||||
export const filterProvidersByCategoryId = (
|
||||
objects: ProviderObject[],
|
||||
categoryId: number
|
||||
): ProviderObject[] =>
|
||||
objects.filter((obj) => {
|
||||
const paymentCats = get(obj, 'data.payment_terms.categories.value', []);
|
||||
const recurrentCats = get(obj, 'data.recurrent_paytool_terms.categories.value', []);
|
||||
return !![...paymentCats, ...recurrentCats]
|
||||
.map((c) => c.id)
|
||||
.find((id) => id === categoryId);
|
||||
});
|
@ -1 +0,0 @@
|
||||
export * from './filter-providers-by-category-id';
|
@ -2,6 +2,7 @@ import { Injectable, NgZone } from '@angular/core';
|
||||
import { DepositParams } from '@vality/fistful-proto/lib/fistful_admin';
|
||||
import { DepositParams as DepositParamsObject } from '@vality/fistful-proto/lib/fistful_admin/gen-nodejs/fistful_admin_types';
|
||||
import * as FistfulAdmin from '@vality/fistful-proto/lib/fistful_admin/gen-nodejs/FistfulAdmin';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
@ -9,8 +10,12 @@ import { ThriftService } from '../services/thrift/thrift-service';
|
||||
|
||||
@Injectable()
|
||||
export class FistfulAdminService extends ThriftService {
|
||||
constructor(zone: NgZone, keycloakTokenInfoService: KeycloakTokenInfoService) {
|
||||
super(zone, keycloakTokenInfoService, '/v1/admin', FistfulAdmin);
|
||||
constructor(
|
||||
zone: NgZone,
|
||||
keycloakTokenInfoService: KeycloakTokenInfoService,
|
||||
keycloakService: KeycloakService
|
||||
) {
|
||||
super(zone, keycloakTokenInfoService, keycloakService, '/v1/admin', FistfulAdmin);
|
||||
}
|
||||
|
||||
createDeposit(params: DepositParams): Observable<void> {
|
||||
|
@ -2,6 +2,7 @@ import { Inject, Injectable, NgZone } from '@angular/core';
|
||||
import { StatDeposit, StatRequest, StatResponse } from '@vality/fistful-proto/lib/fistful_stat';
|
||||
import { StatRequest as ThriftStatRequest } from '@vality/fistful-proto/lib/fistful_stat/gen-nodejs/fistful_stat_types';
|
||||
import * as FistfulStatistics from '@vality/fistful-proto/lib/fistful_stat/gen-nodejs/FistfulStatistics';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@ -21,9 +22,10 @@ export class FistfulStatisticsService extends ThriftService {
|
||||
keycloakTokenInfoService: KeycloakTokenInfoService,
|
||||
zone: NgZone,
|
||||
@Inject(SEARCH_LIMIT) private searchLimit: number,
|
||||
@Inject(SMALL_SEARCH_LIMIT) private smallSearchLimit: number
|
||||
@Inject(SMALL_SEARCH_LIMIT) private smallSearchLimit: number,
|
||||
keycloakService: KeycloakService
|
||||
) {
|
||||
super(zone, keycloakTokenInfoService, '/fistful/stat', FistfulStatistics);
|
||||
super(zone, keycloakTokenInfoService, keycloakService, '/fistful/stat', FistfulStatistics);
|
||||
}
|
||||
|
||||
getDeposits(
|
||||
|
@ -2,6 +2,7 @@ import { Injectable, NgZone } from '@angular/core';
|
||||
import { RepairScenario, SessionID } from '@vality/fistful-proto/lib/withdrawal_session';
|
||||
import * as Repairer from '@vality/fistful-proto/lib/withdrawal_session/gen-nodejs/Repairer';
|
||||
import { RepairScenario as RepairScenarioObject } from '@vality/fistful-proto/lib/withdrawal_session/gen-nodejs/withdrawal_session_types';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
@ -9,8 +10,18 @@ import { ThriftService } from '../services/thrift/thrift-service';
|
||||
|
||||
@Injectable()
|
||||
export class RepairerService extends ThriftService {
|
||||
constructor(zone: NgZone, keycloakTokenInfoService: KeycloakTokenInfoService) {
|
||||
super(zone, keycloakTokenInfoService, '/v1/repair/withdrawal/session', Repairer);
|
||||
constructor(
|
||||
zone: NgZone,
|
||||
keycloakTokenInfoService: KeycloakTokenInfoService,
|
||||
keycloakService: KeycloakService
|
||||
) {
|
||||
super(
|
||||
zone,
|
||||
keycloakTokenInfoService,
|
||||
keycloakService,
|
||||
'/v1/repair/withdrawal/session',
|
||||
Repairer
|
||||
);
|
||||
}
|
||||
|
||||
repair = (id: SessionID, scenario: RepairScenario): Observable<void> =>
|
||||
|
@ -1,5 +1,3 @@
|
||||
export * from './filters';
|
||||
export * from './utils/get-thrift-instance';
|
||||
export * from './file-storage';
|
||||
export * from './messages';
|
||||
export * from './damsel';
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
MachineDescriptor as MachineDescriptorObject,
|
||||
Reference as ReferenceObject,
|
||||
} from '@vality/machinegun-proto/lib/state_processing/gen-nodejs/state_processing_types';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
@ -13,8 +14,12 @@ import { ThriftService } from '../services/thrift/thrift-service';
|
||||
|
||||
@Injectable()
|
||||
export class AutomatonService extends ThriftService {
|
||||
constructor(zone: NgZone, keycloakTokenInfoService: KeycloakTokenInfoService) {
|
||||
super(zone, keycloakTokenInfoService, '/v1/automaton', Automaton);
|
||||
constructor(
|
||||
zone: NgZone,
|
||||
keycloakTokenInfoService: KeycloakTokenInfoService,
|
||||
keycloakService: KeycloakService
|
||||
) {
|
||||
super(zone, keycloakTokenInfoService, keycloakService, '/v1/automaton', Automaton);
|
||||
}
|
||||
|
||||
simpleRepair = (ns: Namespace, ref: Reference): Observable<void> =>
|
||||
|
@ -1 +0,0 @@
|
||||
export * from './messages.module';
|
@ -1,8 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { MessagesService } from './messages.service';
|
||||
|
||||
@NgModule({
|
||||
providers: [MessagesService],
|
||||
})
|
||||
export class MessagesModule {}
|
@ -1,40 +0,0 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import {
|
||||
Conversation,
|
||||
ConversationFilter,
|
||||
ConversationId,
|
||||
GetConversationResponse,
|
||||
User,
|
||||
} from '@vality/messages-proto';
|
||||
import {
|
||||
Conversation as ConversationType,
|
||||
ConversationFilter as ConversationFilterType,
|
||||
User as UserType,
|
||||
} from '@vality/messages-proto/lib/messages/gen-nodejs/messages_types';
|
||||
import * as MessageServiceClient from '@vality/messages-proto/lib/messages/gen-nodejs/MessageService';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { KeycloakTokenInfoService } from '../../keycloak-token-info.service';
|
||||
import { ThriftService } from '../services/thrift/thrift-service';
|
||||
|
||||
@Injectable()
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export class MessagesService extends ThriftService {
|
||||
constructor(zone: NgZone, keycloakTokenInfoService: KeycloakTokenInfoService) {
|
||||
super(zone, keycloakTokenInfoService, '/v1/messages', MessageServiceClient);
|
||||
}
|
||||
|
||||
getConversations = (
|
||||
ids: ConversationId[],
|
||||
filter: ConversationFilter
|
||||
): Observable<GetConversationResponse> =>
|
||||
this.toObservableAction('GetConversations')(ids, new ConversationFilterType(filter));
|
||||
|
||||
saveConversations = (conversations: Conversation[], user: User): Observable<void> =>
|
||||
this.toObservableAction('SaveConversations')(
|
||||
conversations.map((c) => new ConversationType(c)),
|
||||
new UserType(user)
|
||||
);
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
import { Conversation, ConversationStatus } from '@vality/messages-proto';
|
||||
import * as moment from 'moment';
|
||||
import * as uuid from 'uuid/v4';
|
||||
|
||||
export const createSingleMessageConversationParams = (
|
||||
conversationId: string,
|
||||
text: string,
|
||||
userId: string
|
||||
): Conversation => ({
|
||||
conversation_id: conversationId,
|
||||
messages: [{ message_id: uuid(), text, user_id: userId, timestamp: moment().toISOString() }],
|
||||
status: ConversationStatus.ACTUAL,
|
||||
});
|
@ -1 +0,0 @@
|
||||
export * from './create-single-message-conversation-params';
|
@ -1,8 +1,13 @@
|
||||
import { NgZone } from '@angular/core';
|
||||
import connectClient from '@vality/woody';
|
||||
import { Observable } from 'rxjs';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { Observable, from, switchMap } from 'rxjs';
|
||||
import { timeout } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
createWachterHeaders,
|
||||
createAuthorizationHeaders,
|
||||
} from '../../../api/utils/create-thrift-api/utils';
|
||||
import { KeycloakTokenInfoService } from '../../../keycloak-token-info.service';
|
||||
|
||||
type Exception<N = string, T = any> = {
|
||||
@ -18,8 +23,10 @@ export class ThriftService {
|
||||
constructor(
|
||||
private zone: NgZone,
|
||||
private keycloakTokenInfoService: KeycloakTokenInfoService,
|
||||
private keycloakService: KeycloakService,
|
||||
endpoint: string,
|
||||
thriftService: any
|
||||
thriftService: any,
|
||||
private wachterServiceName?: string
|
||||
) {
|
||||
this.endpoint = endpoint;
|
||||
this.service = thriftService;
|
||||
@ -30,27 +37,37 @@ export class ThriftService {
|
||||
deprecatedHeaders = true
|
||||
): T {
|
||||
return ((...args) =>
|
||||
new Observable<any>((observer) => {
|
||||
const cb = (msg) => {
|
||||
observer.error(msg);
|
||||
observer.complete();
|
||||
};
|
||||
this.zone.run(() => {
|
||||
try {
|
||||
const client = this.createClient(cb, deprecatedHeaders);
|
||||
client[name](...args, (ex: Exception, result) => {
|
||||
if (ex) observer.error(ex);
|
||||
else observer.next(result);
|
||||
observer.complete();
|
||||
});
|
||||
} catch (e) {
|
||||
cb(e);
|
||||
}
|
||||
});
|
||||
}).pipe(timeout(60000 * 3))) as any;
|
||||
from(this.keycloakService.getToken()).pipe(
|
||||
switchMap(
|
||||
(token) =>
|
||||
new Observable<any>((observer) => {
|
||||
const cb = (msg) => {
|
||||
observer.error(msg);
|
||||
observer.complete();
|
||||
};
|
||||
this.zone.run(() => {
|
||||
try {
|
||||
const client = this.createClient(cb, deprecatedHeaders, token);
|
||||
client[name](...args, (ex: Exception, result) => {
|
||||
if (ex) observer.error(ex);
|
||||
else observer.next(result);
|
||||
observer.complete();
|
||||
});
|
||||
} catch (e) {
|
||||
cb(e);
|
||||
}
|
||||
});
|
||||
})
|
||||
),
|
||||
timeout(60000 * 3)
|
||||
)) as any;
|
||||
}
|
||||
|
||||
private createClient(errorCb: (cb: () => void) => void, deprecatedHeaders: boolean) {
|
||||
private createClient(
|
||||
errorCb: (cb: () => void) => void,
|
||||
deprecatedHeaders: boolean,
|
||||
token: string
|
||||
) {
|
||||
const { email, preferred_username, sub } = this.keycloakTokenInfoService.decodedUserToken;
|
||||
return connectClient(
|
||||
location.hostname,
|
||||
@ -71,6 +88,12 @@ export class ThriftService {
|
||||
'x-rbk-meta-user-identity.id': sub,
|
||||
}
|
||||
: undefined),
|
||||
...(this.wachterServiceName
|
||||
? {
|
||||
...createWachterHeaders(this.wachterServiceName),
|
||||
...createAuthorizationHeaders(token),
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
deadlineConfig: {
|
||||
amount: 3,
|
||||
|
Loading…
Reference in New Issue
Block a user