Skip to content

Commit

Permalink
Merge branch 'master' into ustutt
Browse files Browse the repository at this point in the history
  • Loading branch information
lharzenetter committed Jun 17, 2019
2 parents ac26331 + 5b9d45b commit de6b901
Show file tree
Hide file tree
Showing 12 changed files with 416 additions and 1 deletion.
1 change: 1 addition & 0 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Copyright (c) 2018 Vladimir Yussupov
Copyright (c) 2019 Dominik Voigt
Copyright (c) 2019 Lisa Podszun
Copyright (c) 2019 Ruben Verma
Copyright (c) 2019 Tobias Mathony
Copyright (c) 2019 Yannik Dietrich
Copyright (c) 2019 Yuye Tong

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/********************************************************************************
* Copyright (c) 2019 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*******************************************************************************/
div.enrichmentContainer {
margin-top: 1em;
margin-left: 1em;
margin-right: 1em;
}

a.title {
font-weight: bold;
}
.innerContainer {
margin: 1em auto;
}

button.btn.btn-sm {
margin-left: 1em;
margin-bottom: 1em;
margin-right: 1em;
width: 40%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Copyright (c) 2019 Contributors to the Eclipse Foundation
~
~ See the NOTICE file(s) distributed with this work for additional
~ information regarding copyright ownership.
~
~ This program and the accompanying materials are made available under the
~ terms of the Eclipse Public License 2.0 which is available at
~ http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0
~ which is available at https://www.apache.org/licenses/LICENSE-2.0.
~
~ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

<div id="EnricherView" *ngIf="availableFeatures" class="sidebar-root">
<div class="enrichmentContainer">
<a class="title">Management Feature Enrichment</a>
<accordion>
<accordion-group class="innerContainer" [isOpen]="i === 0"
heading="{{availableFeatures[i].nodeTemplateId}}"
panelClass="panel-info"
(mouseover)="onHoverOver(entry)"
(mouseleave)="hoverOut()"
*ngFor="let entry of availableFeatures; let i = index;">
Available Enrichments:
<div *ngFor="let feature of entry.features">
<input type="checkbox" (change)="featureSelectionChanged(feature, entry, $event)">
{{feature.featureName}}
</div>
</accordion-group>
</accordion>
</div>
<div class="innerContainer">
<button type="button" class="btn btn-sm btn-primary"
[disabled]="toApply.length===0"
(click)="applyEnrichment()">Apply
</button>
<button type="button" class="btn btn-sm btn-danger"
(click)="cancel()">
Cancel
</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/*******************************************************************************
* Copyright (c) 2019 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*******************************************************************************/
import { Component } from '@angular/core';
import { NgRedux } from '@angular-redux/store';
import { IWineryState } from '../redux/store/winery.store';
import { TopologyRendererActions } from '../redux/actions/topologyRenderer.actions';
import { WineryActions } from '../redux/actions/winery.actions';
import { TopologyRendererState } from '../redux/reducers/topologyRenderer.reducer';
import { HttpErrorResponse } from '@angular/common/http';
import { ToastrService } from 'ngx-toastr';
import { TTopologyTemplate } from '../models/ttopology-template';
import { Utils } from '../models/utils';
import { EnricherService } from './enricher.service';
import { Enrichment, FeatureEntity } from './enrichmentEntity';

@Component({
selector: 'winery-enricher',
templateUrl: './enricher.component.html',
styleUrls: ['./enricher.component.css']
})
export class EnricherComponent {

// enrichment object containing available features
availableFeatures: Enrichment;
// array to store enrichment to be applied
toApply = [];

constructor(private ngRedux: NgRedux<IWineryState>,
private actions: TopologyRendererActions,
private wineryActions: WineryActions,
private alert: ToastrService,
private enricherService: EnricherService) {
this.ngRedux.select(state => state.topologyRendererState)
.subscribe(currentButtonsState => this.checkButtonsState(currentButtonsState));
}

/**
* This method checks the current button state of Winery UI to take action when the Enrichment Button was clicked.
* @param currentButtonsState TopologyRendererState object containt state of Winery UI Buttons
*/
private checkButtonsState(currentButtonsState: TopologyRendererState) {
// check if Enrichment Button is clicked and available features are pulled
if (currentButtonsState.buttonsState.enrichmentButton && !this.availableFeatures) {
this.enricherService.getAvailableFeatures().subscribe(
data => this.showAvailableFeatures(data),
error => this.handleError(error)
);
// if button is unclicked, reset available features
} else if (!currentButtonsState.buttonsState.enrichmentButton) {
this.availableFeatures = null;
}
}

/**
* This method is called when the selection of a enrichment is changed.
* It pushs/removes the selected/removed enrichment from the array of enrichments to be applied
* @param feature: feature which changed
* @param node: node template id where enrichment shall be applied later
* @param event: selection changed event from checkbox
*/
protected featureSelectionChanged(feature: FeatureEntity, node: Enrichment, event: any) {
const isChecked = event.target.checked;
const nodeTemplate = node.nodeTemplateId;
// if a new feature was selected and to applicable enrichment array is empty or node template is not added yet
if (isChecked && (this.toApply.length === 0) || !this.checkIfNodeTypeSelected(nodeTemplate)) {
const selectedEnrichment = {
nodeTemplateId: nodeTemplate,
features: []
};
selectedEnrichment.features.push(feature);
this.toApply.push(selectedEnrichment);
// if feature was selected and node template id is already existing
} else if (isChecked && this.checkIfNodeTypeSelected(nodeTemplate)) {
this.toApply[this.checkWhichIndexNodeType(nodeTemplate)].features.push(feature);
// if feature was unselected
} else if (!event.target.checked && this.checkIfNodeTypeSelected(nodeTemplate)) {
this.removeFeatureForNodeTemplate(feature, this.checkWhichIndexNodeType(nodeTemplate));
}
}

/**
* This method checks whether to applicable enrichments array already contains an entry for a given node template.
* @param nodeTemplateId: id of node template which shall be checked
* @return boolean: true if array already contains node template, false else
*/
private checkIfNodeTypeSelected(nodeTemplateId: string): boolean {
for (const element of this.toApply) {
// if entry node template matches node template we're searching for, return true
if (element.nodeTemplateId === nodeTemplateId) {
return true;
}
}
// if node template id was not found after iterating over all entries, return false
return false;
}

/**
* This method returns the index of an node template entry in the to applicable enrichments array.
* This is used to determine the entry which shall be removed when unselecting the last feature of a node template.
* @param nodeTemplateId: id of node template to be checked
* @return i: number of index of node template entry in to applicable enrichments array
*/
private checkWhichIndexNodeType(nodeTemplateId: string): number {
for (let i = 0; i < this.toApply.length; i++) {
// if node template id is found, return the index of the entry
if (this.toApply[i].nodeTemplateId === nodeTemplateId) {
return i;
}
}
}

/**
* This method removes a feature of a node template entry in the to applicable enrichments array.
* @param feature: feature entry which shall be modified
* @param index: index of entry to be removed
*/
private removeFeatureForNodeTemplate(feature: FeatureEntity, index: number): void {
for (let i = 0; i < this.toApply[index].features.length; i++) {
// check if feature is feature to be modified
if (this.toApply[index].features[i] === feature) {
this.toApply[index].features.splice(i, 1);
}
}
// delete entry if no feature selected anymore
if (this.toApply[index].features.length === 0) {
this.toApply.splice(index, 1);
}
}

/**
* This method is called when clicking the "Apply" button.
* It starts the Enricher Service to apply the selected enrichments.
*/
protected applyEnrichment() {
this.enricherService.applySelectedFeatures(this.toApply).subscribe(
data => this.enrichmentApplied(data),
error => this.handleError(error)
);
}

/**
* This method is called when available features are retrieved and fills the available features array with the
* gathered data.
* @param data: json response of backend containing available features for all node templates
*/
private showAvailableFeatures(data: Enrichment): void {
// check if array contains data at all (data != null does not work, as data is not null but an empty array)
if (data.length > 0) {
this.availableFeatures = data;
} else {
this.alert.info('No enrichment found!');
}
}

/**
* This method is called when an error occurs durring fetching or pushing the enrichments.
* It alerts the merror message in the UI.
* @param error: error message
*/
private handleError(error: HttpErrorResponse) {
this.alert.error(error.message);
}

/**
* This method is called when the User hovers over a node template in the enrichment sidebar
* It highlights the respective node template in the topology modeler.
* @param entry: entry of available features displayed in the UI
*/
protected onHoverOver(entry: Enrichment) {
const nodeTemplateIds: string[] = [];
nodeTemplateIds.push(entry.nodeTemplateId);
this.ngRedux.dispatch(this.actions.highlightNodes(nodeTemplateIds));
}

/**
* This method is called when the user hovers out of a node template.
*/
protected hoverOut() {
this.ngRedux.dispatch(this.actions.highlightNodes([]));
}

/**
* This method is called when the User clicks "Cancel".
* It resets the available features, which lets the enrichment sidebar disappear.
*/
protected cancel() {
this.availableFeatures = null;
this.ngRedux.dispatch(this.actions.enrichNodeTemplates());
}

/**
* This method is called when the enrichment is successfully applied in the backend.
* It updates the topology template then, resets the available features and displays an success message.
* @param data: topology template that was updated
*/
private enrichmentApplied(data: TTopologyTemplate) {
Utils.updateTopologyTemplate(this.ngRedux, this.wineryActions, data);
// reset available features since they are no longer valid
this.availableFeatures = null;
this.alert.success('Updated Topology Template!');
this.ngRedux.dispatch(this.actions.enrichNodeTemplates());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*******************************************************************************
* Copyright (c) 2019 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*******************************************************************************/
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BackendService } from '../services/backend.service';
import { TopologyModelerConfiguration } from '../models/topologyModelerConfiguration';
import { Observable } from 'rxjs';
import { Enrichment } from './enrichmentEntity';
import { TTopologyTemplate } from '../models/ttopology-template';

@Injectable({
providedIn: 'root'
})
export class EnricherService {

private readonly configuration: TopologyModelerConfiguration;
private readonly httpHeaders: HttpHeaders;

constructor(private http: HttpClient,
backendService: BackendService) {
this.configuration = backendService.configuration;
this.httpHeaders = new HttpHeaders().set('Accept', 'application/json');
}

/**
* This method fetches available enrichments/features for a topology template.
*/
getAvailableFeatures(): Observable<Enrichment> {
const url = this.configuration.repositoryURL
+ '/servicetemplates/'
+ encodeURIComponent(encodeURIComponent(this.configuration.ns))
+ '/'
+ encodeURIComponent(this.configuration.id)
+ '/topologytemplate/availablefeatures';
return this.http.get<Enrichment>(url, { headers: this.httpHeaders });
}

/**
* This method applies selected enrichments/features for a topology template.
* @param toApplyFeatures: Enrichment Object containing selected features for node templates.
*/
applySelectedFeatures(toApplyFeatures: Enrichment[]): Observable<TTopologyTemplate> {
const url = this.configuration.repositoryURL
+ '/servicetemplates/'
+ encodeURIComponent(encodeURIComponent(this.configuration.ns))
+ '/'
+ encodeURIComponent(this.configuration.id)
+ '/topologytemplate/availablefeatures';
return this.http.put<TTopologyTemplate>(url, toApplyFeatures, { headers: this.httpHeaders });
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/********************************************************************************
* Copyright (c) 2019 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*******************************************************************************/
import { QName } from '../models/qname';

/**
* Enrichment interface containing features of FeatureEntity type and a node template id.
*/
export interface Enrichment {
features: FeatureEntity[];
nodeTemplateId: string;
length: number;
}

/**
* FeatureEntity interface containing type of the feature and the feature name.
*/
export interface FeatureEntity {
type: QName;
featureName: string;
}
Loading

0 comments on commit de6b901

Please sign in to comment.