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

Create and Update the validation service #97

Draft
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

asmataamallah25
Copy link
Collaborator

No description provided.

@flopezag flopezag added the patch Should be applied for dependency updates and small bugfixes. label Jan 21, 2025
The validation service implements a three-step verification protocol.

### Initial Validation Request
The client initiates the verification process by submitting a POST request to the Canis Major Validator service.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Canis Major Validator service or Canis Major Validation service?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is Canis Major Validation service. I will change it.

</plugin>
</plugins>
</build>
</project>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a new line at the end of the file.

// Adds Link header for JSON-LD context
.header("Link", "<https://raw.githubusercontent.com/smart-data-models/dataModel.DistributedLedgerTech/master/context.jsonld>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"")
// Sets the NGSILD-Tenant header to "orion"
.header("NGSILD-Tenant", "orion")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question, Is this NGSILD-Tenant fixed in Canis Major?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upon reviewing the code in the StepDefinition.java file, I can confirm that in the Canis Major blockchain adaptor, the NGSI-LD tenant is indeed configured as a static final constant:
public static final String NGSILD_TENANT = "orion";

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The StepDefinition.java is just defining the steps and calls for Integration-Testing. The tenant is not fixed and needs to be configurable.

// Sends the request and returns the response body as a String
return client.send(request, HttpResponse.BodyHandlers.ofString()).body();
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a new line at the end of the file.

public List<String> getMessages() {
return messages;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add newline at the end of the file

}
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add newline to the end of the file

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is missing in this diagram the message 4) with the communication of the results.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the diagram you sent me in the chat. I can make a new diagram and add this step

public HttpResponse<ValidationResult> compareResponses(@Body CompareRequest request) {
// Call the validation service to perform the validation
ValidationResult result = validationService.validateEntity(request.getEntityId());
return HttpResponse.ok(result);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are returning always a HttpResponse.ok, but what's about an error returning in the validationService.validateEntity function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add error handling in this case

@@ -0,0 +1,12 @@
#Stop and remove all Docker containers:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at this point, I prefer to have the two options that let the user select which option he wants to use, let's say, request to the user which option to use 1) Clean delete of the docker compose resources, or 2) Delete all docker resources.

@asmataamallah25 asmataamallah25 marked this pull request as draft January 22, 2025 08:56
@@ -0,0 +1,22 @@
# Validation service

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why didn't you put this in a separate repo? Currently the service is placed in the repo but not included in the build system ( neither as submodule nor in the github flows).


<build>
<plugins>
<plugin>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the further plan? At the moment no container will be build. Will there be another PR adding functionality?

@Singleton
public class ValidationHttpClient {
// Creates a single HttpClient instance to be reused for all requests
private final HttpClient client = HttpClient.newHttpClient();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be to much for the current level but its possible to use a generated client for the ngsi-ld standard. Either you generate it yourself in this project -> https://github.com/wistefan/ngsi-ld-java-mapping/blob/main/pom.xml#L400-L442 or you could use an even more abstract approach using the lib to access ngsi-ld context broker via a convenient repository: https://github.com/wistefan/ngsi-ld-java-mapping/tree/main

private final HttpClient client = HttpClient.newHttpClient();

// Method to fetch data from Orion Context Broker
public String fetchOrionData(String entityId) throws Exception {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Canis Major does not request Orion-ld but a NGSI_LD compatible broker right? Then the name would be misleading

// Builds an HTTP request:
HttpRequest request = HttpRequest.newBuilder()
// Sets the URI for the request, querying for DLTtxReceipt entities with matching refEntity
.uri(new URI("http://localhost:1026/ngsi-ld/v1/entities/?type=DLTtxReceipt&q=refEntity==" + entityId))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The broker location should be configurable

// Adds Link header for JSON-LD context
.header("Link", "<https://raw.githubusercontent.com/smart-data-models/dataModel.DistributedLedgerTech/master/context.jsonld>; rel=\"http://www.w3.org/ns/json-ld#context\"; type=\"application/ld+json\"")
// Sets the NGSILD-Tenant header to "orion"
.header("NGSILD-Tenant", "orion")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tenant should be configurable too

.build();

// Sends the request and returns the response body as a String
return client.send(request, HttpResponse.BodyHandlers.ofString()).body();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For future maintainability the use of async mechanisms would be nice, or else we can run into annoying errors when running it

}

// Method to fetch data from a blockchain service
public String fetchBlockchainData(String entityId) throws Exception {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really a blockchain service (somehow generic) or is it CanisMajor?

// Builds an HTTP request:
HttpRequest request = HttpRequest.newBuilder()
// Sets the URI for the blockchain service endpoint
.uri(new URI("http://localhost:4000/entity/" + entityId))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Configurable please 😄

import validator.service.ValidationService;
import validator.model.ValidationResult;

@Controller("/service/v1/validation")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have an openapi file and generate the api from it (like here https://github.com/FIWARE/CanisMajor/blob/master/src/main/java/org/fiware/canismajor/rest/EntitiesController.java#L21)

}

// Inner class to represent the request body
public static class CompareRequest {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be generated too


@Singleton
public class ValidationService {
private static final Logger logger = LoggerFactory.getLogger(ValidationService.class);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for fun you should check out Lombok. Its a very convenient tool to reduce boilerplate

public class ValidationService {
private static final Logger logger = LoggerFactory.getLogger(ValidationService.class);
private final ValidationHttpClient validationHttpClient;
private final ObjectMapper mapper = new ObjectMapper();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Micronaut in its basic/default config lets you inject an ObjectMapper afaik


if (orionData == null || orionData.isEmpty()) {
logger.error("No data found from Orion for entityId: {}", entityId);
return new ValidationResult(false, List.of("No data found from Orion"));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return new ValidationResult(false, List.of("No data found from Orion"));
return new ValidationResult(false, List.of("No data found from Context Broker"));


// Marks this class as a singleton - only one instance will exist in the application
@Singleton
public class ValidationHttpClient {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nicer if the methods of this class would return meaningful objects rather than unchecked strings

JsonNode orionNode = mapper.readTree(orionData);
JsonNode blockchainNode = mapper.readTree(blockchainData);

JsonNode txReceipts = orionNode.get("TxReceipts").get("value");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible NPE, better have the clients return checked objects

@wistefan
Copy link
Contributor

Hi @asmataamallah25 ,
I think there is quite some misconception of validation in the context of CanisMajor. The proposed service does not validate anything. It just retrieves the same entity through two different endpoints(directly from the broker and additional from canis major, which also requests it from the same broker). As far as I understand the readme, the service should "verify transaction integrity".
In order to do so, you would have to take a different approach:

  1. The api should receive the entity to be checked and its transaction receipt.
  2. The service need to access the blockchain(not CanisMajor, since it only writes, but not reads) and retrieve the linked transaction.
  3. Retrieve the entity hash from the transaction.
  4. Build the hash of the entity to be checked(e.g. the one that was received), the same hash method that was used for writing needs to be used
  5. Compare the hash in the transaction and the hash that was build.

I hope it does not sound rude, but the code in the PR does not add any validation functionality. Since you compare the exact same entities, from the exact same source, it does not add any value.

@asmataamallah25
Copy link
Collaborator Author

asmataamallah25 commented Jan 23, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
patch Should be applied for dependency updates and small bugfixes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants