discovery.. etc

This commit is contained in:
insanity 2018-03-16 19:28:50 +09:00
parent e75b382035
commit fe9e3cd8f3
23 changed files with 383 additions and 222 deletions

View File

@ -1,57 +1,5 @@
<mat-tab-group>
<mat-tab label="Zone">
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>Zone - 192.168.1.0/24</mat-card-title>
<mat-card-subtitle>Windows / Probe</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<mat-grid-list cols="2" rowHeight="5:1">
<mat-grid-tile>Host</mat-grid-tile>
<mat-grid-tile>192.168.1.162</mat-grid-tile>
</mat-grid-list>
<mat-grid-list cols="2" rowHeight="5:1">
<mat-grid-tile>Service</mat-grid-tile>
<mat-grid-tile>FTP MySQL SMB</mat-grid-tile>
</mat-grid-list>
<mat-grid-list cols="2" rowHeight="5:1">
<mat-grid-tile>Sensor(2)</mat-grid-tile>
<mat-grid-tile>
MySQL SNMP
<button mat-button>Add Sensor</button>
</mat-grid-tile>
</mat-grid-list>
</mat-card-content>
<!-- <mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions> -->
</mat-card>
</mat-tab>
<mat-tab label="Host">
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>Host - 192.168.1.106</mat-card-title>
<mat-card-subtitle>MySQL</mat-card-subtitle>
</mat-card-header>
<button mat-raised-button color="primary" (click)="authProbe()">Probe 인증</button>
<button mat-raised-button color="primary" (click)="discovery()">Probe Discovery</button>
<mat-card-content>
<mat-grid-list cols="2" rowHeight="5:1">
<mat-grid-tile>MySQL</mat-grid-tile>
<mat-grid-tile>Port : 3306 | TCP | TLS</mat-grid-tile>
</mat-grid-list>
<mat-grid-list cols="2" rowHeight="5:1">
<mat-grid-tile>Sensor</mat-grid-tile>
<mat-grid-tile>PostgreSQL
<button mat-button>Add Sensor</button>
</mat-grid-tile>
</mat-grid-list>
</mat-card-content>
<!-- <mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions> -->
</mat-card>
</mat-tab>
</mat-tab-group>
<of-infra-map></of-infra-map>

View File

@ -1,8 +0,0 @@
.example-card {
width: 400px;
}
.example-header-image {
background-image: url('https://material.angular.io/assets/img/examples/shiba1.jpg');
background-size: cover;
}

View File

@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material';
import { SettingComponent as DiscoverySettingComponent } from 'packages/discovery/component/setting/setting.component';
@Component({
selector: 'of-infra-page',
@ -7,9 +9,24 @@ import { Component, OnInit } from '@angular/core';
})
export class InfraPageComponent implements OnInit {
constructor() { }
constructor(
private dialog: MatDialog
) { }
ngOnInit() {
}
discovery() {
const dialogRef = this.dialog.open(DiscoverySettingComponent, {
width: '80%',
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
});
}
authProbe() {
}
}

View File

@ -7,6 +7,7 @@ import { InfraPageRoutingModule } from './infra-page-routing.module';
import { MaterialModule } from 'app/commons/ui/material/material.module';
import { InfraModule } from 'packages/infra/infra.module';
import { SettingComponent as DiscoverySettingComponent } from 'packages/discovery/component/setting/setting.component';
@NgModule({
imports: [
@ -15,6 +16,11 @@ import { InfraModule } from 'packages/infra/infra.module';
MaterialModule,
InfraModule
],
declarations: [InfraPageComponent]
declarations: [
InfraPageComponent
],
entryComponents: [
DiscoverySettingComponent
]
})
export class InfraPageModule { }

View File

@ -1,3 +1,90 @@
<p>
map works!
</p>
<mat-tab-group>
<mat-tab label="Zone">
<!-- zone -->
<mat-card class="infra-card">
<mat-card-header>
<mat-card-title>Zone - 192.168.1.0/24</mat-card-title>
</mat-card-header>
<mat-card-content *ngFor="let infra of infras" matTooltip="이렇게 마우스 오버하면 Meta 정보 출력할꺼야">
<mat-grid-list cols="4" rowHeight="5:1">
<mat-grid-tile [colspan]="1" [rowspan]="3">
{{infra.target.displayName}}
</mat-grid-tile>
<mat-grid-tile [colspan]="2" [rowspan]="1" class="text-inside-grid">
<div class="text-inside-grid">
{{infra.infraType.name}}
</div>
</mat-grid-tile>
<mat-grid-tile [colspan]="1" [rowspan]="1">
</mat-grid-tile>
<mat-grid-tile [colspan]="2" [rowspan]="1" class="text-inside-grid">
<div class="text-inside-grid">????</div>
</mat-grid-tile>
<mat-grid-tile [colspan]="1" [rowspan]="1">
</mat-grid-tile>
<mat-grid-tile [colspan]="2" [rowspan]="1" class="text-inside-grid">
<div class="text-inside-grid">?????</div>
</mat-grid-tile>
<mat-grid-tile [colspan]="1" [rowspan]="1">
<div class="add-sensor-button">
<button mat-raised-button color="primary" (click)="addSensor(infra)">Add Sensor</button>
</div>
</mat-grid-tile>
</mat-grid-list>
<!-- <mat-grid-list cols="3" rowHeight="5:1">
<mat-grid-tile>{{infra.infraType.name}}</mat-grid-tile>
<mat-grid-tile>192.168.1.162</mat-grid-tile>
<mat-grid-tile></mat-grid-tile>
</mat-grid-list>
<mat-grid-list cols="3" rowHeight="5:1">
<mat-grid-tile>Service</mat-grid-tile>
<mat-grid-tile>FTP MySQL SMB</mat-grid-tile>
<mat-grid-tile></mat-grid-tile>
</mat-grid-list>
<mat-grid-list cols="3" rowHeight="5:1">
<mat-grid-tile>Sensor(2)</mat-grid-tile>
<mat-grid-tile>
MySQL SNMP
</mat-grid-tile>
<mat-grid-tile>
<button mat-raised-button color="primary" fxLayoutAlign="end">Add Sensor</button>
</mat-grid-tile>
</mat-grid-list> -->
<mat-divider></mat-divider>
</mat-card-content>
</mat-card>
</mat-tab>
<!-- host -->
<mat-tab label="Host">
<mat-card class="infra-card">
<mat-card-header>
<mat-card-title>Host - 192.168.1.106</mat-card-title>
<mat-card-subtitle>MySQL</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<mat-grid-list cols="2" rowHeight="5:1">
<mat-grid-tile>MySQL</mat-grid-tile>
<mat-grid-tile>Port : 3306 | TCP | TLS</mat-grid-tile>
</mat-grid-list>
<mat-grid-list cols="2" rowHeight="5:1">
<mat-grid-tile>Sensor</mat-grid-tile>
<mat-grid-tile>PostgreSQL
<button mat-button>Add Sensor</button>
</mat-grid-tile>
</mat-grid-list>
</mat-card-content>
<!-- <mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions> -->
</mat-card>
</mat-tab>
</mat-tab-group>

View File

@ -0,0 +1,13 @@
.infra-card {
width: 70%;
}
.text-inside-grid {
position: absolute;
left: 5px;
}
.add-sensor-button {
position: absolute;
right: 1px;
}

View File

@ -1,15 +1,78 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, AfterContentInit } from '@angular/core';
import { Infra, InfraHost, InfraOSApplication } from '../../model';
import { Store, select } from '@ngrx/store';
import { RPCError } from 'packages/core/rpc/error';
import { AuthSelector } from 'packages/member/store';
import * as ListStore from '../../store/list';
import { ListSelector } from '../../store';
import { Page, PageParams } from 'app/commons/model';
import { Domain } from '../../../domain/model';
import { MatDialog } from '@angular/material';
import { SensorSettingPageComponent } from 'app/pages/sensor-setting/sensor-setting-page.component';
@Component({
selector: 'of-map',
selector: 'of-infra-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {
export class MapComponent implements OnInit, AfterContentInit {
constructor() { }
infras$ = this.listStore.pipe(select(ListSelector.select('page')));
infras: Infra[];
constructor(
private listStore: Store<ListStore.State>,
public dialog: MatDialog
) { }
ngOnInit() {
this.infras$.subscribe(
(page: Page) => {
if (page !== null) {
console.log(page);
this.infras = page.content;
}
},
(error: RPCError) => {
console.log(error.message);
}
);
}
ngAfterContentInit() {
this.getInfraList();
}
getInfraList() {
this.listStore.select(AuthSelector.select('domain')).subscribe(
(domain: Domain) => {
const pageParams: PageParams = {
pageNo: '0',
countPerPage: '9999999',
sortCol: 'id',
sortDirection: 'descending'
};
this.listStore.dispatch(new ListStore.ReadAllByDomain({domain, pageParams}));
},
(error) => {
console.log(error);
}
);
}
addSensor(infra: Infra) {
const targetId = infra.target.id;
console.log(targetId);
const dialogRef = this.dialog.open(SensorSettingPageComponent, {
width: '80%',
data: { }
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
});
}
}

View File

@ -7,12 +7,15 @@ import { InfraStoreModule } from './infra-store.module';
import { COMPONENTS } from './component';
import { SERVICES } from './service';
import { SensorSettingPageComponent } from 'app/pages/sensor-setting/sensor-setting-page.component';
import { SensorSettingPageModule } from 'app/pages/sensor-setting/sensor-setting-page.module';
@NgModule({
imports: [
CommonModule,
MaterialModule,
InfraStoreModule
InfraStoreModule,
SensorSettingPageModule
],
declarations: [
COMPONENTS,
@ -22,6 +25,9 @@ import { SERVICES } from './service';
],
providers: [
SERVICES
],
entryComponents: [
SensorSettingPageComponent,
]
})
export class InfraModule { }

View File

@ -6,7 +6,7 @@ import 'rxjs/add/operator/map';
import { RPCClient } from 'packages/core/rpc/client/RPCClient';
import { Infra } from '../model';
import { Page } from '../../../app/commons/model';
import { Page, PageParams } from '../../../app/commons/model';
import { Domain } from '../../domain/model';
import { Probe } from '../../probe/model';
@ -19,11 +19,11 @@ export class InfraService {
}
public readByDomain(domain: Domain): Observable<Page> {
return this.rpcClient.call<Page>('InfraService.', domain);
public readAllByDomain(domain: Domain, pageParams: PageParams): Observable<Page> {
return this.rpcClient.call('InfraService.readAllByDomain', domain, pageParams);
}
public readByProbe(probe: Probe): Observable<Page> {
return this.rpcClient.call<Page>('InfraService.', probe);
public readAllByProbe(probe: Probe, pageParams: PageParams): Observable<Page> {
return this.rpcClient.call('InfraService.readAllByProbe', probe, pageParams);
}
}

View File

@ -6,32 +6,26 @@ import {
import { MODULE } from '../infra.constant';
import * as ReadByDomainStore from './readbydomain';
import * as ListStore from './list';
import { StateSelector } from '../../core/ngrx/store';
export interface State {
readbydomain: ReadByDomainStore.State;
list: ListStore.State;
}
export const REDUCERS = {
readbydomain: ReadByDomainStore.reducer,
list: ListStore.reducer,
};
export const EFFECTS = [
ReadByDomainStore.Effects,
ListStore.Effects,
];
export const selectInfraState = createFeatureSelector<State>(MODULE.name);
export const selectInfraReadByDomainState = createSelector(
export const ListSelector = new StateSelector<ListStore.State>(createSelector(
selectInfraState,
(state: State) => state.readbydomain
);
(state: State) => state.list
));
export const AuthSelector = new ReadByDomainStore.StateSelector(selectInfraReadByDomainState);
export const selectInfraReadByDomianState = createSelector(
selectInfraState,
(state: State) => state.readbydomain
);

View File

@ -0,0 +1,4 @@
export * from './list.action';
export * from './list.effect';
export * from './list.reducer';
export * from './list.state';

View File

@ -0,0 +1,63 @@
import { Action } from '@ngrx/store';
import { RPCError } from 'packages/core/rpc/error';
import { PageParams, Page } from 'app/commons/model';
import { Domain } from '../../../domain/model';
import { Probe } from '../../../probe/model';
export enum ActionType {
ReadAllByDomain = '[Infra.list] ReadAllByDomain',
ReadAllByDomainSuccess = '[Infra.list] ReadAllByDomainSuccess',
ReadAllByDomainFailure = '[Infra.list] ReadAllByDomainFailure',
ReadAllByProbe = '[Infra.list] ReadAllByProbe',
ReadAllByProbeSuccess = '[Infra.list] ReadAllByProbeSuccess',
ReadAllByProbeFailure = '[Infra.list] ReadAllByProbeFailure',
}
export class ReadAllByDomain implements Action {
readonly type = ActionType.ReadAllByDomain;
constructor(public payload: { domain: Domain, pageParams: PageParams }) { }
}
export class ReadAllByDomainSuccess implements Action {
readonly type = ActionType.ReadAllByDomainSuccess;
constructor(public payload: Page) { }
}
export class ReadAllByDomainFailure implements Action {
readonly type = ActionType.ReadAllByDomainFailure;
constructor(public payload: RPCError) { }
}
export class ReadAllByProbe implements Action {
readonly type = ActionType.ReadAllByProbe;
constructor(public payload: { probe: Probe, pageParams: PageParams }) { }
}
export class ReadAllByProbeSuccess implements Action {
readonly type = ActionType.ReadAllByProbeSuccess;
constructor(public payload: Page) { }
}
export class ReadAllByProbeFailure implements Action {
readonly type = ActionType.ReadAllByProbeFailure;
constructor(public payload: RPCError) { }
}
export type Actions =
| ReadAllByDomain
| ReadAllByDomainSuccess
| ReadAllByDomainFailure
| ReadAllByProbe
| ReadAllByProbeSuccess
| ReadAllByProbeFailure
;

View File

@ -1,8 +1,8 @@
import { TestBed, inject } from '@angular/core/testing';
import { Effects } from './readbydomain.effect';
import { Effects } from './list.effect';
describe('Signup.Effects', () => {
describe('list.Effects', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [Effects]

View File

@ -0,0 +1,64 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { Action } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/exhaustMap';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import { RPCError } from 'packages/core/rpc/error';
import { Infra } from '../../model';
import { InfraService } from '../../service/infra.service';
import {
ReadAllByDomain,
ReadAllByDomainSuccess,
ReadAllByDomainFailure,
ReadAllByProbe,
ReadAllByProbeSuccess,
ReadAllByProbeFailure,
ActionType,
} from './list.action';
import { Domain } from 'packages/domain/model';
@Injectable()
export class Effects {
constructor(
private actions$: Actions,
private infraService: InfraService,
private router: Router
) { }
@Effect()
readAllByDomain$: Observable<Action> = this.actions$
.ofType(ActionType.ReadAllByDomain)
.map((action: ReadAllByDomain) => action.payload)
.switchMap(payload => this.infraService.readAllByDomain(payload.domain, payload.pageParams))
.map(page => {
return new ReadAllByDomainSuccess(page);
})
.catch((error: RPCError) => {
return of(new ReadAllByDomainFailure(error));
});
@Effect()
readAllByProbe$: Observable<Action> = this.actions$
.ofType(ActionType.ReadAllByProbe)
.map((action: ReadAllByProbe) => action.payload)
.switchMap(payload => this.infraService.readAllByProbe(payload.probe, payload.pageParams))
.map(page => {
return new ReadAllByProbeSuccess(page);
})
.catch((error: RPCError) => {
return of(new ReadAllByProbeFailure(error));
});
}

View File

@ -1,34 +1,34 @@
import { Actions, ActionType } from './readbydomain.action';
import { Actions, ActionType } from './list.action';
import { State, initialState } from './readbydomain.state';
import { State, initialState } from './list.state';
import { Infra } from '../../model';
export function reducer(state = initialState, action: Actions): State {
switch (action.type) {
case ActionType.Readbydomain: {
case ActionType.ReadAllByDomain: {
return {
...state,
error: null,
isPending: true
isPending: true,
};
}
case ActionType.ReadbydomainSuccess: {
case ActionType.ReadAllByDomainSuccess: {
return {
...state,
error: null,
isPending: false,
infraList: action.payload.content
page: action.payload
};
}
case ActionType.ReadbydomainFailure: {
case ActionType.ReadAllByDomainFailure: {
return {
...state,
error: action.payload,
isPending: false,
infraList: null
page: null
};
}

View File

@ -9,24 +9,22 @@ import { Infra } from '../../model';
import { Page } from '../../../../app/commons/model';
export interface State {
isSignin: boolean;
error: RPCError | null;
isPending: boolean;
infraList: Page | null;
page: Page | null;
}
export const initialState: State = {
isSignin: false,
error: null,
isPending: false,
infraList: null,
page: null,
};
export class StateSelector {
public constructor(private _selector: MemoizedSelector<any, any>) {
}
public getInfraList = createSelector(this._selector, (state: State) => state.infraList);
public getInfraList = createSelector(this._selector, (state: State) => state.page);
public getError = createSelector(this._selector, (state: State) => state.error);
public isPending = createSelector(this._selector, (state: State) => state.isPending);
}

View File

@ -1,4 +0,0 @@
export * from './readbydomain.action';
export * from './readbydomain.effect';
export * from './readbydomain.reducer';
export * from './readbydomain.state';

View File

@ -1,36 +0,0 @@
import { Action } from '@ngrx/store';
import { RPCError } from 'packages/core/rpc/error';
import { Infra } from '../../model';
import { Page } from '../../../../app/commons/model';
export enum ActionType {
Readbydomain = '[infra.readbydomain] Readbydomain',
ReadbydomainSuccess = '[infra.readbydomain] ReadbydomainSuccess',
ReadbydomainFailure = '[infra.readbydomain] ReadbydomainFailure',
}
export class Readbydomain implements Action {
readonly type = ActionType.Readbydomain;
constructor(public payload: Infra) {}
}
export class ReadbydomainSuccess implements Action {
readonly type = ActionType.ReadbydomainSuccess;
constructor(public payload: Page) {}
}
export class ReadbydomainFailure implements Action {
readonly type = ActionType.ReadbydomainFailure;
constructor(public payload: RPCError) {}
}
export type Actions =
| Readbydomain
| ReadbydomainSuccess
| ReadbydomainFailure
;

View File

@ -1,54 +0,0 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { Action } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/exhaustMap';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
import { RPCError } from 'packages/core/rpc/error';
import { Infra } from '../../model';
import { InfraService } from '../../service/infra.service';
import {
Readbydomain,
ReadbydomainSuccess,
ReadbydomainFailure,
ActionType,
} from './readbydomain.action';
import { Domain } from 'packages/domain/model';
@Injectable()
export class Effects {
constructor(
private actions$: Actions,
private infraService: InfraService,
private router: Router
) { }
@Effect()
readbydomain$: Observable<Action> = this.actions$
.ofType(ActionType.Readbydomain)
.map((action: Readbydomain) => action.payload)
.exhaustMap(member =>
this.infraService
.readByDomain(member)
.map(_member => new ReadbydomainSuccess(_member))
.catch(error => of(new ReadbydomainFailure(error)))
);
@Effect({ dispatch: false })
readbydomainSuccess$ = this.actions$
.ofType(ActionType.ReadbydomainSuccess)
.do(() => this.router.navigate(['/']));
}

View File

@ -1,11 +1,11 @@
import { DiscoverySettingComponent } from './setting/setting.component';
import { SettingComponent } from './setting/setting.component';
import { SettingResultComponent } from './setting-result/setting-result.component';
import { FilterComponent } from './list/filter/filter.component';
import { ListComponent } from './list/list.component';
import { DetailComponent } from './detail/detail.component';
export const COMPONENTS = [
DiscoverySettingComponent,
SettingComponent,
SettingResultComponent,
ListComponent,
FilterComponent,

View File

@ -2,7 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SettingComponent } from './setting.component';
describe('SettingComponent', () => {
describe('SensorSettingComponent', () => {
let component: SettingComponent;
let fixture: ComponentFixture<SettingComponent>;

View File

@ -7,7 +7,7 @@ import { AfterContentInit } from '@angular/core/src/metadata/lifecycle_hooks';
templateUrl: './setting.component.html',
styleUrls: ['./setting.component.scss']
})
export class DiscoverySettingComponent implements OnInit, AfterContentInit {
export class SettingComponent implements OnInit, AfterContentInit {
constructor() { }