diff --git a/package.json b/package.json index 314f4f8..aa6b365 100644 --- a/package.json +++ b/package.json @@ -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" } } diff --git a/src/app/app-store.module.ts b/src/app/app-store.module.ts index bbb2785..565c473 100644 --- a/src/app/app-store.module.ts +++ b/src/app/app-store.module.ts @@ -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 = { -}; @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 = { maxAge: 50, logOnly: environment.production, }), - EffectsModule.forRoot(EFFECTS), + EffectsModule.forRoot(AppStore.EFFECTS), ], providers: [ /** diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 26e2411..8abd564 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -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, ], diff --git a/src/app/commons/service/rpc.service.ts b/src/app/commons/service/rpc.service.ts index 340e23b..7febfb0 100644 --- a/src/app/commons/service/rpc.service.ts +++ b/src/app/commons/service/rpc.service.ts @@ -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, ) { super(_rpcClientCodec, _rpcClientRWC); } + + protected onNotification(notiCodec: RPCClientNotificationCodec): void { + this.store.dispatch(notificationAction(notiCodec.method(), notiCodec.params())); + } } diff --git a/src/app/commons/store/index.ts b/src/app/commons/store/index.ts index b5f3921..64ea21e 100644 --- a/src/app/commons/store/index.ts +++ b/src/app/commons/store/index.ts @@ -1,5 +1,13 @@ +import { ActionReducerMap } from '@ngrx/store'; + import * as SigninInitStore from './signin-init'; +export interface State { +} + +export const REDUCERS: ActionReducerMap = { +}; + export const EFFECTS = [ SigninInitStore.Effects, ]; diff --git a/src/packages/core/rpc/client/RPCClient.ts b/src/packages/core/rpc/client/RPCClient.ts index f436d46..3758ea1 100644 --- a/src/packages/core/rpc/client/RPCClient.ts +++ b/src/packages/core/rpc/client/RPCClient.ts @@ -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; 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(method: string, ...args: any[]): Observable { - return this.send(true, method, args); + return this.sendInternal(true, method, args); } /** @@ -75,7 +79,7 @@ export class RPCClient { return undefined; } - private send(hasResponse: boolean, method: string, args?: any[]): Observable | undefined { + private sendInternal(hasResponse: boolean, method: string, args?: any[]): Observable | undefined { let id: number; let resSubject: Subject; 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; } diff --git a/src/packages/core/rpc/protocol/RPCClientCodec.ts b/src/packages/core/rpc/protocol/RPCClientCodec.ts index 61ace58..e5de713 100644 --- a/src/packages/core/rpc/protocol/RPCClientCodec.ts +++ b/src/packages/core/rpc/protocol/RPCClientCodec.ts @@ -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; } diff --git a/src/packages/core/rpc/protocol/json/RPCClientJSONCodec.ts b/src/packages/core/rpc/protocol/json/RPCClientJSONCodec.ts index 1ea9cab..d87534b 100644 --- a/src/packages/core/rpc/protocol/json/RPCClientJSONCodec.ts +++ b/src/packages/core/rpc/protocol/json/RPCClientJSONCodec.ts @@ -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; + } } diff --git a/src/packages/core/rpc/registry/RPCInvoker.ts b/src/packages/core/rpc/registry/RPCInvoker.ts deleted file mode 100644 index aadf8e2..0000000 --- a/src/packages/core/rpc/registry/RPCInvoker.ts +++ /dev/null @@ -1,17 +0,0 @@ - -export class RPCInvoker { - - /** - * hasMethod - */ - public hasMethod(method: string): boolean { - return false; - } - - /** - * invoke - */ - public invoke() { - - } -} diff --git a/src/packages/core/rpc/registry/RPCRegistry.ts b/src/packages/core/rpc/registry/RPCRegistry.ts deleted file mode 100644 index 074572b..0000000 --- a/src/packages/core/rpc/registry/RPCRegistry.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { RPCInvoker } from './RPCInvoker'; - -export class RPCRegistry extends RPCInvoker { - - /** - * registerService - */ - public registerService(receiver: T, name: string) { - - } - - /** - * getService - */ - public getService(name: string): T { - return undefined; - } -} diff --git a/src/packages/core/rpc/store/notification/index.ts b/src/packages/core/rpc/store/notification/index.ts new file mode 100644 index 0000000..2bf53bc --- /dev/null +++ b/src/packages/core/rpc/store/notification/index.ts @@ -0,0 +1 @@ +export * from './notification.action'; diff --git a/src/packages/core/rpc/store/notification/notification.action.ts b/src/packages/core/rpc/store/notification/notification.action.ts new file mode 100644 index 0000000..a322323 --- /dev/null +++ b/src/packages/core/rpc/store/notification/notification.action.ts @@ -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; +} + diff --git a/src/packages/discovery/model/DiscoveryHost.ts b/src/packages/discovery/model/DiscoveryHost.ts new file mode 100644 index 0000000..9c04c20 --- /dev/null +++ b/src/packages/discovery/model/DiscoveryHost.ts @@ -0,0 +1,10 @@ +import { DiscoveryPort } from './DiscoveryPort'; + +export interface DiscoveryHost { + firstScanRange: string; + lastScanRange: string; + excludeHosts: string[]; + includeHosts: string[]; + + discoveryPort: DiscoveryPort; +} diff --git a/src/packages/discovery/model/DiscoveryPort.ts b/src/packages/discovery/model/DiscoveryPort.ts new file mode 100644 index 0000000..0320c47 --- /dev/null +++ b/src/packages/discovery/model/DiscoveryPort.ts @@ -0,0 +1,11 @@ +import { DiscoveryService } from './DiscoveryService'; + +export interface DiscoveryPort { + firstScanRange: number; + lastScanRange: number; + excludePorts: number[]; + includeTCP: boolean; + includeUDP: boolean; + + discoveryService: DiscoveryService; +} diff --git a/src/packages/discovery/model/DiscoveryService.ts b/src/packages/discovery/model/DiscoveryService.ts new file mode 100644 index 0000000..96ffe70 --- /dev/null +++ b/src/packages/discovery/model/DiscoveryService.ts @@ -0,0 +1,3 @@ +export interface DiscoveryService { + includeServices: string[]; +} diff --git a/src/packages/discovery/model/DiscoveryZone.ts b/src/packages/discovery/model/DiscoveryZone.ts new file mode 100644 index 0000000..d3aba60 --- /dev/null +++ b/src/packages/discovery/model/DiscoveryZone.ts @@ -0,0 +1,7 @@ +import { DiscoveryHost } from './DiscoveryHost'; + +export interface DiscoveryZone { + excludePatterns: string[]; + + discoveryHost: DiscoveryHost; +} diff --git a/src/packages/discovery/model/Host.ts b/src/packages/discovery/model/Host.ts index 3783f60..2d358ea 100644 --- a/src/packages/discovery/model/Host.ts +++ b/src/packages/discovery/model/Host.ts @@ -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 | null; +} diff --git a/src/packages/discovery/model/Port.ts b/src/packages/discovery/model/Port.ts index 8302d4d..6f6dbda 100644 --- a/src/packages/discovery/model/Port.ts +++ b/src/packages/discovery/model/Port.ts @@ -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 | null; +} diff --git a/src/packages/discovery/model/PortType.ts b/src/packages/discovery/model/PortType.ts index 26c1130..6b864bf 100644 --- a/src/packages/discovery/model/PortType.ts +++ b/src/packages/discovery/model/PortType.ts @@ -5,6 +5,4 @@ // TLS = 3, // } -type PortType = 'TCP' | 'UDP' | 'TLS'; - -export default PortType; +export type PortType = 'TCP' | 'UDP' | 'TLS'; diff --git a/src/packages/discovery/model/Service.ts b/src/packages/discovery/model/Service.ts index 2297bc4..2549d06 100644 --- a/src/packages/discovery/model/Service.ts +++ b/src/packages/discovery/model/Service.ts @@ -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; diff --git a/src/packages/discovery/model/Zone.ts b/src/packages/discovery/model/Zone.ts index c60435b..6eaa24b 100644 --- a/src/packages/discovery/model/Zone.ts +++ b/src/packages/discovery/model/Zone.ts @@ -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 | null; +} diff --git a/src/packages/discovery/model/index.ts b/src/packages/discovery/model/index.ts index c59956a..c2583d5 100644 --- a/src/packages/discovery/model/index.ts +++ b/src/packages/discovery/model/index.ts @@ -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'; diff --git a/src/packages/discovery/service/discovery.service.ts b/src/packages/discovery/service/discovery.service.ts index 82d1026..ab229e0 100644 --- a/src/packages/discovery/service/discovery.service.ts +++ b/src/packages/discovery/service/discovery.service.ts @@ -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); + } } diff --git a/src/packages/discovery/store/index.ts b/src/packages/discovery/store/index.ts index a82a213..977eefb 100644 --- a/src/packages/discovery/store/index.ts +++ b/src/packages/discovery/store/index.ts @@ -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(MODULE.name); + +export const NotificationSelector = new StateSelector(createSelector( + selectDiscoveryState, + (state: State) => state.notification +)); diff --git a/src/packages/discovery/store/notification/index.ts b/src/packages/discovery/store/notification/index.ts new file mode 100644 index 0000000..f9e09d0 --- /dev/null +++ b/src/packages/discovery/store/notification/index.ts @@ -0,0 +1,3 @@ +export * from './notification.action'; +export * from './notification.reducer'; +export * from './notification.state'; diff --git a/src/packages/discovery/store/notification/notification.action.ts b/src/packages/discovery/store/notification/notification.action.ts new file mode 100644 index 0000000..52b43ac --- /dev/null +++ b/src/packages/discovery/store/notification/notification.action.ts @@ -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 +; diff --git a/src/packages/discovery/store/notification/notification.reducer.ts b/src/packages/discovery/store/notification/notification.reducer.ts new file mode 100644 index 0000000..b781753 --- /dev/null +++ b/src/packages/discovery/store/notification/notification.reducer.ts @@ -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 = action.payload; + state.zones.set(zone.network, zone); + + return state; + } + + case ActionType.DiscoveredHost: { + const 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 = 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 = 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; + } + } +} diff --git a/src/packages/discovery/store/notification/notification.state.ts b/src/packages/discovery/store/notification/notification.state.ts new file mode 100644 index 0000000..1299095 --- /dev/null +++ b/src/packages/discovery/store/notification/notification.state.ts @@ -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 | null; +} + +export const initialState: State = { + error: null, + processing: false, + zones: null, +}; diff --git a/src/packages/member/store/index.ts b/src/packages/member/store/index.ts index ae97d0d..4ab9499 100644 --- a/src/packages/member/store/index.ts +++ b/src/packages/member/store/index.ts @@ -2,6 +2,7 @@ import { createSelector, createFeatureSelector, ActionReducerMap, + Selector, } from '@ngrx/store'; import { StateSelector } from 'packages/core/ngrx/store'; diff --git a/yarn.lock b/yarn.lock index 61d9491..1a62f59 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"