Skip to content

Commit

Permalink
Merge pull request #209 from bci-oss/feature/add-deprecated-api-query
Browse files Browse the repository at this point in the history
Add deprecated function query. This is needed for the release 3.2
  • Loading branch information
tunacicek authored Aug 30, 2023
2 parents 90c29ac + ed2daf8 commit c977334
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 96 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.15-M1
### Added

## fixed
- Add deprecated api `/query` for release 3.2. The Api `query` is not a part of AAS 3.0. But for release 3.2, this api will be added and marked as deprecated. This api will be removed in future releases.

## 0.3.14-M1
### Added

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,14 @@ public ResponseEntity<List<SpecificAssetId>> postAllAssetLinksById(byte[] aasIde
* Since /query is not part of AAS 3.0, so this method is not used.
* Keeping it for the reason that it might come up in next version.
*/
@Deprecated
public ResponseEntity<List<String>> postQueryAllAssetAdministrationShellIds(ShellLookup shellLookup,@RequestHeader String externalSubjectId) {
List<SpecificAssetId> assetIds = shellLookup.getQuery().getAssetIds();
List<String> externalIds = shellService.findExternalShellIdsByIdentifiersByAnyMatch(shellMapper.fromApiDto(assetIds),getExternalSubjectIdOrEmpty(externalSubjectId));
return new ResponseEntity<>(externalIds, HttpStatus.OK);
}

private String getExternalSubjectIdOrEmpty(String externalSubjectId) {
private String getExternalSubjectIdOrEmpty(String externalSubjectId) {
return (null ==externalSubjectId) ? "" : externalSubjectId;
}

Expand All @@ -194,6 +195,5 @@ private String getDecodedId( byte[] aasIdentifier ) {
throw new IllegalArgumentException("Incorrect Base64 encoded value provided as parameter");
}
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,18 @@ List<String> findExternalShellIdsByIdentifiersByExactMatch(@Param("keyValueCombi
* @param keyValueCombinations the keys values to search for as tuples
* @return external shell ids for the given key value combinations
*/
@Query(value =
"select distinct s.id_external from shell s where s.id in (" +
"select si.fk_shell_id from shell_identifier si " +
"where concat(si.namespace,si.identifier) in (:keyValueCombinations) " +
"and (si.external_subject_id is null or :tenantId = :owningTenantId or si.external_subject_id = :tenantId) " +
"group by si.fk_shell_id " +
")",nativeQuery = true
)
@Query( value = "select s.id_external from shell s where s.id in (" +
"select si.fk_shell_id from shell_identifier si " +
"where concat(si.namespace,si.identifier) in (:keyValueCombinations) " +
"and (:tenantId = :owningTenantId or si.namespace= :globalAssetId or exists (" +
"Select sider.ref_key_value from SHELL_IDENTIFIER_EXTERNAL_SUBJECT_REFERENCE_KEY sider where (sider.ref_key_value = :tenantId or (sider.ref_key_value = :publicWildcardPrefix and si.namespace in (:publicWildcardAllowedTypes) )) and sider.FK_SI_EXTERNAL_SUBJECT_REFERENCE_ID="+
"(select sies.id from SHELL_IDENTIFIER_EXTERNAL_SUBJECT_REFERENCE sies where sies.FK_SHELL_IDENTIFIER_EXTERNAL_SUBJECT_ID=si.id)"+
")) group by si.fk_shell_id " +
")",nativeQuery = true )
List<String> findExternalShellIdsByIdentifiersByAnyMatch(@Param("keyValueCombinations") List<String> keyValueCombinations,
@Param("tenantId") String tenantId,
@Param("owningTenantId") String owningTenantId);
@Param("tenantId") String tenantId,
@Param ("publicWildcardPrefix") String publicWildcardPrefix,
@Param ("publicWildcardAllowedTypes") List<String> publicWildcardAllowedTypes,
@Param("owningTenantId") String owningTenantId,
@Param("globalAssetId") String globalAssetId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,13 @@ private int getCursorDecoded( String cursor, List<String> queryResult ) {
public List<String> findExternalShellIdsByIdentifiersByAnyMatch(Set<ShellIdentifier> shellIdentifiers,String externalSubjectId) {
List<String> keyValueCombinations=shellIdentifiers.stream().map( shellIdentifier -> shellIdentifier.getKey()+shellIdentifier.getValue()).toList();

return shellRepository.findExternalShellIdsByIdentifiersByAnyMatch(keyValueCombinations,externalSubjectId , owningTenantId);
return shellRepository.findExternalShellIdsByIdentifiersByAnyMatch(
keyValueCombinations,
externalSubjectId,
externalSubjectIdWildcardPrefix,
externalSubjectIdWildcardAllowedTypes,
owningTenantId,
ShellIdentifier.GLOBAL_ASSET_ID_KEY);
}

// Not used in AAS3
Expand Down
28 changes: 28 additions & 0 deletions backend/src/main/resources/static/aas-registry-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,34 @@ paths:
description: Asset identifier key-value-pairs deleted successfully
x-semanticIds:
- https://admin-shell.io/aas/API/DeleteAllAssetLinksById/1/0/RC02
/lookup/shells/query:
post:
tags:
- Registry and Discovery Interface
summary: Returns a list of Asset Administration Shell ids based on Asset identifier key-value-pairs.
operationId: PostQueryAllAssetAdministrationShellIds
parameters:
- $ref: '#/components/parameters/ExternalSubjectIdHeader'
requestBody:
description: Asset Administration Shell Descriptor object
content:
application/json:
schema:
$ref: '#/components/schemas/ShellLookup'
required: true
responses:
"200":
description: Requested Asset Administration Shell ids
content:
application/json:
schema:
type: array
maxItems: 10000
items:
$ref: '#/components/schemas/Identifier'
examples:
complete:
$ref: '#/components/examples/lookup-shells-by-aas-identifier-response'
components:
securitySchemes:
bearerAuth:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -573,8 +573,7 @@ public void testRbacCreateShellInBatch() throws Exception {
.andExpect(status().isCreated());
}

//TODO: Test will be ignored, because the new api does not provided batch, fetch and query. This will be come later in version 0.3.1
//@Test
@Test
public void testRbacForFindShellsWithAnyMatch() throws Exception {
JsonNode anyMatchLookupPayload = mapper.createObjectNode().set("query", mapper.createObjectNode()
.set("assetIds", emptyArrayNode().add(specificAssetId("abc", "123")))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -838,42 +838,102 @@ public void testCreateShellInBatchExpectSuccess() throws Exception {
.andExpect( jsonPath( "$", hasSize( 5 ) ) );
}

//@Test
@Test
public void testFindExternalShellIdsBySpecificAssetIdsWithAnyMatchExpectSuccess() throws Exception {
// the keyPrefix ensures that this test can run against a persistent database multiple times
String keyPrefix = UUID.randomUUID().toString();
ObjectNode commonAssetId = specificAssetId( keyPrefix + "commonAssetIdKey", "commonAssetIdValue" );
// first shell
ObjectNode firstShellPayload = createBaseIdPayload( "sampleForQuery", "idShortSampleForQuery" );
firstShellPayload.set( "specificAssetIds", emptyArrayNode()
.add( specificAssetId( keyPrefix + "findExternalShellIdQueryKey_1", "value_1" ) ) );
performShellCreateRequest( toJson( firstShellPayload ) );

// second shell
ObjectNode secondShellPayload = createBaseIdPayload( "sampleForQuery", "idShortSampleForQuery" );
secondShellPayload.set( "specificAssetIds", emptyArrayNode()
.add( specificAssetId( keyPrefix + "findExternalShellIdQueryKey_2", "value_2" ) ) );
performShellCreateRequest( toJson( secondShellPayload ) );

// query to retrieve any match
JsonNode anyMatchAueryByAssetIds = mapper.createObjectNode().set( "query", mapper.createObjectNode()
AssetAdministrationShellDescriptor shellPayload = TestUtil.createCompleteAasDescriptor();
shellPayload.setSpecificAssetIds(null);
shellPayload.setId(UUID.randomUUID().toString());
SpecificAssetId asset1 = TestUtil.createSpecificAssetId(keyPrefix + "findExternal_2","value_2",null);
SpecificAssetId asset2 = TestUtil.createSpecificAssetId(keyPrefix + "findExternal_2_1","value_2_1",List.of(jwtTokenFactory.tenantTwo().getTenantId()));
SpecificAssetId asset3 = TestUtil.createSpecificAssetId(keyPrefix + "findExternal_2_2","value_2_2",List.of(jwtTokenFactory.tenantThree().getTenantId()));

shellPayload.setSpecificAssetIds(List.of(asset1,asset2,asset3));

performShellCreateRequest(mapper.writeValueAsString(shellPayload));

// query to retrieve any match (asset1 is only visible for OWNER TENANT_ONE)
JsonNode anyMatchQueryByOwnerAssetIds = mapper.createObjectNode().set( "query", mapper.createObjectNode()
.set( "assetIds", emptyArrayNode()
.add( specificAssetId( keyPrefix + "findExternalShellIdQueryKey_1", "value_1" ) )
.add( specificAssetId( keyPrefix + "findExternalShellIdQueryKey_2", "value_2" ) )
.add( commonAssetId ) )
.add( specificAssetId( asset1.getName(), asset1.getValue() ) )
.add( specificAssetId( "not_available_key_in_shell","not_available_value_in_shell" ) ))
);

// Test with non Owner(TENANT_TWO)
mvc.perform(
MockMvcRequestBuilders
.post( LOOKUP_SHELL_BASE_PATH + "/query" )
.content( toJson( anyMatchAueryByAssetIds ) )
.content( toJson( anyMatchQueryByOwnerAssetIds ) )
.contentType( MediaType.APPLICATION_JSON )
.header( EXTERNAL_SUBJECT_ID_HEADER, jwtTokenFactory.tenantTwo().getTenantId() )
.with( jwtTokenFactory.allRoles() )
)
.andDo( MockMvcResultHandlers.print() )
.andExpect( status().isOk() )
.andExpect( jsonPath( "$", hasSize( 2 ) ) )
.andExpect( jsonPath( "$", containsInAnyOrder( getId( firstShellPayload ), getId( secondShellPayload ) ) ) );
.andExpect( jsonPath( "$", hasSize( 0 ) ) );

// Test with owner DTR (TENANT_ONE)
mvc.perform(
MockMvcRequestBuilders
.post( LOOKUP_SHELL_BASE_PATH + "/query" )
.content( toJson( anyMatchQueryByOwnerAssetIds ) )
.contentType( MediaType.APPLICATION_JSON )
.header( EXTERNAL_SUBJECT_ID_HEADER, jwtTokenFactory.tenantOne().getTenantId() )
.with( jwtTokenFactory.allRoles() )
)
.andDo( MockMvcResultHandlers.print() )
.andExpect( status().isOk() )
.andExpect( jsonPath( "$", hasSize( 1 ) ) )
.andExpect( jsonPath( "$[0]" ,is(shellPayload.getId()) ));

// query to retrieve any match (asset2 is only visible for OWNER TENANT_ONE and TENANT_TWO)
JsonNode anyMatchQueryByTenantTwoAssetIds = mapper.createObjectNode().set( "query", mapper.createObjectNode()
.set( "assetIds", emptyArrayNode()
.add( specificAssetId( asset2.getName(), asset2.getValue() ) )
.add( specificAssetId( "not_available_key_in_shell","not_available_value_in_shell" ) ))
);

// Test with non Owner(TENANT_TWO)
mvc.perform(
MockMvcRequestBuilders
.post( LOOKUP_SHELL_BASE_PATH + "/query" )
.content( toJson( anyMatchQueryByTenantTwoAssetIds ) )
.contentType( MediaType.APPLICATION_JSON )
.header( EXTERNAL_SUBJECT_ID_HEADER, jwtTokenFactory.tenantTwo().getTenantId() )
.with( jwtTokenFactory.allRoles() )
)
.andDo( MockMvcResultHandlers.print() )
.andExpect( jsonPath( "$", hasSize( 1 ) ) )
.andExpect( jsonPath( "$[0]" ,is(shellPayload.getId()) ));

// Test with non Owner(TENANT_THREE)
mvc.perform(
MockMvcRequestBuilders
.post( LOOKUP_SHELL_BASE_PATH + "/query" )
.content( toJson( anyMatchQueryByOwnerAssetIds ) )
.contentType( MediaType.APPLICATION_JSON )
.header( EXTERNAL_SUBJECT_ID_HEADER, jwtTokenFactory.tenantThree().getTenantId() )
.with( jwtTokenFactory.allRoles() )
)
.andDo( MockMvcResultHandlers.print() )
.andExpect( status().isOk() )
.andExpect( jsonPath( "$", hasSize( 0 ) ) );

// Test with owner DTR (TENANT_ONE)
mvc.perform(
MockMvcRequestBuilders
.post( LOOKUP_SHELL_BASE_PATH + "/query" )
.content( toJson( anyMatchQueryByTenantTwoAssetIds ) )
.contentType( MediaType.APPLICATION_JSON )
.header( EXTERNAL_SUBJECT_ID_HEADER, jwtTokenFactory.tenantOne().getTenantId() )
.with( jwtTokenFactory.allRoles() )
)
.andDo( MockMvcResultHandlers.print() )
.andExpect( status().isOk() )
.andExpect( jsonPath( "$", hasSize( 1 ) ) )
.andExpect( jsonPath( "$[0]" ,is(shellPayload.getId()) ));

}

//@Test
Expand Down
Loading

0 comments on commit c977334

Please sign in to comment.