Skip to content

Commit 37bf0e5

Browse files
authored
Merge pull request #139 from SwevenSoftware/develop
Incr-Utilizzo
2 parents 00767f6 + 83bfbfd commit 37bf0e5

83 files changed

Lines changed: 3153 additions & 516 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,8 @@ export KEYSTORE_TYPE=
99
export KEYSTORE=
1010
export KEYSTORE_PASSWORD=
1111
export KEYSTORE_ALIAS=
12-
export SSL_ENABLED=false
12+
export SSL_ENABLED=0
1313
export SERVER_PORT=8091
14+
export REPORT_DIR=./reports
15+
# This should be commented when deploying on a real netork
16+
export spring_profiles_active=ganache

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ requests are handled properly. **Without a valid keystore the server will fail t
2525
#### Blockchain
2626
In order to save the hashes of generated reports on a blockchain network you need to:
2727
* Select a network to deploy your contract: you can simply use the provided *containered* solution and test the server
28-
behavior trough *ganache*. Otherwise, there are a number of ethereum test network such as [Infura](https://infura.io/)
28+
behavior trough *ganache*. Otherwise, you should have an endpoint to communicate to the selected ethereum network,
29+
such as [Infura](https://infura.io/);
2930

30-
* Open an account on that particular network
31+
* Open an account on that particular network.
3132

3233
once you have such information compile the file `.env`.
3334
An example could be the following (also included in the project)
@@ -49,8 +50,14 @@ export KEYSTORE_PASSWORD=
4950
export KEYSTORE_ALIAS=
5051
export SSL_ENABLED=false
5152
# server port, this will only affect the container exposed port,
52-
# not he internal port
53+
# not the internal port
5354
export SERVER_PORT=8091
55+
# existing directory where reports will be saved
56+
export REPORT_DIR=
57+
# This should be commented when deploying on a real network,
58+
# specifies the active profile of the application, the ganache profile is made
59+
# specifically to interact with ganache
60+
export spring_profiles_active=ganache
5461
```
5562

5663
### Building
@@ -66,8 +73,7 @@ Once all the prerequisites are satisfied, and the artifact is built the applicat
6673
#### Test container start
6774
This way you can test the application with a container version of mongodb and ganache cli
6875
```shell
69-
sudo docker-compose build && \
70-
sudo docker-compose up
76+
sudo docker-compose up --build
7177
```
7278
The containers will then be created and started. Eventually when the run ends you can dismantle the built containers
7379
with

docker-compose.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ networks:
66
blockchain-net:
77
driver: "bridge"
88

9+
volumes:
10+
reports:
11+
912
services:
1013

1114
mongo:
@@ -32,3 +35,7 @@ services:
3235
networks:
3336
- db-net
3437
- blockchain-net
38+
volumes:
39+
- type: bind
40+
source: ${REPORT_DIR}
41+
target: /reports
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package it.sweven.blockcovid.blockchain.assemblers;
2+
3+
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
4+
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
5+
6+
import it.sweven.blockcovid.blockchain.controllers.ListReportsController;
7+
import it.sweven.blockcovid.blockchain.dto.ReportInformation;
8+
import java.util.stream.Collectors;
9+
import java.util.stream.StreamSupport;
10+
import org.springframework.hateoas.CollectionModel;
11+
import org.springframework.hateoas.EntityModel;
12+
import org.springframework.hateoas.server.RepresentationModelAssembler;
13+
import org.springframework.stereotype.Component;
14+
15+
@Component
16+
public class ReportInformationAssembler
17+
implements RepresentationModelAssembler<ReportInformation, EntityModel<ReportInformation>> {
18+
@Override
19+
public EntityModel<ReportInformation> toModel(ReportInformation entity) {
20+
return EntityModel.of(
21+
entity,
22+
linkTo(methodOn(ListReportsController.class).listReports(null))
23+
.withRel("list_all_reports"));
24+
}
25+
26+
@Override
27+
public CollectionModel<EntityModel<ReportInformation>> toCollectionModel(
28+
Iterable<? extends ReportInformation> entities) {
29+
return CollectionModel.of(
30+
StreamSupport.stream(entities.spliterator(), true)
31+
.map(this::toModel)
32+
.collect(Collectors.toList()),
33+
linkTo(methodOn(ListReportsController.class).listReports(null)).withSelfRel());
34+
}
35+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package it.sweven.blockcovid.blockchain.controllers;
2+
3+
import it.sweven.blockcovid.blockchain.services.DocumentService;
4+
import it.sweven.blockcovid.blockchain.services.SignRegistrationService;
5+
import it.sweven.blockcovid.rooms.services.RoomService;
6+
import java.io.IOException;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.scheduling.annotation.Scheduled;
11+
import org.springframework.stereotype.Controller;
12+
import org.web3j.protocol.core.methods.response.TransactionReceipt;
13+
14+
@Controller
15+
public class AutomaticCleanerController {
16+
private final SignRegistrationService signRegistrationService;
17+
private final DocumentService documentService;
18+
private final RoomService roomService;
19+
private final Logger logger = LoggerFactory.getLogger(AutomaticCleanerController.class);
20+
21+
@Autowired
22+
public AutomaticCleanerController(
23+
SignRegistrationService signRegistrationService,
24+
DocumentService documentService,
25+
RoomService roomService) {
26+
this.signRegistrationService = signRegistrationService;
27+
this.documentService = documentService;
28+
this.roomService = roomService;
29+
}
30+
31+
@Scheduled(cron = "0 0 0 * * *")
32+
public void run() throws Exception {
33+
String savedPath = documentService.generateCleanerReport(roomService.getAllRooms());
34+
try {
35+
TransactionReceipt receipt =
36+
signRegistrationService.registerString(documentService.hashOf(savedPath));
37+
String newPath = documentService.setAsVerified(savedPath);
38+
logger.info(
39+
"registered file "
40+
+ savedPath
41+
+ " (now "
42+
+ newPath
43+
+ ") on the blockchain on block "
44+
+ receipt.getBlockNumber().toString());
45+
} catch (IOException exception) {
46+
logger.error("Unable to open file stream for file at path: " + savedPath);
47+
}
48+
}
49+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package it.sweven.blockcovid.blockchain.controllers;
2+
3+
import it.sweven.blockcovid.blockchain.services.DocumentService;
4+
import it.sweven.blockcovid.blockchain.services.SignRegistrationService;
5+
import it.sweven.blockcovid.reservations.servicies.ReservationService;
6+
import java.io.IOException;
7+
import java.time.LocalDateTime;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.scheduling.annotation.Scheduled;
12+
import org.springframework.stereotype.Controller;
13+
import org.web3j.protocol.core.methods.response.TransactionReceipt;
14+
15+
@Controller
16+
public class AutomaticUsageController {
17+
private final SignRegistrationService signRegistrationService;
18+
private final DocumentService documentService;
19+
private final ReservationService reservationService;
20+
private final Logger logger = LoggerFactory.getLogger(AutomaticUsageController.class);
21+
22+
@Autowired
23+
public AutomaticUsageController(
24+
DocumentService documentService,
25+
SignRegistrationService signRegistrationService,
26+
ReservationService reservationService) {
27+
this.signRegistrationService = signRegistrationService;
28+
this.documentService = documentService;
29+
this.reservationService = reservationService;
30+
}
31+
32+
@Scheduled(cron = "0 0 0 * * *")
33+
public void run() throws Exception {
34+
String savedPath =
35+
documentService.generateUsageReport(
36+
reservationService.findByTimeInterval(
37+
LocalDateTime.now().minusDays(1), LocalDateTime.now()));
38+
39+
try {
40+
TransactionReceipt receipt =
41+
signRegistrationService.registerString(documentService.hashOf(savedPath));
42+
String newPath = documentService.setAsVerified(savedPath);
43+
logger.info(
44+
"registered file "
45+
+ savedPath
46+
+ " (now "
47+
+ newPath
48+
+ ") on the blockchain on block "
49+
+ receipt.getBlockNumber().toString());
50+
} catch (IOException exception) {
51+
logger.error("Unable to open file stream for file at path: " + savedPath);
52+
}
53+
}
54+
}

src/main/java/it/sweven/blockcovid/blockchain/controllers/BlockchainController.java

Lines changed: 0 additions & 48 deletions
This file was deleted.

src/main/java/it/sweven/blockcovid/blockchain/controllers/AdminCleanerReportController.java renamed to src/main/java/it/sweven/blockcovid/blockchain/controllers/CleanerReportController.java

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package it.sweven.blockcovid.blockchain.controllers;
22

3+
import io.swagger.v3.oas.annotations.Parameter;
34
import io.swagger.v3.oas.annotations.media.Content;
45
import io.swagger.v3.oas.annotations.media.Schema;
56
import io.swagger.v3.oas.annotations.responses.ApiResponse;
67
import io.swagger.v3.oas.annotations.responses.ApiResponses;
7-
import it.sweven.blockcovid.blockchain.services.BlockchainService;
8-
import it.sweven.blockcovid.blockchain.services.DocumentContractService;
98
import it.sweven.blockcovid.blockchain.services.DocumentService;
9+
import it.sweven.blockcovid.blockchain.services.SignRegistrationService;
1010
import it.sweven.blockcovid.rooms.services.RoomService;
1111
import it.sweven.blockcovid.users.entities.User;
12-
import java.io.FileInputStream;
1312
import java.io.IOException;
13+
import org.slf4j.Logger;
14+
import org.slf4j.LoggerFactory;
1415
import org.springframework.beans.factory.annotation.Autowired;
1516
import org.springframework.http.HttpStatus;
1617
import org.springframework.http.MediaType;
@@ -20,29 +21,22 @@
2021
import org.springframework.web.bind.annotation.ResponseBody;
2122
import org.springframework.web.bind.annotation.RestController;
2223
import org.springframework.web.server.ResponseStatusException;
23-
import org.web3j.crypto.Credentials;
24-
import org.web3j.documentcontract.DocumentContract;
2524

2625
@RestController
27-
public class AdminCleanerReportController implements ReportsController {
26+
public class CleanerReportController implements ReportsController {
2827
private final RoomService roomService;
2928
private final DocumentService documentService;
30-
private final BlockchainService blockchainService;
31-
private final DocumentContractService documentContractService;
32-
private final Credentials blockchainCredentials;
29+
private final SignRegistrationService signRegistrationService;
30+
private final Logger logger = LoggerFactory.getLogger(CleanerReportController.class);
3331

3432
@Autowired
35-
public AdminCleanerReportController(
33+
public CleanerReportController(
3634
RoomService roomService,
3735
DocumentService documentService,
38-
BlockchainService blockchainService,
39-
DocumentContractService documentContractService,
40-
Credentials blockchainCredentials) {
36+
SignRegistrationService signRegistrationService) {
4137
this.roomService = roomService;
4238
this.documentService = documentService;
43-
this.blockchainService = blockchainService;
44-
this.documentContractService = documentContractService;
45-
this.blockchainCredentials = blockchainCredentials;
39+
this.signRegistrationService = signRegistrationService;
4640
}
4741

4842
@GetMapping(value = "/cleaner", produces = MediaType.APPLICATION_PDF_VALUE)
@@ -59,20 +53,25 @@ public AdminCleanerReportController(
5953
content = @Content(schema = @Schema(implementation = void.class)))
6054
})
6155
@PreAuthorize("#submitter.isAdmin()")
62-
public byte[] report(@AuthenticationPrincipal User submitter) {
56+
public byte[] report(@Parameter(hidden = true) @AuthenticationPrincipal User submitter) {
6357
try {
6458
String path = documentService.generateCleanerReport(roomService.getAllRooms());
65-
DocumentContract contract =
66-
documentContractService.getContractByAccount(blockchainCredentials);
67-
blockchainService.registerReport(contract, new FileInputStream(path));
59+
logger.info("file saved at path " + path);
60+
Thread registrationThread =
61+
new Thread(
62+
() -> {
63+
try {
64+
signRegistrationService.registerString(documentService.hashOf(path));
65+
documentService.setAsVerified(path);
66+
} catch (Exception exception) {
67+
logger.error("Unable to open file stream for file at path: " + path);
68+
}
69+
});
70+
registrationThread.start();
6871
return documentService.readReport(path);
6972
} catch (IOException e) {
7073
throw new ResponseStatusException(
7174
HttpStatus.INTERNAL_SERVER_ERROR, "An error occurred while creating the report");
72-
} catch (Exception e) {
73-
throw new ResponseStatusException(
74-
HttpStatus.INTERNAL_SERVER_ERROR,
75-
"An error occurred while registering the document on the provided blockchain");
7675
}
7776
}
7877
}

0 commit comments

Comments
 (0)