Skip to content

Commit

Permalink
Adds AAS Discovery Service (#111)
Browse files Browse the repository at this point in the history
* Initial commit for AasDiscoveryService skeleton

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Updates Readme

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Defines Aas discovery service interface

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Adds AasDiscoveryServiceSuite

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Refactors AasDiscoveryServiceSuite test case

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* basyx.aasdiscoveryservice-core

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Updates parent pom

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Adds AssetLink model and updates test suite

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Adds HTTP module with Tests

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Add in memory aas discovery service

Signed-off-by: Zai Müller-Zhang <[email protected]>

* Adds TCK component

- Refactors InMemory code and TCK
- Refactors Aas Discovery component
- Refactors AAS Discovery Service Backend InMemory
- Refactors AAS Discovery Service Backend InMemory
- Refactors AAS Discovery Service Backend MongoDB
- Refactors AAS Discovery Service core
- Refactors AAS Discovery Service http
- Updates Readme
- Refactors TCK name

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Minor improvements and refactoring

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Improves variable naming

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>

* Refactors during Review
* Replaces Sys.out with logger
* Refactors stream-API-Statement to a smaller footprint

Signed-off-by: Jannis Jung <[email protected]>

* Refactors during Review
* applies BaSyx formatter
* adds trailing empty line to poms

Signed-off-by: Jannis Jung <[email protected]>

* Address review remarks

- Renames property basyx.aasdiscserv.name to basyx.aasdiscoveryservice.name

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>
Co-authored-by: Zai Müller-Zhang <[email protected]>

---------

Signed-off-by: Mohammad Ghazanfar Ali Danish <[email protected]>
Signed-off-by: Zai Müller-Zhang <[email protected]>
Signed-off-by: Jannis Jung <[email protected]>
Co-authored-by: Zai Müller-Zhang <[email protected]>
Co-authored-by: Jannis Jung <[email protected]>
  • Loading branch information
3 people authored Oct 26, 2023
1 parent 1889d73 commit d77bd05
Show file tree
Hide file tree
Showing 46 changed files with 3,002 additions and 0 deletions.
25 changes: 25 additions & 0 deletions basyx.aasdiscoveryservice/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Eclipse BaSyx - Aas Discovery Service
Eclipse BaSyx provides the Aas Discovery Service as off-the-shelf component:

docker run --name=aas-discovery-service -p:8081:8081 -v C:/tmp/application.properties:/application/application.properties eclipsebasyx/aasdiscovery-service:2.0.0-SNAPSHOT

> *Disclaimer*: In this example, configuration files are located in `C:/tmp`
> *Disclaimer*: The binding of volume `C:/tmp/application.properties` to `/application/application.properties` is tested using Windows Powershell. Other terminals might run into an error.
The API endpoint documentation is available at:

http://{host}:{port}/v3/api-docs

The Swagger UI for the endpoint is available at:

http://{host}:{port}/swagger-ui/index.html

It supports DotAAS Part 1 V3 and all HTTP/REST endpoints defined in [DotAAS Part 2 V3 - AasDiscovery Service](https://app.swaggerhub.com/apis/Plattform_i40/Entire-API-Collection/V3.0.1#/Asset%20Administration%20Shell%20Basic%20Discovery%20API/).
In addition, it supports InMemory as well as MongoDB backends.

For a configuration example, see [application.properties](basyx.aasdiscoveryservice.component/src/main/resources/application.properties)

The Health Endpoint and CORS Documentation can be found [here](../docs/Readme.md).

Right now, no additional input parameters modifying the output (e.g., cursor, serializationModifier) are supported.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.eclipse.digitaltwin.basyx</groupId>
<artifactId>basyx.aasdiscoveryservice</artifactId>
<version>${revision}</version>
</parent>

<artifactId>basyx.aasdiscoveryservice-backend-inmemory</artifactId>
<name>AAS Discovery Service Backend InMemory</name>

<dependencies>
<dependency>
<groupId>org.eclipse.digitaltwin.basyx</groupId>
<artifactId>basyx.aasdiscoveryservice-core</artifactId>
</dependency>

<dependency>
<groupId>org.eclipse.digitaltwin.basyx</groupId>
<artifactId>basyx.aasdiscoveryservice-core</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*******************************************************************************
* Copyright (C) 2023 the Eclipse BaSyx Authors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* SPDX-License-Identifier: MIT
******************************************************************************/

package org.eclipse.digitaltwin.basyx.aasdiscoveryservice.backend.inmemory;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.eclipse.digitaltwin.aas4j.v3.model.SpecificAssetID;
import org.eclipse.digitaltwin.basyx.aasdiscoveryservice.core.AasDiscoveryService;
import org.eclipse.digitaltwin.basyx.aasdiscoveryservice.core.model.AssetLink;
import org.eclipse.digitaltwin.basyx.core.exceptions.AssetLinkDoesNotExistException;
import org.eclipse.digitaltwin.basyx.core.exceptions.CollidingAssetLinkException;
import org.eclipse.digitaltwin.basyx.core.pagination.CursorResult;
import org.eclipse.digitaltwin.basyx.core.pagination.PaginationInfo;
import org.eclipse.digitaltwin.basyx.core.pagination.PaginationSupport;

/**
* In-memory implementation of the {@link AasDiscoveryService}
*
* @author zhangzai
*
*/
public class InMemoryAasDiscoveryService implements AasDiscoveryService {

private String aasDiscoveryServiceName;

private Map<String, AssetLink> assetLinks = new LinkedHashMap<>();

/**
* Creates the {@link InMemoryAasDiscoveryService}
*
*/
public InMemoryAasDiscoveryService() {
}

/**
* Creates the {@link InMemoryAasDiscoveryService}
*
* @param name
* of the Aas Discovery Service
*/
public InMemoryAasDiscoveryService(String aasDiscoveryServiceName) {
this.aasDiscoveryServiceName = aasDiscoveryServiceName;
}

@Override
public CursorResult<List<String>> getAllAssetAdministrationShellIdsByAssetLink(PaginationInfo pInfo, List<String> assetIds) {
Set<String> shellIds = assetIds.stream()
.map(this::getShellIdWithAssetId)
.collect(Collectors.toSet());

List<String> result = new ArrayList<>();
result.addAll(shellIds);

return paginateList(pInfo, result);
}

@Override
public List<SpecificAssetID> getAllAssetLinksById(String shellIdentifier) {
throwIfAssetLinkDoesNotExist(shellIdentifier);

AssetLink assetLink = assetLinks.get(shellIdentifier);

return assetLink.getSpecificAssetIDs();
}

@Override
public List<SpecificAssetID> createAllAssetLinksById(String shellIdentifier, List<SpecificAssetID> assetIds) {
throwIfAssetLinkExists(shellIdentifier);

assetLinks.put(shellIdentifier, new AssetLink(shellIdentifier, assetIds));

return assetIds;
}

@Override
public void deleteAllAssetLinksById(String shellIdentifier) {
throwIfAssetLinkDoesNotExist(shellIdentifier);

assetLinks.remove(shellIdentifier);
}

@Override
public String getName() {
return aasDiscoveryServiceName == null ? AasDiscoveryService.super.getName() : aasDiscoveryServiceName;
}

private CursorResult<List<String>> paginateList(PaginationInfo pInfo, List<String> shellIdentifiers) {
TreeMap<String, String> shellIdentifierMap = shellIdentifiers.stream()
.collect(Collectors.toMap(Function.identity(), Function.identity(), (a, b) -> a, TreeMap::new));

PaginationSupport<String> paginationSupport = new PaginationSupport<>(shellIdentifierMap, Function.identity());

return paginationSupport.getPaged(pInfo);
}

private String getShellIdWithAssetId(String id) {
return assetLinks.values()
.stream()
.filter(link -> link.getSpecificAssetIDStrings()
.contains(id))
.findFirst()
.map(link -> link.getShellIdentifier())
.get();
}

private void throwIfAssetLinkDoesNotExist(String shellIdentifier) {
if (!assetLinks.containsKey(shellIdentifier))
throw new AssetLinkDoesNotExistException(shellIdentifier);
}

private void throwIfAssetLinkExists(String shellIdentifier) {
if (assetLinks.containsKey(shellIdentifier))
throw new CollidingAssetLinkException(shellIdentifier);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright (C) 2023 the Eclipse BaSyx Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* SPDX-License-Identifier: MIT
******************************************************************************/

package org.eclipse.digitaltwin.basyx.aasdiscoveryservice.backend.inmemory;

import org.eclipse.digitaltwin.basyx.aasdiscoveryservice.core.AasDiscoveryService;
import org.eclipse.digitaltwin.basyx.aasdiscoveryservice.core.AasDiscoveryServiceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;

/**
* {@link AasDiscoveryService} factory returning an in-memory backend
* {@link AasDiscoveryService}
*
* @author zhangzai
*/
@Component
@ConditionalOnExpression("'${basyx.backend}'.equals('InMemory')")
public class InMemoryAasDiscoveryServiceFactory implements AasDiscoveryServiceFactory {

private String aasDiscoveryServiceName;

@Autowired(required = false)
public InMemoryAasDiscoveryServiceFactory() {
}

@Autowired(required = false)
public InMemoryAasDiscoveryServiceFactory(@Value("${basyx.aasdiscoveryservice.name:aas-discovery-service}") String aasDiscoveryServiceName) {
this.aasDiscoveryServiceName = aasDiscoveryServiceName;
}

@Override
public AasDiscoveryService create() {
return new InMemoryAasDiscoveryService(aasDiscoveryServiceName);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (C) 2023 the Eclipse BaSyx Authors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* SPDX-License-Identifier: MIT
******************************************************************************/

package org.eclipse.digitaltwin.basyx.aasdiscoveryservice.backend.inmemory;

import org.eclipse.digitaltwin.basyx.aasdiscoveryservice.core.AasDiscoveryService;
import org.eclipse.digitaltwin.basyx.aasdiscoveryservice.core.AasDiscoveryServiceSuite;

/**
* Tests the {@link InMemoryAasDiscoveryService}
*
* @author zhangzai
*
*/
public class TestInMemoryAasDiscoveryService extends AasDiscoveryServiceSuite {

@Override
protected AasDiscoveryService getAasDiscoveryService() {
return new InMemoryAasDiscoveryService();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.eclipse.digitaltwin.basyx</groupId>
<artifactId>basyx.aasdiscoveryservice</artifactId>
<version>${revision}</version>
</parent>

<artifactId>basyx.aasdiscoveryservice-backend-mongodb</artifactId>
<name>AAS Discovery Service Backend MongoDB</name>

<dependencies>
<dependency>
<groupId>org.eclipse.digitaltwin.basyx</groupId>
<artifactId>basyx.aasdiscoveryservice-core</artifactId>
</dependency>

<dependency>
<groupId>org.eclipse.digitaltwin.basyx</groupId>
<artifactId>basyx.aasdiscoveryservice-core</artifactId>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>
</project>
Loading

0 comments on commit d77bd05

Please sign in to comment.