Skip to content

Commit

Permalink
Execution Information Interface (#151)
Browse files Browse the repository at this point in the history
* Execution Information Interface

* NVD API KEY

* NVD API KEY output
  • Loading branch information
ndc-dxc authored Nov 29, 2024
1 parent 54725a6 commit 278652c
Show file tree
Hide file tree
Showing 16 changed files with 3,116 additions and 211 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/gradlebuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
- name: checkout code
uses: actions/checkout@v2
- name: Dependency Check
run: ./gradlew dependencyCheckAnalyze
run: ./gradlew dependencyCheckAnalyze -DnvdApiKey="${{ secrets.NVD_API_KEY }}"

publish:
runs-on: ubuntu-latest
Expand Down
8 changes: 7 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
id 'java'
id 'checkstyle'
id 'jacoco'
id 'org.owasp.dependencycheck' version '8.2.1'
id 'org.owasp.dependencycheck' version '11.1.0'
id 'com.github.spotbugs' version '6.0.19'
id 'org.openapi.generator' version '7.7.0'
id 'idea'
Expand Down Expand Up @@ -242,6 +242,12 @@ spotbugsTest {
}

dependencyCheck {
nvd {
apiKey = System.getProperty("nvdApiKey")
System.out.print("NVD API is set: ")
System.out.println(null != apiKey)
delay = 16000
}
//set up a quality gate for vulnerabilities with high severity level:
//let's consider that a vulnerability has a high severity level if its CVSS score is higher than 7
//the build is going to fail if vulnerabilities with high severity level found
Expand Down
2 changes: 2 additions & 0 deletions config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@
<message key="ws.notPreceded"
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
</module>
<!--
<module name="Indentation">
<property name="basicOffset" value="4"/>
<property name="braceAdjustment" value="0"/>
Expand All @@ -253,6 +254,7 @@
<property name="lineWrappingIndentation" value="4"/>
<property name="arrayInitIndent" value="2"/>
</module>
-->
<module name="AbbreviationAsWordInName">
<property name="ignoreFinal" value="false"/>
<property name="allowedAbbreviationLength" value="3"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package it.gov.innovazione.ndc.controller;

import it.gov.innovazione.ndc.harvester.SemanticAssetType;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class SemanticAssetStatSample {
private final String resourceUri;
private final SemanticAssetType resourceType;
private final String rightHolder;
private final boolean hasErrors;
private final boolean hasWarnings;
private final String statusType;
private final int yearOfHarvest;
}
Original file line number Diff line number Diff line change
@@ -1,45 +1,65 @@
package it.gov.innovazione.ndc.controller;

import lombok.Builder;
import lombok.Data;

import java.math.BigDecimal;
import java.math.RoundingMode;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class SemanticAssetStats {
private final SemanticAssetTypeStats total;
private final SemanticAssetTypeStats controlledVocabulary;
private final SemanticAssetTypeStats ontology;
private final SemanticAssetTypeStats schema;

@Data
@Builder
public static class SemanticAssetTypeStats {
private final long current;
private final long lastYear;
private final StatusStat status;

public long getIncrementOverLastYear() {
return current - lastYear;
}

public double getIncrementPercentageOverLastYear() {
BigDecimal bigDecimal = BigDecimal.valueOf(
lastYear == 0
? 0
: ((double) current - lastYear) / lastYear * 100);
return bigDecimal.setScale(1, RoundingMode.HALF_UP).doubleValue();
}
private final SemanticAssetTypeStats total;
private final SemanticAssetTypeStats controlledVocabulary;
private final SemanticAssetTypeStats ontology;
private final SemanticAssetTypeStats schema;

private static double round(double value) {
BigDecimal bigDecimal = BigDecimal.valueOf(value);
return bigDecimal.setScale(1, RoundingMode.HALF_UP).doubleValue();
}

@Data
@Builder
public static class SemanticAssetTypeStats {
private final long current;
private final long lastYear;
private final StatusStat status;

public long getIncrementOverLastYear() {
return current - lastYear;
}

public double getIncrementPercentageOverLastYear() {
return round(lastYear == 0 ? 0 : ((double) current - lastYear) / lastYear * 100);
}
}

@Builder
public static class StatusStat {
private final double archived;
private final double published;
private final double closedAccess;
private final double draft;
private final double unknown;

public double getArchived() {
return round(archived * 100);
}

public double getPublished() {
return round(published * 100);
}

public double getClosedAccess() {
return round(closedAccess * 100);
}

public double getDraft() {
return round(draft * 100);
}

@Data
@Builder
public static class StatusStat {
private final double archived;
private final double published;
private final double closedAccess;
private final double draft;
public double getUnknown() {
return round(unknown * 100);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package it.gov.innovazione.ndc.controller;

import static it.gov.innovazione.ndc.gen.dto.Direction.ASC;

import com.github.jsonldjava.shaded.com.google.common.base.CaseFormat;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
Expand All @@ -15,100 +17,53 @@
import it.gov.innovazione.ndc.harvester.model.index.RightsHolder;
import it.gov.innovazione.ndc.harvester.service.RepositoryService;
import it.gov.innovazione.ndc.service.SemanticAssetSearchService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import static it.gov.innovazione.ndc.gen.dto.Direction.ASC;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
public class SemanticAssetsController implements SemanticAssetsApi {
private final SemanticAssetSearchService searchService;
private final RepositoryService repositoryService;

/**
* GET /semantic-assets/rights-holders
* Retrieves the rights holders of the semantic assets.
*
* @return OK (status code 200)
*/
@Operation(tags = {"semantic-assets"},
summary = "Retrieves the rights holders",
description = "Retrieves the rights holders of the semantic assets.",
operationId = "getRightsHolders",
responses = {@ApiResponse(responseCode = "200", description = "OK", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = RightsHolder.class))
})})
@GetMapping(value = "/semantic-assets/rights-holders", produces = {"application/json"})
List<RightsHolder> getRightsHolders() {
/**
* GET /semantic-assets/rights-holders Retrieves the rights holders of the semantic assets.
*
* @return OK (status code 200)
*/
@Operation(
tags = {"semantic-assets"},
summary = "Retrieves the rights holders",
description = "Retrieves the rights holders of the semantic assets.",
operationId = "getRightsHolders",
responses = {
@ApiResponse(
responseCode = "200",
description = "OK",
content = {
@Content(
mediaType = "application/json",
schema = @Schema(implementation = RightsHolder.class))
})
})
@GetMapping(
value = "/semantic-assets/rights-holders",
produces = {"application/json"})
List<RightsHolder> getRightsHolders() {
return repositoryService.getRightsHolders();

}

@Operation(tags = {"semantic-assets"},
summary = "Retrieves the statistics",
description = "Retrieves the statistics of the semantic assets.",
operationId = "getStats",
responses = {@ApiResponse(responseCode = "200", description = "OK", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = SemanticAssetStats.class))
})})
@GetMapping(value = "/semantic-assets/stats", produces = {"application/json"})
SemanticAssetStats getStats() {
return SemanticAssetStats.builder()
.total(SemanticAssetStats.SemanticAssetTypeStats.builder()
.current(118)
.lastYear(115)
.status(SemanticAssetStats.StatusStat.builder()
.archived(0.1)
.published(0.8)
.closedAccess(0.1)
.draft(0.0)
.build())
.build())
.controlledVocabulary(SemanticAssetStats.SemanticAssetTypeStats.builder()
.current(120)
.lastYear(118)
.status(SemanticAssetStats.StatusStat.builder()
.archived(0.1)
.published(0.8)
.closedAccess(0.1)
.draft(0.0)
.build())
.build())
.ontology(SemanticAssetStats.SemanticAssetTypeStats.builder()
.current(100)
.lastYear(98)
.status(SemanticAssetStats.StatusStat.builder()
.archived(0.1)
.published(0.8)
.closedAccess(0.1)
.draft(0.0)
.build())
.build())
.schema(SemanticAssetStats.SemanticAssetTypeStats.builder()
.current(80)
.lastYear(80)
.status(SemanticAssetStats.StatusStat.builder()
.archived(0.1)
.published(0.8)
.closedAccess(0.1)
.draft(0.0)
.build())
.build())
.build();
}

@Override
public ResponseEntity<SearchResult> search(
String q,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package it.gov.innovazione.ndc.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import it.gov.innovazione.ndc.harvester.service.SemanticContentStatsService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;

@RequiredArgsConstructor
@RestController
public class SemanticAssetsStatsController {

private final SemanticContentStatsService semanticContentStatsService;

@Operation(
tags = {"semantic-assets"},
summary = "Retrieves the statistics",
description = "Retrieves the statistics of the semantic assets.",
operationId = "getStats",
responses = {
@ApiResponse(
responseCode = "200",
description = "OK",
content = {
@Content(
mediaType = "application/json",
schema = @Schema(implementation = SemanticAssetStats.class))
})
})
@GetMapping(
value = "semantic-assets/stats",
produces = {"application/json"})
public SemanticAssetStats getStats(@RequestParam(name = "year", required = false) Integer year) {
// get current year from system date
if (year == null) {
year = LocalDate.now().getYear();
}
return semanticContentStatsService.getStats(year);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package it.gov.innovazione.ndc.harvester.model;

import it.gov.innovazione.ndc.validator.model.ValidationOutcome;
import lombok.Builder;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Builder;
import lombok.Data;

@Data
@Builder(toBuilder = true)
Expand Down Expand Up @@ -74,7 +73,7 @@ private static List<ValidationOutcome> getNormalized(List<ValidationOutcome> val
.collect(Collectors.toList());
}

public void addValidationException(RuntimeException invalidModelException) {
public synchronized void addValidationException(RuntimeException invalidModelException) {
if (validationContextType == ValidationContextType.ERROR) {
if (getNormalizedErrors().contains(invalidModelException.getMessage())) {
return;
Expand Down
Loading

0 comments on commit 278652c

Please sign in to comment.