Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Sofia Papacharalampous 2024-04-11 17:46:58 +03:00
commit 928babb9d5
18 changed files with 457 additions and 135 deletions

View File

@ -114,6 +114,7 @@ public class AuditableAction {
public static final EventId StorageFile_Download = new EventId(14000, "StorageFile_Download");
public static final EventId StorageFile_Upload = new EventId(14001, "StorageFile_Upload");
public static final EventId StorageFile_Query = new EventId(14002, "StorageFile_Query");
public static final EventId Dashboard_MyRecentActivityItems = new EventId(15000, "Dashboard_MyRecentActivityItems");
public static final EventId Dashboard_MyDashboardStatistics = new EventId(15001, "Dashboard_MyDashboardStatistics");

View File

@ -1,4 +1,4 @@
package eu.eudat.types;
package eu.eudat.commons.metrics;
public class MetricNames {
public static final String DATASET_TEMPLATE = "argos_dmp_templates";

View File

@ -3,6 +3,7 @@ package eu.eudat.model.builder.descriptionpropertiesdefinition;
import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.commons.enums.FieldType;
import eu.eudat.commons.types.description.FieldEntity;
import eu.eudat.commons.types.descriptiontemplate.fielddata.LabelAndMultiplicityDataEntity;
import eu.eudat.commons.types.descriptiontemplate.fielddata.SelectDataEntity;
import eu.eudat.convention.ConventionService;
import eu.eudat.model.Reference;
@ -72,12 +73,16 @@ public class FieldBuilder extends BaseBuilder<Field, FieldEntity> {
if (fields.hasField(this.asIndexer(Field._dateValue)) && FieldType.isDateType(fieldType)) m.setDateValue(d.getDateValue());
if (fields.hasField(this.asIndexer(Field._textValue)) && FieldType.isTextType(fieldType)) m.setTextValue(d.getTextValue());
if (fields.hasField(this.asIndexer(Field._textListValue)) && FieldType.isTextListType(fieldType)) {
boolean isSelectMultiSelect = true;
if(this.fieldEntity != null && this.fieldEntity.getData() != null && this.fieldEntity.getData().getFieldType().equals(FieldType.SELECT) && this.fieldEntity.getData() instanceof SelectDataEntity){
isSelectMultiSelect = ((SelectDataEntity) this.fieldEntity.getData()).getMultipleSelect();
}
if (fieldType.equals(FieldType.SELECT) && !isSelectMultiSelect && !this.conventionService.isListNullOrEmpty(d.getTextListValue())){
m.setTextValue(d.getTextListValue().stream().findFirst().orElse(null));
boolean isMultiSelect = true;
if(this.fieldEntity != null && this.fieldEntity.getData() != null && (this.fieldEntity.getData().getFieldType().equals(FieldType.SELECT) || this.fieldEntity.getData().getFieldType().equals(FieldType.INTERNAL_ENTRIES_DMPS) || this.fieldEntity.getData().getFieldType().equals(FieldType.INTERNAL_ENTRIES_DESCRIPTIONS))){
if (this.fieldEntity.getData() instanceof SelectDataEntity) isMultiSelect = ((SelectDataEntity) this.fieldEntity.getData()).getMultipleSelect();
else if (this.fieldEntity.getData() instanceof LabelAndMultiplicityDataEntity) isMultiSelect = ((LabelAndMultiplicityDataEntity) this.fieldEntity.getData()).getMultipleSelect();
if (!isMultiSelect && !this.conventionService.isListNullOrEmpty(d.getTextListValue())){
m.setTextValue(d.getTextListValue().stream().findFirst().orElse(null));
}else{
m.setTextListValue(d.getTextListValue());
}
} else{
m.setTextListValue(d.getTextListValue());
}

View File

@ -516,22 +516,38 @@ public class DescriptionServiceImpl implements DescriptionService {
}
}
else if (FieldType.isTextListType(fieldType)) {
if (FieldType.INTERNAL_ENTRIES_DMPS.equals(fieldType) && !this.conventionService.isListNullOrEmpty(persist.getTextListValue())){
List<UUID> ids = persist.getTextListValue().stream().map(UUID::fromString).toList();
Set<UUID> existingIds = this.queryFactory.query(DmpQuery.class).ids(ids).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(Dmp._id)).stream().map(DmpEntity::getId).collect(Collectors.toSet());
for (UUID id : ids){
if (!existingIds.contains(id)) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale()));
List<UUID> ids = new ArrayList<>();
if (FieldType.INTERNAL_ENTRIES_DMPS.equals(fieldType)) {
if (!this.conventionService.isListNullOrEmpty(persist.getTextListValue())) persist.getTextListValue().stream().map(UUID::fromString).toList();
else if (!this.conventionService.isNullOrEmpty(persist.getTextValue())) ids.add(UUID.fromString(persist.getTextValue()));
if (ids.size() > 0){
Set<UUID> existingIds = this.queryFactory.query(DmpQuery.class).ids(ids).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(Dmp._id)).stream().map(DmpEntity::getId).collect(Collectors.toSet());
for (UUID id : ids){
if (!existingIds.contains(id)) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale()));
}
}
} if (FieldType.INTERNAL_ENTRIES_DESCRIPTIONS.equals(fieldType) && !this.conventionService.isListNullOrEmpty(persist.getTextListValue())){
List<UUID> ids = persist.getTextListValue().stream().map(UUID::fromString).toList();
Set<UUID> existingIds = this.queryFactory.query(DescriptionQuery.class).ids(ids).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(Description._id)).stream().map(DescriptionEntity::getId).collect(Collectors.toSet());
for (UUID id : ids){
if (!existingIds.contains(id)) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Description.class.getSimpleName()}, LocaleContextHolder.getLocale()));
} if (FieldType.INTERNAL_ENTRIES_DESCRIPTIONS.equals(fieldType)){
if ( !this.conventionService.isListNullOrEmpty(persist.getTextListValue())) ids = persist.getTextListValue().stream().map(UUID::fromString).toList();
else if (!this.conventionService.isNullOrEmpty(persist.getTextValue())) ids.add(UUID.fromString(persist.getTextValue()));
if (ids.size() > 0) {
Set<UUID> existingIds = this.queryFactory.query(DescriptionQuery.class).ids(ids).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(Description._id)).stream().map(DescriptionEntity::getId).collect(Collectors.toSet());
for (UUID id : ids){
if (!existingIds.contains(id)) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Description.class.getSimpleName()}, LocaleContextHolder.getLocale()));
}
}
}
if (!ids.isEmpty()){
if (ids.size() > 1) data.setTextListValue(persist.getTextListValue());
else data.setTextListValue(List.of(persist.getTextValue()));
}else{
data.setTextListValue(persist.getTextListValue());
}
if (fieldType.equals(FieldType.SELECT) && this.conventionService.isListNullOrEmpty(persist.getTextListValue()) && !this.conventionService.isNullOrEmpty(persist.getTextValue())){
data.setTextListValue(List.of(persist.getTextValue()));
} else{
} else if (fieldType.equals(FieldType.SELECT) || fieldType.equals(FieldType.TAGS)){
data.setTextListValue(persist.getTextListValue());
}
}

View File

@ -0,0 +1,11 @@
package eu.eudat.service.metrics;
import io.prometheus.client.Gauge;
import javax.management.InvalidApplicationException;
import java.util.Map;
public interface MetricsService {
void calculate(Map<String, Gauge> gauges) throws InvalidApplicationException;
Map<String, Gauge> gaugesBuild();
}

View File

@ -0,0 +1,92 @@
package eu.eudat.service.metrics;
import eu.eudat.commons.enums.DmpStatus;
import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.metrics.MetricNames;
import eu.eudat.data.TenantEntityManager;
import eu.eudat.query.DmpQuery;
import gr.cite.tools.data.query.QueryFactory;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.Gauge;
import org.springframework.stereotype.Service;
import javax.management.InvalidApplicationException;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
public class MetricsServiceImpl implements MetricsService {
private final PrometheusMeterRegistry registry;
private final QueryFactory queryFactory;
private final TenantEntityManager entityManager;
public MetricsServiceImpl(PrometheusMeterRegistry registry, QueryFactory queryFactory, TenantEntityManager entityManager) {
this.registry = registry;
this.queryFactory = queryFactory;
this.entityManager = entityManager;
}
@Override
public void calculate(Map<String, Gauge> gauges) throws InvalidApplicationException {
try {
this.entityManager.disableTenantFilters();
this.setGauseValue(gauges, MetricNames.DMP, calculateFinalizedDmps(), MetricNames.FINALIZED);
}finally {
this.entityManager.enableTenantFilters();
}
}
@Override
public Map<String, Gauge> gaugesBuild() {
registry.clear();
return Stream.of( new Object[][]{
{MetricNames.DMP, Gauge.build().name(MetricNames.DMP).help("Number of managed DMPs").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.DMP, Gauge.build().name(MetricNames.NEXUS + MetricNames.DMP).help("Number of managed DMPs during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.FUNDERS, Gauge.build().name(MetricNames.FUNDERS).help("Number of registered Funders").register(registry.getPrometheusRegistry())},
{MetricNames.GRANTS, Gauge.build().name(MetricNames.GRANTS).help("Number of registered Grants").register(registry.getPrometheusRegistry())},
{MetricNames.PROJECT, Gauge.build().name(MetricNames.PROJECT).help("Number of registered Projects").register(registry.getPrometheusRegistry())},
{MetricNames.RESEARCHER, Gauge.build().name(MetricNames.RESEARCHER).help("Number of Colaborators/Researchers").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.FUNDERS, Gauge.build().name(MetricNames.NEXUS + MetricNames.FUNDERS).help("Number of registered Funders during Nexus").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.GRANTS, Gauge.build().name(MetricNames.NEXUS + MetricNames.GRANTS).help("Number of registered Grants during Nexus").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.PROJECT, Gauge.build().name(MetricNames.NEXUS + MetricNames.PROJECT).help("Number of registered Projects during Nexus").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.RESEARCHER, Gauge.build().name(MetricNames.NEXUS + MetricNames.RESEARCHER).help("Number of Colaborators/Researchers during Nexus").register(registry.getPrometheusRegistry())},
{MetricNames.DATASET, Gauge.build().name(MetricNames.DATASET).help("Number of managed Dataset Descriptions").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.DATASET, Gauge.build().name(MetricNames.NEXUS + MetricNames.DATASET).help("Number of managed Dataset Descriptions during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.DATASET_TEMPLATE, Gauge.build().name(MetricNames.DATASET_TEMPLATE).help("Number of dataset Templates").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.DATASET_TEMPLATE, Gauge.build().name(MetricNames.NEXUS + MetricNames.DATASET_TEMPLATE).help("Number of dataset Templates during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.USERS, Gauge.build().name(MetricNames.USERS).help("Number of users").labelNames("type").register(registry.getPrometheusRegistry())},
{MetricNames.LANGUAGES, Gauge.build().name(MetricNames.LANGUAGES).help("Number of Languages").register(registry.getPrometheusRegistry())},
{MetricNames.DMP_WITH_GRANT, Gauge.build().name(MetricNames.DMP_WITH_GRANT).help("Number of Grants based on the status of the DMP that is using them").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.DMP_WITH_GRANT, Gauge.build().name(MetricNames.NEXUS + MetricNames.DMP_WITH_GRANT).help("Number of Grants based on the status of the DMP that is using them during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.INSTALLATIONS, Gauge.build().name(MetricNames.INSTALLATIONS).help("Number of Installations").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.INSTALLATIONS, Gauge.build().name(MetricNames.NEXUS + MetricNames.INSTALLATIONS).help("Number of Installations").register(registry.getPrometheusRegistry())},
}).collect(Collectors.toMap(data -> (String)data[0], data -> (Gauge) data[1]));
}
private double calculateFinalizedDmps(){
return this.queryFactory.query(DmpQuery.class).statuses(DmpStatus.Finalized).isActive(IsActive.Active).count();
}
private void setGauseValue(Map<String, Gauge> gauges, String name, Double amount, String label) {
if(label != null) {
gauges.get(name).labels(label).set(amount);
} else {
gauges.get(name).set(amount);
}
}
}

View File

@ -0,0 +1,130 @@
package eu.eudat.service.metrics;
import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.fake.FakeRequestScope;
import eu.eudat.commons.metrics.MetricNames;
import eu.eudat.commons.scope.tenant.TenantScope;
import eu.eudat.data.QueueInboxEntity;
import eu.eudat.data.StorageFileEntity;
import eu.eudat.data.TenantEntity;
import eu.eudat.data.TenantEntityManager;
import eu.eudat.integrationevent.inbox.EventProcessingStatus;
import eu.eudat.model.StorageFile;
import eu.eudat.model.Tenant;
import eu.eudat.query.QueueInboxQuery;
import eu.eudat.query.StorageFileQuery;
import eu.eudat.query.TenantQuery;
import eu.eudat.service.storage.StorageFileService;
import gr.cite.queueinbox.entity.QueueInboxStatus;
import gr.cite.queueinbox.repository.CandidateInfo;
import gr.cite.tools.data.query.Ordering;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.logging.LoggerService;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.Gauge;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.OptimisticLockException;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.io.Closeable;
import java.io.IOException;
import java.time.Instant;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class UpdateMetricsTask implements Closeable, ApplicationListener<ApplicationReadyEvent> {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UpdateMetricsTask.class));
private final UpdateMetricsTaskProperties _config;
private final ApplicationContext applicationContext;
private ScheduledExecutorService scheduler;
private Map<String, Gauge> gauges;
public UpdateMetricsTask(
UpdateMetricsTaskProperties config,
ApplicationContext applicationContext) {
this._config = config;
this.applicationContext = applicationContext;
this.gauges = null;
}
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
long intervalSeconds = this._config .getIntervalSeconds();
if (this._config .getEnable() && intervalSeconds > 0) {
logger.info("File clean up run in {} seconds", intervalSeconds);
scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(this::process, 10, intervalSeconds, TimeUnit.SECONDS);
} else {
scheduler = null;
}
}
@Override
public void close() throws IOException {
if (scheduler != null) this.scheduler.close();
}
protected void process() {
if (!this._config.getEnable()) return;
try {
this.ensureGauges();
this.calculate();
} catch (Exception ex) {
logger.error("Problem processing file cleanups. Breaking for next interval", ex);
}
}
private void ensureGauges() {
if (this.gauges != null) return;
try (FakeRequestScope ignored = new FakeRequestScope()) {
MetricsService metricsService = this.applicationContext.getBean(MetricsService.class);
this.gauges = metricsService.gaugesBuild();
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
}
}
private void calculate() {
EntityManager entityManager = null;
try (FakeRequestScope ignored = new FakeRequestScope()) {
try {
EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class);
entityManager = entityManagerFactory.createEntityManager();
TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class);
tenantEntityManager.setEntityManager(entityManager);
TenantScope tenantScope = this.applicationContext.getBean(TenantScope.class);
tenantScope.setTenant(null, tenantScope.getDefaultTenantCode());
MetricsService metricsService = this.applicationContext.getBean(MetricsService.class);
metricsService.calculate(this.gauges);
} finally {
if (entityManager != null) entityManager.close();
}
} catch (Exception ex) {
logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex);
}
}
}

View File

@ -0,0 +1,9 @@
package eu.eudat.service.metrics;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(UpdateMetricsTaskProperties.class)
public class UpdateMetricsTaskConfiguration {
}

View File

@ -0,0 +1,27 @@
package eu.eudat.service.metrics;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "metrics.task")
public class UpdateMetricsTaskProperties {
private boolean enable;
private int intervalSeconds;
public boolean getEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public int getIntervalSeconds() {
return intervalSeconds;
}
public void setIntervalSeconds(int intervalSeconds) {
this.intervalSeconds = intervalSeconds;
}
}

View File

@ -1,23 +1,27 @@
package eu.eudat.controllers;
import eu.eudat.audit.AuditableAction;
import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.authorization.Permission;
import eu.eudat.commons.enums.StorageType;
import eu.eudat.commons.scope.user.UserScope;
import eu.eudat.convention.ConventionService;
import eu.eudat.data.StorageFileEntity;
import eu.eudat.model.StorageFile;
import eu.eudat.model.builder.StorageFileBuilder;
import eu.eudat.model.persist.StorageFilePersist;
import eu.eudat.query.StorageFileQuery;
import eu.eudat.service.storage.StorageFileProperties;
import eu.eudat.service.storage.StorageFileService;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.auditing.AuditService;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.exception.MyForbiddenException;
import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidatorFactory;
@ -25,8 +29,8 @@ import org.apache.commons.io.FilenameUtils;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
@ -45,6 +49,7 @@ public class StorageFileController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(StorageFileController.class));
private final AuditService auditService;
private final QueryFactory queryFactory;
private final BuilderFactory builderFactory;
private final MessageSource messageSource;
private final StorageFileService storageFileService;
private final StorageFileProperties config;
@ -55,13 +60,14 @@ public class StorageFileController {
public StorageFileController(
AuditService auditService,
QueryFactory queryFactory,
MessageSource messageSource,
BuilderFactory builderFactory, MessageSource messageSource,
StorageFileService storageFileService,
StorageFileProperties config,
UserScope userScope,
AuthorizationService authorizationService, ConventionService conventionService, ValidatorFactory validatorFactory) {
this.auditService = auditService;
this.queryFactory = queryFactory;
this.builderFactory = builderFactory;
this.messageSource = messageSource;
this.storageFileService = storageFileService;
this.config = config;
@ -71,21 +77,23 @@ public class StorageFileController {
this.validatorFactory = validatorFactory;
}
@GetMapping("/name/{id}")
public String getName(@PathVariable("id") UUID id) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("get name" ).And("id", id));
@GetMapping("{id}")
public StorageFile get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("retrieving " + StorageFile.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.authorizationService.authorizeForce(Permission.BrowseStorageFile);
StorageFileEntity storageFile = this.queryFactory.query(StorageFileQuery.class).ids(id).firstAs(new BaseFieldSet().ensure(StorageFile._fullName));
if (storageFile == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, StorageFile.class.getSimpleName()}, LocaleContextHolder.getLocale()));
StorageFileQuery query = this.queryFactory.query(StorageFileQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).ids(id);
StorageFile model = this.builderFactory.builder(StorageFileBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(fieldSet, query.firstAs(fieldSet));
if (model == null)
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, StorageFile.class.getSimpleName()}, LocaleContextHolder.getLocale()));
this.auditService.track(AuditableAction.StorageFile_Download, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("id", id)
this.auditService.track(AuditableAction.StorageFile_Query, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("id", id),
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
));
return storageFile.getName();
return model;
}
@ -115,8 +123,8 @@ public class StorageFileController {
return addedFiles;
}
@GetMapping("{id}")
public ResponseEntity<ByteArrayResource> get(@PathVariable("id") UUID id) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
@GetMapping("download/{id}")
public ResponseEntity<byte[]> get(@PathVariable("id") UUID id) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("download" ).And("id", id));
this.authorizationService.authorizeForce(Permission.BrowseStorageFile);
@ -134,10 +142,14 @@ public class StorageFileController {
String contentType = storageFile.getMimeType();
if (this.conventionService.isNullOrEmpty(contentType)) contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
return ResponseEntity.ok()
.contentType(MediaType.valueOf(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + storageFile.getName() + (storageFile.getExtension().startsWith(".") ? "" : ".") + storageFile.getExtension() + "\"")
.body(new ByteArrayResource(file));
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentLength(file.length);
responseHeaders.setContentType(MediaType.valueOf(contentType));
responseHeaders.set("Content-Disposition", "attachment; filename=\"" + storageFile.getName() + (storageFile.getExtension().startsWith(".") ? "" : ".") + storageFile.getExtension() + "\"");
responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition");
responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type");
return new ResponseEntity<>(file, responseHeaders, HttpStatus.OK);
}
}

View File

@ -1,7 +1,7 @@
package eu.eudat.logic.managers;
import eu.eudat.commons.enums.DescriptionTemplateStatus;
import eu.eudat.types.MetricNames;
import eu.eudat.commons.metrics.MetricNames;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.Gauge;
import jakarta.annotation.PostConstruct;
@ -75,37 +75,37 @@ public class MetricsManager {
public MetricsManager(PrometheusMeterRegistry registry) {
registry.clear();
this.gauges = Stream.of( new Object[][]{
{MetricNames.DMP, Gauge.build().name(MetricNames.DMP).help("Number of managed DMPs").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.DMP, Gauge.build().name(MetricNames.NEXUS + MetricNames.DMP).help("Number of managed DMPs during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.FUNDERS, Gauge.build().name(MetricNames.FUNDERS).help("Number of registered Funders").register(registry.getPrometheusRegistry())},
{MetricNames.GRANTS, Gauge.build().name(MetricNames.GRANTS).help("Number of registered Grants").register(registry.getPrometheusRegistry())},
{MetricNames.PROJECT, Gauge.build().name(MetricNames.PROJECT).help("Number of registered Projects").register(registry.getPrometheusRegistry())},
{MetricNames.RESEARCHER, Gauge.build().name(MetricNames.RESEARCHER).help("Number of Colaborators/Researchers").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.FUNDERS, Gauge.build().name(MetricNames.NEXUS + MetricNames.FUNDERS).help("Number of registered Funders during Nexus").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.GRANTS, Gauge.build().name(MetricNames.NEXUS + MetricNames.GRANTS).help("Number of registered Grants during Nexus").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.PROJECT, Gauge.build().name(MetricNames.NEXUS + MetricNames.PROJECT).help("Number of registered Projects during Nexus").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.RESEARCHER, Gauge.build().name(MetricNames.NEXUS + MetricNames.RESEARCHER).help("Number of Colaborators/Researchers during Nexus").register(registry.getPrometheusRegistry())},
{MetricNames.DATASET, Gauge.build().name(MetricNames.DATASET).help("Number of managed Dataset Descriptions").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.DATASET, Gauge.build().name(MetricNames.NEXUS + MetricNames.DATASET).help("Number of managed Dataset Descriptions during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.DATASET_TEMPLATE, Gauge.build().name(MetricNames.DATASET_TEMPLATE).help("Number of dataset Templates").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.DATASET_TEMPLATE, Gauge.build().name(MetricNames.NEXUS + MetricNames.DATASET_TEMPLATE).help("Number of dataset Templates during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.USERS, Gauge.build().name(MetricNames.USERS).help("Number of users").labelNames("type").register(registry.getPrometheusRegistry())},
{MetricNames.LANGUAGES, Gauge.build().name(MetricNames.LANGUAGES).help("Number of Languages").register(registry.getPrometheusRegistry())},
{MetricNames.DMP_WITH_GRANT, Gauge.build().name(MetricNames.DMP_WITH_GRANT).help("Number of Grants based on the status of the DMP that is using them").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.DMP_WITH_GRANT, Gauge.build().name(MetricNames.NEXUS + MetricNames.DMP_WITH_GRANT).help("Number of Grants based on the status of the DMP that is using them during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
{MetricNames.INSTALLATIONS, Gauge.build().name(MetricNames.INSTALLATIONS).help("Number of Installations").register(registry.getPrometheusRegistry())},
{MetricNames.NEXUS + MetricNames.INSTALLATIONS, Gauge.build().name(MetricNames.NEXUS + MetricNames.INSTALLATIONS).help("Number of Installations").register(registry.getPrometheusRegistry())},
// {MetricNames.DMP, Gauge.build().name(MetricNames.DMP).help("Number of managed DMPs").labelNames("status").register(registry.getPrometheusRegistry())},
// {MetricNames.NEXUS + MetricNames.DMP, Gauge.build().name(MetricNames.NEXUS + MetricNames.DMP).help("Number of managed DMPs during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
//
// {MetricNames.FUNDERS, Gauge.build().name(MetricNames.FUNDERS).help("Number of registered Funders").register(registry.getPrometheusRegistry())},
// {MetricNames.GRANTS, Gauge.build().name(MetricNames.GRANTS).help("Number of registered Grants").register(registry.getPrometheusRegistry())},
// {MetricNames.PROJECT, Gauge.build().name(MetricNames.PROJECT).help("Number of registered Projects").register(registry.getPrometheusRegistry())},
// {MetricNames.RESEARCHER, Gauge.build().name(MetricNames.RESEARCHER).help("Number of Colaborators/Researchers").register(registry.getPrometheusRegistry())},
//
// {MetricNames.NEXUS + MetricNames.FUNDERS, Gauge.build().name(MetricNames.NEXUS + MetricNames.FUNDERS).help("Number of registered Funders during Nexus").register(registry.getPrometheusRegistry())},
// {MetricNames.NEXUS + MetricNames.GRANTS, Gauge.build().name(MetricNames.NEXUS + MetricNames.GRANTS).help("Number of registered Grants during Nexus").register(registry.getPrometheusRegistry())},
// {MetricNames.NEXUS + MetricNames.PROJECT, Gauge.build().name(MetricNames.NEXUS + MetricNames.PROJECT).help("Number of registered Projects during Nexus").register(registry.getPrometheusRegistry())},
// {MetricNames.NEXUS + MetricNames.RESEARCHER, Gauge.build().name(MetricNames.NEXUS + MetricNames.RESEARCHER).help("Number of Colaborators/Researchers during Nexus").register(registry.getPrometheusRegistry())},
//
// {MetricNames.DATASET, Gauge.build().name(MetricNames.DATASET).help("Number of managed Dataset Descriptions").labelNames("status").register(registry.getPrometheusRegistry())},
//
// {MetricNames.NEXUS + MetricNames.DATASET, Gauge.build().name(MetricNames.NEXUS + MetricNames.DATASET).help("Number of managed Dataset Descriptions during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
//
// {MetricNames.DATASET_TEMPLATE, Gauge.build().name(MetricNames.DATASET_TEMPLATE).help("Number of dataset Templates").labelNames("status").register(registry.getPrometheusRegistry())},
//
// {MetricNames.NEXUS + MetricNames.DATASET_TEMPLATE, Gauge.build().name(MetricNames.NEXUS + MetricNames.DATASET_TEMPLATE).help("Number of dataset Templates during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
//
// {MetricNames.USERS, Gauge.build().name(MetricNames.USERS).help("Number of users").labelNames("type").register(registry.getPrometheusRegistry())},
//
// {MetricNames.LANGUAGES, Gauge.build().name(MetricNames.LANGUAGES).help("Number of Languages").register(registry.getPrometheusRegistry())},
//
// {MetricNames.DMP_WITH_GRANT, Gauge.build().name(MetricNames.DMP_WITH_GRANT).help("Number of Grants based on the status of the DMP that is using them").labelNames("status").register(registry.getPrometheusRegistry())},
//
// {MetricNames.NEXUS + MetricNames.DMP_WITH_GRANT, Gauge.build().name(MetricNames.NEXUS + MetricNames.DMP_WITH_GRANT).help("Number of Grants based on the status of the DMP that is using them during Nexus").labelNames("status").register(registry.getPrometheusRegistry())},
//
// {MetricNames.INSTALLATIONS, Gauge.build().name(MetricNames.INSTALLATIONS).help("Number of Installations").register(registry.getPrometheusRegistry())},
// {MetricNames.NEXUS + MetricNames.INSTALLATIONS, Gauge.build().name(MetricNames.NEXUS + MetricNames.INSTALLATIONS).help("Number of Installations").register(registry.getPrometheusRegistry())},
}).collect(Collectors.toMap(data -> (String)data[0], data -> (Gauge) data[1]));

View File

@ -32,6 +32,7 @@ spring:
optional:classpath:config/dashboard.yml[.yml], optional:classpath:config/dashboard-${spring.profiles.active}.yml[.yml], optional:file:../config/dashboard-${spring.profiles.active}.yml[.yml],
optional:classpath:config/transformer.yml[.yml], optional:classpath:config/transformer-${spring.profiles.active}.yml[.yml], optional:file:../config/transformer-${spring.profiles.active}.yml[.yml],
optional:classpath:config/authorization.yml[.yml], optional:classpath:config/authorization-${spring.profiles.active}.yml[.yml], optional:file:../config/authorization-${spring.profiles.active}.yml[.yml],
optional:classpath:config/metrics.yml[.yml], optional:classpath:config/metrics-${spring.profiles.active}.yml[.yml], optional:file:../config/metrics-${spring.profiles.active}.yml[.yml],
optional:classpath:config/lock.yml[.yml], optional:classpath:config/lock-${spring.profiles.active}.yml[.yml], optional:file:../config/lock-${spring.profiles.active}.yml[.yml]

View File

@ -0,0 +1,30 @@
metrics:
task:
enable: true
intervalSeconds: 600
management:
endpoint:
metrics:
enabled: true
prometheus:
enabled: true
health:
show-details: always
web:
base-path: /
exposure:
include: ["prometheus","health","metrics" ]
metrics:
enabled: true
export:
prometheus:
enabled: true
enable:
http: true
jvm: true
jdbc: true
tomcat: true
logback: true
hikaricp: true
cache: true

View File

@ -2,7 +2,7 @@ web:
security:
enabled: true
authorized-endpoints: [ api ]
allowed-endpoints: [ api/public, api/dmp/public, api/description/public, /api/supportive-material/public, api/language/public, api/contact-support/public, api/dashboard/public ]
allowed-endpoints: [ api/public, api/dmp/public, api/description/public, /api/supportive-material/public, api/language/public, api/contact-support/public, api/dashboard/public, prometheus, health, metrics ]
idp:
api-key:
enabled: false

View File

@ -21,20 +21,25 @@ export class StorageFileService {
private get apiBase(): string { return `${this.configurationService.server}storage-file`; }
getName(id: Guid ): Observable<string> {
const url = `${this.apiBase}/name/${id}`;
getSingle(id: Guid, reqFields: string[] = []): Observable<StorageFile> {
const url = `${this.apiBase}/${id}`;
const options = { params: { f: reqFields } };
return this.http
.get<string>(url).pipe(
.get<StorageFile>(url, options).pipe(
catchError((error: any) => throwError(error)));
}
download(id: Guid ): Observable<HttpResponse<Blob>> {
const url = `${this.apiBase}/${id}`;
const url = `${this.apiBase}/download/${id}`;
const params = new BaseHttpParams();
params.interceptorContext = {
excludedInterceptors: [InterceptorType.JSONContentType, InterceptorType.ResponsePayload]
};
return this.http
.get<HttpResponse<Blob>>(url).pipe(
catchError((error: any) => throwError(error)));
.get(url, {params: params, responeType: 'blob', observe: 'response'});
}
uploadTempFiles(item: File): Observable<StorageFile[]> {

View File

@ -178,8 +178,8 @@
<app-description-template-editor-external-datasets-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.EXTERNAL_DATASETS" class="col-12" [form]="form"></app-description-template-editor-external-datasets-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DMPS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-label-and-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DMPS" class="col-12" [form]="form"></app-description-template-editor-label-and-multiplicity-field-component>
<app-description-template-editor-label-and-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS" class="col-12" [form]="form"></app-description-template-editor-label-and-multiplicity-field-component>
</div>
</ng-container>

View File

@ -47,13 +47,13 @@
<div class="row">
<mat-form-field class="col-md-12">
<ng-container *ngIf="field.data.multipleSelect">
<app-multiple-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" [configuration]="multipleAutoCompleteConfiguration">
<app-multiple-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" [configuration]="descriptionService.multipleAutocompleteConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</ng-container>
<ng-container *ngIf="!(field.data.multipleSelect)">
<app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="singleAutoCompleteConfiguration" [required]="isRequired">
<app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="descriptionService.singleAutocompleteConfiguration" [required]="isRequired">
</app-single-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
@ -62,17 +62,17 @@
</mat-form-field>
</div>
</div>
<div *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_DMP_ENTRIES_DMPS" class="col-12">
<div *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DMPS" class="col-12">
<div class="row">
<mat-form-field class="col-md-12">
<ng-container *ngIf="field.data.multipleSelect">
<app-multiple-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" [configuration]="multipleAutoCompleteConfiguration">
<app-multiple-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" [configuration]="dmpService.multipleAutocompleteConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textListValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</ng-container>
<ng-container *ngIf="!(field.data.multipleSelect)">
<app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="singleAutoCompleteConfiguration" [required]="isRequired">
<app-single-auto-complete placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" [configuration]="dmpService.singleAutocompleteConfiguration" [required]="isRequired">
</app-single-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('backendError')">{{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}}</mat-error>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
@ -107,9 +107,9 @@
</ng-container>
<ng-container *ngSwitchCase="descriptionTemplateFieldTypeEnum.UPLOAD">
<div class="col-12 d-flex justify-content-center">
<ngx-dropzone #drop class="drop-file col-12" (change)="fileChangeEvent($event, true)" [multiple]="false" [accept]="typesToString()" [disabled]="propertiesFormGroup?.get(field.id).get('textValue').disabled">
<ngx-dropzone-preview *ngIf="propertiesFormGroup?.get(field.id).get('textValue').value && fileNameDisplay" class="file-preview" [removable]="true" (removed)="onRemove()">
<ngx-dropzone-label class="file-label">{{ fileNameDisplay}}</ngx-dropzone-label>
<ngx-dropzone class="drop-file col-12" (change)="fileChangeEvent($event, true)" [multiple]="false" [accept]="typesToString()" [disabled]="propertiesFormGroup?.get(field.id).get('textValue').disabled">
<ngx-dropzone-preview *ngIf="propertiesFormGroup?.get(field.id).get('textValue').value" class="file-preview" [removable]="true" (removed)="onRemove()">
<ngx-dropzone-label class="file-label">{{ fileNameDisplay }}</ngx-dropzone-label>
</ngx-dropzone-preview>
</ngx-dropzone>
</div>
@ -157,7 +157,7 @@
<div *ngSwitchCase="descriptionTemplateFieldTypeEnum.TAGS" class="col-12">
<div class="row">
<mat-form-field class="col-md-12">
<app-multiple-auto-complete [configuration]="tagsAutoCompleteConfiguration" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" placeholder="{{('DATASET-EDITOR.FIELDS.TAGS' | translate) + (isRequired? ' *': '')}}"></app-multiple-auto-complete>
<app-multiple-auto-complete [configuration]="tagService.multipleAutocompleteConfiguration" [formControl]="propertiesFormGroup?.get(field.id).get('textListValue')" placeholder="{{ (field.data.label | translate) + (isRequired? ' *': '') }}"></app-multiple-auto-complete>
<mat-error *ngIf="propertiesFormGroup?.get(field.id).get('textListValue').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>

View File

@ -6,10 +6,13 @@ import { MatDialog } from "@angular/material/dialog";
import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type';
import { DescriptionTemplateFieldValidationType } from '@app/core/common/enum/description-template-field-validation-type';
import { DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelAndMultiplicityData, DescriptionTemplateUploadData } from '@app/core/model/description-template/description-template';
import { StorageFile } from '@app/core/model/storage-file/storage-file';
import { DescriptionService } from '@app/core/services/description/description.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { SnackBarNotificationLevel, UiNotificationService } from "@app/core/services/notification/ui-notification-service";
import { ReferenceService } from '@app/core/services/reference/reference.service';
import { StorageFileService } from '@app/core/services/storage-file/storage-file.service';
import { TagService } from '@app/core/services/tag/tag.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
@ -21,6 +24,7 @@ import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver';
import { Observable } from 'rxjs';
import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
@Component({
selector: 'app-description-form-field',
@ -70,11 +74,13 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
];
filesToUpload: FileList;
fileNameDisplay: string;
fileNameDisplay: string = null;
constructor(
private language: TranslateService,
private dmpService: DmpService,
public dmpService: DmpService,
public descriptionService: DescriptionService,
public tagService: TagService,
private cdr: ChangeDetectorRef,
private uiNotificationService: UiNotificationService,
public dialog: MatDialog,
@ -92,8 +98,24 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
ngOnInit() {
if(this.field?.data?.fieldType == DescriptionTemplateFieldType.UPLOAD && this.field && this.field.id && (this.propertiesFormGroup?.get(this.field.id).get('textValue').value != undefined)) this.getUploadFileName();
if(this.field?.data?.fieldType == DescriptionTemplateFieldType.UPLOAD && this.field && this.field.id && (this.propertiesFormGroup?.get(this.field.id).get('textValue').value != undefined) && !this.fileNameDisplay) {
const id = Guid.parse((this.propertiesFormGroup?.get(this.field.id).get('textValue').value as string));
const fields = [
nameof<StorageFile>(x => x.id),
nameof<StorageFile>(x => x.name),
]
this.storageFileService.getSingle(id, fields).pipe(takeUntil(this._destroyed)).subscribe(storageFile => {
this.fileNameDisplay = storageFile.name;
this.applyFieldType();
});
} else {
this.applyFieldType();
}
}
private applyFieldType(){
this.isRequired = this.field.validations?.includes(DescriptionTemplateFieldValidationType.Required);
switch (this.field?.data?.fieldType) {
@ -140,12 +162,6 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
// this.form.disable();
// }
break;
case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DESCRIPTIONS:
this.makeAutocompleteConfiguration(this.searchDatasets.bind(this), "label");
break;
case DescriptionTemplateFieldType.INTERNAL_ENTRIES_DMPS:
this.makeAutocompleteConfiguration(this.searchDmps.bind(this), "label");
break;
}
// this.form = this.visibilityRulesService.getFormGroup(this.field.id);
@ -161,28 +177,6 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
});
}
searchDatasets(query: string) {
//TODO refactor
return null;
// let fields: Array<string> = new Array();
// const datasetsAutocompleteRequestItem: DataTableRequest<DatasetCriteria> = new DataTableRequest(0, 25, { fields: fields });
// datasetsAutocompleteRequestItem.criteria = new DatasetCriteria();
// datasetsAutocompleteRequestItem.criteria.like = query;
// //TODO: refactor this
// // return this.datasetService.getPaged(datasetsAutocompleteRequestItem).pipe(map(item => item.data));
// return null;
}
searchDmps(query: string) {
//TODO refactor
return null;
// let fields: Array<string> = new Array();
// const dmpsAutocompleteRequestItem: DataTableRequest<DmpCriteria> = new DataTableRequest(0, 25, { fields: fields });
// dmpsAutocompleteRequestItem.criteria = new DmpCriteria();
// dmpsAutocompleteRequestItem.criteria.like = query;
// return this.dmpService.getPaged(dmpsAutocompleteRequestItem).pipe(map(item => item.data));
}
makeAutocompleteConfiguration(myfunc: Function, title: string, subtitle?: string): void {
if (!((this.field.data as DescriptionTemplateLabelAndMultiplicityData).multipleSelect)) {
this.singleAutoCompleteConfiguration = {
@ -275,16 +269,6 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
}
private getUploadFileName(){
const id = Guid.parse((this.propertiesFormGroup?.get(this.field.id).get('textValue').value as string));
this.storageFileService.getName(id)
.pipe(takeUntil(this._destroyed)).subscribe((name) => {
this.fileNameDisplay = name;
}, error => {
this.fileNameDisplay = null;
})
}
public upload() {
this.storageFileService.uploadTempFiles(this.filesToUpload[0])
@ -364,13 +348,12 @@ export class DescriptionFormFieldComponent extends BaseComponent implements OnIn
if (this.propertiesFormGroup?.get(this.field.id).get('textValue').value) {
const id = Guid.parse((this.propertiesFormGroup?.get(this.field.id).get('textValue').value as string));
this.storageFileService.download(id).subscribe((response) => {
const blob = new Blob([response.body]);
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
}, error => {
this.onCallbackUploadFail(error.error);
})
this.storageFileService.download(id).pipe(takeUntil(this._destroyed))
.subscribe(response => {
const blob = new Blob([response.body]);
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
});
}
}