io.gravitee.rest.api.service.impl.AbstractReferenceMetadataService Maven / Gradle / Ivy
/**
* Copyright (C) 2015 The Gravitee team (http://gravitee.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.gravitee.rest.api.service.impl;
import static io.gravitee.repository.management.model.Audit.AuditProperties.METADATA;
import static io.gravitee.repository.management.model.Audit.AuditProperties.USER;
import static io.gravitee.repository.management.model.Metadata.AuditEvent.*;
import static io.gravitee.rest.api.service.sanitizer.CustomFieldSanitizer.formatKeyValue;
import static java.util.stream.Collectors.toMap;
import io.gravitee.common.util.Maps;
import io.gravitee.common.utils.IdGenerator;
import io.gravitee.repository.exceptions.TechnicalException;
import io.gravitee.repository.management.api.MetadataRepository;
import io.gravitee.repository.management.model.Audit;
import io.gravitee.repository.management.model.Metadata;
import io.gravitee.repository.management.model.MetadataReferenceType;
import io.gravitee.rest.api.model.*;
import io.gravitee.rest.api.model.api.ApiEntity;
import io.gravitee.rest.api.service.ApiService;
import io.gravitee.rest.api.service.ApplicationService;
import io.gravitee.rest.api.service.AuditService;
import io.gravitee.rest.api.service.MetadataService;
import io.gravitee.rest.api.service.exceptions.*;
import java.util.*;
import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author Azize ELAMRANI (azize at graviteesource.com)
* @author GraviteeSource Team
*/
public abstract class AbstractReferenceMetadataService {
private final Logger LOGGER = LoggerFactory.getLogger(io.gravitee.rest.api.service.impl.AbstractReferenceMetadataService.class);
@Autowired
protected MetadataRepository metadataRepository;
@Autowired
private MetadataService metadataService;
@Autowired
private AuditService auditService;
@Autowired
private ApiService apiService;
@Autowired
private ApplicationService applicationService;
protected List findAllByReference(
final MetadataReferenceType referenceType,
final String referenceId,
final boolean withDefaults
) {
try {
LOGGER.debug("Find all metadata by reference {} / {}", referenceType, referenceId);
final List referenceMetadataList = metadataRepository.findByReferenceTypeAndReferenceId(referenceType, referenceId);
Map referenceMetadataMap = referenceMetadataList
.stream()
.map(this::convert)
.peek(m -> m.setValue(m.getValue() == null ? "" : m.getValue()))
.collect(toMap(ReferenceMetadataEntity::getKey, Function.identity()));
final List allMetadata = new ArrayList<>();
if (withDefaults) {
final List defaultMetadataList = metadataService.findAllDefault();
defaultMetadataList.forEach(
defaultMetadata -> {
ReferenceMetadataEntity referenceMetadataEntity = referenceMetadataMap.get(defaultMetadata.getKey());
if (referenceMetadataEntity != null) {
//update the reference metadata in the map
referenceMetadataEntity.setDefaultValue(defaultMetadata.getValue());
} else {
final Optional optReferenceMetadata = referenceMetadataList
.stream()
.filter(referenceMetadata -> defaultMetadata.getKey().equals(referenceMetadata.getKey()))
.findAny();
allMetadata.add(convert(optReferenceMetadata, defaultMetadata));
}
}
);
}
//add all reference metadata
allMetadata.addAll(referenceMetadataMap.values());
return allMetadata;
} catch (TechnicalException ex) {
LOGGER.error("An error occurred while trying to find all metadata by REFERENCE", ex);
throw new TechnicalManagementException("An error occurred while trying to find all metadata by REFERENCE", ex);
}
}
protected ReferenceMetadataEntity findByIdAndReference(
final String metadataId,
final MetadataReferenceType referenceType,
final String referenceId,
final boolean withDefaults
) {
LOGGER.debug("Find metadata by id {} and reference {} / {}", metadataId, referenceType, referenceId);
final List allMetadata = findAllByReference(referenceType, referenceId, withDefaults);
final Optional optMetadata = allMetadata.stream().filter(m -> metadataId.equals(m.getKey())).findAny();
if (optMetadata.isPresent()) {
final ReferenceMetadataEntity metadata = optMetadata.get();
if (metadata.getValue() == null) {
metadata.setValue(metadata.getDefaultValue());
}
return metadata;
} else {
if (referenceType.equals(MetadataReferenceType.APPLICATION)) {
throw new ApplicationMetadataNotFoundException(referenceId, metadataId);
} else {
throw new ApiMetadataNotFoundException(referenceId, metadataId);
}
}
}
protected void delete(final String metadataId, final MetadataReferenceType referenceType, final String referenceId) {
LOGGER.debug("Delete metadata by id {} and reference {} / {}", metadataId, referenceType, referenceId);
try {
// prevent deletion of a metadata not in the given reference
final Optional optMetadata = metadataRepository.findById(metadataId, referenceId, referenceType);
if (optMetadata.isPresent()) {
metadataRepository.delete(metadataId, referenceId, referenceType);
// Audit
createReferenceAuditLog(referenceType, referenceId, optMetadata.get(), null, METADATA_DELETED);
} else {
if (referenceType.equals(MetadataReferenceType.APPLICATION)) {
throw new ApplicationMetadataNotFoundException(referenceId, metadataId);
} else if (referenceType.equals(MetadataReferenceType.API)) {
throw new ApiMetadataNotFoundException(referenceId, metadataId);
} else {
throw new MetadataNotFoundException(metadataId);
}
}
} catch (TechnicalException ex) {
final String message = "An error occurs while trying to delete metadata " + metadataId;
LOGGER.error(message, ex);
throw new TechnicalManagementException(message, ex);
}
}
protected ReferenceMetadataEntity create(
final NewReferenceMetadataEntity metadataEntity,
final MetadataReferenceType referenceType,
final String referenceId,
final boolean withDefaults
) {
// if no format defined, we just set String format
if (metadataEntity.getFormat() == null) {
metadataEntity.setFormat(MetadataFormat.STRING);
}
checkReferenceMetadataFormat(metadataEntity.getFormat(), metadataEntity.getValue(), referenceType, referenceId);
// First we prevent the duplicate metadata name
final Optional optionalMetadata = findAllByReference(referenceType, referenceId, withDefaults)
.stream()
.filter(metadata -> metadataEntity.getName().equalsIgnoreCase(metadata.getName()))
.findAny();
if (optionalMetadata.isPresent()) {
throw new DuplicateMetadataNameException(optionalMetadata.get().getName());
}
try {
final Metadata metadata = convertForReference(metadataEntity, referenceType, referenceId);
final Date now = new Date();
metadata.setCreatedAt(now);
metadata.setUpdatedAt(now);
metadataRepository.create(metadata);
// Audit
createReferenceAuditLog(referenceType, referenceId, null, metadata, METADATA_CREATED);
return convert(metadata);
} catch (TechnicalException ex) {
final String message =
"An error occurred while trying to create metadata " + metadataEntity.getName() + " on reference " + referenceId;
LOGGER.error(message, ex);
throw new TechnicalManagementException(message, ex);
}
}
private void checkReferenceMetadataFormat(
MetadataFormat format,
String value,
MetadataReferenceType referenceType,
String referenceId
) {
switch (referenceType) {
case API:
final ApiEntity apiEntity = apiService.findById(referenceId);
metadataService.checkMetadataFormat(format, value, referenceType, apiEntity);
break;
case APPLICATION:
final ApplicationEntity applicationEntity = applicationService.findById(referenceId);
metadataService.checkMetadataFormat(format, value, referenceType, applicationEntity);
break;
case USER:
// do nothing for User, currently on String is used without templating
break;
}
}
private void createReferenceAuditLog(
MetadataReferenceType referenceType,
String referenceId,
Metadata oldMetadata,
Metadata metadata,
Metadata.AuditEvent auditEvent
) {
final String key = metadata == null ? oldMetadata.getKey() : metadata.getKey();
final Date updatedAt = metadata == null ? oldMetadata.getUpdatedAt() : metadata.getUpdatedAt();
switch (referenceType) {
case API:
auditService.createApiAuditLog(
referenceId,
Collections.singletonMap(METADATA, key),
auditEvent,
updatedAt,
oldMetadata,
metadata
);
break;
case APPLICATION:
auditService.createApplicationAuditLog(
referenceId,
Collections.singletonMap(METADATA, key),
auditEvent,
updatedAt,
oldMetadata,
metadata
);
break;
case USER:
auditService.createOrganizationAuditLog(
Maps.builder().put(USER, referenceId).put(METADATA, key).build(),
auditEvent,
updatedAt,
oldMetadata,
metadata
);
break;
}
}
protected ReferenceMetadataEntity update(
final UpdateReferenceMetadataEntity metadataEntity,
final MetadataReferenceType referenceType,
final String referenceId,
final boolean withDefaults
) {
checkReferenceMetadataFormat(metadataEntity.getFormat(), metadataEntity.getValue(), referenceType, referenceId);
try {
final Optional referenceMetadata = metadataRepository.findById(metadataEntity.getKey(), referenceId, referenceType);
final Metadata savedMetadata;
final Metadata metadata = convertForReference(metadataEntity, referenceType, referenceId);
final Date now = new Date();
if (referenceMetadata.isPresent()) {
metadata.setUpdatedAt(now);
savedMetadata = metadataRepository.update(metadata);
// Audit
createReferenceAuditLog(referenceType, referenceId, referenceMetadata.get(), metadata, METADATA_UPDATED);
} else {
metadata.setCreatedAt(now);
metadata.setUpdatedAt(now);
savedMetadata = metadataRepository.create(metadata);
// Audit
createReferenceAuditLog(referenceType, referenceId, null, metadata, METADATA_CREATED);
}
final ReferenceMetadataEntity referenceMetadataEntity = convert(savedMetadata);
if (withDefaults) {
final List defaultMetatata = metadataService.findAllDefault();
final Optional optDefaultMetadata = defaultMetatata
.stream()
.filter(m -> m.getKey().equals(metadataEntity.getKey()))
.findAny();
optDefaultMetadata.ifPresent(defaultMetadata -> referenceMetadataEntity.setDefaultValue(defaultMetadata.getValue()));
}
return referenceMetadataEntity;
} catch (TechnicalException ex) {
LOGGER.error("An error occurred while trying to update metadata {} on REFERENCE {}", metadataEntity.getName(), referenceId, ex);
throw new TechnicalManagementException(
"An error occurred while trying to update metadata " + metadataEntity.getName() + " on REFERENCE " + referenceId,
ex
);
}
}
private ReferenceMetadataEntity convert(final Optional optMetadata, final MetadataEntity defaultMetadata) {
final Metadata metadata;
if (optMetadata.isPresent()) {
metadata = optMetadata.get();
} else {
metadata = convert(defaultMetadata);
metadata.setValue(null);
}
final ReferenceMetadataEntity referenceMetadataEntity = convert(metadata);
referenceMetadataEntity.setDefaultValue(defaultMetadata.getValue());
return referenceMetadataEntity;
}
private ReferenceMetadataEntity convert(final Metadata metadata) {
final ReferenceMetadataEntity referenceMetadataEntity = new ReferenceMetadataEntity();
referenceMetadataEntity.setValue(metadata.getValue());
referenceMetadataEntity.setKey(metadata.getKey());
referenceMetadataEntity.setName(metadata.getName());
referenceMetadataEntity.setFormat(MetadataFormat.valueOf(metadata.getFormat().name()));
return referenceMetadataEntity;
}
private Metadata convert(final MetadataEntity metadataEntity) {
final Metadata metadata = new Metadata();
metadata.setKey(metadataEntity.getKey());
metadata.setName(metadataEntity.getName());
metadata.setFormat(io.gravitee.repository.management.model.MetadataFormat.valueOf(metadataEntity.getFormat().name()));
if (metadataEntity.getValue() != null) {
if (MetadataFormat.DATE.equals(metadataEntity.getFormat())) {
metadata.setValue(metadataEntity.getValue().substring(0, 10));
} else {
metadata.setValue(metadataEntity.getValue());
}
}
return metadata;
}
private Metadata convertForReference(
final NewReferenceMetadataEntity metadataEntity,
final MetadataReferenceType referenceType,
final String referenceId
) {
final Metadata metadata = new Metadata();
if (referenceType.equals(MetadataReferenceType.USER)) {
metadata.setKey(formatKeyValue(metadataEntity.getName()));
} else {
metadata.setKey(IdGenerator.generate(metadataEntity.getName()));
}
metadata.setName(metadataEntity.getName());
metadata.setFormat(io.gravitee.repository.management.model.MetadataFormat.valueOf(metadataEntity.getFormat().name()));
if (metadataEntity.getValue() != null) {
if (MetadataFormat.DATE.equals(metadataEntity.getFormat())) {
metadata.setValue(metadataEntity.getValue().substring(0, 10));
} else {
metadata.setValue(metadataEntity.getValue());
}
}
metadata.setReferenceId(referenceId);
metadata.setReferenceType(referenceType);
return metadata;
}
private Metadata convertForReference(
final UpdateReferenceMetadataEntity metadataEntity,
final MetadataReferenceType referenceType,
final String referenceId
) {
final Metadata metadata = new Metadata();
metadata.setKey(metadataEntity.getKey());
metadata.setName(metadataEntity.getName());
metadata.setFormat(io.gravitee.repository.management.model.MetadataFormat.valueOf(metadataEntity.getFormat().name()));
if (metadataEntity.getValue() != null) {
if (MetadataFormat.DATE.equals(metadataEntity.getFormat())) {
metadata.setValue(metadataEntity.getValue().substring(0, 10));
} else {
metadata.setValue(metadataEntity.getValue());
}
}
metadata.setReferenceId(referenceId);
metadata.setReferenceType(referenceType);
return metadata;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy