Skip to content
This repository was archived by the owner on May 14, 2025. It is now read-only.

Commit 9bfd410

Browse files
committed
Add platform-list to stream deployment page
resolves #600: enable to define a target platform on the stream deployment page (single and multiple) if Skipper is enabled
1 parent e6845ae commit 9bfd410

19 files changed

+598
-259
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Test {@link Platform} model.
3+
*
4+
* @author Damien Vitrac
5+
*/
6+
7+
import {Platform} from './platform';
8+
9+
describe('Platform', () => {
10+
11+
it('Platform simple deserialize', () => {
12+
const m = new Platform().deserialize({
13+
name: 'foobar',
14+
type: 'foo',
15+
description: 'bar',
16+
});
17+
expect(m.name).toEqual('foobar');
18+
expect(m.type).toEqual('foo');
19+
expect(m.description).toEqual('bar');
20+
});
21+
22+
});

ui/src/app/streams/model/platform.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {Serializable} from '../../shared/model/serialization/serializable.model';
2+
3+
/**
4+
* Represents a Platform.
5+
*
6+
* @author Damien Vitrac
7+
*/
8+
export class Platform implements Serializable<Platform> {
9+
10+
public name: String;
11+
public type: String;
12+
public description: String;
13+
14+
constructor(name: String = '', type: String = '', description: String = '') {
15+
this.name = name;
16+
this.type = type;
17+
this.description = description;
18+
}
19+
20+
deserialize(inputJson) {
21+
this.name = inputJson.name;
22+
this.type = inputJson.type;
23+
this.description = inputJson.description;
24+
return this;
25+
}
26+
27+
}
Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div class="modal-header">
2-
<h4 class="modal-title pull-left">Add deployment properties for <strong>{{stream.name}}</strong></h4>
2+
<h4 class="modal-title pull-left">Deployment properties for <strong>{{stream.name}}</strong></h4>
33
<button type="button" class="close pull-right" aria-label="Close" (click)="cancelDeployment()">
44
<span aria-hidden="true">&times;</span>
55
</button>
@@ -14,34 +14,48 @@ <h4 class="modal-title pull-left">Add deployment properties for <strong>{{stream
1414
field below or alternatively, you can point to an external properties file,
1515
which will be used to populate the text-area field.<br><br>
1616
For more information please see the
17-
<a href="http://docs.spring.io/spring-cloud-dataflow/docs/current-SNAPSHOT/reference/htmlsingle/#_passing_application_properties_when_deploying_stream"
18-
target="_blank">Technical Documentation</a>.
17+
<a
18+
href="http://docs.spring.io/spring-cloud-dataflow/docs/current-SNAPSHOT/reference/htmlsingle/#_passing_application_properties_when_deploying_stream"
19+
target="_blank">Technical Documentation</a>.
1920
</p>
2021

21-
<div class="form-group" [ngClass]="form.controls.deploymentProperties.errors ? 'has-warning has-feedback' : ''">
22-
<label for="deploymentProperties" class="control-label">Deployment Properties</label>
23-
<div>
22+
<div id="groupPlatform" class="form-group" *ngIf="skipperEnabled">
23+
<label for="deploymentPlatform" class="control-label">Platform</label>
24+
<div>
25+
<select id="deploymentPlatform" name="deploymentPlatform" formControlName="deploymentPlatform">
26+
<option *ngFor="let p of platforms" [value]="p.name">{{p.name}} ({{ p.type }})</option>
27+
</select>
28+
<p class="help-block">You can specify the platform for the deployment.</p>
29+
</div>
30+
</div>
31+
32+
<div class="form-group" [ngClass]="form.controls.deploymentProperties.errors ? 'has-warning has-feedback' : ''">
33+
<label for="deploymentProperties" class="control-label">Deployment Properties</label>
34+
<div>
2435
<textarea class="form-control" id="deploymentProperties" name="deploymentProperties"
2536
formControlName="deploymentProperties" autofocus rows="5"
2637
placeholder="Enter optional deployment properties.
2738
1 line per property e.g.:
2839
property1=Spring
2940
property2=Data Flow"></textarea>
30-
<span class="glyphicon glyphicon-warning-sign form-control-feedback" *ngIf="form.controls.deploymentProperties.errors"></span>
31-
<p class="help-block" *ngIf="form.controls.deploymentProperties.errors">The format of your deployment properties is invalid. {{form.controls.deploymentProperties.errors.validateDeploymentProperties.reason}}</p>
32-
</div>
41+
<span class="glyphicon glyphicon-warning-sign form-control-feedback"
42+
*ngIf="form.controls.deploymentProperties.errors"></span>
43+
<p class="help-block" *ngIf="form.controls.deploymentProperties.errors">The format of your deployment properties
44+
is invalid. {{form.controls.deploymentProperties.errors.validateDeploymentProperties.reason}}</p>
3345
</div>
34-
<div class="form-group">
35-
<label class="control-label">Select Properties File</label>
36-
<div>
37-
<input type="file" (change)="displayFileContents($event)"/>
38-
<p class="help-block">Please provide a text file containing deployment properties. This will be used to populate the text area above.</p>
39-
</div>
46+
</div>
47+
<div class="form-group">
48+
<label class="control-label">Select Properties File</label>
49+
<div>
50+
<input type="file" (change)="displayFileContents($event)"/>
51+
<p class="help-block">Please provide a text file containing deployment properties. This will be used to populate
52+
the text area above.</p>
4053
</div>
54+
</div>
4155
</div>
4256

4357
<div class="modal-footer">
4458
<button type="button" class="btn btn-default" (click)="cancelDeployment()">Back</button>
45-
<button type="submit" class="btn btn-primary">Add</button>
59+
<button type="submit" class="btn btn-primary" [disabled]="!form.valid">Update deployment parameters</button>
4660
</div>
4761
</form>

ui/src/app/streams/stream-definitions/deployment-properties/deployment-properties.component.spec.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
import {TestBed, async, ComponentFixture} from '@angular/core/testing';
1+
import {TestBed, async, ComponentFixture, tick, fakeAsync} from '@angular/core/testing';
22
import {DeploymentPropertiesComponent} from './deployment-properties.component';
33
import {ReactiveFormsModule, FormsModule} from '@angular/forms';
44
import {StreamDefinition} from '../../model/stream-definition';
5+
import {By} from '@angular/platform-browser';
6+
import {DebugElement} from '@angular/core';
7+
import {SharedAboutService} from '../../../shared/services/shared-about.service';
8+
import {MocksSharedAboutService} from '../../../tests/mocks/shared-about';
9+
import {MockStreamsService} from '../../../tests/mocks/streams';
10+
import {StreamsService} from '../../streams.service';
511

612
/**
713
* Test {@link DeploymentPropertiesComponent}.
@@ -12,6 +18,8 @@ describe('DeploymentPropertiesComponent', () => {
1218

1319
let component: DeploymentPropertiesComponent;
1420
let fixture: ComponentFixture<DeploymentPropertiesComponent>;
21+
const sharedAboutService = new MocksSharedAboutService();
22+
const streamsService = new MockStreamsService();
1523

1624
beforeEach(async(() => {
1725
TestBed.configureTestingModule({
@@ -22,7 +30,10 @@ describe('DeploymentPropertiesComponent', () => {
2230
FormsModule,
2331
ReactiveFormsModule,
2432
],
25-
providers: []
33+
providers: [
34+
{provide: StreamsService, useValue: streamsService},
35+
{provide: SharedAboutService, useValue: sharedAboutService}
36+
]
2637
})
2738
.compileComponents();
2839
}));
@@ -51,6 +62,27 @@ describe('DeploymentPropertiesComponent', () => {
5162
expect(component.deploymentProperties.value).toBe('');
5263
});
5364

65+
it('should display the platform input (skipper enabled)', () => {
66+
component.stream = new StreamDefinition('foo2', 'time |log', 'undeployed');
67+
component.stream.deploymentProperties = {};
68+
sharedAboutService.dataflowVersionInfo.featureInfo.skipperEnabled = true;
69+
fixture.detectChanges();
70+
const de: DebugElement = fixture.debugElement.query(By.css('#groupPlatform'));
71+
const el: HTMLElement = fixture.debugElement.query(By.css('#deploymentPlatform')).nativeElement;
72+
expect(de == null).not.toBeTruthy();
73+
expect(el.innerHTML.indexOf('foo (bar)') !== -1).toBe(true);
74+
expect(el.innerHTML.indexOf('default (local)') !== -1).toBe(true);
75+
});
76+
77+
it('should not display the platform input (skipper disabled)', () => {
78+
component.stream = new StreamDefinition('foo2', 'time |log', 'undeployed');
79+
component.stream.deploymentProperties = {};
80+
sharedAboutService.dataflowVersionInfo.featureInfo.skipperEnabled = false;
81+
fixture.detectChanges();
82+
const de: DebugElement = fixture.debugElement.query(By.css('#groupPlatform'));
83+
expect(de == null).toBeTruthy();
84+
});
85+
5486
it('should not populate properties input (invalid data)', () => {
5587
component.stream = new StreamDefinition('foo2', 'time |log', 'undeployed');
5688
component.stream.deploymentProperties = 'aa';

ui/src/app/streams/stream-definitions/deployment-properties/deployment-properties.component.ts

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import {Component, OnInit, Output, EventEmitter, Input} from '@angular/core';
2-
import { FormGroup, FormControl, FormBuilder } from '@angular/forms';
2+
import {FormGroup, FormControl, FormBuilder} from '@angular/forms';
33
import {validateDeploymentProperties} from '../../stream-deploy/stream-deploy-validators';
44
import {StreamDefinition} from '../../model/stream-definition';
5+
import {Subscription} from 'rxjs/Subscription';
6+
import {Platform} from '../../model/platform';
7+
import {SharedAboutService} from '../../../shared/services/shared-about.service';
8+
import {StreamsService} from '../../streams.service';
59

610
@Component({
711
selector: 'app-stream-deployment-properties',
@@ -18,6 +22,13 @@ export class DeploymentPropertiesComponent implements OnInit {
1822
id: String;
1923
form: FormGroup;
2024
deploymentProperties = new FormControl('', validateDeploymentProperties);
25+
deploymentPlatform = new FormControl('');
26+
27+
platforms: Platform[];
28+
29+
subscriptionPlatforms: Subscription;
30+
subscriptionFeatureInfo: Subscription;
31+
skipperEnabled = false;
2132

2233
@Output()
2334
public cancel = new EventEmitter();
@@ -31,26 +42,47 @@ export class DeploymentPropertiesComponent implements OnInit {
3142
/**
3243
* Adds deployment properties to the FormBuilder
3344
* @param fb used establish the deployment properties as a part of the form.
45+
* @param sharedAboutService used to check if skipper is enable
46+
* @param streamsService The service used to deploy the stream.
3447
*/
35-
constructor(
36-
fb: FormBuilder
37-
) {
38-
this.form = fb.group({
39-
'deploymentProperties': this.deploymentProperties
40-
});
48+
constructor(private fb: FormBuilder,
49+
private sharedAboutService: SharedAboutService,
50+
private streamsService: StreamsService) {
51+
this.form = fb.group({
52+
'deploymentProperties': this.deploymentProperties,
53+
'deploymentPlatform': this.deploymentPlatform
54+
});
4155
}
4256

57+
/**
58+
* Initialize states
59+
* Load platforms if skipper is enabled
60+
* Parse the current parameters and populate fields
61+
*/
4362
ngOnInit() {
63+
this.subscriptionFeatureInfo = this.sharedAboutService.getFeatureInfo().subscribe(featureInfo => {
64+
this.skipperEnabled = featureInfo.skipperEnabled;
65+
if (this.skipperEnabled) {
66+
this.subscriptionPlatforms = this.streamsService.platforms().subscribe((platforms: Platform[]) => {
67+
this.platforms = platforms;
68+
});
69+
}
70+
});
71+
this.deploymentPlatform.setValue('default');
4472
if (this.stream.deploymentProperties instanceof Object) {
73+
if (this.stream.deploymentProperties.platformName) {
74+
this.deploymentPlatform.setValue(this.stream.deploymentProperties.platformName);
75+
}
4576
this.deploymentProperties.setValue(Object.keys(this.stream.deploymentProperties)
77+
.filter(a => a !== 'spring.cloud.dataflow.skipper.platformName')
4678
.map(a => {
4779
return a + '=' + this.stream.deploymentProperties[a];
4880
}).join('\n'));
4981
}
5082
}
5183

5284
/**
53-
* Deploy the definition and submit the event
85+
* Deploy the definition and emit on submit event
5486
*/
5587
deployDefinition() {
5688
const propertiesAsMap = {};
@@ -64,10 +96,16 @@ export class DeploymentPropertiesComponent implements OnInit {
6496
}
6597
}
6698
}
99+
if (this.skipperEnabled) {
100+
propertiesAsMap['spring.cloud.dataflow.skipper.platformName'] = this.deploymentPlatform.value;
101+
}
67102
this.stream.deploymentProperties = propertiesAsMap;
68103
this.submit.emit();
69104
}
70105

106+
/**
107+
* Fire cancel event
108+
*/
71109
cancelDeployment() {
72110
this.cancel.emit();
73111
}
@@ -80,7 +118,7 @@ export class DeploymentPropertiesComponent implements OnInit {
80118
const file: File = event.target.files[0];
81119
const reader: FileReader = new FileReader();
82120
const _form = this.form;
83-
reader.onloadend = function(e){
121+
reader.onloadend = function (e) {
84122
_form.patchValue({deploymentProperties: reader.result});
85123
};
86124
reader.readAsText(file);

ui/src/app/streams/stream-definitions/stream-definitions.component.html

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -198,69 +198,6 @@ <h4 class="modal-title pull-left">Confirm Destroy Stream Definitions</h4>
198198
</div>
199199
</div>
200200

201-
<div id="deployMultipleStreamDefinitionsModal" bsModal #deployMultipleStreamDefinitionsModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
202-
<div class="modal-dialog">
203-
204-
<div class="modal-content" *ngIf="!selectStreamDefinition">
205-
<div class="modal-header">
206-
<h4 class="modal-title pull-left">Confirm Deployment of Stream Definitions</h4>
207-
<button type="button" class="close pull-right" aria-label="Close" (click)="cancelDeployMultipleStreamDefinitions()">
208-
<span aria-hidden="true">&times;</span>
209-
</button>
210-
</div>
211-
<div class="modal-body" *ngIf="streamDefinitionsToDeploy">
212-
<p>
213-
This action will deploy the <strong>{{streamDefinitionsToDeploy.length}}
214-
stream definition{{streamDefinitionsToDeploy.length > 1 ? 's' : ''}}</strong> listed below.
215-
Optionally, you can add deployment properties for each stream definition.
216-
</p>
217-
<br/>
218-
<table class="table table-striped">
219-
<thead>
220-
<tr>
221-
<th>Name</th>
222-
<th>Definition</th>
223-
<th>Deployment properties</th>
224-
</tr>
225-
</thead>
226-
<tbody>
227-
<tr *ngFor="let item of streamDefinitionsToDeploy">
228-
<td>{{item.name}}</td>
229-
<td>{{item.dslText}}</td>
230-
<td width="10" nowrap="">
231-
<div *ngIf="(item.deploymentProperties | keyvalues)?.length > 0">
232-
<p style="padding-bottom: 6px"><strong>{{(item.deploymentProperties | keyvalues)?.length}} propert{{(item.deploymentProperties | keyvalues)?.length > 1 ? 'ies' : 'y'}}</strong></p>
233-
<a class="btn btn-sm btn-default" (click)="deployAddDeploymentProperties(item)">
234-
<span class="glyphicon glyphicon-edit"></span>
235-
Edit deployment properties
236-
</a>
237-
</div>
238-
<div *ngIf="(item.deploymentProperties | keyvalues)?.length == 0">
239-
<a class="btn btn-sm btn-default" (click)="deployAddDeploymentProperties(item)">
240-
<span class="glyphicon glyphicon-plus"></span>
241-
Add deployment properties
242-
</a>
243-
</div>
244-
</td>
245-
</tr>
246-
</tbody>
247-
</table>
248-
</div>
249-
<div class="modal-footer">
250-
<button type="button" class="btn btn-default" (click)="cancelDeployMultipleStreamDefinitions()">Cancel</button>
251-
<button type="button" class="btn btn-primary" (click)="proceedToDeployMultipleStreamDefinitions(streamDefinitionsToDeploy)">Deploy</button>
252-
</div>
253-
</div>
254-
255-
<div class="modal-content" *ngIf="selectStreamDefinition">
256-
<app-stream-deployment-properties [stream]="selectStreamDefinition"
257-
(submit)="backDeployMultipleStreamDefinitions()" (cancel)="backDeployMultipleStreamDefinitions()">
258-
</app-stream-deployment-properties>
259-
</div>
260-
261-
</div>
262-
</div>
263-
264201
<div id="undeployMultipleStreamDefinitionsModal" bsModal #undeployMultipleStreamDefinitionsModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
265202
<div class="modal-dialog">
266203
<div class="modal-content">

0 commit comments

Comments
 (0)