Skip to content

Commit

Permalink
Merge pull request #177 from bci-oss/feature/model-mapper-changes
Browse files Browse the repository at this point in the history
Feat: Model mapper changes aligned with AAS 3.0 standard
  • Loading branch information
tunacicek authored Aug 4, 2023
2 parents 98703c7 + 908a1ab commit a82688c
Show file tree
Hide file tree
Showing 60 changed files with 4,709 additions and 278 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.3.13-M1
### Added
- In this version the models have been adjusted to new version AAS 3.0.

## fixed

## 0.3.12-M1
### Added

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ public Optional<NativeWebRequest> getRequest() {
}

@Override
// TODO: 21.06.2023 implement correct and not just give back dummy, implement test cases for this endpoint
public ResponseEntity<ServiceDescription> getDescription() {
ServiceDescription serviceDescription = new ServiceDescription();
serviceDescription.setProfiles( List.of( ServiceDescription.ProfilesEnum.ASSETADMINISTRATIONSHELLREPOSITORYSERVICESPECIFICATION_V3_0_MINIMALPROFILE,
Expand Down Expand Up @@ -120,6 +119,7 @@ public ResponseEntity<SubmodelDescriptor> getSubmodelDescriptorByIdThroughSuperp
public ResponseEntity<AssetAdministrationShellDescriptor> postAssetAdministrationShellDescriptor( AssetAdministrationShellDescriptor assetAdministrationShellDescriptor ) {
Shell shell = shellMapper.fromApiDto(assetAdministrationShellDescriptor);
shellService.mapShellCollection( shell );
if(!shell.getSubmodels().isEmpty()) shellService.mapSubmodel( shell.getSubmodels() );
Shell saved = shellService.save(shell);
return new ResponseEntity<>(shellMapper.toApiDto(saved), HttpStatus.CREATED);
}
Expand All @@ -128,6 +128,7 @@ public ResponseEntity<AssetAdministrationShellDescriptor> postAssetAdministratio
public ResponseEntity<SubmodelDescriptor> postSubmodelDescriptorThroughSuperpath( byte[] aasIdentifier, SubmodelDescriptor submodelDescriptor ) {
Submodel toBeSaved = submodelMapper.fromApiDto(submodelDescriptor);
toBeSaved.setIdExternal( submodelDescriptor.getId() );
shellService.mapSubmodel( Set.of(toBeSaved) );
Submodel savedSubModel = shellService.save(getDecodedId( aasIdentifier ), toBeSaved, getExternalSubjectIdOrEmpty(null));
return new ResponseEntity<>(submodelMapper.toApiDto(savedSubModel), HttpStatus.CREATED);
}
Expand All @@ -142,10 +143,9 @@ public ResponseEntity<Void> putAssetAdministrationShellDescriptorById( byte[] aa

@Override
public ResponseEntity<Void> putSubmodelDescriptorByIdThroughSuperpath( byte[] aasIdentifier, byte[] submodelIdentifier, SubmodelDescriptor submodelDescriptor ) {
Submodel submodel = submodelMapper.fromApiDto( submodelDescriptor );
Submodel fromDB = shellService.findSubmodelByExternalId( getDecodedId( aasIdentifier ),getDecodedId( submodelIdentifier ),getExternalSubjectIdOrEmpty( null ) );
shellService.deleteSubmodel(getDecodedId( aasIdentifier ), getDecodedId( submodelIdentifier ),getExternalSubjectIdOrEmpty( null ));
shellService.update( getDecodedId( aasIdentifier ), submodel.withIdExternal( getDecodedId( submodelIdentifier ) ).withId( fromDB.getId() ) ,getExternalSubjectIdOrEmpty( "" ));
submodelDescriptor.setId( getDecodedId( submodelIdentifier ));
postSubmodelDescriptorThroughSuperpath(aasIdentifier,submodelDescriptor);
return new ResponseEntity<>( HttpStatus.NO_CONTENT );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@
********************************************************************************/
package org.eclipse.tractusx.semantics.registry.mapper;

import org.eclipse.tractusx.semantics.aas.registry.model.AssetAdministrationShellDescriptor;
import org.eclipse.tractusx.semantics.aas.registry.model.GetAssetAdministrationShellDescriptorsResult;
import org.eclipse.tractusx.semantics.aas.registry.model.LangStringTextType;
import org.eclipse.tractusx.semantics.aas.registry.model.SpecificAssetId;
import org.eclipse.tractusx.semantics.registry.dto.ShellCollectionDto;
import org.eclipse.tractusx.semantics.registry.model.Shell;
import org.eclipse.tractusx.semantics.registry.model.ShellDescription;
import org.eclipse.tractusx.semantics.registry.model.ShellDisplayName;
import org.eclipse.tractusx.semantics.registry.model.ShellIdentifier;
import org.mapstruct.*;

import java.util.List;
import java.util.Set;
import org.eclipse.tractusx.semantics.aas.registry.model.*;
import org.eclipse.tractusx.semantics.registry.dto.ShellCollectionDto;
import org.eclipse.tractusx.semantics.registry.model.*;
import org.mapstruct.AfterMapping;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.InjectionStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings;
import org.mapstruct.NullValuePropertyMappingStrategy;


@Mapper(uses = {SubmodelMapper.class}, componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR ,nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE )
Expand All @@ -44,7 +44,8 @@ public interface ShellMapper {
@Mapping(target = "shellType", source = "assetType"),
@Mapping(target = "shellKind", source = "assetKind"),
@Mapping(target = "id", ignore = true),
@Mapping(target = "displayNames", source = "displayName")
@Mapping(target = "displayNames", source = "displayName"),
@Mapping(target = "shellExtensions", source = "extensions"),
})
Shell fromApiDto(AssetAdministrationShellDescriptor apiDto);

Expand All @@ -54,9 +55,31 @@ public interface ShellMapper {

@Mappings({
@Mapping(target = "key", source = "name"),
@Mapping(target = "supplementalSemanticIds", source = "supplementalSemanticIds"),
@Mapping(target = "semanticId", source = "semanticId"),
@Mapping(target = "externalSubjectId", source = "externalSubjectId"),
})
ShellIdentifier fromApiDto(SpecificAssetId apiDto);

ShellIdentifierSupplemSemanticReference maptoShellIdentifierSupplemSemanticReference ( Reference supplementalSemanticId );

ShellIdentifierSemanticReference maptoShellIdentifierSemanticReference ( Reference semanticId );

ShellIdentifierExternalSubjectReference maptoShellIdentifierExternalSubjectReference ( Reference externalSubjectId );

@Mappings({
@Mapping(target = "supplementalSemanticIds", source = "supplementalSemanticIds"),
@Mapping(target = "semanticId", source = "semanticId"),
@Mapping(target = "refersTo", source = "refersTo"),
})
ShellExtension fromApiDto( Extension apiDto);

ShellExtensionSupplemSemanticIdReference maptoShellExtensionSupplemSemanticReference ( Reference supplementalSemanticId );

ShellExtensionSemanticIdReference maptoShellExtensionSemanticReference ( Reference semanticId );

ShellExtensionRefersToReference maptoShellExtensionRefersToReference ( Reference refersTo );

Set<ShellIdentifier> fromApiDto(List<SpecificAssetId> apiDto);

@Mappings({
Expand All @@ -70,7 +93,7 @@ public interface ShellMapper {
@Mapping(source = "descriptions", target = "description"),
@Mapping(source = "submodels", target = "submodelDescriptors"),
@Mapping(source = "displayNames", target = "displayName"),

@Mapping(source = "shellExtensions", target = "extensions"),
})
@InheritInverseConfiguration
AssetAdministrationShellDescriptor toApiDto(Shell shell);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,19 @@
********************************************************************************/
package org.eclipse.tractusx.semantics.registry.mapper;

import com.google.common.base.Strings;
import org.checkerframework.checker.units.qual.K;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.eclipse.tractusx.semantics.aas.registry.model.AssetAdministrationShellDescriptor;
// import org.eclipse.tractusx.semantics.aas.registry.model.IdentifierKeyValuePair;
import org.eclipse.tractusx.semantics.aas.registry.model.Key;
import org.eclipse.tractusx.semantics.aas.registry.model.Reference;
import org.eclipse.tractusx.semantics.aas.registry.model.SpecificAssetId;
import org.eclipse.tractusx.semantics.registry.model.Shell;
import org.eclipse.tractusx.semantics.registry.model.ShellIdentifier;

import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import com.google.common.base.Strings;

/**
* The globalAssetId of a AssetAdministrationShellDescriptor is the same as specificAssetIds from persistence point of view.
Expand Down Expand Up @@ -89,7 +88,7 @@ private static Optional<ShellIdentifier> extractGlobalAssetId(String globalAsset
if(Strings.isNullOrEmpty(globalAssetId)){
return Optional.empty();
}
return Optional.of(new ShellIdentifier(null, ShellIdentifier.GLOBAL_ASSET_ID_KEY, globalAssetId, null, null));
return Optional.of(new ShellIdentifier(null, ShellIdentifier.GLOBAL_ASSET_ID_KEY, globalAssetId, null, null, null, null));
}

public static void removeGlobalAssetIdIdentifier(List<SpecificAssetId> specificAssetIds){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,61 +19,59 @@
********************************************************************************/
package org.eclipse.tractusx.semantics.registry.mapper;



import org.eclipse.tractusx.semantics.aas.registry.model.Endpoint;
import org.eclipse.tractusx.semantics.aas.registry.model.GetSubmodelDescriptorsResult;
import org.eclipse.tractusx.semantics.aas.registry.model.Key;
import org.eclipse.tractusx.semantics.aas.registry.model.KeyTypes;
import org.eclipse.tractusx.semantics.aas.registry.model.LangStringTextType;
import org.eclipse.tractusx.semantics.aas.registry.model.Reference;
import org.eclipse.tractusx.semantics.aas.registry.model.ReferenceTypes;
import org.eclipse.tractusx.semantics.aas.registry.model.SubmodelDescriptor;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.tractusx.semantics.aas.registry.model.*;
import org.eclipse.tractusx.semantics.registry.dto.SubmodelCollectionDto;
import org.eclipse.tractusx.semantics.registry.model.Submodel;
import org.eclipse.tractusx.semantics.registry.model.SubmodelDescription;
import org.eclipse.tractusx.semantics.registry.model.SubmodelEndpoint;
import org.mapstruct.AfterMapping;
import org.eclipse.tractusx.semantics.registry.model.*;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.InjectionStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
import org.mapstruct.NullValuePropertyMappingStrategy;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface SubmodelMapper {
@Mappings({
@Mapping(target="idExternal", source="id"),
@Mapping(target = "descriptions", source = "description"),
@Mapping(target="semanticId", source = "semanticId"),
@Mapping(target = "id", ignore = true)
@Mapping(target = "id", ignore = true),
@Mapping(target = "displayNames", source = "displayName"),
@Mapping(target = "submodelExtensions", source = "extensions"),
@Mapping(target = "submodelSupplemSemanticIds", source = "supplementalSemanticId")
})
Submodel fromApiDto(SubmodelDescriptor apiDto);

SubmodelDescription mapShellDescription (LangStringTextType description);

@Mappings({
@Mappings({
@Mapping(target="submodSemanticId", source = "semanticId"),
@Mapping(target="submodSupplementalIds", source = "supplementalSemanticIds"),
@Mapping(target="name", source = "name"),
@Mapping(target="valueType", source = "valueType"),
@Mapping(target="value", source = "value"),
@Mapping(target="refersTo", source = "refersTo")
})
SubmodelExtension mapSubmodelExtension (Extension submodelExtensions);

@Mappings({
@Mapping(target="interfaceName", source = "interface"),
@Mapping(target="endpointAddress", source = "protocolInformation.href"),
@Mapping(target="endpointProtocol", source = "protocolInformation.endpointProtocol"),
@Mapping(target="subProtocol", source = "protocolInformation.subprotocol"),
@Mapping(target="subProtocolBody", source = "protocolInformation.subprotocolBody"),
@Mapping(target="subProtocolBodyEncoding", source = "protocolInformation.subprotocolBodyEncoding"),
@Mapping(target = "endpointProtocolVersion", source = "protocolInformation.endpointProtocolVersion" , qualifiedByName = "endpointProtocolVersionMapping"),
@Mapping( target = "submodelSecurityAttribute", source = "protocolInformation.securityAttributes")
})
SubmodelEndpoint fromApiDto(Endpoint apiDto);

//TODO:Change the data base column to List of String
@Named("endpointProtocolVersionMapping")
default String endpointProtocolVersion(List<String> endpointProtocolVersions) {
return Optional.ofNullable(endpointProtocolVersions).map(endpointPVs -> String.join(",", endpointPVs)).orElse(null);
Expand All @@ -95,6 +93,7 @@ default List<String> protocolVersionDescriptor(String version){

@Mappings({
@Mapping(source = "endpointProtocolVersion", target = "protocolInformation.endpointProtocolVersion" , qualifiedByName = "protocolVersionDescriptor"),
@Mapping( source = "submodelSecurityAttribute", target = "protocolInformation.securityAttributes")
})
@InheritInverseConfiguration
Endpoint toApiDto(SubmodelEndpoint apiDto);
Expand All @@ -104,40 +103,19 @@ default List<String> protocolVersionDescriptor(String version){

LangStringTextType mapSubModelDescription (SubmodelDescription description);

@Mappings({
@Mapping(source = "submodelExtensions", target = "extensions"),
})
@InheritInverseConfiguration
List<SubmodelDescriptor> toApiDto( Set<Submodel> submodels );

default String map(Reference reference) {
return Optional.ofNullable(reference).map(Reference::getKeys)
.map( Collection::stream)
.orElseGet( Stream::empty)
.map(Key::getValue)
.filter( Objects::nonNull)
.findFirst()
.orElse(null);
}

// todo: implement types
default Reference map(String semanticId){
if(semanticId == null || semanticId.isBlank()) {
return null;
}
Reference reference = new Reference();
reference.setType( ReferenceTypes.EXTERNALREFERENCE );
Key key = new Key();
key.setType( KeyTypes.SUBMODEL );
key.setValue( semanticId );
reference.setKeys( List.of(key) );
return reference;
}

@AfterMapping
default Submodel mapSemanticIds( SubmodelDescriptor apiDto, @MappingTarget Submodel submodel){
if(apiDto.getSemanticId().getKeys()!=null){
return submodel.withSemanticId( apiDto.getSemanticId().getKeys().get( 0 ).getValue() );
}else{
return submodel.withSemanticId( "" );
}
}

@Mappings({
@Mapping(source="submodSemanticId", target = "semanticId"),
@Mapping(source="submodSupplementalIds", target = "supplementalSemanticIds"),
@Mapping(source="name", target = "name"),
@Mapping(source="valueType", target = "valueType"),
@Mapping(source="value", target = "value"),
@Mapping(source="refersTo", target = "refersTo")
})
Extension mapExtension (SubmodelExtension submodelExtension);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/********************************************************************************
* Copyright (c) 2023 Robert Bosch Manufacturing Solutions GmbH
* 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 Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
package org.eclipse.tractusx.semantics.registry.model;

public enum DataTypeXsd {
ANYURI("xs:anyURI"),
BASE64BINARY("xs:base64Binary"),
BOOLEAN("xs:boolean"),
BYTE("xs:byte"),
DATE("xs:date"),
DATETIME("xs:dateTime"),
DECIMAL("xs:decimal"),
DOUBLE("xs:double"),
DURATION("xs:duration"),
FLOAT("xs:float"),
GDAY("xs:gDay"),
GMONTH("xs:gMonth"),
GMONTHDAY("xs:gMonthDay"),
GYEAR("xs:gYear"),
GYEARMONTH("xs:gYearMonth"),
HEXBINARY("xs:hexBinary"),
INT("xs:int"),
INTEGER("xs:integer"),
LONG("xs:long"),
NEGATIVEINTEGER("xs:negativeInteger"),
NONNEGATIVEINTEGER("xs:nonNegativeInteger"),
NONPOSITIVEINTEGER("xs:nonPositiveInteger"),
POSITIVEINTEGER("xs:positiveInteger"),
SHORT("xs:short"),
STRING("xs:string"),
TIME("xs:time"),
UNSIGNEDBYTE("xs:unsignedByte"),
UNSIGNEDINT("xs:unsignedInt"),
UNSIGNEDLONG("xs:unsignedLong"),
UNSIGNEDSHORT("xs:unsignedShort");
private String value;
DataTypeXsd(String value) {this.value = value;}
public String getValue() {return value;}
@Override
public String toString() {return String.valueOf(value);}
}
Loading

0 comments on commit a82688c

Please sign in to comment.