Skip to content

Commit

Permalink
Pattern based modeling (winery#725)
Browse files Browse the repository at this point in the history
  • Loading branch information
lharzenetter authored Apr 25, 2023
1 parent 69b3a8a commit 81fa884
Show file tree
Hide file tree
Showing 129 changed files with 2,343 additions and 758 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ export class EntitiesModalComponent implements OnInit, OnChanges, OnDestroy {
nodeId: this.currentNodeData.id,
newPolicy: policyToBeSavedToRedux
};
if (this.deploymentArtifactOrPolicyModalData.nodeTemplateId.startsWith('con')) {
if (this.deploymentArtifactOrPolicyModalData.nodeTemplateId.includes('con_')) {
this.ngRedux.dispatch(this.actions.setPolicyForRelationship(actionObject));
} else {
this.ngRedux.dispatch(this.actions.setPolicy(actionObject));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
<div id="EnricherView" *ngIf="availableFeatures">
<div class="enrichmentContainer">
<a class="title">Management Feature Enrichment</a>
<winery-loader *ngIf="loading">
</winery-loader>
<accordion>
<accordion-group class="innerContainer" [isOpen]="i === 0"
heading="{{availableFeatures[i].nodeTemplateId}}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*******************************************************************************/
import { Component, Input } from '@angular/core';
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';
Expand Down Expand Up @@ -39,6 +39,7 @@ export class EnricherComponent {
availableFeatures: Enrichment;
// array to store enrichment to be applied
toApply = [];
loading = true;

constructor(private ngRedux: NgRedux<IWineryState>,
private actions: TopologyRendererActions,
Expand Down Expand Up @@ -88,6 +89,7 @@ export class EnricherComponent {
* It starts the Enricher Service to apply the selected enrichments.
*/
protected applyEnrichment() {
this.loading = true;
this.enricherService.applySelectedFeatures(this.toApply).subscribe(
data => this.enrichmentApplied(data),
error => this.handleError(error)
Expand Down Expand Up @@ -128,11 +130,12 @@ export class EnricherComponent {
private checkButtonsState(currentButtonsState: TopologyRendererState) {
// check if Enrichment Button is clicked and available features are pulled
if (currentButtonsState.buttonsState.enrichmentButton && !this.availableFeatures) {
this.loading = true;
this.enricherService.getAvailableFeatures().subscribe(
data => this.showAvailableFeatures(data),
error => this.handleError(error)
);
// if button is unclicked, reset available features
// if button is clicked again, reset available features
} else if (!currentButtonsState.buttonsState.enrichmentButton) {
this.availableFeatures = null;
}
Expand Down Expand Up @@ -193,6 +196,7 @@ export class EnricherComponent {
* @param data: json response of backend containing available features for all node templates
*/
private showAvailableFeatures(data: Enrichment): void {
this.loading = false;
// 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;
Expand All @@ -203,11 +207,12 @@ export class EnricherComponent {

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

/**
Expand All @@ -216,6 +221,7 @@ export class EnricherComponent {
* @param data: topology template that was updated
*/
private enrichmentApplied(data: TTopologyTemplate) {
this.loading = false;
TopologyTemplateUtil.updateTopologyTemplate(this.ngRedux, this.wineryActions, data, this.entityTypes, this.configurationService.isYaml());
// reset available features since they are no longer valid
this.availableFeatures = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2023 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
*******************************************************************************/

export interface InstancePlugin {
id: string;
discoveredIds: string[];
}

export interface InstanceDeploymentTechnology extends InstancePlugin {
technologyId: string;
managedIds: string[];
properties: any;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { InheritanceUtils } from './InheritanceUtils';
import { QName } from '../../../../shared/src/app/model/qName';
import { TPolicy } from './policiesModalData';
import * as _ from 'lodash';
import { TNode } from '@angular/core/src/render3/interfaces/node';

export abstract class TopologyTemplateUtil {

Expand Down Expand Up @@ -119,7 +118,7 @@ export abstract class TopologyTemplateUtil {
}
// look for missing capabilities and add them
const capDefs: CapabilityDefinitionModel[] = InheritanceUtils.getEffectiveCapabilityDefinitionsOfNodeType(node.type, types);
if (!node.capabilities ) {
if (!node.capabilities) {
node.capabilities = [];
}
capDefs.forEach((def) => {
Expand Down Expand Up @@ -169,8 +168,8 @@ export abstract class TopologyTemplateUtil {
otherAttributes,
node.x,
node.y,
node.capabilities ? node.capabilities : [] ,
node.requirements ? node.requirements : [],
node.capabilities ? node.capabilities : [],
node.requirements ? node.requirements : [],
node.deploymentArtifacts ? node.deploymentArtifacts : [],
node.policies ? node.policies : [],
node.artifacts ? node.artifacts : [],
Expand Down Expand Up @@ -320,8 +319,8 @@ export abstract class TopologyTemplateUtil {
return true;
}

return typeof o1 === 'object' && Object.keys(o1).length > 0
? Object.keys(o1).length === Object.keys(o2).length
return typeof o1 === 'object' && typeof o2 === 'object'
&& Object.keys(o1).length > 0 ? Object.keys(o1).length === Object.keys(o2).length
&& Object.keys(o1).every((p) => {
return this.objectsEquals(o1[p], o2[p]);
})
Expand Down Expand Up @@ -368,10 +367,10 @@ export abstract class TopologyTemplateUtil {

static findLastSavedRelationshipTemplate(lastSavedTopology: TTopologyTemplate, currentRelationshipTemplate: TRelationshipTemplate): TRelationshipTemplate {
return lastSavedTopology.relationshipTemplates.find((relationshipTemplate) => {
return relationshipTemplate.sourceElement.ref === currentRelationshipTemplate.sourceElement.ref &&
relationshipTemplate.targetElement.ref === currentRelationshipTemplate.targetElement.ref &&
relationshipTemplate.type === currentRelationshipTemplate.type;
}
return relationshipTemplate.sourceElement.ref === currentRelationshipTemplate.sourceElement.ref &&
relationshipTemplate.targetElement.ref === currentRelationshipTemplate.targetElement.ref &&
relationshipTemplate.type === currentRelationshipTemplate.type;
}
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,13 @@ button.btn.btn-sm.btn-outline-secondary:hover, button.btn.btn-sm.btn-outline-sec
max-height: 30px;
}

.deploymentTech {
position: absolute;
top: 3px;
float: right;
left: 185px;
}

.newVersionTriangle {
position: absolute;
right: -4px;
Expand Down Expand Up @@ -258,7 +265,3 @@ div.overlay .overlay-icon {
top: 0;
transform: translate(50%, -50%);
}

div.pattern > bs-tooltip-container {
z-index: 50;
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,24 @@
<img *ngFor="let policyIcon of policyIcons" [src]="policyIcon.imageUrl" class="policyAnnotation"
alt="Policy icon" tooltip="{{ policyIcon.policyType }}">
</div>

<!-- <div *ngIf="instanceInformation?.discoveredBy">-->
<!-- discovered-->
<!-- </div>-->
<div *ngIf="instanceInformation?.deploymentTech" class="deploymentTech">
<img *ngIf="instanceInformation.deploymentTech === 'kubernetes'"
alt="Kubernetes"
src="https://www.linuxfoundation.org/hs-fs/hubfs/trademark-kubernetes-icon-correct-140x140-1.png?width=62&name=trademark-kubernetes-icon-correct-140x140-1.png"
class="policyAnnotation">
<img *ngIf="instanceInformation.deploymentTech === 'puppet'"
alt="Puppet"
src="https://static-00.iconduck.com/assets.00/file-type-puppet-icon-333x512-rln688e4.png"
class="policyAnnotation">
<img *ngIf="instanceInformation.deploymentTech === 'terraform'"
alt="Terraform"
src="https://static-00.iconduck.com/assets.00/file-type-terraform-icon-455x512-csyun60o.png"
class="policyAnnotation">
</div>

<div *ngIf="newerVersions?.length !== 0">
<i *wineryRepositoryFeatureToggle="configEnum.updateTemplates"
Expand Down Expand Up @@ -135,9 +153,9 @@
<div class="endpointContainer center-block row" style="border: 0; box-shadow: none"
*ngIf="connectorEndpointVisible && !readonly"
(mouseover)="makeSource()">
<div class="btn-group-vertical btn-group-sm center-block" role="group" id={{dragSource}}
(mousedown)="passCurrentType($event)">
<div class="btn-group-vertical btn-group-sm center-block" role="group" id={{dragSource}}>
<button *ngFor="let rel of entityTypes.relationshipTypes"
(mousedown)="passCurrentType(rel)"
type="button" class="btn btn-sm btn-outline-secondary btn-block"
[style.color]="rel.color"
style="font-size: x-small;">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
********************************************************************************/

import {
AfterViewInit, Component, ComponentRef, DoCheck, ElementRef, EventEmitter, Input, KeyValueDiffers, NgZone,
OnDestroy, OnInit, Output, Renderer2, ViewChild
AfterViewInit, Component, ComponentRef, DoCheck, ElementRef, EventEmitter, Input, KeyValueDiffers, NgZone, OnDestroy, OnInit, Output, Renderer2, ViewChild
} from '@angular/core';
import { animate, keyframes, state, style, transition, trigger } from '@angular/animations';
import { NgRedux } from '@angular-redux/store';
import { IWineryState } from '../redux/store/winery.store';
import { WineryActions } from '../redux/actions/winery.actions';
import { EntityType, OTParticipant, TGroupDefinition, TNodeTemplate } from '../models/ttopology-template';
import { EntityType, OTParticipant, TGroupDefinition, TNodeTemplate, VisualEntityType } from '../models/ttopology-template';
import { LiveModelingStates, NodeTemplateInstanceStates, PropertyDefinitionType, urlElement } from '../models/enums';
import { BackendService } from '../services/backend.service';
import { GroupedNodeTypeModel } from '../models/groupedNodeTypeModel';
Expand All @@ -32,17 +31,14 @@ import { Visuals } from '../models/visuals';
import { VersionElement } from '../models/versionElement';
import { VersionsComponent } from './versions/versions.component';
import { WineryVersion } from '../../../../tosca-management/src/app/model/wineryVersion';
import {
FeatureEnum
} from '../../../../tosca-management/src/app/wineryFeatureToggleModule/wineryRepository.feature.direct';
import { FeatureEnum } from '../../../../tosca-management/src/app/wineryFeatureToggleModule/wineryRepository.feature.direct';
import { PropertiesComponent } from '../properties/properties.component';
import { Subscription } from 'rxjs';
import {
WineryRepositoryConfigurationService
} from '../../../../tosca-management/src/app/wineryFeatureToggleModule/WineryRepositoryConfiguration.service';
import { WineryRepositoryConfigurationService } from '../../../../tosca-management/src/app/wineryFeatureToggleModule/WineryRepositoryConfiguration.service';
import { InheritanceUtils } from '../models/InheritanceUtils';
import { QName } from '../../../../shared/src/app/model/qName';
import { DetailsSidebarState } from '../sidebars/node-details/node-details-sidebar';
import { InstanceDeploymentTechnology, InstancePlugin } from '../models/instanceModeling';

/**
* Every node has its own component and gets created dynamically.
Expand Down Expand Up @@ -93,6 +89,8 @@ export class NodeComponent implements OnInit, AfterViewInit, OnDestroy, DoCheck
groupDefinitions: TGroupDefinition[];
participants: OTParticipant[];

instanceInformation: { discoveredBy: string[]; deploymentTech: string };

@Input() readonly: boolean;
@Input() entityTypes: EntityTypesModel;
@Input() nodeEntityType: EntityType;
Expand Down Expand Up @@ -290,6 +288,9 @@ export class NodeComponent implements OnInit, AfterViewInit, OnDestroy, DoCheck
.subscribe((liveModelingState) => {
this.liveModelingEnabled = liveModelingState !== LiveModelingStates.DISABLED;
}));

this.$ngRedux.select((store) => store.wineryState.instanceInformation)
.subscribe((instanceInformation) => this.setInstanceInformation(instanceInformation));
}

/**
Expand All @@ -308,7 +309,7 @@ export class NodeComponent implements OnInit, AfterViewInit, OnDestroy, DoCheck
* Get the icons of the policies.
*/
setPolicyIcons() {
if (this.nodeTemplate.policies) {
if (this.nodeTemplate && this.nodeTemplate.policies) {
this.policyIcons = [];
const list: TPolicy[] = this.nodeTemplate.policies;

Expand Down Expand Up @@ -367,19 +368,11 @@ export class NodeComponent implements OnInit, AfterViewInit, OnDestroy, DoCheck
}

/**
* Sets the current type of a node.
* Sets the type of the currently created relation.
*/
passCurrentType($event): void {
$event.stopPropagation();
$event.preventDefault();
let currentType: string;
try {
currentType = $event.srcElement.innerText.replace(/\n/g, '').replace(/\s+/g, '');
} catch (e) {
currentType = $event.target.innerText.replace(/\n/g, '').replace(/\s+/g, '');
}
passCurrentType(relation: VisualEntityType): void {
this.entityTypes.relationshipTypes.some(relType => {
if (relType.qName.includes(currentType)) {
if (relType.qName === relation.qName) {
this.sendSelectedRelationshipType.emit(relType);
return true;
}
Expand Down Expand Up @@ -497,18 +490,18 @@ export class NodeComponent implements OnInit, AfterViewInit, OnDestroy, DoCheck
new DetailsSidebarState(false, true, this.nodeEntityType)));
} else {
this.$ngRedux.dispatch(this.actions.triggerSidebar({
visible: true,
nodeClicked: true,
nodeData: {
entityTypes: this.entityTypes,
nodeTemplate: this.nodeTemplate,
propertyDefinitionType: this.propertyDefinitionType,
entityType: this.nodeEntityType
},
template: this.nodeTemplate,
// special handling for instance restrictions due to infinity
minInstances: this.nodeTemplate.minInstances,
maxInstances: this.nodeTemplate.maxInstances,
visible: true,
nodeClicked: true,
nodeData: {
entityTypes: this.entityTypes,
nodeTemplate: this.nodeTemplate,
propertyDefinitionType: this.propertyDefinitionType,
entityType: this.nodeEntityType
},
template: this.nodeTemplate,
// special handling for instance restrictions due to infinity
minInstances: this.nodeTemplate.minInstances,
maxInstances: this.nodeTemplate.maxInstances,
}));
}
}
Expand Down Expand Up @@ -647,4 +640,43 @@ export class NodeComponent implements OnInit, AfterViewInit, OnDestroy, DoCheck

return result;
}

private setInstanceInformation(instanceInfo: { plugins: InstancePlugin[]; deploymentTechs: InstanceDeploymentTechnology[] }) {
if (this.nodeTemplate) {
this.instanceInformation = {
discoveredBy: [],
deploymentTech: '',
};

if (instanceInfo && instanceInfo.deploymentTechs) {
instanceInfo.deploymentTechs.forEach((tech) => {
if (tech.managedIds) {
for (const managedId of tech.managedIds) {
if (managedId === this.nodeTemplate.id) {
this.instanceInformation.deploymentTech = tech.technologyId;
}
}
}
if (tech.discoveredIds) {
for (const discoveredId of tech.discoveredIds) {
if (discoveredId === this.nodeTemplate.id) {
this.instanceInformation.discoveredBy.push(tech.technologyId);
}
}
}
});
}
if (instanceInfo && instanceInfo.plugins) {
instanceInfo.plugins.forEach((plugin) => {
if (plugin.discoveredIds) {
for (const discoveredId of plugin.discoveredIds) {
if (discoveredId === this.nodeTemplate.id) {
this.instanceInformation.discoveredBy.push(plugin.id);
}
}
}
});
}
}
}
}
Loading

0 comments on commit 81fa884

Please sign in to comment.