Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Feature/properties in boundary definitions #113

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ export class InstanceService {
break;
case ToscaTypes.ServiceTemplate:
subMenu = [SubMenuItems.readme, SubMenuItems.license, SubMenuItems.topologyTemplate, SubMenuItems.plans, SubMenuItems.selfServicePortal,
SubMenuItems.boundaryDefinitions, SubMenuItems.tags, SubMenuItems.constraintChecking, SubMenuItems.documentation, SubMenuItems.xml];
SubMenuItems.boundaryDefinitions, SubMenuItems.tags, SubMenuItems.propertiesDefinition, SubMenuItems.constraintChecking,
SubMenuItems.documentation, SubMenuItems.xml];
if (this.configurationService.configuration.features.nfv) {
subMenu.push(SubMenuItems.threatModeling);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ import { InterfacesComponent } from '../../sharedComponents/interfaces/interface
import { InterfacesModule } from '../../sharedComponents/interfaces/interfaces.module';
import { WineryQNameSelectorModule } from '../../../wineryQNameSelector/wineryQNameSelector.module';
import { WineryEditorModule } from '../../../wineryEditorModule/wineryEditor.module';
import { PropertiesComponent } from '../../sharedComponents/properties/properties.component';

export const boundaryDefinitionsRoutes: Routes = [
{ path: 'properties', component: EditXMLComponent },
{ path: 'properties', component: PropertiesComponent},
{ path: 'propertymappings', component: PropertyMappingsComponent },
{ path: 'propertyconstraints', component: PropertyConstraintsComponent },
{ path: 'requirements', component: RequirementsComponent },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,15 @@
<div class="form-group">
<span>Service Template Property</span>
<br>
<div>
<ng-select #serviceTemplateProperty
*ngIf="propertiesAreKeyValuePairs"
[items]="propertiesList"
(selected)="onPropertySelected($event)"
required
placeholder="no property specified">
</ng-select>

<div *ngIf="!propertiesAreKeyValuePairs">
<label for="serviceTemplatePropertyRef">Property Name</label>
<input #serviceTemplateProp="ngModel"
name="serviceTemplatePropertyRef"
Expand All @@ -41,13 +49,13 @@
type="text"
required
[(ngModel)]="currentSelectedItem.serviceTemplatePropertyRef"/>
</div>

<div style="clear:both"
*ngIf="serviceTemplateProp.errors && (serviceTemplateProp.dirty || serviceTemplateProp.touched)"
class="alert alert-danger">
<div [hidden]="!serviceTemplateProp.errors.required">
Property name is required!
<div style="clear:both"
*ngIf="serviceTemplateProp.errors && (serviceTemplateProp.dirty || serviceTemplateProp.touched)"
class="alert alert-danger">
<div [hidden]="!serviceTemplateProp.errors.required">
Property name is required!
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -145,8 +153,9 @@
<winery-modal-footer
(onOk)="addPropertyMapping()"
[okButtonLabel]="addOrUpdate"
[disableOkButton]="!(propertyMappingForm?.form.valid && currentSelectedItem.targetObjectRef && currentSelectedItem.targetObjectRef.length > 0
&& currentSelectedItem.targetPropertyRef && currentSelectedItem.targetPropertyRef.length > 0)">
[disableOkButton]="!(propertyMappingForm?.form.valid && currentSelectedItem.serviceTemplatePropertyRef && currentSelectedItem.serviceTemplatePropertyRef.length > 0
&& currentSelectedItem.targetObjectRef && currentSelectedItem.targetObjectRef.length > 0
&& currentSelectedItem.targetPropertyRef && currentSelectedItem.targetPropertyRef.length > 0)">
</winery-modal-footer>
</winery-modal>

Expand All @@ -164,7 +173,7 @@
</winery-modal-body>
<winery-modal-footer
(onOk)="removeConfirmed();"
[okButtonLabel]="'Yes'">
[okButtonLabel]="'Delete'">
</winery-modal-footer>
</winery-modal>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class PropertyMappingsComponent implements OnInit {

loading = true;
targetTypeSelected = false;
apiData: PropertyMappingsApiData;
apiData: PropertyMappingsApiData = { propertyMappings: { propertyMapping: [] } };
columns: Array<WineryTableColumn> = [
{ title: 'Service Template Property', name: 'serviceTemplatePropertyRef', sort: true },
{ title: 'Target', name: 'targetObjectRef', sort: true },
Expand All @@ -53,6 +53,8 @@ export class PropertyMappingsComponent implements OnInit {
currentSelectedItem: Property = new Property();
addOrUpdate = 'Add';
properties: { name: string, property: string } = { name: '', property: '' };
propertiesList: Array<SelectData> = [];
propertiesAreKeyValuePairs = false;
xmlData: any;
selectedProperty = '';
templateList: Array<SelectData> = [];
Expand All @@ -71,13 +73,14 @@ export class PropertyMappingsComponent implements OnInit {

ngOnInit() {
this.getMappings();
this.getProperties();
this.getTopologyTemplate();
}

getMappings() {
this.service.getPropertyMappings().subscribe(
data => this.handleData(data),
data => {
this.handleData(data);
this.getProperties();
},
error => this.notify.error(error.toString())
);
}
Expand All @@ -91,26 +94,42 @@ export class PropertyMappingsComponent implements OnInit {

getProperties() {
this.service.getPropertiesOfServiceTemplate().subscribe(
data => this.handleProperties(data),
data => {
this.handleProperties(data);
this.getTopologyTemplate();
},
error => this.handleError(error)
);
}

handleTopologyTemplateData(data: WineryTopologyTemplate) {
this.topologyTemplate = data;
if (!isNullOrUndefined(this.xmlData) && !isNullOrUndefined(this.apiData)) {
this.loading = false;
}
this.loading = false;
}

handleProperties(props: string) {
const parser = new DOMParser();
this.xmlData = parser.parseFromString(props, 'application/xml');
this.properties.name = this.xmlData.firstChild.localName;
this.properties.property = '/*[local-name()=\'' + this.properties.name + '\']';
handleProperties(props: any) {
if (props.isXML) {
if (props.properties) {
const parser = new DOMParser();
this.xmlData = parser.parseFromString(props.properties, 'application/xml');
this.properties.name = this.xmlData.firstChild.localName;
this.properties.property = '/*[local-name()=\'' + this.properties.name + '\']';
}
} else {
this.propertiesAreKeyValuePairs = true;
if (props.properties) {
for (const p in props.properties) {
if (props.properties.hasOwnProperty(p)) {
this.propertiesList.push({ 'id': p, 'text': p });
}
}
}
}
}

if (!isNullOrUndefined(this.topologyTemplate) && !isNullOrUndefined(this.apiData)) {
this.loading = false;
onPropertySelected(property: any) {
if (property.text && property.text.length > 0) {
this.currentSelectedItem.serviceTemplatePropertyRef = property.text;
}
}

Expand Down Expand Up @@ -200,9 +219,6 @@ export class PropertyMappingsComponent implements OnInit {

handleData(data: PropertyMappingsApiData) {
this.apiData = data;
if (!isNullOrUndefined(this.xmlData) && !isNullOrUndefined(this.topologyTemplate)) {
this.loading = false;
}
}

onCellSelected(selectedItem: WineryRowData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { backendBaseURL } from '../../../../configuration';
import { ModalDirective } from 'ngx-bootstrap';
import { PropertiesDefinitionsResourceApiData } from '../../../sharedComponents/propertiesDefinition/propertiesDefinitionsResourceApiData';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { map } from 'rxjs/operators';

export class Property {
serviceTemplatePropertyRef: string;
Expand Down Expand Up @@ -66,14 +67,18 @@ export class PropertyMappingService {
);
}

getPropertiesOfServiceTemplate(): Observable<string> {
const headers = new HttpHeaders({ 'Accept': 'application/xml' });
getPropertiesOfServiceTemplate(): Observable<any> {
const newPath: string = this.path.replace('propertymappings', 'properties');

return this.http
.get(newPath + '/',
{ headers: headers, responseType: 'text' }
);
return this.http.get(newPath, { observe: 'response', responseType: 'text' })
.pipe(map(res => {
if (res.headers.get('Content-Type') === 'application/json') {
return {
isXML: false, properties: JSON.parse(res.body)
};
} else {
return { isXML: true, properties: res.body };
}
}));
}

getTargetObjKVProperties(targetPath: string): Observable<PropertiesDefinitionsResourceApiData> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { Observable } from 'rxjs';
import { backendBaseURL } from '../../../configuration';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { map } from 'rxjs/operators';
import { ToscaTypes } from '../../../model/enums';

@Injectable()
export class PropertiesService {
Expand All @@ -26,6 +27,9 @@ export class PropertiesService {
constructor(private http: HttpClient,
private sharedData: InstanceService) {
this.path = backendBaseURL + this.sharedData.path + '/properties/';
if (this.sharedData.toscaComponent.toscaType === ToscaTypes.ServiceTemplate ) {
this.path = this.path.replace('/properties/', '/boundarydefinitions/properties/');
}
}

/**
Expand All @@ -46,8 +50,7 @@ export class PropertiesService {
}

public saveProperties(properties: any, isXML: boolean): Observable<HttpResponse<string>> {
const headers = new HttpHeaders();
headers.set('Content-Type', isXML ? 'application/xml' : 'application/json');
const headers = new HttpHeaders({ 'Content-Type' : isXML ? 'application/xml' : 'application/json'});
return this.http
.put(
this.path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ServiceTemplateRouterModule } from './serviceTemplateRouter.module';
import { TopologyTemplateComponent } from '../../instance/sharedComponents/topologyTemplate/topologyTemplate.component';
import { PlansComponent } from '../../instance/serviceTemplates/plans/plans.component';
import { WineryLoaderModule } from '../../wineryLoader/wineryLoader.module';
import { WineryModalModule } from '../../wineryModalModule/winery.modal.module';
Expand All @@ -34,7 +33,8 @@ import { WineryLicenseModule } from '../../wineryLicenseModule/wineryLicense.mod
import { WinerySourceModule } from '../../instance/sharedComponents/artifactSource/source.module';
import { ConstraintCheckingComponent } from '../../instance/serviceTemplates/constraintChecking/constraintChecking.component';
import { WineryEditorModule } from '../../wineryEditorModule/wineryEditor.module';
import { TopologyTemplateModule } from '../../instance/sharedComponents/topologyTemplate/topologyTemplate.module';
import { TopologyTemplateModule } from '../../instance/serviceTemplates/topologyTemplate/topologyTemplate.module';
import { PropertiesDefinitionModule } from '../../instance/sharedComponents/propertiesDefinition/propertiesDefinition.module';
import { ThreatAssessmentComponent } from '../../instance/serviceTemplates/threatAssessment/threatAssessment.component';

@NgModule({
Expand All @@ -57,7 +57,8 @@ import { ThreatAssessmentComponent } from '../../instance/serviceTemplates/threa
WineryTableModule,
ServiceTemplateRouterModule,
WineryReadmeModule,
WineryLicenseModule
WineryLicenseModule,
PropertiesDefinitionModule
],
declarations: [
PlansComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { WineryReadmeComponent } from '../../wineryReadmeModule/wineryReadme.com
import { WineryLicenseComponent } from '../../wineryLicenseModule/wineryLicense.component';
import { ConstraintCheckingComponent } from '../../instance/serviceTemplates/constraintChecking/constraintChecking.component';
import { ThreatAssessmentComponent } from '../../instance/serviceTemplates/threatAssessment/threatAssessment.component';
import { PropertiesDefinitionComponent } from '../../instance/sharedComponents/propertiesDefinition/propertiesDefinition.component';

const toscaType = ToscaTypes.ServiceTemplate;

Expand Down Expand Up @@ -60,6 +61,7 @@ const serviceTemplateRoutes: Routes = [
// 'app/instance/serviceTemplates/boundaryDefinitions/boundaryDefinitions.module#BoundaryDefinitionsModule'
children: boundaryDefinitionsRoutes
},
{ path: 'propertiesdefinition', component: PropertiesDefinitionComponent},
{ path: 'constraintchecking', component: ConstraintCheckingComponent },
{ path: 'tags', component: TagComponent },
{ path: 'documentation', component: DocumentationComponent },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

Expand Down Expand Up @@ -174,26 +173,11 @@ public List<TExportedInterface> getInterface() {
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"any",
"propertyMappings"
})
public static class Properties implements Serializable {
public static class Properties extends TEntityTemplate.Properties {

@XmlAnyElement(lax = true)
protected Object any;
@XmlElement(name = "PropertyMappings")
protected TBoundaryDefinitions.Properties.PropertyMappings propertyMappings;

@Nullable
public Object getAny() {
return any;
}

public void setAny(@Nullable Object value) {
this.any = value;
}

public TBoundaryDefinitions.Properties.@Nullable PropertyMappings getPropertyMappings() {
return propertyMappings;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.namespace.QName;

import org.eclipse.winery.model.tosca.kvproperties.WinerysPropertiesDefinition;
import org.eclipse.winery.model.tosca.visitor.Visitor;

import com.fasterxml.jackson.annotation.JsonIgnore;
Expand All @@ -52,7 +50,6 @@
TPolicyType.class
})
public abstract class TEntityType extends TExtensibleElements implements HasName, HasInheritance, HasTargetNamespace {
public static final String NS_SUFFIX_PROPERTIESDEFINITION_WINERY = "propertiesdefinition/winery";

@XmlElement(name = "Tags")
protected TTags tags;
Expand Down Expand Up @@ -184,47 +181,6 @@ public void setTargetNamespace(@Nullable String value) {
this.targetNamespace = value;
}

/**
* This is a special method for Winery. Winery allows to define a property definition by specifying name/type
* values. Instead of parsing the extensible elements returned TDefinitions, this method is a convenience method to
* access this information
*
* @return a WinerysPropertiesDefinition object, which includes a map of name/type-pairs denoting the associated
* property definitions. A default element name and namespace is added if it is not defined in the underlying XML.
* null if no Winery specific KV properties are defined for the given entity type
*/
@XmlTransient
@JsonIgnore
public WinerysPropertiesDefinition getWinerysPropertiesDefinition() {
// similar implementation as org.eclipse.winery.repository.resources.entitytypes.properties.PropertiesDefinitionResource.getListFromEntityType(TEntityType)
WinerysPropertiesDefinition res = null;
for (Object o : this.getAny()) {
if (o instanceof WinerysPropertiesDefinition) {
res = (WinerysPropertiesDefinition) o;
}
}

if (res != null) {
// we put defaults if elementname and namespace have not been set

if (res.getElementName() == null) {
res.setElementName("Properties");
}

if (res.getNamespace() == null) {
// we use the targetnamespace of the original element
String ns = this.getTargetNamespace();
if (!ns.endsWith("/")) {
ns += "/";
}
ns += NS_SUFFIX_PROPERTIESDEFINITION_WINERY;
res.setNamespace(ns);
}
}

return res;
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
public static class DerivedFrom implements HasType {
Expand Down
Loading