diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f53b73..1d55270 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.3.0] + +### Added + +- Audit log (per-project) with possibility to browse, filter, and clear using + a simple dialog in client-side + +### Changed + +- Prepared getting and passing SHACL specs from FDP to OpenRefine frontend +- Updated for compatibility with newer FAIR Data Point 1.3.0 + +### Fixed + +- Persisting information about stored metadata + ## [1.2.0] ### Added @@ -64,8 +80,8 @@ Initial version based on reproducing functionality of deprecated [FAIRifier](htt - About dialog with basic information about the extension and its compatibility - Report a bug link to create a GitHub issue easily -[Unreleased]: /../../compare/v1.1.0...develop +[Unreleased]: /../../compare/v1.3.0...develop [1.0.0]: /../../tree/v1.0.0 [1.1.0]: /../../tree/v1.1.0 [1.2.0]: /../../tree/v1.2.0 - +[1.3.0]: /../../tree/v1.3.0 diff --git a/pom.xml b/pom.xml index 4004ada..d0e6465 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ solutions.fairdata.openrefine metadata - 1.2.0 + 1.3.0 jar OpenRefine - FAIR Metadata extension diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/MetadataModuleImpl.java b/src/main/java/solutions/fairdata/openrefine/metadata/MetadataModuleImpl.java index c900416..7d07094 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/MetadataModuleImpl.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/MetadataModuleImpl.java @@ -146,14 +146,18 @@ private void readStorageConfig(File file) { } } - public static ProjectConfigDTO getProjectConfigDTO(Project project) { + public static MetadataOverlayModel getProjectModel(Project project) { MetadataOverlayModel metadataOverlayModel = (MetadataOverlayModel) project.overlayModels.get(OVERLAY_MODEL); if (metadataOverlayModel == null) { metadataOverlayModel = new MetadataOverlayModel(); metadataOverlayModel.setProjectData(new ProjectConfigDTO()); project.overlayModels.put(OVERLAY_MODEL, metadataOverlayModel); } - return metadataOverlayModel.getProjectData(); + return metadataOverlayModel; + } + + public static ProjectConfigDTO getProjectConfigDTO(Project project) { + return getProjectModel(project).getProjectData(); } public static void setProjectConfigDTO(Project project, ProjectConfigDTO projectData) { diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/ProjectAudit.java b/src/main/java/solutions/fairdata/openrefine/metadata/ProjectAudit.java new file mode 100644 index 0000000..050f049 --- /dev/null +++ b/src/main/java/solutions/fairdata/openrefine/metadata/ProjectAudit.java @@ -0,0 +1,102 @@ +/** + * The MIT License + * Copyright © 2019 FAIR Data Team + * + * 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. + */ +package solutions.fairdata.openrefine.metadata; + +import com.google.refine.model.Project; +import solutions.fairdata.openrefine.metadata.dto.audit.AuditEntryDTO; +import solutions.fairdata.openrefine.metadata.dto.audit.AuditLogDTO; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; +import solutions.fairdata.openrefine.metadata.dto.audit.EventType; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.time.OffsetDateTime; +import java.util.ArrayList; + +public class ProjectAudit { + + private final AuditLogDTO log; + private final int level; + + private static String currentTimestamp() { + return OffsetDateTime.now().toString(); + } + + private static String getStackTrace(Exception e) { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + return sw.toString(); + } + public ProjectAudit() { + this.level = MetadataModuleImpl.getInstance().getSettings().getAudit().getLevel(); + this.log = null; + } + + public ProjectAudit(Project project) { + this.level = MetadataModuleImpl.getInstance().getSettings().getAudit().getLevel(); + if (MetadataModuleImpl.getProjectModel(project).getProjectLog() == null) { + MetadataModuleImpl.getProjectModel(project).setProjectLog(new AuditLogDTO(project.id, new ArrayList<>())); + } + this.log = MetadataModuleImpl.getProjectModel(project).getProjectLog(); + } + + public void report(EventType eventType, EventSource eventSource, String message) { + if (eventType.getLevel() <= level && this.log != null) { + this.log.getEntries().add(new AuditEntryDTO(eventType, eventSource, message, currentTimestamp())); + } + } + + public void reportError(EventSource eventSource, String message) { + MetadataModuleImpl.getLogger().error(eventSource + ": " + message); + report(EventType.ERROR, eventSource, message); + } + + public void reportWarning(EventSource eventSource, String message) { + MetadataModuleImpl.getLogger().warn(eventSource + ": " + message); + report(EventType.WARNING, eventSource, message); + } + + public void reportInfo(EventSource eventSource, String message) { + MetadataModuleImpl.getLogger().info(eventSource + ": " + message); + report(EventType.INFO, eventSource, message); + } + + public void reportDebug(EventSource eventSource, String message) { + MetadataModuleImpl.getLogger().debug(eventSource + ": " + message); + report(EventType.DEBUG, eventSource, message); + } + + public void reportTrace(EventSource eventSource, Exception e) { + String message = e.getClass().getSimpleName() + " appeared:\n" + getStackTrace(e); + MetadataModuleImpl.getLogger().trace(eventSource + ": " + message); + report(EventType.TRACE, eventSource, message); + } + + public AuditLogDTO getAuditLog() { + return log; + } + + public void clearLog() { + this.log.getEntries().clear(); + } +} diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/AuditCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/AuditCommand.java new file mode 100644 index 0000000..4f51a7d --- /dev/null +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/AuditCommand.java @@ -0,0 +1,93 @@ +/** + * The MIT License + * Copyright © 2019 FAIR Data Team + * + * 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. + */ +package solutions.fairdata.openrefine.metadata.commands; + +import com.google.refine.commands.Command; +import solutions.fairdata.openrefine.metadata.ProjectAudit; +import solutions.fairdata.openrefine.metadata.commands.request.audit.AuditRequest; +import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; +import solutions.fairdata.openrefine.metadata.commands.response.audit.AuditResponse; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.Writer; + +public class AuditCommand extends Command { + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + + try { + pa.reportDebug(EventSource.AUDIT, "Returning audit log for project"); + CommandUtils.objectMapper.writeValue(w, new AuditResponse(pa.getAuditLog())); + } catch (Exception e) { + pa.reportError(EventSource.AUDIT, "Could not retrieve audit log for project"); + pa.reportTrace(EventSource.AUDIT, e); + CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); + } finally { + w.flush(); + w.close(); + } + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + AuditRequest auditRequest = CommandUtils.objectMapper.readValue(request.getReader(), AuditRequest.class); + Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + + try { + pa.report(auditRequest.getEventType(), EventSource.FRONTEND, auditRequest.getMessage()); + } catch (Exception e) { + pa.reportError(EventSource.AUDIT, "Could not add message to audit log"); + pa.reportTrace(EventSource.AUDIT, e); + CommandUtils.objectMapper.writeValue(w, new ErrorResponse("auth-fdp-command/error", e)); + } finally { + w.flush(); + w.close(); + } + } + + @Override + public void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + + try { + pa.reportInfo(EventSource.AUDIT, "Clearing audit log for project"); + pa.clearLog(); + } catch (Exception e) { + pa.reportError(EventSource.AUDIT, "Could not clear audit log for project"); + pa.reportTrace(EventSource.AUDIT, e); + CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); + } finally { + w.flush(); + w.close(); + } + } +} diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/AuthCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/AuthCommand.java index 8325366..25800e1 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/AuthCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/AuthCommand.java @@ -24,9 +24,11 @@ import com.google.refine.commands.Command; import solutions.fairdata.openrefine.metadata.MetadataModuleImpl; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.request.auth.AuthRequest; import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; import solutions.fairdata.openrefine.metadata.commands.response.auth.AuthResponse; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; import solutions.fairdata.openrefine.metadata.dto.auth.AuthDTO; import solutions.fairdata.openrefine.metadata.dto.auth.TokenDTO; import solutions.fairdata.openrefine.metadata.dto.config.FDPConfigDTO; @@ -34,6 +36,7 @@ import solutions.fairdata.openrefine.metadata.dto.config.FDPInfoDTO; import solutions.fairdata.openrefine.metadata.fdp.FairDataPointClient; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -51,36 +54,44 @@ public class AuthCommand extends Command { @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { AuthRequest authRequest = CommandUtils.objectMapper.readValue(request.getReader(), AuthRequest.class); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); - try { - AuthDTO authDTO = authRequest.getAuthDTO(); - String fdpUri = authRequest.getFdpUri(); - if (authRequest.isConfiguredMode()) { - FDPConnectionConfigDTO fdpConnectionConfigDTO = MetadataModuleImpl.getInstance().getSettings().getFdpConnections().get(authRequest.getConfigId()); - authDTO.setEmail(fdpConnectionConfigDTO.getEmail()); - authDTO.setPassword(fdpConnectionConfigDTO.getPassword()); - fdpUri = fdpConnectionConfigDTO.getBaseURI(); - } else if (authRequest.isCustomMode() && !MetadataModuleImpl.getInstance().getSettings().getAllowCustomFDP()) { - throw new IOException("Custom FDP connection is not allowed!"); - } - + AuthDTO authDTO = authRequest.getAuthDTO(); + String fdpUri = authRequest.getFdpUri(); + if (authRequest.isConfiguredMode()) { + pa.reportDebug(EventSource.FDP_CONNECTION, "Using pre-configured FDP connection"); + FDPConnectionConfigDTO fdpConnectionConfigDTO = MetadataModuleImpl.getInstance().getSettings().getFdpConnections().get(authRequest.getConfigId()); + authDTO.setEmail(fdpConnectionConfigDTO.getEmail()); + authDTO.setPassword(fdpConnectionConfigDTO.getPassword()); + fdpUri = fdpConnectionConfigDTO.getBaseURI(); + } else if (authRequest.isCustomMode() && !MetadataModuleImpl.getInstance().getSettings().getAllowCustomFDP()) { + pa.reportInfo(EventSource.FDP_CONNECTION, "Used forbidden custom FDP connection"); + throw new IOException("Custom FDP connection is not allowed!"); + } else { + pa.reportDebug(EventSource.FDP_CONNECTION, "Using custom FDP connection"); + } - FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, logger); + pa.reportInfo(EventSource.FDP_CONNECTION, "Initiating communication with FDP: " + fdpUri); + FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, pa); + try { + pa.reportDebug(EventSource.FDP_CONNECTION, "Authenticating with FDP: " + fdpUri); TokenDTO tokenDTO = fdpClient.postAuthentication(authDTO); + pa.reportDebug(EventSource.FDP_CONNECTION, "Getting FDP info: " + fdpUri); FDPInfoDTO fdpInfoDTO = fdpClient.getFairDataPointInfo(); + pa.reportDebug(EventSource.FDP_CONNECTION, "Getting FDP config: " + fdpUri); FDPConfigDTO fdpConfigDTO = fdpClient.getFairDataPointConfig(); CommandUtils.objectMapper.writeValue(w, new AuthResponse(tokenDTO.getToken(), fdpClient.getBaseURI(), fdpInfoDTO, fdpConfigDTO)); } catch (Exception e) { - logger.error("Error while authenticating with FAIR Data Point: " + authRequest.getFdpUri() + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.FDP_CONNECTION, "Error while authenticating with FAIR Data Point: " + authRequest.getFdpUri()); + pa.reportTrace(EventSource.FDP_CONNECTION, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("auth-fdp-command/error", e)); } finally { w.flush(); w.close(); } - } } diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/CatalogsMetadataCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/CatalogsMetadataCommand.java index 1b6c8b6..c17e563 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/CatalogsMetadataCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/CatalogsMetadataCommand.java @@ -23,14 +23,17 @@ package solutions.fairdata.openrefine.metadata.commands; import com.google.refine.commands.Command; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.request.metadata.CatalogPostRequest; import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; import solutions.fairdata.openrefine.metadata.commands.response.metadata.CatalogPostResponse; import solutions.fairdata.openrefine.metadata.commands.response.metadata.CatalogsMetadataResponse; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; import solutions.fairdata.openrefine.metadata.dto.metadata.CatalogDTO; import solutions.fairdata.openrefine.metadata.dto.metadata.FDPMetadataDTO; import solutions.fairdata.openrefine.metadata.fdp.FairDataPointClient; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -46,23 +49,27 @@ public class CatalogsMetadataCommand extends Command { @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String fdpUri = request.getParameter("fdpUri"); + String repositoryUri = request.getParameter("repositoryUri"); + String token = request.getParameter("token"); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, token, pa); - logger.info("Retrieving Catalogs metadata from FDP URI: " + fdpUri); + pa.reportInfo(EventSource.FDP_METADATA, "Retrieving catalogs from FDP URI: " + fdpUri); try { - FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, logger); - FDPMetadataDTO fdpMetadataDTO = fdpClient.getFairDataPointMetadata(); + FDPMetadataDTO fdpMetadataDTO = fdpClient.getFairDataPointMetadata(repositoryUri); ArrayList catalogDTOs = new ArrayList<>(); for (String catalogURI : fdpMetadataDTO.getChildren()) { catalogDTOs.add(fdpClient.getCatalogMetadata(catalogURI)); } - logger.info("Catalogs metadata retrieved from FDP: " + fdpUri); + pa.reportDebug(EventSource.FDP_METADATA, "Catalogs retrieved from FDP: " + fdpUri); CommandUtils.objectMapper.writeValue(w, new CatalogsMetadataResponse(catalogDTOs)); } catch (Exception e) { - logger.error("Error while contacting FAIR Data Point: " + fdpUri + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.FDP_METADATA, "Error while getting catalogs from FDP: " + fdpUri); + pa.reportTrace(EventSource.FDP_METADATA, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); @@ -71,17 +78,21 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro } @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { CatalogPostRequest catalogPostRequest = CommandUtils.objectMapper.readValue(request.getReader(), CatalogPostRequest.class); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + FairDataPointClient fdpClient = new FairDataPointClient(catalogPostRequest.getFdpUri(), catalogPostRequest.getToken(), pa); try { - FairDataPointClient fdpClient = new FairDataPointClient(catalogPostRequest.getFdpUri(), catalogPostRequest.getToken(), logger); + pa.reportInfo(EventSource.FDP_METADATA, "Creating catalog: " + catalogPostRequest.getFdpUri()); CatalogDTO catalogDTO = fdpClient.postCatalog(catalogPostRequest.getCatalog()); + pa.reportDebug(EventSource.FDP_METADATA, "Catalog created: " + catalogDTO.getIri()); CommandUtils.objectMapper.writeValue(w, new CatalogPostResponse(catalogDTO)); } catch (Exception e) { - logger.error("Error while creating catalog in FAIR Data Point: " + catalogPostRequest.getFdpUri() + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.FDP_METADATA, "Error while creating catalog in FDP: " + catalogPostRequest.getFdpUri()); + pa.reportTrace(EventSource.FDP_METADATA, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/DashboardCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/DashboardCommand.java index 79f6a0a..b0afe40 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/DashboardCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/DashboardCommand.java @@ -23,11 +23,14 @@ package solutions.fairdata.openrefine.metadata.commands; import com.google.refine.commands.Command; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.response.DashboardResponse; import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; import solutions.fairdata.openrefine.metadata.dto.dashboard.DashboardItemDTO; import solutions.fairdata.openrefine.metadata.fdp.FairDataPointClient; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -43,17 +46,20 @@ public class DashboardCommand extends Command { @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String fdpUri = request.getParameter("fdpUri"); String token = request.getParameter("token"); Writer w = CommandUtils.prepareWriter(response); - FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, token, logger); + ProjectAudit pa = new ProjectAudit(getProject(request)); + FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, token, pa); try { + pa.reportInfo(EventSource.FDP_CONNECTION, "Getting use dashboard: " + fdpUri); List dashboard = fdpClient.getDashboard(); CommandUtils.objectMapper.writeValue(w, new DashboardResponse(dashboard)); } catch (Exception e) { - logger.error("Error while getting dashboard: " + fdpUri + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.FDP_CONNECTION,"Error while getting user dashboard: " + fdpUri); + pa.reportTrace(EventSource.FDP_CONNECTION, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/DatasetsMetadataCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/DatasetsMetadataCommand.java index 478d737..daa61b3 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/DatasetsMetadataCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/DatasetsMetadataCommand.java @@ -23,14 +23,17 @@ package solutions.fairdata.openrefine.metadata.commands; import com.google.refine.commands.Command; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.request.metadata.DatasetPostRequest; import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; import solutions.fairdata.openrefine.metadata.commands.response.metadata.DatasetPostResponse; import solutions.fairdata.openrefine.metadata.commands.response.metadata.DatasetsMetadataResponse; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; import solutions.fairdata.openrefine.metadata.dto.metadata.CatalogDTO; import solutions.fairdata.openrefine.metadata.dto.metadata.DatasetDTO; import solutions.fairdata.openrefine.metadata.fdp.FairDataPointClient; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -46,24 +49,26 @@ public class DatasetsMetadataCommand extends Command { @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String fdpUri = request.getParameter("fdpUri"); String catalogUri = request.getParameter("catalogUri"); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, pa); - logger.info("Retrieving Datasets metadata from catalog URI: " + catalogUri); + pa.reportInfo(EventSource.FDP_METADATA, "Retrieving datasets from catalog: " + catalogUri); try { - FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, logger); CatalogDTO catalogDTO = fdpClient.getCatalogMetadata(catalogUri); ArrayList datasetDTOs = new ArrayList<>(); for (String datasetURI : catalogDTO.getChildren()) { datasetDTOs.add(fdpClient.getDatasetMetadata(datasetURI)); } - logger.info("Datasets metadata retrieved from catalog: " + catalogUri); + pa.reportDebug(EventSource.FDP_METADATA, "Datasets retrieved from catalog: " + catalogUri); CommandUtils.objectMapper.writeValue(w, new DatasetsMetadataResponse(datasetDTOs)); } catch (Exception e) { - logger.error("Error while contacting FAIR Data Point: " + catalogUri + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.FDP_METADATA, "Error while getting datasets from catalog: " + catalogUri); + pa.reportTrace(EventSource.FDP_METADATA, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); @@ -72,17 +77,21 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro } @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { DatasetPostRequest datasetPostRequest = CommandUtils.objectMapper.readValue(request.getReader(), DatasetPostRequest.class); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + FairDataPointClient fdpClient = new FairDataPointClient(datasetPostRequest.getFdpUri(), datasetPostRequest.getToken(), pa); try { - FairDataPointClient fdpClient = new FairDataPointClient(datasetPostRequest.getFdpUri(), datasetPostRequest.getToken(), logger); + pa.reportInfo(EventSource.FDP_METADATA, "Creating dataset in catalog: " + datasetPostRequest.getDataset().getParent()); DatasetDTO datasetDTO = fdpClient.postDataset(datasetPostRequest.getDataset()); + pa.reportDebug(EventSource.FDP_METADATA, "Dataset created: " + datasetDTO.getIri()); CommandUtils.objectMapper.writeValue(w, new DatasetPostResponse(datasetDTO)); } catch (Exception e) { - logger.error("Error while creating catalog in FAIR Data Point: " + datasetPostRequest.getFdpUri() + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.FDP_METADATA, "Error while creating dataset in catalog: " + datasetPostRequest.getDataset().getParent()); + pa.reportTrace(EventSource.FDP_METADATA, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/DistributionsMetadataCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/DistributionsMetadataCommand.java index 8251662..62fb018 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/DistributionsMetadataCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/DistributionsMetadataCommand.java @@ -23,14 +23,17 @@ package solutions.fairdata.openrefine.metadata.commands; import com.google.refine.commands.Command; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.request.metadata.DistributionPostRequest; import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; import solutions.fairdata.openrefine.metadata.commands.response.metadata.DistributionPostResponse; import solutions.fairdata.openrefine.metadata.commands.response.metadata.DistributionsMetadataResponse; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; import solutions.fairdata.openrefine.metadata.dto.metadata.DatasetDTO; import solutions.fairdata.openrefine.metadata.dto.metadata.DistributionDTO; import solutions.fairdata.openrefine.metadata.fdp.FairDataPointClient; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -46,24 +49,26 @@ public class DistributionsMetadataCommand extends Command { @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String fdpUri = request.getParameter("fdpUri"); String datasetUri = request.getParameter("datasetUri"); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, pa); - logger.info("Retrieving Distributions metadata from dataset URI: " + datasetUri); + pa.reportInfo(EventSource.FDP_METADATA, "Retrieving distributions from dataset: " + datasetUri); try { - FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, logger); DatasetDTO datasetDTO = fdpClient.getDatasetMetadata(datasetUri); ArrayList distributionDTOs = new ArrayList<>(); for (String distributionURI : datasetDTO.getChildren()) { distributionDTOs.add(fdpClient.getDistributionMetadata(distributionURI)); } - logger.info("Distributions metadata retrieved from dataset: " + datasetUri); + pa.reportDebug(EventSource.FDP_METADATA, "Distributions retrieved from dataset: " + datasetUri); CommandUtils.objectMapper.writeValue(w, new DistributionsMetadataResponse(distributionDTOs)); } catch (Exception e) { - logger.error("Error while contacting FAIR Data Point: " + datasetUri + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.FDP_METADATA, "Error while getting distributions from dataset: " + datasetUri); + pa.reportTrace(EventSource.FDP_METADATA, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); @@ -72,17 +77,21 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro } @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { DistributionPostRequest distributionPostRequest = CommandUtils.objectMapper.readValue(request.getReader(), DistributionPostRequest.class); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + FairDataPointClient fdpClient = new FairDataPointClient(distributionPostRequest.getFdpUri(), distributionPostRequest.getToken(), pa); try { - FairDataPointClient fdpClient = new FairDataPointClient(distributionPostRequest.getFdpUri(), distributionPostRequest.getToken(), logger); + pa.reportDebug(EventSource.FDP_METADATA, "Creating distribution in dataset: " + distributionPostRequest.getDistribution().getParent()); DistributionDTO distributionDTO = fdpClient.postDistribution(distributionPostRequest.getDistribution()); + pa.reportDebug(EventSource.FDP_METADATA, "Distribution created: " + distributionDTO.getIri()); CommandUtils.objectMapper.writeValue(w, new DistributionPostResponse(distributionDTO)); } catch (Exception e) { - logger.error("Error while creating distribution in FAIR Data Point: " + distributionPostRequest.getFdpUri() + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.FDP_METADATA, "Error while creating distribution in dataset: " + distributionPostRequest.getDistribution().getParent()); + pa.reportTrace(EventSource.FDP_METADATA, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/FDPMetadataCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/FDPMetadataCommand.java index a1510f4..800fb2d 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/FDPMetadataCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/FDPMetadataCommand.java @@ -23,11 +23,14 @@ package solutions.fairdata.openrefine.metadata.commands; import com.google.refine.commands.Command; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; import solutions.fairdata.openrefine.metadata.commands.response.metadata.FDPMetadataResponse; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; import solutions.fairdata.openrefine.metadata.dto.metadata.FDPMetadataDTO; import solutions.fairdata.openrefine.metadata.fdp.FairDataPointClient; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -42,19 +45,22 @@ public class FDPMetadataCommand extends Command { @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String fdpUri = request.getParameter("fdpUri"); + String repositoryUri = request.getParameter("repositoryUri"); + String token = request.getParameter("token"); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, token, pa); - logger.info("Retrieving FAIR Data Point metadata from URI: " + fdpUri); + pa.reportInfo(EventSource.FDP_METADATA, "Retrieving FAIR Data Point (repository) metadata from URI: " + fdpUri); try { - FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, logger); - FDPMetadataDTO fdpMetadataDTO = fdpClient.getFairDataPointMetadata(); - - logger.info("FAIR Data Point metadata retrieved: " + fdpUri); + FDPMetadataDTO fdpMetadataDTO = fdpClient.getFairDataPointMetadata(repositoryUri); + pa.reportInfo(EventSource.FDP_METADATA, "FAIR Data Point (repository) metadata retrieved from: " + fdpUri); CommandUtils.objectMapper.writeValue(w, new FDPMetadataResponse("connect-fdp-command/success", fdpMetadataDTO)); } catch (Exception e) { - logger.error("Error while contacting FAIR Data Point: " + fdpUri + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.FDP_METADATA, "Error while getting FAIR Data Point metadata from: " + fdpUri); + pa.reportTrace(EventSource.FDP_METADATA, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/MetadataSpecsCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/MetadataSpecsCommand.java index 5c580e5..948aca9 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/MetadataSpecsCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/MetadataSpecsCommand.java @@ -23,10 +23,13 @@ package solutions.fairdata.openrefine.metadata.commands; import com.google.refine.commands.Command; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; import solutions.fairdata.openrefine.metadata.commands.response.metadata.MetadataSpecResponse; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; import solutions.fairdata.openrefine.metadata.fdp.FairDataPointClient; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -38,27 +41,20 @@ public class MetadataSpecsCommand extends Command { @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String fdpUri = request.getParameter("fdpUri"); String token = request.getParameter("token"); String type = request.getParameter("type"); Writer w = CommandUtils.prepareWriter(response); - FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, token, logger); + ProjectAudit pa = new ProjectAudit(getProject(request)); + FairDataPointClient fdpClient = new FairDataPointClient(fdpUri, token, pa); try { - Object result; - if ("catalog".equalsIgnoreCase(type)) { - result = fdpClient.getCatalogSpec(); - } else if ("dataset".equalsIgnoreCase(type)) { - result = fdpClient.getDatasetSpec(); - } else if ("distribution".equalsIgnoreCase(type)) { - result = fdpClient.getDistributionSpec(); - } else { - throw new IOException("Invalid metadata type requested"); - } - CommandUtils.objectMapper.writeValue(w, new MetadataSpecResponse(result)); + String spec = fdpClient.getMetadataSpec(type); + CommandUtils.objectMapper.writeValue(w, new MetadataSpecResponse(spec)); } catch (Exception e) { - logger.error("Error while getting dashboard: " + fdpUri + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.FDP_CONNECTION,"Error while getting metadata specs: " + fdpUri); + pa.reportTrace(EventSource.FDP_CONNECTION, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/ServiceCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/ServiceCommand.java index 2938ff8..89486e6 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/ServiceCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/ServiceCommand.java @@ -24,9 +24,12 @@ import com.google.refine.commands.Command; import solutions.fairdata.openrefine.metadata.MetadataModuleImpl; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.request.ServiceRequest; import solutions.fairdata.openrefine.metadata.commands.response.ServiceResponse; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -48,6 +51,7 @@ public enum ServiceTask { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { ServiceRequest serviceRequest = CommandUtils.objectMapper.readValue(request.getReader(), ServiceRequest.class); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(); // no project for service tasks String command = System.getenv(ServiceCommand.ENVVAR); ServiceResponse serviceResponse = new ServiceResponse(); @@ -55,21 +59,26 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr try { if (ENABLED.equalsIgnoreCase(command)) { ServiceTask task = ServiceTask.valueOf(serviceRequest.getTask().toUpperCase()); + pa.reportInfo(EventSource.SERVICE, "Requested to execute service task " + task.toString()); if (task == ServiceTask.RELOAD_CONFIG) { MetadataModuleImpl.getInstance().loadConfig(); serviceResponse.setStatus(ServiceResponse.STATUS_OK); serviceResponse.setMessage("Configuration reloaded"); + pa.reportDebug(EventSource.SERVICE, "Config has been reloaded"); } } else { + pa.reportWarning(EventSource.SERVICE, "Requested to execute service task but it is disabled"); serviceResponse.setMessage("Service tasks are not enabled"); } CommandUtils.objectMapper.writeValue(w, serviceResponse); } catch (IllegalArgumentException e) { + pa.reportWarning(EventSource.SERVICE, "Requested unknown service task: " + serviceRequest.getTask()); serviceResponse.setMessage("Unknown service task: " + serviceRequest.getTask()); CommandUtils.objectMapper.writeValue(w, serviceResponse); } catch (Exception e) { - logger.error("Error while performing service task: " + serviceRequest.getTask() + " (" + e.getMessage() + ")"); - serviceResponse.setMessage("Error while performing service task (" + e.getMessage() + ")"); + pa.reportError(EventSource.SERVICE,"Error while performing service task: " + serviceRequest.getTask()); + pa.reportTrace(EventSource.SERVICE, e); + serviceResponse.setMessage("Error while performing service task: " + serviceRequest.getTask() ); CommandUtils.objectMapper.writeValue(w, serviceResponse); } finally { w.flush(); diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/SettingsCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/SettingsCommand.java index 1de3241..86cba46 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/SettingsCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/SettingsCommand.java @@ -26,10 +26,12 @@ import com.google.refine.commands.Command; import com.google.refine.model.Project; import solutions.fairdata.openrefine.metadata.MetadataModuleImpl; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.request.config.SettingsRequest; import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; import solutions.fairdata.openrefine.metadata.commands.response.config.SettingsResponse; import solutions.fairdata.openrefine.metadata.dto.ProjectInfoDTO; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; import solutions.fairdata.openrefine.metadata.dto.config.ProjectConfigDTO; import solutions.fairdata.openrefine.metadata.dto.config.SettingsConfigDTO; @@ -55,10 +57,14 @@ private SettingsResponse createSettingsResponse(Project project) { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { Writer w = CommandUtils.prepareWriter(response); Project project = getProject(request); + ProjectAudit pa = new ProjectAudit(getProject(request)); + try { + pa.reportDebug(EventSource.SETTINGS,"Retrieving current configuration bundle"); CommandUtils.objectMapper.writeValue(w, createSettingsResponse(project)); } catch (Exception e) { - logger.error("Error while getting Settings"); + pa.reportError(EventSource.SETTINGS,"Error occurred while getting Settings"); + pa.reportTrace(EventSource.SETTINGS, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); @@ -71,13 +77,15 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr SettingsRequest settingsRequest = CommandUtils.objectMapper.readValue(request.getReader(), SettingsRequest.class); Project project = getProject(request); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); try { + pa.reportDebug(EventSource.SETTINGS,"Persisting project configuration"); MetadataModuleImpl.setProjectConfigDTO(project, settingsRequest.getProjectData()); - CommandUtils.objectMapper.writeValue(w, createSettingsResponse(project)); } catch (Exception e) { - logger.error("Error while persisting Settings"); + pa.reportError(EventSource.SETTINGS,"Error occurred while persisting Settings"); + pa.reportTrace(EventSource.SETTINGS, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("auth-fdp-command/error", e)); } finally { w.flush(); diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/StoreDataCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/StoreDataCommand.java index 896844e..6209ab8 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/StoreDataCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/StoreDataCommand.java @@ -28,12 +28,14 @@ import com.google.refine.exporters.ExporterRegistry; import com.google.refine.exporters.StreamExporter; import com.google.refine.exporters.WriterExporter; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.exceptions.MetadataCommandException; import solutions.fairdata.openrefine.metadata.commands.request.storage.StoreDataRequest; import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; import solutions.fairdata.openrefine.metadata.commands.response.storage.StoreDataInfoResponse; import solutions.fairdata.openrefine.metadata.commands.response.storage.StoreDataPreviewResponse; import solutions.fairdata.openrefine.metadata.commands.response.storage.StoreDataResponse; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; import solutions.fairdata.openrefine.metadata.dto.storage.ExportFormatDTO; import solutions.fairdata.openrefine.metadata.dto.storage.StorageDTO; import solutions.fairdata.openrefine.metadata.storage.Storage; @@ -91,11 +93,15 @@ private static void updateFormats() { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + + pa.reportDebug(EventSource.STORAGE,"Updating possible and known export formats"); updateFormats(); String defaultFilename = getProject(request).getMetadata().getName().replaceAll("\\W+", "_"); String defaultBaseURI = "http://" + request.getServerName() + "/" + defaultFilename; + pa.reportDebug(EventSource.STORAGE,"Retrieving storage information"); StoreDataInfoResponse storeDataInfoResponse = new StoreDataInfoResponse( new ArrayList<>(formats.values()), new ArrayList<>(StorageRegistryUtil.getStorages().stream().map(Storage::getStorageDTO).map(StorageDTO::toInfo).collect(Collectors.toList())) @@ -112,8 +118,10 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { StoreDataRequest storeDataRequest = CommandUtils.objectMapper.readValue(request.getReader(), StoreDataRequest.class); Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); try { + pa.reportDebug(EventSource.STORAGE,"Preparing information for storing data"); Engine engine = getEngine(request, getProject(request)); Properties params = getRequestParameters(request); String defaultFilename = getProject(request).getMetadata().getName().replaceAll("\\W+", "_"); @@ -122,18 +130,21 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr Exporter exporter = ExporterRegistry.getExporter(storeDataRequest.getFormat()); Storage storage = StorageRegistryUtil.getStorage(storeDataRequest.getStorage()); if (exporter == null) { + pa.reportWarning(EventSource.STORAGE,"Unknown export format requested"); throw new MetadataCommandException("store-data-dialog/error/unknown-export-format"); } else if (storage == null) { + pa.reportWarning(EventSource.STORAGE,"Unknown storage requested"); throw new MetadataCommandException("store-data-dialog/error/unknown-storage"); } else if (storage.forbidsContentType(exporter.getContentType())) { + pa.reportWarning(EventSource.STORAGE,"Requested content-type is forbidden for selected storage"); throw new MetadataCommandException("store-data-dialog/error/unsupported-type"); } try ( - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - OutputStreamWriter writer = new OutputStreamWriter(stream, StandardCharsets.UTF_8) + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + OutputStreamWriter writer = new OutputStreamWriter(stream, StandardCharsets.UTF_8) ) { if (exporter instanceof WriterExporter) { WriterExporter writerExporter = (WriterExporter) exporter; @@ -142,6 +153,7 @@ else if (storage.forbidsContentType(exporter.getContentType())) { StreamExporter streamExporter = (StreamExporter) exporter; streamExporter.export(getProject(request), params, engine, stream); } else { + pa.reportWarning(EventSource.STORAGE,"Failed to export to selected format"); throw new MetadataCommandException("store-data-dialog/error/unusable-exporter"); } @@ -154,17 +166,25 @@ else if (storage.forbidsContentType(exporter.getContentType())) { String filename = storeDataRequest.getMetadata().get("filenameExt"); if (storeDataRequest.getMode().equals("preview")) { + pa.reportInfo(EventSource.STORAGE,"Preparing preview of data: " + filename); + pa.reportDebug(EventSource.STORAGE,"File size is (bytes): " + data.length); + pa.reportDebug(EventSource.STORAGE,"File content-type is: " + exporter.getContentType()); String base64Data = Base64.getEncoder().encodeToString(data); CommandUtils.objectMapper.writeValue(w, new StoreDataPreviewResponse(filename, exporter.getContentType(), base64Data) ); } else { if (storage.forbidsName(filename)) { + pa.reportWarning(EventSource.STORAGE,"Filename violates storage requirements"); throw new MetadataCommandException("store-data-dialog/error/naming-violation"); } else if (storage.fordbidsByteSize(data.length)) { + pa.reportWarning(EventSource.STORAGE,"File is too big for selected storage"); throw new MetadataCommandException("store-data-dialog/error/too-big"); } + pa.reportInfo(EventSource.STORAGE,"Storing data: " + filename); + pa.reportDebug(EventSource.STORAGE,"File size is (bytes): " + data.length); + pa.reportDebug(EventSource.STORAGE,"File content-type is: " + exporter.getContentType()); storage.storeData(data, storeDataRequest.getMetadata(), exporter.getContentType()); CommandUtils.objectMapper.writeValue(w, @@ -173,10 +193,10 @@ else if (storage.fordbidsByteSize(data.length)) { } } } catch (MetadataCommandException e) { - logger.warn("Unable to store data (bad request)"); CommandUtils.objectMapper.writeValue(w, new ErrorResponse(e.getMessage(), e)); } catch (Exception e) { - logger.warn("Unable to store data: " + e.getMessage()); + pa.reportError(EventSource.STORAGE,"Unable to store data"); + pa.reportTrace(EventSource.STORAGE, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("store-data-dialog/error/exporting", e)); } finally { w.flush(); diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/TypehintsCommand.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/TypehintsCommand.java index 1e5e092..59cae30 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/TypehintsCommand.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/TypehintsCommand.java @@ -23,14 +23,12 @@ package solutions.fairdata.openrefine.metadata.commands; import com.google.refine.commands.Command; +import solutions.fairdata.openrefine.metadata.ProjectAudit; import solutions.fairdata.openrefine.metadata.commands.response.ErrorResponse; import solutions.fairdata.openrefine.metadata.commands.response.TypehintsResponse; import solutions.fairdata.openrefine.metadata.dto.TypehintDTO; -import solutions.fairdata.openrefine.metadata.typehinting.TypehintService; -import solutions.fairdata.openrefine.metadata.typehinting.LanguageTypehintService; -import solutions.fairdata.openrefine.metadata.typehinting.LicenseTypehintService; -import solutions.fairdata.openrefine.metadata.typehinting.MediaTypeTypehintService; -import solutions.fairdata.openrefine.metadata.typehinting.ThemeTypehintService; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; +import solutions.fairdata.openrefine.metadata.typehinting.*; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -67,7 +65,9 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro query = ""; } Writer w = CommandUtils.prepareWriter(response); + ProjectAudit pa = new ProjectAudit(getProject(request)); + pa.reportInfo(EventSource.TYPEHINTS, "Retrieving typehints \"" + name + "\" with query \"" + query + "\""); try { List typehints = null; String source = "none"; @@ -76,11 +76,15 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro typehints = typehintService.getTypehints(query); source = typehintService.getSource(); typehints.sort(Comparator.comparing(TypehintDTO::getTitle)); + pa.reportInfo(EventSource.TYPEHINTS, "Retrieved " + typehints.size() + " typehint items"); + } else { + pa.reportWarning(EventSource.TYPEHINTS, "Unknown typehints requested: " + name); } CommandUtils.objectMapper.writeValue(w, new TypehintsResponse(source, typehints)); } catch (Exception e) { - logger.error("Error while preparing typehints of name: " + name + " (" + e.getMessage() + ")"); + pa.reportError(EventSource.TYPEHINTS,"Error while retrieving typehints: " + name); + pa.reportTrace(EventSource.TYPEHINTS, e); CommandUtils.objectMapper.writeValue(w, new ErrorResponse("connect-fdp-command/error", e)); } finally { w.flush(); diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/request/audit/AuditRequest.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/request/audit/AuditRequest.java new file mode 100644 index 0000000..dc3b76f --- /dev/null +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/request/audit/AuditRequest.java @@ -0,0 +1,38 @@ +/** + * The MIT License + * Copyright © 2019 FAIR Data Team + * + * 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. + */ +package solutions.fairdata.openrefine.metadata.commands.request.audit; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import solutions.fairdata.openrefine.metadata.dto.audit.EventType; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class AuditRequest { + private EventType eventType; + private String message; +} diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/response/audit/AuditResponse.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/response/audit/AuditResponse.java new file mode 100644 index 0000000..6c35747 --- /dev/null +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/response/audit/AuditResponse.java @@ -0,0 +1,44 @@ +/** + * The MIT License + * Copyright © 2019 FAIR Data Team + * + * 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. + */ +package solutions.fairdata.openrefine.metadata.commands.response.audit; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import solutions.fairdata.openrefine.metadata.dto.audit.AuditLogDTO; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class AuditResponse { + + private String status; + private AuditLogDTO auditLog; + + public AuditResponse(AuditLogDTO auditLog) { + this.status = "ok"; + this.auditLog = auditLog; + } +} diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/commands/response/metadata/MetadataSpecResponse.java b/src/main/java/solutions/fairdata/openrefine/metadata/commands/response/metadata/MetadataSpecResponse.java index 8374715..0d71582 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/commands/response/metadata/MetadataSpecResponse.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/commands/response/metadata/MetadataSpecResponse.java @@ -34,9 +34,9 @@ public class MetadataSpecResponse { public String status; - public Object spec; + public String spec; - public MetadataSpecResponse(Object spec) { + public MetadataSpecResponse(String spec) { this.status = "ok"; this.spec = spec; } diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/AuditEntryDTO.java b/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/AuditEntryDTO.java new file mode 100644 index 0000000..542eef5 --- /dev/null +++ b/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/AuditEntryDTO.java @@ -0,0 +1,40 @@ +/** + * The MIT License + * Copyright © 2019 FAIR Data Team + * + * 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. + */ +package solutions.fairdata.openrefine.metadata.dto.audit; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class AuditEntryDTO { + private EventType eventType; + private EventSource eventSource; + private String message; + private String timestamp; +} diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/AuditLogDTO.java b/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/AuditLogDTO.java new file mode 100644 index 0000000..0ca1d27 --- /dev/null +++ b/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/AuditLogDTO.java @@ -0,0 +1,41 @@ +/** + * The MIT License + * Copyright © 2019 FAIR Data Team + * + * 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. + */ +package solutions.fairdata.openrefine.metadata.dto.audit; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class AuditLogDTO { + private Long projectId; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-ddTHH:mm:ss.SSSZ") + private List entries; +} diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/EventSource.java b/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/EventSource.java new file mode 100644 index 0000000..16a3f88 --- /dev/null +++ b/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/EventSource.java @@ -0,0 +1,34 @@ +/** + * The MIT License + * Copyright © 2019 FAIR Data Team + * + * 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. + */ +package solutions.fairdata.openrefine.metadata.dto.audit; + +public enum EventSource { + FDP_CONNECTION, + FDP_METADATA, + SERVICE, + STORAGE, + AUDIT, + TYPEHINTS, + FRONTEND, + SETTINGS; +} diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/EventType.java b/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/EventType.java new file mode 100644 index 0000000..084a4e0 --- /dev/null +++ b/src/main/java/solutions/fairdata/openrefine/metadata/dto/audit/EventType.java @@ -0,0 +1,42 @@ +/** + * The MIT License + * Copyright © 2019 FAIR Data Team + * + * 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. + */ +package solutions.fairdata.openrefine.metadata.dto.audit; + +public enum EventType { + OFF(0), + ERROR(200), + WARNING(300), + INFO(400), + DEBUG(500), + TRACE(900); + + private int level; + + EventType(int level) { + this.level = level; + } + + public int getLevel() { + return level; + } +} diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/dto/config/FDPConfigDTO.java b/src/main/java/solutions/fairdata/openrefine/metadata/dto/config/FDPConfigDTO.java index e44363d..c4d1425 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/dto/config/FDPConfigDTO.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/dto/config/FDPConfigDTO.java @@ -32,5 +32,5 @@ @Getter @Setter public class FDPConfigDTO { - private String instanceUrl; + private String persistentUrl; } diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/dto/config/SettingsConfigDTO.java b/src/main/java/solutions/fairdata/openrefine/metadata/dto/config/SettingsConfigDTO.java index ee5668d..5bad526 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/dto/config/SettingsConfigDTO.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/dto/config/SettingsConfigDTO.java @@ -26,6 +26,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import solutions.fairdata.openrefine.metadata.dto.audit.EventType; import java.util.HashMap; import java.util.LinkedList; @@ -37,21 +38,27 @@ @Getter @Setter public class SettingsConfigDTO { - private Boolean allowCustomFDP; + private Boolean allowCustomFDP = true; + private EventType audit = EventType.INFO; + private Boolean auditShow = false; private HashMap metadata = new HashMap<>(); private List fdpConnections = new LinkedList<>(); - SettingsConfigDTO(Boolean allowCustomFDP) { + SettingsConfigDTO(Boolean allowCustomFDP, EventType audit, Boolean auditShow) { this.allowCustomFDP = allowCustomFDP; + this.audit = audit; + this.auditShow = auditShow; } public static SettingsConfigDTO getDefaultSettings() { - return new SettingsConfigDTO(true); + return new SettingsConfigDTO(true, EventType.OFF, false); } public SettingsConfigDTO copyDetails() { SettingsConfigDTO details = new SettingsConfigDTO(); details.setAllowCustomFDP(getAllowCustomFDP()); + details.setAudit(getAudit()); + details.setAuditShow(getAuditShow()); details.setMetadata(getMetadata()); details.setFdpConnections(getFdpConnections().stream().map(FDPConnectionConfigDTO::copyDetails).collect(Collectors.toList())); return details; diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/fdp/FairDataPointClient.java b/src/main/java/solutions/fairdata/openrefine/metadata/fdp/FairDataPointClient.java index 4a23f10..c9f298b 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/fdp/FairDataPointClient.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/fdp/FairDataPointClient.java @@ -31,8 +31,9 @@ import org.eclipse.rdf4j.rio.RDFParser; import org.eclipse.rdf4j.rio.Rio; import org.eclipse.rdf4j.rio.helpers.StatementCollector; -import org.slf4j.Logger; import solutions.fairdata.openrefine.metadata.MetadataModuleImpl; +import solutions.fairdata.openrefine.metadata.ProjectAudit; +import solutions.fairdata.openrefine.metadata.dto.audit.EventSource; import solutions.fairdata.openrefine.metadata.dto.auth.AuthDTO; import solutions.fairdata.openrefine.metadata.dto.auth.TokenDTO; import solutions.fairdata.openrefine.metadata.dto.config.FDPConfigDTO; @@ -50,6 +51,7 @@ import java.io.*; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.*; @@ -72,7 +74,7 @@ public class FairDataPointClient { )); private static final String INFO_PART = "actuator/info"; - private static final String CONFIG_PART = "configuration"; + private static final String CONFIG_PART = "configs/bootstrap"; private static final String CATALOG_PART = "catalog"; private static final String DATASET_PART = "dataset"; private static final String DISTRIBUTION_PART = "distribution"; @@ -84,22 +86,23 @@ public class FairDataPointClient { private static final String MEDIA_TYPE_TURTLE = "text/turtle"; private static final String USER_AGENT = MetadataModuleImpl.USER_AGENT; + private static final Charset CHARSET = StandardCharsets.UTF_8; - private final Logger logger; + private final ProjectAudit projectAudit; private final String token; private final String fdpBaseURI; - public FairDataPointClient(String fdpBaseURI, Logger logger) { - this(fdpBaseURI, null, logger); + public FairDataPointClient(String fdpBaseURI, ProjectAudit projectAudit) { + this(fdpBaseURI, null, projectAudit); } - public FairDataPointClient(String fdpBaseURI, String token, Logger logger) { + public FairDataPointClient(String fdpBaseURI, String token, ProjectAudit projectAudit) { while (fdpBaseURI.endsWith("/")) { fdpBaseURI = fdpBaseURI.substring(0, fdpBaseURI.length() - 1); } this.fdpBaseURI = fdpBaseURI; this.token = token; - this.logger = logger; + this.projectAudit = projectAudit; } /** @@ -114,11 +117,14 @@ public TokenDTO postAuthentication(AuthDTO auth) throws IOException, FairDataPoi HttpURLConnection conn = createConnection(url(fdpBaseURI, AUTH_PART), "POST", MEDIA_TYPE_JSON); conn.addRequestProperty(HttpHeaders.CONTENT_TYPE, MEDIA_TYPE_JSON); conn.setDoOutput(true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending POST authentication request to FDP"); objectMapper.writeValue(conn.getOutputStream(), auth); if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Received authentication response"); return objectMapper.readValue(conn.getInputStream(), TokenDTO.class); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to authenticate: " + conn.getResponseCode()); throw new FairDataPointException(conn.getResponseCode(), conn.getResponseMessage()); } } @@ -132,10 +138,13 @@ public TokenDTO postAuthentication(AuthDTO auth) throws IOException, FairDataPoi */ public List getDashboard() throws IOException, FairDataPointException { HttpURLConnection conn = request(url(fdpBaseURI,DASHBOARD_PART), "GET", MEDIA_TYPE_JSON, true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending GET dashboard request to FDP"); if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Received dashboard response"); return objectMapper.readValue(conn.getInputStream(), new TypeReference>(){}); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to get dashboard: " + conn.getResponseCode()); throw new FairDataPointException(conn.getResponseCode(), conn.getResponseMessage()); } } @@ -147,15 +156,18 @@ public List getDashboard() throws IOException, FairDataPointEx * @throws IOException in case of a communication error * @throws FairDataPointException in case that FDP responds with an unexpected code */ - public FDPMetadataDTO getFairDataPointMetadata() throws IOException, FairDataPointException { + public FDPMetadataDTO getFairDataPointMetadata(String repositoryUri) throws IOException, FairDataPointException { HttpURLConnection conn = request(fdpBaseURI, "GET", MEDIA_TYPE_TURTLE, true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending GET repository metadata request to FDP"); if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { - String actualURI = conn.getURL().toString(); - + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Received repository metadata"); + String actualURI = repositoryUri != null ? repositoryUri : conn.getURL().toString(); ArrayList statements = parseStatements(conn, actualURI); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Parsed and processed repository metadata"); return FDPMetadataTransformerUtils.metadata2DTO(statements, actualURI); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to get repository metadata: " + conn.getResponseCode()); throw new FairDataPointException(conn.getResponseCode(), conn.getResponseMessage()); } } @@ -168,10 +180,13 @@ public FDPMetadataDTO getFairDataPointMetadata() throws IOException, FairDataPoi */ public FDPInfoDTO getFairDataPointInfo() throws IOException { HttpURLConnection conn = request(url(fdpBaseURI, INFO_PART), "GET", MEDIA_TYPE_JSON, true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending GET info request to FDP"); if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Received FDP info"); return objectMapper.readValue(conn.getInputStream(), FDPInfoDTO.class); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to get FDP info: " + conn.getResponseCode()); return null; } } @@ -184,10 +199,13 @@ public FDPInfoDTO getFairDataPointInfo() throws IOException { */ public FDPConfigDTO getFairDataPointConfig() throws IOException { HttpURLConnection conn = request(url(fdpBaseURI, CONFIG_PART), "GET", MEDIA_TYPE_JSON, true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending GET config request to FDP"); if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Received FDP config"); return objectMapper.readValue(conn.getInputStream(), FDPConfigDTO.class); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to get FDP config: " + conn.getResponseCode()); return null; } } @@ -202,12 +220,14 @@ public FDPConfigDTO getFairDataPointConfig() throws IOException { */ public CatalogDTO getCatalogMetadata(String catalogURI) throws IOException, FairDataPointException { HttpURLConnection conn = request(catalogURI, "GET", MEDIA_TYPE_TURTLE, true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending GET catalog request to FDP"); if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Received catalog from FDP"); String actualURI = conn.getURL().toString(); - return CatalogTransformerUtils.statements2DTO(parseStatements(conn, actualURI), actualURI); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to get catalog: " + conn.getResponseCode()); throw new FairDataPointException(conn.getResponseCode(), conn.getResponseMessage()); } } @@ -222,12 +242,14 @@ public CatalogDTO getCatalogMetadata(String catalogURI) throws IOException, Fair */ public DatasetDTO getDatasetMetadata(String datasetURI) throws IOException, FairDataPointException { HttpURLConnection conn = request(datasetURI, "GET", MEDIA_TYPE_TURTLE, true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending GET dataset request to FDP"); if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Received dataset from FDP"); String actualURI = conn.getURL().toString(); - return DatasetTransformerUtils.statements2DTO(parseStatements(conn, actualURI), actualURI); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to get dataset: " + conn.getResponseCode()); throw new FairDataPointException(conn.getResponseCode(), conn.getResponseMessage()); } } @@ -242,66 +264,35 @@ public DatasetDTO getDatasetMetadata(String datasetURI) throws IOException, Fair */ public DistributionDTO getDistributionMetadata(String distributionURI) throws IOException, FairDataPointException { HttpURLConnection conn = request(distributionURI, "GET", MEDIA_TYPE_TURTLE, true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending GET distribution request to FDP"); if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Received distribution from FDP"); String actualURI = conn.getURL().toString(); - return DistributionTransformerUtils.statements2DTO(parseStatements(conn, actualURI), actualURI); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to get distribution: " + conn.getResponseCode()); throw new FairDataPointException(conn.getResponseCode(), conn.getResponseMessage()); } } /** - * Get specs of catalog layer (form specs) - * - * @return form specs as generic object - * @throws IOException in case of a communication error - * @throws FairDataPointException in case that FDP responds with an unexpected code - */ - public Object getCatalogSpec() throws IOException, FairDataPointException { - return getMetadataSpec(CATALOG_PART); - } - - - /** - * Get specs of dataset layer (form specs) - * - * @return form specs as generic object - * @throws IOException in case of a communication error - * @throws FairDataPointException in case that FDP responds with an unexpected code - */ - public Object getDatasetSpec() throws IOException, FairDataPointException { - return getMetadataSpec(DATASET_PART); - } - - - /** - * Get specs of distribution layer (form specs) - * - * @return form specs as generic object - * @throws IOException in case of a communication error - * @throws FairDataPointException in case that FDP responds with an unexpected code - */ - public Object getDistributionSpec() throws IOException, FairDataPointException { - return getMetadataSpec(DISTRIBUTION_PART); - } - - - /** - * Get form specs + * Get shape specs * - * @param metadataPart specification of layer (catalog, dataset, or distribution) - * @return form specs as generic object + * @param shapeName specification of layer (catalog, dataset, or distribution) + * @return SHACL definition as string * @throws IOException in case of a communication error * @throws FairDataPointException in case that FDP responds with an unexpected code */ - private Object getMetadataSpec(String metadataPart) throws IOException, FairDataPointException { - HttpURLConnection conn = request(url(fdpBaseURI, metadataPart, SPEC_PART), "GET", MEDIA_TYPE_JSON, true); + public String getMetadataSpec(String shapeName) throws IOException, FairDataPointException { + HttpURLConnection conn = request(url(fdpBaseURI, shapeName, SPEC_PART), "GET", MEDIA_TYPE_TURTLE, true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending GET metadata spec request to FDP - " + shapeName); if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) { - return objectMapper.readValue(conn.getInputStream(), Object.class); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Received metadata specs from FDP"); + return readInputStream(conn.getInputStream()); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to get metadata specs: " + conn.getResponseCode()); throw new FairDataPointException(conn.getResponseCode(), conn.getResponseMessage()); } } @@ -318,6 +309,7 @@ public CatalogDTO postCatalog(CatalogDTO catalogDTO) throws IOException, FairDat HttpURLConnection conn = createConnection(url(fdpBaseURI, CATALOG_PART), "POST", MEDIA_TYPE_TURTLE); conn.addRequestProperty(HttpHeaders.CONTENT_TYPE, MEDIA_TYPE_TURTLE); conn.setDoOutput(true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending POST catalog request to FDP"); // Generate random IRI, FDP will replace it with really unique String uri = url(fdpBaseURI, CATALOG_PART, UUID.randomUUID().toString()); @@ -326,15 +318,17 @@ public CatalogDTO postCatalog(CatalogDTO catalogDTO) throws IOException, FairDat ArrayList statements = CatalogTransformerUtils.dto2Statements(catalogDTO); String metadata = serializeStatements(statements); - BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8)); + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), CHARSET)); bw.write(metadata); bw.flush(); bw.close(); if(conn.getResponseCode() == HttpURLConnection.HTTP_CREATED) { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Created new catalog and received it as response"); String actualURI = conn.getHeaderField(HttpHeaders.LOCATION); return CatalogTransformerUtils.statements2DTO(parseStatements(conn, actualURI), actualURI); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to create new catalog: " + conn.getResponseCode()); throw new FairDataPointException(conn.getResponseCode(), conn.getResponseMessage()); } } @@ -351,6 +345,7 @@ public DatasetDTO postDataset(DatasetDTO datasetDTO) throws IOException, FairDat HttpURLConnection conn = createConnection(url(fdpBaseURI, DATASET_PART), "POST", MEDIA_TYPE_TURTLE); conn.addRequestProperty(HttpHeaders.CONTENT_TYPE, MEDIA_TYPE_TURTLE); conn.setDoOutput(true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending POST dataset request to FDP"); // Generate random IRI, FDP will replace it with really unique String uri = url(fdpBaseURI, DATASET_PART, UUID.randomUUID().toString()); @@ -359,15 +354,17 @@ public DatasetDTO postDataset(DatasetDTO datasetDTO) throws IOException, FairDat ArrayList statements = DatasetTransformerUtils.dto2Statements(datasetDTO); String metadata = serializeStatements(statements); - BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8)); + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), CHARSET)); bw.write(metadata); bw.flush(); bw.close(); if(conn.getResponseCode() == HttpURLConnection.HTTP_CREATED) { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Created new dataset and received it as response"); String actualURI = conn.getHeaderField(HttpHeaders.LOCATION); return DatasetTransformerUtils.statements2DTO(parseStatements(conn, actualURI), actualURI); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to create new dataset: " + conn.getResponseCode()); throw new FairDataPointException(conn.getResponseCode(), conn.getResponseMessage()); } } @@ -384,6 +381,7 @@ public DistributionDTO postDistribution(DistributionDTO distributionDTO) throws HttpURLConnection conn = createConnection(url(fdpBaseURI, DISTRIBUTION_PART), "POST", MEDIA_TYPE_TURTLE); conn.addRequestProperty(HttpHeaders.CONTENT_TYPE, MEDIA_TYPE_TURTLE); conn.setDoOutput(true); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Sending POST distribution request to FDP"); // Generate random IRI, FDP will replace it with really unique String uri = url(fdpBaseURI, DISTRIBUTION_PART, UUID.randomUUID().toString()); @@ -392,15 +390,17 @@ public DistributionDTO postDistribution(DistributionDTO distributionDTO) throws ArrayList statements = DistributionTransformerUtils.dto2Statements(distributionDTO); String metadata = serializeStatements(statements); - BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8)); + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), CHARSET)); bw.write(metadata); bw.flush(); bw.close(); if(conn.getResponseCode() == HttpURLConnection.HTTP_CREATED) { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Created new distribution and received it as response"); String actualURI = conn.getHeaderField(HttpHeaders.LOCATION); return DistributionTransformerUtils.statements2DTO(parseStatements(conn, actualURI), actualURI); } else { + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "Failed to create new distribution: " + conn.getResponseCode()); throw new FairDataPointException(conn.getResponseCode(), conn.getResponseMessage()); } } @@ -418,7 +418,7 @@ private ArrayList parseStatements(HttpURLConnection conn, String uri) StatementCollector collector = new StatementCollector(); parser.setRDFHandler(collector); - parser.parse(new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)), uri); + parser.parse(new BufferedReader(new InputStreamReader(conn.getInputStream(), CHARSET)), uri); return new ArrayList<>(collector.getStatements()); } @@ -448,7 +448,7 @@ private HttpURLConnection createConnection(String url, String method, String acc conn.setRequestMethod(method); conn.addRequestProperty(HttpHeaders.ACCEPT, accept); conn.addRequestProperty(HttpHeaders.USER_AGENT, USER_AGENT); - conn.addRequestProperty(HttpHeaders.CONTENT_ENCODING, StandardCharsets.UTF_8.displayName()); + conn.addRequestProperty(HttpHeaders.CONTENT_ENCODING, CHARSET.displayName()); if (token != null) { conn.addRequestProperty(HttpHeaders.AUTHORIZATION, "Bearer " + token); @@ -469,7 +469,7 @@ private HttpURLConnection createConnection(String url, String method, String acc private HttpURLConnection request(String url, String method, String accept, boolean followRedirects) throws IOException { HttpURLConnection conn = createConnection(url, method, accept); - logger.info("FDP HTTP {} request to {} (response: {})", method, url, conn.getResponseCode()); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, String.format("HTTP %s request to %s (response: %d)", method, url, conn.getResponseCode())); conn.connect(); // HttpUrlConnection redirection does not work with HTTPS and has others flaws @@ -481,7 +481,7 @@ private HttpURLConnection request(String url, String method, String accept, bool String nextUrl = conn.getHeaderField(HttpHeaders.LOCATION); String cookies = conn.getHeaderField("Set-Cookie"); - logger.info("HTTP request (caused by redirect) to " + nextUrl); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, "HTTP request (caused by redirect) to " + nextUrl); if (visited.contains(nextUrl)) { throw new IOException("HTTP redirection loop detected"); @@ -491,7 +491,7 @@ private HttpURLConnection request(String url, String method, String accept, bool conn = createConnection(nextUrl, method, accept); conn.setRequestProperty("Cookie", cookies); - logger.info("FDP HTTP {} request to {} after redirect (response: {})", method, url, conn.getResponseCode()); + projectAudit.reportDebug(EventSource.FDP_CONNECTION, String.format("HTTP %s request to %s (response: %d)", method, url, conn.getResponseCode())); conn.connect(); } } @@ -506,6 +506,16 @@ public static String url(String base, String ... fragment) { return sb.toString(); } + private String readInputStream(InputStream inputStream) throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + return result.toString(CHARSET.name()); + } + public String getBaseURI() { return fdpBaseURI; } diff --git a/src/main/java/solutions/fairdata/openrefine/metadata/model/MetadataOverlayModel.java b/src/main/java/solutions/fairdata/openrefine/metadata/model/MetadataOverlayModel.java index d26aca5..6b2a30a 100644 --- a/src/main/java/solutions/fairdata/openrefine/metadata/model/MetadataOverlayModel.java +++ b/src/main/java/solutions/fairdata/openrefine/metadata/model/MetadataOverlayModel.java @@ -28,6 +28,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import solutions.fairdata.openrefine.metadata.dto.audit.AuditLogDTO; import solutions.fairdata.openrefine.metadata.dto.config.ProjectConfigDTO; @NoArgsConstructor @@ -37,6 +38,7 @@ public class MetadataOverlayModel implements OverlayModel { private ProjectConfigDTO projectData; + private AuditLogDTO projectLog; @Override public void onBeforeSave(Project project) { diff --git a/src/main/resources/module/MOD-INF/controller.js b/src/main/resources/module/MOD-INF/controller.js index 7678df9..37083ff 100644 --- a/src/main/resources/module/MOD-INF/controller.js +++ b/src/main/resources/module/MOD-INF/controller.js @@ -10,6 +10,7 @@ function init() { const MetadataCommands = Packages.solutions.fairdata.openrefine.metadata.commands; // Commands + RefineServlet.registerCommand(module, "audit", new MetadataCommands.AuditCommand()); RefineServlet.registerCommand(module, "settings", new MetadataCommands.SettingsCommand()); RefineServlet.registerCommand(module, "fdp-auth", new MetadataCommands.AuthCommand()); RefineServlet.registerCommand(module, "fdp-dashboard", new MetadataCommands.DashboardCommand()); @@ -36,6 +37,7 @@ function init() { "scripts/metadata-specs.js", "scripts/storages-specs.js", "scripts/dialogs/about-dialog.js", + "scripts/dialogs/audit-dialog.js", "scripts/dialogs/fdp-info-dialog.js", "scripts/dialogs/metadata-form-dialog.js", "scripts/dialogs/post-fdp-dialog.js", @@ -47,6 +49,7 @@ function init() { [ "styles/metadata-common.less", "styles/dialogs/about-dialog.less", + "styles/dialogs/audit-dialog.less", "styles/dialogs/fdp-info-dialog.less", "styles/dialogs/store-data-dialog.less", "styles/dialogs/metadata-form-dialog.less", diff --git a/src/main/resources/module/config/settings.example.yaml b/src/main/resources/module/config/settings.example.yaml index b498011..fa9923f 100644 --- a/src/main/resources/module/config/settings.example.yaml +++ b/src/main/resources/module/config/settings.example.yaml @@ -5,6 +5,11 @@ # Do not set this to "false" when no fdpConnections are specified! allowCustomFDP: true +# - Enable per-project audit log for extension to keep track of various actions +audit: INFO +# - Show audit in OpenRefine front-end dialog +auditShow: true + # - You may pre-configure some metadata to appear prefilled in the metadata forms. # The keys should correspond with metadata form specs metadata: diff --git a/src/main/resources/module/langs/translation-en.json b/src/main/resources/module/langs/translation-en.json index 66641f1..e6f8527 100644 --- a/src/main/resources/module/langs/translation-en.json +++ b/src/main/resources/module/langs/translation-en.json @@ -6,7 +6,6 @@ "menu-bar-extension/bug-report": "Report a bug", "post-fdp-dialog/title": "Create metadata in FAIR Data Point", "post-fdp-dialog/button-connect": "Connect", - "post-fdp-dialog/button-close": "Close", "post-fdp-dialog/label-email": "Email", "post-fdp-dialog/label-password": "Password", "post-fdp-dialog/label-uri": "FAIR Data Point base URI", @@ -159,10 +158,33 @@ "common/select-option": "-- select $1 --", "common/select-option/storage": "-- select storage --", "common/select-option/format": "-- select format --", + "common/button-close": "Close", + "common/button-audit": "Audit", "fdp-info-dialog/name": "Service name", "fdp-info-dialog/version": "Version", "fdp-info-dialog/builtAt": "Built at", "fdp-info-dialog/baseUri": "Base URI", - "fdp-info-dialog/instanceUrl": "Instance URI", - "fdp-info-dialog/unknown": "(unknown)" + "fdp-info-dialog/persistentUrl": "Persistent URL", + "fdp-info-dialog/unknown": "(unknown)", + "audit/title": "Audit log (metadata extension)", + "audit/entries": "entries", + "audit/button-refresh": "Refresh", + "audit/button-clear": "Clear", + "audit/format/JSON": "JSON data", + "audit/format/PLAIN": "Plain text", + "audit/format/TABLE": "Table", + "audit/type/ERROR": "ERROR", + "audit/type/WARNING": "WARNING", + "audit/type/INFO": "INFO", + "audit/type/DEBUG": "DEBUG", + "audit/type/TRACE": "TRACE", + "audit/source/ANY": "any", + "audit/source/FDP_CONNECTION": "FDP connection", + "audit/source/FDP_METADATA": "FDP metadata", + "audit/source/STORAGE": "Storage handling", + "audit/source/SERVICE": "Service tasks", + "audit/source/AUDIT": "Audit logs", + "audit/source/TYPEHINTS": "Typehints queries", + "audit/source/FRONTEND": "OpenRefine client", + "audit/source/SETTINGS": "Settings" } diff --git a/src/main/resources/module/scripts/api-client.js b/src/main/resources/module/scripts/api-client.js index 5fe099c..e9f05ca 100644 --- a/src/main/resources/module/scripts/api-client.js +++ b/src/main/resources/module/scripts/api-client.js @@ -4,6 +4,7 @@ class MetadataApiClient { constructor() { this.fdpUri = null; + this.repositoryUri = null; this.token = null; this.fdpConfig = null; this.fdpInfo = null; @@ -31,6 +32,7 @@ class MetadataApiClient { }), [(result) => { this.fdpUri = result.fdpUri; + this.repositoryUri = result.fdpConfig.persistentUrl; this.token = result.token; this.fdpConfig = result.fdpConfig; this.fdpInfo = result.fdpInfo; @@ -44,9 +46,26 @@ class MetadataApiClient { this._ajaxGeneric("settings","GET", {}, callbacks, []); } + getStorageInfo(callbacks) { + this._ajaxGeneric("store-data", "GET", {}, callbacks, []); + } + postSettings(projectData, callbacks) { - const settingsPostRequest = JSON.stringify({ projectData }); - this._ajaxGeneric("settings","POST", settingsPostRequest, callbacks, [], true); + const settingsPostRequest = JSON.stringify(projectData); + this._ajaxGeneric("settings", "POST", settingsPostRequest, callbacks, [], true); + } + + getAuditLog(callbacks) { + this._ajaxGeneric("audit", "GET", undefined, callbacks, []); + } + + clearAuditLog(callbacks) { + this._ajaxGeneric("audit", "DELETE", null, callbacks, [], true); + } + + postAuditEntry(eventType, message, callbacks) { + const entryData = JSON.stringify({ eventType, message }); + this._ajaxGeneric("audit","POST", entryData, callbacks, [], true); } getDashboard(callbacks, errorCallbacks) { @@ -55,37 +74,25 @@ class MetadataApiClient { } getFDPMetadata(callbacks, errorCallbacks) { - const params = { fdpUri: this.fdpUri }; + const params = { fdpUri: this.fdpUri, repositoryUri: this.repositoryUri, token: this.token }; this._ajaxGeneric("fdp-metadata", "GET", params, callbacks, errorCallbacks); } getCatalogs(callbacks, errorCallbacks) { - const params = { fdpUri: this.fdpUri }; + const params = { fdpUri: this.fdpUri, repositoryUri: this.repositoryUri, token: this.token }; this._ajaxGeneric("catalogs-metadata", "GET", params, callbacks, errorCallbacks); } getDatasets(catalogUri, callbacks, errorCallbacks) { - const params = { fdpUri: this.fdpUri, catalogUri }; + const params = { fdpUri: this.fdpUri, repositoryUri: this.repositoryUri, token: this.token, catalogUri }; this._ajaxGeneric("datasets-metadata", "GET", params, callbacks, errorCallbacks); } getDistributions(datasetUri, callbacks, errorCallbacks) { - const params = { fdpUri: this.fdpUri, datasetUri }; + const params = { fdpUri: this.fdpUri, repositoryUri: this.repositoryUri, token: this.token, datasetUri }; this._ajaxGeneric("distributions-metadata", "GET", params, callbacks, errorCallbacks); } - getCatalogSpec(callbacks, errorCallbacks) { - this.getMetadataSpec("catalog", callbacks, errorCallbacks); - } - - getDatasetSpec(callbacks, errorCallbacks) { - this.getMetadataSpec("dataset", callbacks, errorCallbacks); - } - - getDistributionSpec(callbacks, errorCallbacks) { - this.getMetadataSpec("distribution", callbacks, errorCallbacks); - } - getMetadataSpec(type, callbacks, errorCallbacks) { const params = { fdpUri: this.fdpUri, token: this.token, type }; this._ajaxGeneric("metadata-specs", "GET", params, callbacks, errorCallbacks); diff --git a/src/main/resources/module/scripts/dialogs/about-dialog.html b/src/main/resources/module/scripts/dialogs/about-dialog.html index 5820977..353642a 100644 --- a/src/main/resources/module/scripts/dialogs/about-dialog.html +++ b/src/main/resources/module/scripts/dialogs/about-dialog.html @@ -1,7 +1,8 @@