Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#3303 PID registration #3360

Merged
merged 13 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ angular.module('metadatamanagementApp').config([
'dara': 'Dara',
'messageBroker': 'Message Broker (für Websockets)',
'rabbit': 'RabbitMQ',
'seo4Ajax': 'Seo4Ajax (Prerender as a Service)'
'seo4Ajax': 'Seo4Ajax (Prerender as a Service)',
'pid': 'PID'
},
'table': {
'service': 'Servicename',
Expand All @@ -45,6 +46,9 @@ angular.module('metadatamanagementApp').config([
'update': 'Aktualisieren',
'update-success': 'DARA erfolgreich aktualisiert',
'update-failure': 'Es sind Fehler beim Aktualisieren von DARA aufgetreten! (Siehe Details)'
},
'pid': {
'download': 'Daten herunterladen'
}
},
'logs': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ angular.module('metadatamanagementApp').config([
'dara': 'Dara',
'messageBroker': 'Message Broker (for Websockets)',
'rabbit': 'RabbitMQ',
'seo4Ajax': 'Seo4Ajax (Prerender as a Service)'
'seo4Ajax': 'Seo4Ajax (Prerender as a Service)',
'pid': 'PID'
},
'table': {
'service': 'Service name',
Expand All @@ -45,6 +46,9 @@ angular.module('metadatamanagementApp').config([
'update': 'Update',
'update-success': 'DARA update successful',
'update-failure': 'Errors occurred during DARA update! (see details)'
},
'pid': {
'download': 'Download data'
}
},
'logs': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ angular.module('metadatamanagementApp').controller('HealthController', [
'BreadcrumbService',
'SimpleMessageToastService',
'DaraReleaseCustomResource',
'ExportAllVariablesResource',
function($scope, MonitoringService, $uibModal, ElasticSearchAdminService,
PageMetadataService, $state, BreadcrumbService, SimpleMessageToastService, DaraReleaseCustomResource) {
PageMetadataService, $state, BreadcrumbService, SimpleMessageToastService, DaraReleaseCustomResource, ExportAllVariablesResource) {
PageMetadataService.setPageTitle('administration.health.title');
$scope.isRecreatingIndices = false;
$scope.updatingHealth = true;
Expand Down Expand Up @@ -70,6 +71,24 @@ angular.module('metadatamanagementApp').controller('HealthController', [
});
}

/**
* Method to download all variable metadata as needed for PID registration.
* Data will be downloaded as a JSON file.
*/
$scope.downloadPidData = function() {
$scope.isDownloadingData = true;
ExportAllVariablesResource.exportAll().then(function(res) {
var blob = new Blob([angular.toJson(res, true)],{
type: "application/json;charset=utf-8;"
});
var downloadLink = document.createElement('a');
downloadLink.setAttribute('download', 'variable_pid_mdm_export.json');
downloadLink.setAttribute('href', window.URL.createObjectURL(blob));
downloadLink.click();
$scope.isDownloadingData = false;
})
}

$scope.refresh();

$scope.getLabelClass = function(statusState) {
Expand Down
12 changes: 12 additions & 0 deletions mdm-frontend/src/app/legacy/administration/health/health.html.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@
</a>
</td>
</tr>
<tr>
<td>{{'administration.health.indicator.pid' | translate}}</td>
<td class="text-center">
<button class="btn btn-danger btn-xs" data-translate="administration.health.pid.download"
ng-click="downloadPidData()" ng-disabled="isDownloadingData" type="button">
</button>
</td>
<td class="text-center">
</td>
<td class="text-center">
</td>
</tr>
</tbody>
</table>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ angular.module('metadatamanagementApp').config([
'variable-has-invalid-data-set-id': 'Die Variable {{id}} referenziert auf einen unbekannten Datensatz ({{toBereferenzedId}}).',
'variable-has-invalid-question-id': 'Die Variable {{id}} referenziert auf einen unbekannte Frage ({{toBereferenzedId}}).',
'variable-survey-ids-are-not-consistent-with-data-set': 'Die Variable {{id}} referenziert auf andere Erhebungen als ihr Datensatz {{toBereferenzedId}}.'
},
'pid': {
'pattern': 'Der angegebene Wert stimmt nicht mit dem benötigten Format der PID überein.',
'size': 'Der angegebene Wert darf nicht länger als 512 Zeichen sein.'
}
},
'edit': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ angular.module('metadatamanagementApp').config([
'variable-has-invalid-data-set-id': 'The Variable {{id}} references to an unknown Data Set ({{toBereferenzedId}}).',
'variable-has-invalid-question-id': 'The Variable {{id}} references to an unknown Question ({{toBereferenzedId}}).',
'variable-survey-ids-are-not-consistent-with-data-set': 'The Variable {{id}} references different surveys than its Data Set {{toBereferenzedId}}.'
},
'pid': {
'pattern': 'The provided value does not match the PID pattern.',
'size': 'The provided value must not contain more than 512 characters.'
}
},
'edit': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,21 @@ angular.module('metadatamanagementApp')
});
}]);

/**
* Method to request the endpoint that downloads all variables as a PID-formatted json file.
* The response is a list (List<String>) of variable metadata.
* We could not put this into the "VariableResource"-schema (above), because the URLs would not match.
*/
angular.module('metadatamanagementApp').factory('ExportAllVariablesResource', ['$http',
function($http) {
return {
exportAll: function() {
return $http.post('/api/variables/exportAll').then(function(response) {
return response.data;
var blob = new Blob([ response.data ], { type : 'application/json' });
return blob; //{ blob: response.data, filename: "filename.json" };
});
}
}
}]);

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public interface Patterns {
String GERMAN_ALPHANUMERIC_WITH_UNDERSCORE_AND_MINUS_AND_DOT = "^[_A-Za-z0-9äöüÄÖÜß\\-\\.]*$";

String DOI = "^https:\\/\\/doi.org\\/([_A-Za-z0-9äöüÄÖÜß\\-\\/\\:.]{1,}$)";
String PID = "^21\\.T11998\\/dzhw:([_A-Za-z0-9äöüÄÖÜß\\-\\/\\:.]{1,}$)";
String GERMAN_ALPHANUMERIC_WITH_UNDERSCORE_AND_MINUS_AND_DOT_AND_DOLLAR =
"^[_A-Za-z0-9äöüÄÖÜß\\-\\.\\$]*$";
String NO_WHITESPACE = "^[^\\s]*$";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {

/**
* The id of the variable which uniquely identifies the variable in this application.
*
*
* The id must not be empty and must be of the form
* var-{{dataAcquisitionProjectId}}-ds{{dataSetNumber}}-{{name}}$. The id must not contain more
* than 512 characters.
Expand All @@ -134,9 +134,22 @@ public class Variable extends AbstractShadowableRdcDomainObject {
@Indexed
private String masterId;

/**
* The PID of the variable.
*
* Must not contain more than 512 characters.
*
* Must match the pattern of a PID "21.T11998/dzhw:{DataPackageID}_{VariableID}:{version}
*/
@Size(max = StringLengths.MEDIUM, message = "variable-management.error.pid.size")
@Pattern(
message = "variable-management.error.pid.pattern",
regexp = Patterns.PID)
private String pid;

/**
* The id of the {@link DataAcquisitionProject} to which this variable belongs.
*
*
* The dataAcquisitionProjectId must not be empty.
*/
@Indexed
Expand All @@ -145,7 +158,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {

/**
* The name of the variable as it is used in the {@link DataSet}.
*
*
* It must not be empty and must be unique in the {@link DataSet}. It must contain only
* alphanumeric (english) characters and "_". The first character must not be a number. It must
* not contain more than 32 characters.
Expand All @@ -158,7 +171,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {

/**
* The label of the variable should describe its content.
*
*
* It must be specified in at least one language and it must not contain more than 512 characters.
*/
@NotNull(message = "variable-management.error.variable.label.not-null")
Expand All @@ -169,7 +182,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {

/**
* Arbitrary additional text for this variable. Markdown is supported.
*
*
* Must not contain more than 2048 characters.
*/
@I18nStringSize(max = StringLengths.LARGE,
Expand All @@ -178,7 +191,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {

/**
* The id of the {@link DataSet} to which this variable belongs.
*
*
* Must not be empty.
*/
@Indexed
Expand All @@ -187,15 +200,15 @@ public class Variable extends AbstractShadowableRdcDomainObject {

/**
* The number of the {@link DataSet} to which this variable belongs.
*
*
* Must not be empty.
*/
@NotNull(message = "variable-management.error.variable.data-set-number-not-null")
private Integer dataSetNumber;

/**
* The technical type which the {@link ValidResponse}s have.
*
*
* Must be one of {@link DataTypes} and must not be empty.
*/
@NotNull(message = "variable-management.error.variable.data-type.not-null")
Expand All @@ -205,7 +218,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {
/**
* Associated with each data type is a storage type. For instance numerics can be stored as
* integer or double.
*
*
* Must be one of {@link StorageTypes} and must not be empty.
*/
@NotNull(message = "variable-management.error.variable.storage-type.not-null")
Expand All @@ -216,7 +229,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {
* The scale level (or level of measurement) classifies the nature of information within the
* values assigned to this variable ({@link ValidResponse}s). It determines which mathematical
* operations can be performed with the values.
*
*
* It must be one of {@link ScaleLevels} and must not be empty. If the data type of this variable
* is {@link DataTypes#DATE} then the ScaleLevel must be {@link ScaleLevels#ORDINAL},
* {@link ScaleLevels#INTERVAL} or {@link ScaleLevels#NOMINAL}.
Expand All @@ -228,7 +241,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {
/**
* The access way of this variable. Depends on the sensitivity of the data and describes how the
* data user will be able to work with the data.
*
*
* Must not be empty and be one of {@link AccessWays}.
*/
// checks for min size too.
Expand All @@ -245,7 +258,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {
/**
* The index in the {@link DataSet} of this variable. Used for sorting the variables of this
* {@link DataSet} and for displaying successors and predecessors of this variable.
*
*
* Must not be empty and the successor of this variable must have indexInDataSet incremented by
* one.
*/
Expand All @@ -254,7 +267,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {

/**
* List of numbers of {@link Survey}s which have been conducted to create this variable.
*
*
* Must not be empty.
*/
@NotEmpty(message = "variable-management.error.variable.survey-numbers-not-empty")
Expand All @@ -263,7 +276,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {
/**
* Identifier used to group variables within this {@link DataSet} which measure the same across
* multiple waves.
*
*
* Must be of the form {{dataAcquisitionProjectId}}-ds{{dataSetNumber}}-{{string}}$. Must not
* contain more than 512 characters and must contain only (german) alphanumeric characters and "_"
* and "-".
Expand All @@ -277,7 +290,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {
/**
* Identifier used to group variables within this {@link DataSet} which have been derived from
* each other. For instance one variable might be an aggregated version of the other.
*
*
* Must be of the form {{dataAcquisitionProjectId}}-ds{{dataSetNumber}}-{{string}}$. Must not
* contain more than 512 characters and must contain only (german) alphanumeric characters and "_"
* and "-".
Expand Down Expand Up @@ -333,7 +346,7 @@ public class Variable extends AbstractShadowableRdcDomainObject {

/**
* List of ids of {@link Survey}s which have been conducted to create this variable.
*
*
* Must not be empty.
*/
@Indexed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package eu.dzhw.fdz.metadatamanagement.variablemanagement.rest;

import java.io.IOException;

import javax.persistence.PersistenceException;

import eu.dzhw.fdz.metadatamanagement.usermanagement.security.AuthoritiesConstants;
import eu.dzhw.fdz.metadatamanagement.variablemanagement.service.VariableManagementService;
import lombok.RequiredArgsConstructor;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* Controller for exporting all variables for PID registration.
*/
@Controller
@RequestMapping("/api")
@RequiredArgsConstructor
public class ExportAllVariablesResourceController {

private final VariableManagementService variablesManagementService;

/**
* export all variables for PID registration.
*
* @return a JSON file
*/
@PostMapping(value = "/variables/exportAll", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
@Secured(value = {AuthoritiesConstants.ADMIN})
public ResponseEntity<?> exportAllVariables() {
ResponseEntity<?> response = new ResponseEntity<>(null, null, HttpStatus.NOT_FOUND);
try {
response = this.variablesManagementService.exportVariablesAsJson();
} catch (PersistenceException | IOException ex) {
return response;
}

return response;
}


}
Loading
Loading