JpaDistributionSet#metadata made Map (#2411)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -26,7 +26,6 @@ import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusBuilder;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupBuilder;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaSoftwareModuleTypeBuilder;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaTagBuilder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.MetaData;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@@ -71,11 +70,6 @@ public class JpaEntityFactory implements EntityFactory {
|
||||
return distributionSetBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetaData generateDsMetadata(final String key, final String value) {
|
||||
return new JpaDistributionSetMetadata(key, value == null ? null : value.strip());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoftwareModuleMetadataBuilder softwareModuleMetadata() {
|
||||
return softwareModuleMetadataBuilder;
|
||||
|
||||
@@ -119,7 +119,6 @@ import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHol
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionStatusRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetMetadataRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetTagRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetTypeRepository;
|
||||
@@ -536,7 +535,6 @@ public class RepositoryApplicationConfiguration {
|
||||
final DistributionSetRepository distributionSetRepository,
|
||||
final DistributionSetTagManagement distributionSetTagManagement, final SystemManagement systemManagement,
|
||||
final DistributionSetTypeManagement distributionSetTypeManagement, final QuotaManagement quotaManagement,
|
||||
final DistributionSetMetadataRepository distributionSetMetadataRepository,
|
||||
final TargetRepository targetRepository,
|
||||
final TargetFilterQueryRepository targetFilterQueryRepository, final ActionRepository actionRepository,
|
||||
final SystemSecurityContext systemSecurityContext, final TenantConfigurationManagement tenantConfigurationManagement,
|
||||
@@ -544,7 +542,7 @@ public class RepositoryApplicationConfiguration {
|
||||
final DistributionSetTagRepository distributionSetTagRepository,
|
||||
final JpaProperties properties, final RepositoryProperties repositoryProperties) {
|
||||
return new JpaDistributionSetManagement(entityManager, distributionSetRepository, distributionSetTagManagement,
|
||||
systemManagement, distributionSetTypeManagement, quotaManagement, distributionSetMetadataRepository,
|
||||
systemManagement, distributionSetTypeManagement, quotaManagement,
|
||||
targetRepository, targetFilterQueryRepository, actionRepository,
|
||||
TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement),
|
||||
virtualPropertyReplacer, softwareModuleRepository, distributionSetTagRepository,
|
||||
|
||||
@@ -12,9 +12,9 @@ package org.eclipse.hawkbit.repository.jpa.management;
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.IMPLICIT_LOCK_ENABLED;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -24,11 +24,15 @@ import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.MapJoin;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import jakarta.persistence.metamodel.MapAttribute;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.repository.DistributionSetFields;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetMetadataFields;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
|
||||
import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||
@@ -49,14 +53,10 @@ import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaDistributionSetCreate;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity_;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.DsMetadataCompositeKey;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata_;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetMetadataRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetTagRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.SoftwareModuleRepository;
|
||||
@@ -69,10 +69,8 @@ import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.MetaData;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Statistic;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||
@@ -103,7 +101,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
private final SystemManagement systemManagement;
|
||||
private final DistributionSetTypeManagement distributionSetTypeManagement;
|
||||
private final QuotaManagement quotaManagement;
|
||||
private final DistributionSetMetadataRepository distributionSetMetadataRepository;
|
||||
private final TargetRepository targetRepository;
|
||||
private final TargetFilterQueryRepository targetFilterQueryRepository;
|
||||
private final ActionRepository actionRepository;
|
||||
@@ -120,7 +117,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
final DistributionSetRepository distributionSetRepository,
|
||||
final DistributionSetTagManagement distributionSetTagManagement, final SystemManagement systemManagement,
|
||||
final DistributionSetTypeManagement distributionSetTypeManagement, final QuotaManagement quotaManagement,
|
||||
final DistributionSetMetadataRepository distributionSetMetadataRepository,
|
||||
final TargetRepository targetRepository,
|
||||
final TargetFilterQueryRepository targetFilterQueryRepository, final ActionRepository actionRepository,
|
||||
final TenantConfigHelper tenantConfigHelper,
|
||||
@@ -135,7 +131,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
this.systemManagement = systemManagement;
|
||||
this.distributionSetTypeManagement = distributionSetTypeManagement;
|
||||
this.quotaManagement = quotaManagement;
|
||||
this.distributionSetMetadataRepository = distributionSetMetadataRepository;
|
||||
this.targetRepository = targetRepository;
|
||||
this.targetFilterQueryRepository = targetFilterQueryRepository;
|
||||
this.actionRepository = actionRepository;
|
||||
@@ -360,21 +355,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
|
||||
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public DistributionSetMetadata updateMetaData(final long id, final MetaData md) {
|
||||
// check if exists otherwise throw entity not found exception
|
||||
final JpaDistributionSetMetadata toUpdate = (JpaDistributionSetMetadata) findMetaDataByDistributionSetId(id, md.getKey())
|
||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSetMetadata.class, id, md.getKey()));
|
||||
toUpdate.setValue(md.getValue());
|
||||
|
||||
// touch it to update the lock revision because we are modifying the DS indirectly, it will, also check UPDATE access
|
||||
JpaManagementHelper.touch(entityManager, distributionSetRepository, (JpaDistributionSet) getValid(id));
|
||||
return distributionSetMetadataRepository.save(toUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
|
||||
@@ -394,34 +374,60 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
@Transactional
|
||||
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
|
||||
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public List<DistributionSetMetadata> putMetaData(final long id, final Collection<MetaData> md) {
|
||||
public void createMetadata(final long id, final Map<String, String> md) {
|
||||
final JpaDistributionSet distributionSet = (JpaDistributionSet) getValid(id);
|
||||
assertMetaDataQuota(id, md.size());
|
||||
|
||||
md.forEach(meta -> checkAndThrowIfDistributionSetMetadataAlreadyExists(
|
||||
new DsMetadataCompositeKey(id, meta.getKey())));
|
||||
// get the modifiable metadata map
|
||||
final Map<String, String> metadata = distributionSet.getMetadata();
|
||||
md.keySet().forEach(key -> {
|
||||
if (metadata.containsKey(key)) {
|
||||
throw new EntityAlreadyExistsException("Metadata entry with key '" + key + "' already exists");
|
||||
}
|
||||
});
|
||||
metadata.putAll(md);
|
||||
|
||||
JpaManagementHelper.touch(entityManager, distributionSetRepository, distributionSet);
|
||||
assertMetaDataQuota(id, metadata.size());
|
||||
|
||||
return md.stream()
|
||||
.map(meta -> distributionSetMetadataRepository
|
||||
.save(new JpaDistributionSetMetadata(meta.getKey(), distributionSet, meta.getValue())))
|
||||
.collect(Collectors.toUnmodifiableList());
|
||||
distributionSetRepository.save(distributionSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMetadata(final long id) {
|
||||
assertDistributionSetExists(id);
|
||||
return getMap(id, JpaDistributionSet_.metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
|
||||
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public void deleteMetaData(final long id, final String key) {
|
||||
final JpaDistributionSetMetadata metadata = (JpaDistributionSetMetadata) findMetaDataByDistributionSetId(
|
||||
id, key)
|
||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSetMetadata.class, id, key));
|
||||
public void updateMetadata(final long id, final String key, final String value) {
|
||||
final JpaDistributionSet distributionSet = (JpaDistributionSet) getValid(id);
|
||||
|
||||
// touch it to update the lock revision because we are modifying the
|
||||
// DS indirectly, it will, also check UPDATE access
|
||||
JpaManagementHelper.touch(entityManager, distributionSetRepository, metadata.getDistributionSet());
|
||||
distributionSetMetadataRepository.deleteById(metadata.getId());
|
||||
// get the modifiable metadata map
|
||||
final Map<String, String> metadata = distributionSet.getMetadata();
|
||||
if (!metadata.containsKey(key)) {
|
||||
throw new EntityNotFoundException("DistributionSet metadata", id + ":" + key);
|
||||
}
|
||||
metadata.put(key, value);
|
||||
|
||||
distributionSetRepository.save(distributionSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
|
||||
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public void deleteMetadata(final long id, final String key) {
|
||||
final JpaDistributionSet distributionSet = (JpaDistributionSet) getValid(id);
|
||||
|
||||
// get the modifiable metadata map
|
||||
final Map<String, String> metadata = distributionSet.getMetadata();
|
||||
if (metadata.remove(key) == null) {
|
||||
throw new EntityNotFoundException("DistributionSet metadata", id + ":" + key);
|
||||
}
|
||||
|
||||
distributionSetRepository.save(distributionSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -504,33 +510,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
return distributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<DistributionSetMetadata> findMetaDataByDistributionSetId(final long id, final Pageable pageable) {
|
||||
assertDistributionSetExists(id);
|
||||
|
||||
return JpaManagementHelper.findAllWithCountBySpec(distributionSetMetadataRepository, Collections.singletonList(byDsIdSpec(id)), pageable
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countMetaDataByDistributionSetId(final long id) {
|
||||
assertDistributionSetExists(id);
|
||||
|
||||
return distributionSetMetadataRepository.countByDistributionSetId(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<DistributionSetMetadata> findMetaDataByDistributionSetIdAndRsql(final long id, final String rsqlParam,
|
||||
final Pageable pageable) {
|
||||
assertDistributionSetExists(id);
|
||||
|
||||
final List<Specification<JpaDistributionSetMetadata>> specList = Arrays
|
||||
.asList(RSQLUtility.buildRsqlSpecification(rsqlParam, DistributionSetMetadataFields.class,
|
||||
virtualPropertyReplacer, database), byDsIdSpec(id));
|
||||
|
||||
return JpaManagementHelper.findAllWithCountBySpec(distributionSetMetadataRepository, specList, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slice<DistributionSet> findByCompleted(final Pageable pageReq, final Boolean complete) {
|
||||
final List<Specification<JpaDistributionSet>> specifications = buildSpecsByComplete(complete);
|
||||
@@ -577,15 +556,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
DistributionSetSpecification.hasTag(tagId), DistributionSetSpecification.isNotDeleted()), pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<DistributionSetMetadata> findMetaDataByDistributionSetId(final long id, final String key) {
|
||||
assertDistributionSetExists(id);
|
||||
|
||||
return distributionSetMetadataRepository
|
||||
.findById(new DsMetadataCompositeKey(id, key))
|
||||
.map(DistributionSetMetadata.class::cast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countByTypeId(final long typeId) {
|
||||
if (!distributionSetTypeManagement.exists(typeId)) {
|
||||
@@ -732,6 +702,24 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> getMap(final long id, final MapAttribute<JpaDistributionSet, String, String> mapAttribute) {
|
||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
|
||||
|
||||
final Root<JpaDistributionSet> targetRoot = query.from(JpaDistributionSet.class);
|
||||
query.where(cb.equal(targetRoot.get(AbstractJpaBaseEntity_.ID), id));
|
||||
|
||||
final MapJoin<JpaDistributionSet, String, String> mapJoin = targetRoot.join(mapAttribute);
|
||||
query.multiselect(mapJoin.key(), mapJoin.value());
|
||||
query.orderBy(cb.asc(mapJoin.key()));
|
||||
|
||||
return entityManager
|
||||
.createQuery(query)
|
||||
.getResultList()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(entry -> (String) entry[0], entry -> (String) entry[1], (v1, v2) -> v1, LinkedHashMap::new));
|
||||
}
|
||||
|
||||
private JpaSoftwareModule findSoftwareModuleAndThrowExceptionIfNotFound(final Long softwareModuleId) {
|
||||
return softwareModuleRepository.findById(softwareModuleId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
||||
@@ -754,9 +742,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
}
|
||||
|
||||
private void assertMetaDataQuota(final Long dsId, final int requested) {
|
||||
QuotaHelper.assertAssignmentQuota(dsId, requested, quotaManagement.getMaxMetaDataEntriesPerDistributionSet(),
|
||||
DistributionSetMetadata.class, DistributionSet.class,
|
||||
distributionSetMetadataRepository::countByDistributionSetId);
|
||||
final int limit = quotaManagement.getMaxMetaDataEntriesPerDistributionSet();
|
||||
QuotaHelper.assertAssignmentQuota(dsId, requested, limit, "Metadata", DistributionSet.class.getSimpleName(), null);
|
||||
}
|
||||
|
||||
private void assertSoftwareModuleQuota(final Long id, final int requested) {
|
||||
@@ -764,11 +751,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
SoftwareModule.class, DistributionSet.class, softwareModuleRepository::countByAssignedToId);
|
||||
}
|
||||
|
||||
private Specification<JpaDistributionSetMetadata> byDsIdSpec(final long dsId) {
|
||||
return (root, query, cb) -> cb
|
||||
.equal(root.get(JpaDistributionSetMetadata_.distributionSet).get(AbstractJpaBaseEntity_.id), dsId);
|
||||
}
|
||||
|
||||
private void assertDistributionSetIsNotAssignedToTargets(final Long distributionSet) {
|
||||
if (actionRepository.countByDistributionSetId(distributionSet) > 0) {
|
||||
throw new EntityReadOnlyException(String.format(
|
||||
@@ -776,13 +758,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAndThrowIfDistributionSetMetadataAlreadyExists(final DsMetadataCompositeKey metadataId) {
|
||||
if (distributionSetMetadataRepository.existsById(metadataId)) {
|
||||
throw new EntityAlreadyExistsException(
|
||||
"Metadata entry with key '" + metadataId.getKey() + "' already exists");
|
||||
}
|
||||
}
|
||||
|
||||
private List<JpaDistributionSet> getDistributionSets(final Collection<Long> ids) {
|
||||
final List<JpaDistributionSet> foundDs = distributionSetRepository.findAllById(ids);
|
||||
if (foundDs.size() != ids.size()) {
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* The DistributionSet Metadata composite key which contains the meta-data key and the ID of the DistributionSet itself.
|
||||
*/
|
||||
@NoArgsConstructor // Default constructor for JPA
|
||||
@Setter
|
||||
@Getter
|
||||
public final class DsMetadataCompositeKey implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String key;
|
||||
private Long distributionSet;
|
||||
|
||||
/**
|
||||
* @param distributionSet the distribution set for this meta data
|
||||
* @param key the key of the meta data
|
||||
*/
|
||||
public DsMetadataCompositeKey(final Long distributionSet, final String key) {
|
||||
this.distributionSet = distributionSet;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (distributionSet == null ? 0 : distributionSet.hashCode());
|
||||
result = prime * result + (key == null ? 0 : key.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final DsMetadataCompositeKey other = (DsMetadataCompositeKey) obj;
|
||||
if (distributionSet == null) {
|
||||
if (other.distributionSet != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!distributionSet.equals(other.distributionSet)) {
|
||||
return false;
|
||||
}
|
||||
if (key == null) {
|
||||
return other.key == null;
|
||||
} else {
|
||||
return key.equals(other.key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,13 +13,14 @@ import java.io.Serial;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.CollectionTable;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ConstraintMode;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.ForeignKey;
|
||||
@@ -28,9 +29,9 @@ import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MapKeyColumn;
|
||||
import jakarta.persistence.NamedAttributeNode;
|
||||
import jakarta.persistence.NamedEntityGraph;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.UniqueConstraint;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@@ -47,7 +48,6 @@ import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetExcepti
|
||||
import org.eclipse.hawkbit.repository.exception.LockedException;
|
||||
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
@@ -109,11 +109,16 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
|
||||
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_tag_tag")) })
|
||||
private Set<DistributionSetTag> tags = new HashSet<>();
|
||||
|
||||
@ToString.Exclude
|
||||
@OneToMany(mappedBy = "distributionSet", fetch = FetchType.LAZY,
|
||||
cascade = { CascadeType.REMOVE },
|
||||
targetEntity = JpaDistributionSetMetadata.class)
|
||||
private List<DistributionSetMetadata> metadata;
|
||||
// no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent
|
||||
@Getter
|
||||
@ElementCollection
|
||||
@CollectionTable(
|
||||
name = "sp_ds_metadata",
|
||||
joinColumns = { @JoinColumn(name = "ds", nullable = false) },
|
||||
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_metadata_ds"))
|
||||
@MapKeyColumn(name = "meta_key", length = DistributionSet.METADATA_KEY_SIZE)
|
||||
@Column(name = "meta_value", length = DistributionSet.METADATA_VALUE_SIZE)
|
||||
private Map<String, String> metadata;
|
||||
|
||||
@Column(name = "complete")
|
||||
private boolean complete;
|
||||
@@ -217,14 +222,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
|
||||
return tags.remove(tag);
|
||||
}
|
||||
|
||||
public List<DistributionSetMetadata> getMetadata() {
|
||||
if (metadata == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(metadata);
|
||||
}
|
||||
|
||||
public void lock() {
|
||||
if (!isComplete()) {
|
||||
throw new IncompleteDistributionSetException("Could not be locked while incomplete!");
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import jakarta.persistence.ConstraintMode;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.ForeignKey;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.IdClass;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
|
||||
/**
|
||||
* Meta data for {@link DistributionSet}.
|
||||
*/
|
||||
@NoArgsConstructor // Default constructor needed for JPA entities.
|
||||
@Getter
|
||||
@IdClass(DsMetadataCompositeKey.class)
|
||||
@Entity
|
||||
@Table(name = "sp_ds_metadata")
|
||||
public class JpaDistributionSetMetadata extends AbstractJpaMetaData implements DistributionSetMetadata {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@ManyToOne(fetch = FetchType.LAZY, optional = false)
|
||||
@JoinColumn(name = "ds", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_metadata_ds"))
|
||||
private JpaDistributionSet distributionSet;
|
||||
|
||||
public JpaDistributionSetMetadata(final String key, final String value) {
|
||||
super(key, value);
|
||||
}
|
||||
|
||||
public JpaDistributionSetMetadata(final String key, final DistributionSet distributionSet, final String value) {
|
||||
super(key, value);
|
||||
this.distributionSet = (JpaDistributionSet) distributionSet;
|
||||
}
|
||||
|
||||
public DsMetadataCompositeKey getId() {
|
||||
return new DsMetadataCompositeKey(distributionSet.getId(), getKey());
|
||||
}
|
||||
|
||||
public void setDistributionSet(final DistributionSet distributionSet) {
|
||||
this.distributionSet = (JpaDistributionSet) distributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((distributionSet == null) ? 0 : distributionSet.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
// exception squid:S2259 - obj is checked for null in super
|
||||
@SuppressWarnings("squid:S2259")
|
||||
public boolean equals(final Object obj) {
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
}
|
||||
final JpaDistributionSetMetadata other = (JpaDistributionSetMetadata) obj;
|
||||
if (distributionSet == null) {
|
||||
return other.distributionSet == null;
|
||||
} else {
|
||||
return distributionSet.equals(other.distributionSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.repository;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.DsMetadataCompositeKey;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* {@link DistributionSetMetadata} repository.
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public interface DistributionSetMetadataRepository
|
||||
extends PagingAndSortingRepository<JpaDistributionSetMetadata, DsMetadataCompositeKey>,
|
||||
CrudRepository<JpaDistributionSetMetadata, DsMetadataCompositeKey>,
|
||||
JpaSpecificationExecutor<JpaDistributionSetMetadata> {
|
||||
|
||||
/**
|
||||
* Counts the meta data entries that match the given distribution set ID.
|
||||
* <p/>
|
||||
* No access control applied
|
||||
*
|
||||
* @param id of the distribution set.
|
||||
* @return The number of matching meta data entries.
|
||||
*/
|
||||
long countByDistributionSetId(@Param("id") Long id);
|
||||
}
|
||||
Reference in New Issue
Block a user