This commit is contained in:
crusader 2018-03-18 20:53:34 +09:00
parent fe9e3cd8f3
commit 272284e425
30 changed files with 373 additions and 92 deletions

View File

@ -63,6 +63,7 @@
"protractor": "~5.1.2",
"ts-node": "~4.1.0",
"tslint": "~5.9.1",
"typescript": "~2.5.3"
"typescript": "~2.5.3",
"typescript-string-enums": "^0.3.5"
}
}

View File

@ -12,20 +12,15 @@ import { combineReducers, ActionReducer, ActionReducerMap, MetaReducer } from '@
import { SimpleRouterStateSerializer } from './commons/util/ngrx/router-store/serializer/simple-router-state-serializer';
import { environment } from '../environments/environment';
import { EFFECTS } from './commons/store';
import * as AppStore from './commons/store';
export interface AppState {
}
export const reducers: ActionReducerMap<AppState> = {
};
@NgModule({
exports: [
StoreModule,
],
imports: [
StoreModule.forRoot(reducers),
StoreModule.forRoot(AppStore.REDUCERS),
/**
* @ngrx/router-store keeps router state up-to-date in the store.
*/
@ -51,7 +46,7 @@ export const reducers: ActionReducerMap<AppState> = {
maxAge: 50,
logOnly: environment.production,
}),
EffectsModule.forRoot(EFFECTS),
EffectsModule.forRoot(AppStore.EFFECTS),
],
providers: [
/**

View File

@ -30,6 +30,8 @@ import { AppComponent } from './app.component';
import { environment } from '../environments/environment';
import { RPCService } from './commons/service/rpc.service';
import { RESTService } from './commons/service/rest.service';
import { AuthGuard } from './commons/guard/auth.guard';
@ -60,6 +62,7 @@ import { AuthGuard } from './commons/guard/auth.guard';
{
provide: RPCClient, useClass: RPCService
},
CookieService,
AuthGuard,
],

View File

@ -1,4 +1,5 @@
import { Injectable, Inject } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
@ -6,6 +7,11 @@ import { Subject } from 'rxjs/Subject';
import { RPCClient } from 'packages/core/rpc/client/RPCClient';
import { RPCClientCodec } from 'packages/core/rpc/protocol/RPCClientCodec';
import { RPCClientRWC } from 'packages/core/rpc/client/rwc/RPCClientRWC';
import { RPCClientNotificationCodec } from 'packages/core/rpc/protocol/RPCClientCodec';
import { notificationAction } from 'packages/core/rpc/store/notification';
import * as AppStore from '../store';
@Injectable()
@ -13,7 +19,12 @@ export class RPCService extends RPCClient {
constructor(
private _rpcClientCodec: RPCClientCodec,
private _rpcClientRWC: RPCClientRWC,
private store: Store<AppStore.State>,
) {
super(_rpcClientCodec, _rpcClientRWC);
}
protected onNotification(notiCodec: RPCClientNotificationCodec): void {
this.store.dispatch(notificationAction(notiCodec.method(), notiCodec.params()));
}
}

View File

@ -1,5 +1,13 @@
import { ActionReducerMap } from '@ngrx/store';
import * as SigninInitStore from './signin-init';
export interface State {
}
export const REDUCERS: ActionReducerMap<State> = {
};
export const EFFECTS = [
SigninInitStore.Effects,
];

View File

@ -2,15 +2,19 @@ import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { RPCClientRWC } from './rwc/RPCClientRWC';
import { RPCRegistry } from './../registry/RPCRegistry';
import { RPCClientCodec, RPCClientResponseCodec } from '../protocol/RPCClientCodec';
import {
RPCClientCodec,
RPCClientResponseCodec,
RPCClientNotificationCodec,
} from '../protocol/RPCClientCodec';
export interface RPCRequestState {
subject: Subject<any>;
request: any;
}
export class RPCClient {
export abstract class RPCClient {
private _requestID: number;
private _pendingRequestsCount: number;
@ -56,15 +60,15 @@ export class RPCClient {
/**
* notify
*/
public notify(method: string, ...args: any[]): void {
this.send(false, method, args);
public send(method: string, ...args: any[]): void {
this.sendInternal(false, method, args);
}
/**
* call
*/
public call<T>(method: string, ...args: any[]): Observable<T> {
return this.send<T>(true, method, args);
return this.sendInternal<T>(true, method, args);
}
/**
@ -75,7 +79,7 @@ export class RPCClient {
return undefined;
}
private send<T>(hasResponse: boolean, method: string, args?: any[]): Observable<T> | undefined {
private sendInternal<T>(hasResponse: boolean, method: string, args?: any[]): Observable<T> | undefined {
let id: number;
let resSubject: Subject<T>;
if (hasResponse) {
@ -95,7 +99,10 @@ export class RPCClient {
private onMessage(message: Object): void {
const resCodec = this._codec.response(message);
if (undefined !== resCodec.id()) {
if (resCodec.isNotification()) {
this.onNotification(resCodec.notification());
} else {
this.onResponse(resCodec);
}
}
@ -116,4 +123,6 @@ export class RPCClient {
resSubject.error(error);
}
}
protected abstract onNotification(notiCodec: RPCClientNotificationCodec): void;
}

View File

@ -9,4 +9,12 @@ export abstract class RPCClientResponseCodec {
abstract id(): number | undefined;
abstract error(): RPCError | undefined;
abstract result(): any | undefined;
abstract isNotification(): boolean;
abstract notification(): RPCClientNotificationCodec | undefined;
}
export abstract class RPCClientNotificationCodec {
public abstract method(): string;
public abstract params(): any | undefined;
}

View File

@ -1,12 +1,18 @@
import {
RPCClientCodec,
RPCClientResponseCodec,
RPCClientNotificationCodec,
} from '../RPCClientCodec';
import {
RPCError,
} from '../../error';
export interface ClientNotification {
method: string;
params?: any[];
}
export interface ClientRequest {
jsonrpc: string;
method: string;
@ -56,4 +62,35 @@ export class RPCClientJSONResponseCodec extends RPCClientResponseCodec {
public result(): any | undefined {
return this._res.result;
}
public isNotification(): boolean {
if (undefined !== this.id() || undefined === this.result()) {
return false;
}
return true;
}
public notification(): RPCClientNotificationCodec | undefined {
if (undefined !== this.id() || undefined === this.result()) {
return undefined;
}
const _noti: ClientNotification = {
method: this._res.result.method,
params: this._res.result.params,
};
return new RPCClientJSONNotificationCodec(_noti);
}
}
export class RPCClientJSONNotificationCodec extends RPCClientNotificationCodec {
public constructor(private _noti: ClientNotification) {
super();
}
public method(): string {
return this._noti.method;
}
public params(): any[] | undefined {
return this._noti.params;
}
}

View File

@ -1,17 +0,0 @@
export class RPCInvoker {
/**
* hasMethod
*/
public hasMethod(method: string): boolean {
return false;
}
/**
* invoke
*/
public invoke() {
}
}

View File

@ -1,18 +0,0 @@
import { RPCInvoker } from './RPCInvoker';
export class RPCRegistry extends RPCInvoker {
/**
* registerService
*/
public registerService<T>(receiver: T, name: string) {
}
/**
* getService
*/
public getService<T>(name: string): T {
return undefined;
}
}

View File

@ -0,0 +1 @@
export * from './notification.action';

View File

@ -0,0 +1,18 @@
import { Action } from '@ngrx/store';
export interface NotificationAction extends Action {
payload?: any;
}
export function notificationActionEnum(method: string): string {
return `[@@NOTIFICATION] ${method}`;
}
export function notificationAction(method: string, params: any): Action {
const action: NotificationAction = {
type: notificationActionEnum(method),
payload: params,
};
return action;
}

View File

@ -0,0 +1,10 @@
import { DiscoveryPort } from './DiscoveryPort';
export interface DiscoveryHost {
firstScanRange: string;
lastScanRange: string;
excludeHosts: string[];
includeHosts: string[];
discoveryPort: DiscoveryPort;
}

View File

@ -0,0 +1,11 @@
import { DiscoveryService } from './DiscoveryService';
export interface DiscoveryPort {
firstScanRange: number;
lastScanRange: number;
excludePorts: number[];
includeTCP: boolean;
includeUDP: boolean;
discoveryService: DiscoveryService;
}

View File

@ -0,0 +1,3 @@
export interface DiscoveryService {
includeServices: string[];
}

View File

@ -0,0 +1,7 @@
import { DiscoveryHost } from './DiscoveryHost';
export interface DiscoveryZone {
excludePatterns: string[];
discoveryHost: DiscoveryHost;
}

View File

@ -1,16 +1,13 @@
import Port from './Port';
import Zone from './Zone';
import { Zone } from './Zone';
import { Port } from './Port';
interface Host {
export interface Host {
id?: number;
ip: number;
ip: string;
mac: number;
createDate?: Date;
updateDate: Date;
os: string;
target: boolean;
ports?: Port[];
discoveredDate?: Date;
zone?: Zone;
}
export default Host;
ports: Map<number, Port> | null;
}

View File

@ -1,15 +1,13 @@
import Host from './Host';
import Service from './Service';
import PortType from './PortType';
import { Host } from './Host';
import { PortType } from './PortType';
import { Service } from './Service';
interface Port {
export interface Port {
id?: number;
host: Host;
portType: PortType;
portNumber: number;
services?: Service[];
createDate?: Date;
updateDate: Date;
}
discoveredDate?: Date;
host: Host;
export default Port;
services: Map<string, Service> | null;
}

View File

@ -5,6 +5,4 @@
// TLS = 3,
// }
type PortType = 'TCP' | 'UDP' | 'TLS';
export default PortType;
export type PortType = 'TCP' | 'UDP' | 'TLS';

View File

@ -1,14 +1,9 @@
import Port from './Port';
import PortType from './PortType';
import { Port } from './Port';
interface Service {
export interface Service {
id: number;
port: Port;
portType: PortType;
cryptoType: string;
serviceName: string;
createDate: Date;
updateDate: Date;
target: boolean;
discoveredDate?: Date;
port: Port;
}
export default Service;

View File

@ -1,4 +1,4 @@
import Host from './Host';
import { Host } from './Host';
export interface Zone {
id?: number;
@ -6,9 +6,7 @@ export interface Zone {
ip?: string;
iface?: string;
mac?: string;
firstScanRange?: number;
lastScanRange?: number;
hosts?: Host[];
}
discoveredDate?: Date;
export default Zone;
hosts: Map<string, Host> | null;
}

View File

@ -1,3 +1,7 @@
export * from './DiscoveryHost';
export * from './DiscoveryPort';
export * from './DiscoveryService';
export * from './DiscoveryZone';
export * from './DiscoveryStartInfo';
export * from './Host';
export * from './Port';

View File

@ -1,7 +1,17 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { RPCClient } from 'packages/core/rpc/client/RPCClient';
import { DiscoveryStartInfo } from '../model';
import {
DiscoveryStartInfo,
DiscoveryZone,
DiscoveryHost,
DiscoveryPort,
DiscoveryService as M_DiscoveryService,
Zone,
Host,
Port,
Service,
} from '../model';
@Injectable()
export class DiscoveryService {
@ -16,4 +26,17 @@ export class DiscoveryService {
return this.rpcClient.call('DiscoveryService.startDiscovery', dsInfo);
}
public discoverZone(probeID: string, discoveryZone: DiscoveryZone): void {
this.rpcClient.send('DiscoveryService.discoverZone', probeID, discoveryZone);
}
public discoverHost(probeID: string, zone: Zone, discoveryHost: DiscoveryHost): void {
this.rpcClient.send('DiscoveryService.discoverHost', probeID, zone, discoveryHost);
}
public discoverPort(probeID: string, host: Host, discoveryPort: DiscoveryPort): void {
this.rpcClient.send('DiscoveryService.discoverPort', probeID, host, discoveryPort);
}
public discoverService(probeID: string, port: Port, discoveryService: M_DiscoveryService): void {
this.rpcClient.send('DiscoveryService.discoverService', probeID, port, discoveryService);
}
}

View File

@ -1,14 +1,36 @@
import {
createSelector,
createFeatureSelector,
ActionReducerMap,
Selector,
} from '@ngrx/store';
import { StateSelector } from 'packages/core/ngrx/store';
import { MODULE } from '../discovery.constant';
import * as NotificationStore from './notification';
import * as SettingStore from './setting';
export interface State {
notification: NotificationStore.State;
setting: SettingStore.State;
}
export const REDUCERS = {
notification: NotificationStore.reducer,
setting: SettingStore.reducer,
};
export const EFFECTS = [
SettingStore.Effects,
];
export const selectDiscoveryState = createFeatureSelector<State>(MODULE.name);
export const NotificationSelector = new StateSelector<NotificationStore.State>(createSelector(
selectDiscoveryState,
(state: State) => state.notification
));

View File

@ -0,0 +1,3 @@
export * from './notification.action';
export * from './notification.reducer';
export * from './notification.state';

View File

@ -0,0 +1,50 @@
import { Action } from '@ngrx/store';
import { Enum } from 'typescript-string-enums';
import { notificationActionEnum } from 'packages/core/rpc/store/notification';
import { RPCError } from 'packages/core/rpc/error';
import {
Zone,
Host,
Port,
Service,
} from '../../model';
export enum ActionType {
DiscoveredZone = '[@@NOTIFICATION] DiscoveryService.discoveredZone',
DiscoveredHost = '[@@NOTIFICATION] DiscoveryService.discoveredHost',
DiscoveredPort = '[@@NOTIFICATION] DiscoveryService.discoveredPort',
DiscoveredService = '[@@NOTIFICATION] DiscoveryService.discoveredService',
}
export class DiscoveredZone implements Action {
readonly type = ActionType.DiscoveredZone;
constructor(public payload: Zone) {}
}
export class DiscoveredHost implements Action {
readonly type = ActionType.DiscoveredHost;
constructor(public payload: Host) {}
}
export class DiscoveredPort implements Action {
readonly type = ActionType.DiscoveredPort;
constructor(public payload: Port) {}
}
export class DiscoveredService implements Action {
readonly type = ActionType.DiscoveredService;
constructor(public payload: Service) {}
}
export type Actions =
| DiscoveredZone
| DiscoveredHost
| DiscoveredPort
| DiscoveredService
;

View File

@ -0,0 +1,86 @@
import { RPCError } from 'packages/core/rpc/error';
import {
Actions,
ActionType,
} from './notification.action';
import {
State,
initialState,
} from './notification.state';
import {
Zone,
Host,
Port,
Service,
} from '../../model';
export function reducer(state = initialState, action: Actions): State {
switch (action.type) {
case ActionType.DiscoveredZone: {
const zone: Zone = <Zone>action.payload;
state.zones.set(zone.network, zone);
return state;
}
case ActionType.DiscoveredHost: {
const host: Host = <Host>action.payload;
const zone = state.zones.get(host.zone.network);
if (undefined === zone) {
console.error(`Discovery.discoveredHost: Zone[${host.zone.network}] is not exist`);
}
if (null === zone.hosts) {
zone.hosts = new Map();
}
zone.hosts.set(host.ip, host);
return state;
}
case ActionType.DiscoveredPort: {
const port: Port = <Port>action.payload;
const zone = state.zones.get(port.host.zone.network);
if (undefined === zone) {
console.error(`Discovery.DiscoveredPort: Zone[${port.host.zone.network}] is not exist`);
}
if (null === zone.hosts || undefined === zone.hosts.get(port.host.ip)) {
console.error(`Discovery.DiscoveredPort: Host[${port.host.ip}] is not exist`);
}
const host: Host = zone.hosts.get(port.host.ip);
if (null === host.ports) {
host.ports = new Map();
}
host.ports.set(port.portNumber, port);
return state;
}
case ActionType.DiscoveredService: {
const service: Service = <Service>action.payload;
const zone = state.zones.get(service.port.host.zone.network);
if (undefined === zone) {
console.error(`Discovery.DiscoveredService: Zone[${service.port.host.zone.network}] is not exist`);
}
if (null === zone.hosts || undefined === zone.hosts.get(service.port.host.ip)) {
console.error(`Discovery.DiscoveredPort: Host[${service.port.host.ip}] is not exist`);
}
const host: Host = zone.hosts.get(service.port.host.ip);
if (null === host.ports || undefined === host.ports.get(service.port.portNumber)) {
console.error(`Discovery.DiscoveredPort: Port[${service.port.portNumber}] is not exist`);
}
const port: Port = host.ports.get(service.port.portNumber);
if (null === port.services) {
port.services = new Map();
}
port.services.set(service.serviceName, service);
return state;
}
default: {
return state;
}
}
}

View File

@ -0,0 +1,15 @@
import { RPCError } from 'packages/core/rpc/error';
import { Zone } from '../../model';
export interface State {
error: RPCError | null;
processing: boolean;
zones: Map<string, Zone> | null;
}
export const initialState: State = {
error: null,
processing: false,
zones: null,
};

View File

@ -2,6 +2,7 @@ import {
createSelector,
createFeatureSelector,
ActionReducerMap,
Selector,
} from '@ngrx/store';
import { StateSelector } from 'packages/core/ngrx/store';

View File

@ -7113,6 +7113,10 @@ typedarray@~0.0.5:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
typescript-string-enums@^0.3.5:
version "0.3.5"
resolved "https://registry.yarnpkg.com/typescript-string-enums/-/typescript-string-enums-0.3.5.tgz#00f5c30422ec5d8061ed49a0fe06610ae99f02a2"
typescript@~2.5.3:
version "2.5.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.3.tgz#df3dcdc38f3beb800d4bc322646b04a3f6ca7f0d"