JpaSoftwareModule#metadata made map (#2412)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-05-21 16:59:25 +03:00
committed by GitHub
parent 452d8618d7
commit 64ee8b9906
37 changed files with 413 additions and 895 deletions

View File

@@ -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.model.MetaData;
import org.springframework.validation.annotation.Validated;
/**

View File

@@ -11,8 +11,8 @@ package org.eclipse.hawkbit.repository.jpa.management;
import static org.eclipse.hawkbit.repository.model.Action.Status.DOWNLOADED;
import static org.eclipse.hawkbit.repository.model.Action.Status.FINISHED;
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_KEY_SIZE;
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE;
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_MAX_KEY_SIZE;
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_MAX_VALUE_SIZE;
import java.net.URI;
import java.time.Duration;
@@ -618,11 +618,11 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
}
private static boolean isAttributeKeyValid(final String key) {
return key != null && key.length() <= CONTROLLER_ATTRIBUTE_KEY_SIZE && PATTERN.matcher(key).matches();
return key != null && key.length() <= CONTROLLER_ATTRIBUTE_MAX_KEY_SIZE && PATTERN.matcher(key).matches();
}
private static boolean isAttributeValueValid(final String value) {
return value == null || (value.length() <= CONTROLLER_ATTRIBUTE_VALUE_SIZE && PATTERN.matcher(value).matches());
return value == null || (value.length() <= CONTROLLER_ATTRIBUTE_MAX_VALUE_SIZE && PATTERN.matcher(value).matches());
}
private static void copy(final Map<String, String> src, final Map<String, String> trg) {

View File

@@ -10,7 +10,6 @@
package org.eclipse.hawkbit.repository.jpa.management;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -19,7 +18,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jakarta.persistence.EntityManager;
@@ -29,7 +27,6 @@ import org.eclipse.hawkbit.repository.QuotaManagement;
import org.eclipse.hawkbit.repository.RepositoryConstants;
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields;
import org.eclipse.hawkbit.repository.builder.GenericSoftwareModuleMetadataUpdate;
import org.eclipse.hawkbit.repository.builder.GenericSoftwareModuleUpdate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleCreate;
@@ -272,53 +269,61 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public List<SoftwareModuleMetadata> putMetaData(final Collection<SoftwareModuleMetadataCreate> create) {
if (!create.isEmpty()) {
// check if all metadata entries refer to the same software module
final Long id = ((JpaSoftwareModuleMetadataCreate) create.iterator().next()).getSoftwareModuleId();
if (createJpaMetadataCreateStream(create).allMatch(c -> id.equals(c.getSoftwareModuleId()))) {
assertSoftwareModuleExists(id);
assertMetaDataQuota(id, create.size());
// touch to update revision and last modified timestamp
JpaManagementHelper.touch(entityManager, softwareModuleRepository, (JpaSoftwareModule) get(id)
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)));
return createJpaMetadataCreateStream(create).map(this::saveMetadata).toList();
} else {
// group by software module id to minimize database access
final Map<Long, List<JpaSoftwareModuleMetadataCreate>> groups = createJpaMetadataCreateStream(create)
.collect(Collectors.groupingBy(JpaSoftwareModuleMetadataCreate::getSoftwareModuleId));
return groups.entrySet().stream().flatMap(e -> {
final List<JpaSoftwareModuleMetadataCreate> group = e.getValue();
public void createMetadata(final Collection<SoftwareModuleMetadataCreate> create) {
// group by software module id to minimize database access
create.stream()
.map(JpaSoftwareModuleMetadataCreate.class::cast)
.collect(Collectors.groupingBy(JpaSoftwareModuleMetadataCreate::getSoftwareModuleId))
.forEach((id, createsForSoftwareModule) -> {
assertSoftwareModuleExists(id);
assertMetaDataQuota(e.getKey(), group.size());
assertMetadataQuota(id, createsForSoftwareModule.size());
// touch to update revision and last modified timestamp
JpaManagementHelper.touch(entityManager, softwareModuleRepository, (JpaSoftwareModule) get(id)
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)));
return group.stream().map(this::saveMetadata);
}).toList();
}
}
JpaManagementHelper.touch(
entityManager, softwareModuleRepository,
(JpaSoftwareModule) get(id).orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)));
createsForSoftwareModule.forEach(this::saveMetadata);
});
}
return Collections.emptyList();
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public List<SoftwareModuleMetadata> getMetadata(final long id) {
assertSoftwareModuleExists(id);
return (List)softwareModuleMetadataRepository.findAll(metadataBySoftwareModuleIdSpec(id));
}
@Override
public SoftwareModuleMetadata getMetadata(final long id, final String key) {
assertSoftwareModuleExists(id);
return findMetadata(id, key).orElseThrow(() -> new EntityNotFoundException("SoftwareModuleMetadata", id + ":" + key));
}
@Override
public Page<SoftwareModuleMetadata> findMetaDataBySoftwareModuleIdAndTargetVisible(final Pageable pageable, final long id) {
assertSoftwareModuleExists(id);
return JpaManagementHelper.convertPage(softwareModuleMetadataRepository.findBySoftwareModuleIdAndTargetVisible(
id, true, PageRequest.of(0, RepositoryConstants.MAX_META_DATA_COUNT)), pageable);
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public SoftwareModuleMetadata updateMetaData(final SoftwareModuleMetadataCreate c) {
public SoftwareModuleMetadata updateMetadata(final SoftwareModuleMetadataCreate c) {
final JpaSoftwareModuleMetadataCreate create = (JpaSoftwareModuleMetadataCreate) c;
final Long id = create.getSoftwareModuleId();
assertSoftwareModuleExists(id);
assertMetaDataQuota(id, 1);
assertMetadataQuota(id, 1);
// touch to update revision and last modified timestamp
JpaManagementHelper.touch(entityManager, softwareModuleRepository, (JpaSoftwareModule) get(id)
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)));
JpaManagementHelper.touch(
entityManager, softwareModuleRepository,
(JpaSoftwareModule) get(id).orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)));
return saveMetadata(create);
}
@@ -326,13 +331,13 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public SoftwareModuleMetadata updateMetaData(final SoftwareModuleMetadataUpdate u) {
public SoftwareModuleMetadata updateMetadata(final SoftwareModuleMetadataUpdate u) {
final GenericSoftwareModuleMetadataUpdate update = (GenericSoftwareModuleMetadataUpdate) u;
// check if exists otherwise throw entity not found exception
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findMetaDataBySoftwareModuleId(
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findMetadata(
update.getSoftwareModuleId(), update.getKey())
.orElseThrow(() -> new EntityNotFoundException(SoftwareModuleMetadata.class, update.getSoftwareModuleId(), update.getKey()));
.orElseThrow(() -> new EntityNotFoundException("SoftwareModuleMetadata", update.getSoftwareModuleId() + ":" + update.getKey()));
update.getValue().ifPresent(metadata::setValue);
update.isTargetVisible().ifPresent(metadata::setTargetVisible);
@@ -345,9 +350,9 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
@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 JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findMetaDataBySoftwareModuleId0(id, key)
.orElseThrow(() -> new EntityNotFoundException(SoftwareModuleMetadata.class, id, key));
public void deleteMetadata(final long id, final String key) {
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findMetadata(id, key)
.orElseThrow(() -> new EntityNotFoundException("SoftwareModuleMetadata", id + ":" + key));
JpaManagementHelper.touch(entityManager, softwareModuleRepository, metadata.getSoftwareModule());
softwareModuleMetadataRepository.deleteById(metadata.getId());
@@ -424,45 +429,6 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
.map(SoftwareModule.class::cast);
}
@Override
public Optional<SoftwareModuleMetadata> findMetaDataBySoftwareModuleId(final long id, final String key) {
return findMetaDataBySoftwareModuleId0(id, key);
}
private Optional<SoftwareModuleMetadata> findMetaDataBySoftwareModuleId0(final long id, final String key) {
assertSoftwareModuleExists(id);
return softwareModuleMetadataRepository.findById(new SwMetadataCompositeKey(id, key))
.map(SoftwareModuleMetadata.class::cast);
}
@Override
public Page<SoftwareModuleMetadata> findMetaDataBySoftwareModuleId(final Pageable pageable, final long id) {
assertSoftwareModuleExists(id);
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleMetadataRepository,
Collections.singletonList(metadataBySoftwareModuleIdSpec(id)), pageable
);
}
@Override
public Page<SoftwareModuleMetadata> findMetaDataBySoftwareModuleIdAndTargetVisible(final Pageable pageable,
final long id) {
assertSoftwareModuleExists(id);
return JpaManagementHelper.convertPage(softwareModuleMetadataRepository.findBySoftwareModuleIdAndTargetVisible(
id, true, PageRequest.of(0, RepositoryConstants.MAX_META_DATA_COUNT)), pageable);
}
@Override
public Page<SoftwareModuleMetadata> findMetaDataByRsql(final long id, final String rsqlParam, final Pageable pageable) {
assertSoftwareModuleExists(id);
final List<Specification<JpaSoftwareModuleMetadata>> specList = Arrays
.asList(RSQLUtility.buildRsqlSpecification(rsqlParam, SoftwareModuleMetadataFields.class,
virtualPropertyReplacer, database), metadataBySoftwareModuleIdSpec(id));
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleMetadataRepository, specList, pageable);
}
@Override
public Slice<SoftwareModule> findByType(final long typeId, final Pageable pageable) {
assertSoftwareModuleTypeExists(typeId);
@@ -490,18 +456,6 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
return softwareModuleRepository.count(SoftwareModuleSpecification.byAssignedToDs(distributionSetId));
}
@Override
public long countMetaDataBySoftwareModuleId(final long id) {
assertSoftwareModuleExists(id);
return softwareModuleMetadataRepository.countBySoftwareModuleId(id);
}
private static Stream<JpaSoftwareModuleMetadataCreate> createJpaMetadataCreateStream(
final Collection<SoftwareModuleMetadataCreate> create) {
return create.stream().map(JpaSoftwareModuleMetadataCreate.class::cast);
}
private static Specification<JpaSoftwareModuleMetadata> metadataBySoftwareModuleIdSpec(final long id) {
return (root, query, cb) -> cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule).get(AbstractJpaBaseEntity_.id), id);
}
@@ -526,23 +480,30 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
return softwareModuleMetadataRepository.save(create.build());
}
private void assertSoftwareModuleMetadataDoesNotExist(final Long id,
final JpaSoftwareModuleMetadataCreate md) {
private Optional<SoftwareModuleMetadata> findMetadata(final long id, final String key) {
assertSoftwareModuleExists(id);
return softwareModuleMetadataRepository.findById(new SwMetadataCompositeKey(id, key))
.map(SoftwareModuleMetadata.class::cast);
}
private void assertSoftwareModuleMetadataDoesNotExist(final Long id, final JpaSoftwareModuleMetadataCreate md) {
if (softwareModuleMetadataRepository.existsById(new SwMetadataCompositeKey(id, md.getKey()))) {
throw new EntityAlreadyExistsException("Metadata entry with key '" + md.getKey() + "' already exists!");
}
}
/**
* Asserts the meta data quota for the software module with the given ID.
* Asserts the meta-data quota for the software module with the given ID.
*
* @param id The software module ID.
* @param requested Number of meta data entries to be created.
* @param requested Number of meta-data entries to be created.
*/
private void assertMetaDataQuota(final Long id, final int requested) {
private void assertMetadataQuota(final Long id, final int requested) {
final int maxMetaData = quotaManagement.getMaxMetaDataEntriesPerSoftwareModule();
QuotaHelper.assertAssignmentQuota(id, requested, maxMetaData, SoftwareModuleMetadata.class,
SoftwareModule.class, softwareModuleMetadataRepository::countBySoftwareModuleId);
QuotaHelper.assertAssignmentQuota(
id, requested, maxMetaData, SoftwareModuleMetadata.class, SoftwareModule.class,
softwareModuleMetadataRepository::countBySoftwareModuleId);
}
private void assertSoftwareModuleExists(final Long id) {

View File

@@ -1,85 +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.util.Objects;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.MetaData;
/**
* Meta data for entities.
*/
@MappedSuperclass
public abstract class AbstractJpaMetaData implements MetaData {
@Serial
private static final long serialVersionUID = 1L;
@Id
@Column(name = "meta_key", nullable = false, length = MetaData.KEY_MAX_SIZE, updatable = false)
@Size(min = 1, max = MetaData.KEY_MAX_SIZE)
@NotNull
private String key;
@Column(name = "meta_value", length = MetaData.VALUE_MAX_SIZE)
@Size(max = MetaData.VALUE_MAX_SIZE)
@Basic
private String value;
protected AbstractJpaMetaData(final String key, final String value) {
this.key = key;
this.value = value;
}
protected AbstractJpaMetaData() {
// Default constructor needed for JPA entities
}
@Override
public String getKey() {
return key;
}
public void setKey(final String key) {
this.key = key;
}
@Override
public String getValue() {
return value;
}
public void setValue(final String value) {
this.value = value;
}
@Override
public int hashCode() {
return Objects.hash(key, value);
}
@Override
public boolean equals(final Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
final AbstractJpaMetaData that = (AbstractJpaMetaData) o;
return Objects.equals(key, that.key) && Objects.equals(value, that.value);
}
}

View File

@@ -116,8 +116,8 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
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)
@MapKeyColumn(name = "meta_key", length = DistributionSet.METADATA_MAX_KEY_SIZE)
@Column(name = "meta_value", length = DistributionSet.METADATA_MAX_VALUE_SIZE)
private Map<String, String> metadata;
@Column(name = "complete")

View File

@@ -13,10 +13,13 @@ import java.io.Serial;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
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;
@@ -24,6 +27,7 @@ import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.NamedAttributeNode;
import jakarta.persistence.NamedEntityGraph;
import jakarta.persistence.OneToMany;
@@ -69,8 +73,6 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
@Serial
private static final long serialVersionUID = 1L;
private static final String DELETED_PROPERTY = "deleted";
@Setter
@ManyToOne
@JoinColumn(name = "sm_type", nullable = false, updatable = false,
@@ -92,11 +94,16 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
@Column(name = "encrypted")
private boolean encrypted;
@ToString.Exclude
@OneToMany(mappedBy = "softwareModule", fetch = FetchType.LAZY,
cascade = { CascadeType.REMOVE },
targetEntity = JpaSoftwareModuleMetadata.class)
private List<JpaSoftwareModuleMetadata> metadata;
// no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent.
@Getter
@ElementCollection
@CollectionTable(
name = "sp_sm_metadata",
joinColumns = { @JoinColumn(name = "sm", nullable = false) },
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_sm_metadata_sm"))
@MapKeyColumn(name = "meta_key", length = SoftwareModule.METADATA_KEY_MAX_SIZE)
@Column(name = "meta_value", length = SoftwareModule.METADATA_VALUE_MAX_SIZE)
private Map<String, String> metadata;
@Column(name = "locked")
private boolean locked;

View File

@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serial;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.ConstraintMode;
import jakarta.persistence.Entity;
@@ -21,11 +22,11 @@ import jakarta.persistence.IdClass;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
@@ -34,31 +35,42 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
*/
@NoArgsConstructor // Default constructor for JPA
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@IdClass(SwMetadataCompositeKey.class)
@Entity
@Table(name = "sp_sm_metadata")
public class JpaSoftwareModuleMetadata extends AbstractJpaMetaData implements SoftwareModuleMetadata {
public class JpaSoftwareModuleMetadata implements SoftwareModuleMetadata {
@Serial
private static final long serialVersionUID = 1L;
@Id
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "sm", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_sm_metadata_sm"))
@JoinColumn(
name = "sm", nullable = false, updatable = false,
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_sm_metadata_sm"))
private JpaSoftwareModule softwareModule;
@Id
@Column(name = "meta_key", nullable = false, length = SoftwareModule.METADATA_KEY_MAX_SIZE, updatable = false)
@Size(min = 1, max = SoftwareModule.METADATA_KEY_MAX_SIZE)
@NotNull
private String key;
@Column(name = "meta_value", length = SoftwareModule.METADATA_VALUE_MAX_SIZE)
@Size(max = SoftwareModule.METADATA_VALUE_MAX_SIZE)
@Basic
private String value;
@Column(name = "target_visible")
private boolean targetVisible;
public JpaSoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value) {
super(key, value);
this.softwareModule = (JpaSoftwareModule) softwareModule;
this(key, softwareModule, value, false);
}
public JpaSoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value, final boolean targetVisible) {
super(key, value);
this.key = key;
this.value = value;
this.softwareModule = (JpaSoftwareModule) softwareModule;
this.targetVisible = targetVisible;
}

View File

@@ -37,7 +37,6 @@ import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.NamedAttributeNode;
import jakarta.persistence.NamedEntityGraph;
import jakarta.persistence.NamedEntityGraphs;
import jakarta.persistence.NamedSubgraph;
import jakarta.persistence.OneToMany;
import jakarta.persistence.PrimaryKeyJoinColumn;
import jakarta.persistence.Table;
@@ -187,8 +186,8 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
name = "sp_target_attributes",
joinColumns = { @JoinColumn(name = "target", nullable = false) },
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_attributes_target"))
@MapKeyColumn(name = "attribute_key", length = Target.CONTROLLER_ATTRIBUTE_KEY_SIZE)
@Column(name = "attribute_value", length = Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE)
@MapKeyColumn(name = "attribute_key", length = Target.CONTROLLER_ATTRIBUTE_MAX_KEY_SIZE)
@Column(name = "attribute_value", length = Target.CONTROLLER_ATTRIBUTE_MAX_VALUE_SIZE)
private Map<String, String> controllerAttributes;
// no cascade option on an ElementCollection, the target objects are always persisted, merged, removed with their parent
@@ -198,8 +197,8 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
name = "sp_target_metadata",
joinColumns = { @JoinColumn(name = "target", nullable = false) },
foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_metadata_target"))
@MapKeyColumn(name = "meta_key", length = Target.CONTROLLER_METADATA_KEY_SIZE)
@Column(name = "meta_value", length = Target.CONTROLLER_METADATA_VALUE_SIZE)
@MapKeyColumn(name = "meta_key", length = Target.METADATA_MAX_KEY_SIZE)
@Column(name = "meta_value", length = Target.METADATA_MAX_VALUE_SIZE)
private Map<String, String> metadata;
@OneToMany(mappedBy = "target", fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, targetEntity = JpaAction.class)

View File

@@ -46,17 +46,20 @@ class SoftwareManagementSecurityTest
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")
void createMetaDataPermissionsCheck() {
assertPermissions(
() -> softwareModuleManagement.updateMetaData(entityFactory.softwareModuleMetadata().create(1L).key("key").value("value")),
() -> softwareModuleManagement.updateMetadata(entityFactory.softwareModuleMetadata().create(1L).key("key").value("value")),
List.of(SpPermission.UPDATE_REPOSITORY));
assertPermissions(() -> softwareModuleManagement.putMetaData(
List.of(entityFactory.softwareModuleMetadata().create(1L).key("key").value("value"))), List.of(SpPermission.UPDATE_REPOSITORY));
assertPermissions(() -> {
softwareModuleManagement.createMetadata(
List.of(entityFactory.softwareModuleMetadata().create(1L).key("key").value("value")));
return null;
}, List.of(SpPermission.UPDATE_REPOSITORY));
}
@Test
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")
void deleteMetaDataPermissionsCheck() {
assertPermissions(() -> {
softwareModuleManagement.deleteMetaData(1L, "key");
softwareModuleManagement.deleteMetadata(1L, "key");
return null;
}, List.of(SpPermission.UPDATE_REPOSITORY));
}
@@ -88,19 +91,13 @@ class SoftwareManagementSecurityTest
@Test
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")
void getMetaDataBySoftwareModuleIdPermissionsCheck() {
assertPermissions(() -> softwareModuleManagement.findMetaDataBySoftwareModuleId(1L, "key"), List.of(SpPermission.READ_REPOSITORY));
assertPermissions(() -> softwareModuleManagement.getMetadata(1L, "key"), List.of(SpPermission.READ_REPOSITORY));
}
@Test
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")
void findMetaDataBySoftwareModuleIdPermissionsCheck() {
assertPermissions(() -> softwareModuleManagement.findMetaDataBySoftwareModuleId(PAGE, 1L), List.of(SpPermission.READ_REPOSITORY));
}
@Test
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")
void countMetaDataBySoftwareModuleIdPermissionsCheck() {
assertPermissions(() -> softwareModuleManagement.countMetaDataBySoftwareModuleId(1L), List.of(SpPermission.READ_REPOSITORY));
assertPermissions(() -> softwareModuleManagement.getMetadata(1L), List.of(SpPermission.READ_REPOSITORY));
}
@Test
@@ -110,12 +107,6 @@ class SoftwareManagementSecurityTest
List.of(SpPermission.READ_REPOSITORY));
}
@Test
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")
void findMetaDataByRsqlPermissionsCheck() {
assertPermissions(() -> softwareModuleManagement.findMetaDataByRsql(1L, "key==value", PAGE), List.of(SpPermission.READ_REPOSITORY));
}
@Test
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")
void findByTypePermissionsCheck() {
@@ -144,7 +135,7 @@ class SoftwareManagementSecurityTest
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")
void updateMetaDataPermissionsCheck() {
assertPermissions(
() -> softwareModuleManagement.updateMetaData(entityFactory.softwareModuleMetadata().update(1L, "key").value("value")),
() -> softwareModuleManagement.updateMetadata(entityFactory.softwareModuleMetadata().update(1L, "key").value("value")),
List.of(SpPermission.UPDATE_REPOSITORY));
}

View File

@@ -29,6 +29,7 @@ import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.LockedException;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.jpa.RandomGeneratedInputStream;
@@ -58,6 +59,8 @@ import org.springframework.data.domain.PageRequest;
@Story("Software Module Management")
class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
private static final PageRequest PAGE_REQUEST_100 = PageRequest.of(0, 100);
@Test
@Description("Verifies that management get access reacts as specified on calls for non existing entities by means "
+ "of Optional not present.")
@@ -70,7 +73,8 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
assertThat(softwareModuleManagement.findByNameAndVersionAndType(NOT_EXIST_ID, NOT_EXIST_ID, osType.getId()))
.isNotPresent();
assertThat(softwareModuleManagement.findMetaDataBySoftwareModuleId(module.getId(), NOT_EXIST_ID)).isNotPresent();
assertThatExceptionOfType(EntityNotFoundException.class)
.isThrownBy(() -> softwareModuleManagement.getMetadata(module.getId(), NOT_EXIST_ID));
}
@Test
@@ -82,57 +86,40 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
verifyThrownExceptionBy(
() -> softwareModuleManagement.create(Collections
.singletonList(entityFactory.softwareModule().create().name("xxx").type(NOT_EXIST_ID))),
"SoftwareModuleType");
.singletonList(entityFactory.softwareModule().create().name("xxx").type(NOT_EXIST_ID))), "SoftwareModuleType");
verifyThrownExceptionBy(
() -> softwareModuleManagement
.create(entityFactory.softwareModule().create().name("xxx").type(NOT_EXIST_ID)),
"SoftwareModuleType");
.create(entityFactory.softwareModule().create().name("xxx").type(NOT_EXIST_ID)), "SoftwareModuleType");
verifyThrownExceptionBy(
() -> softwareModuleManagement.updateMetaData(
entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx")),
"SoftwareModule");
() -> softwareModuleManagement.updateMetadata(
entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx")), "SoftwareModule");
verifyThrownExceptionBy(
() -> softwareModuleManagement.putMetaData(Collections.singletonList(
entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx"))),
"SoftwareModule");
() -> softwareModuleManagement.createMetadata(Collections.singletonList(
entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx"))), "SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.delete(NOT_EXIST_IDL), "SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.delete(Collections.singletonList(NOT_EXIST_IDL)),
"SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.deleteMetaData(NOT_EXIST_IDL, "xxx"), "SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.deleteMetaData(module.getId(), NOT_EXIST_ID),
"SoftwareModuleMetadata");
verifyThrownExceptionBy(() -> softwareModuleManagement.delete(Collections.singletonList(NOT_EXIST_IDL)), "SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.deleteMetadata(NOT_EXIST_IDL, "xxx"), "SoftwareModule");
verifyThrownExceptionBy(
() -> softwareModuleManagement.updateMetaData(
entityFactory.softwareModuleMetadata().update(NOT_EXIST_IDL, "xxx").value("xxx")),
"SoftwareModule");
() -> softwareModuleManagement.updateMetadata(
entityFactory.softwareModuleMetadata().update(NOT_EXIST_IDL, "xxx").value("xxx")), "SoftwareModule");
verifyThrownExceptionBy(
() -> softwareModuleManagement.updateMetaData(
entityFactory.softwareModuleMetadata().update(module.getId(), NOT_EXIST_ID).value("xxx")),
"SoftwareModuleMetadata");
() -> softwareModuleManagement.updateMetadata(
entityFactory.softwareModuleMetadata().update(module.getId(), NOT_EXIST_ID).value("xxx")), "SoftwareModuleMetadata");
verifyThrownExceptionBy(() -> softwareModuleManagement.findByAssignedTo(NOT_EXIST_IDL, PAGE),
"DistributionSet");
verifyThrownExceptionBy(() -> softwareModuleManagement.findByAssignedTo(NOT_EXIST_IDL, PAGE), "DistributionSet");
verifyThrownExceptionBy(() -> softwareModuleManagement.findByNameAndVersionAndType("xxx", "xxx", NOT_EXIST_IDL),
"SoftwareModuleType");
verifyThrownExceptionBy(
() -> softwareModuleManagement.findMetaDataBySoftwareModuleId(NOT_EXIST_IDL, NOT_EXIST_ID),
"SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.getMetadata(NOT_EXIST_IDL, NOT_EXIST_ID), "SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.findMetaDataBySoftwareModuleId(PAGE, NOT_EXIST_IDL),
"SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.findMetaDataByRsql(NOT_EXIST_IDL, "name==*", PAGE),
"SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.getMetadata(NOT_EXIST_IDL), "SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.findByType(NOT_EXIST_IDL, PAGE), "SoftwareModule");
verifyThrownExceptionBy(
() -> softwareModuleManagement.update(entityFactory.softwareModule().update(NOT_EXIST_IDL)),
"SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.update(entityFactory.softwareModule().update(NOT_EXIST_IDL)), "SoftwareModule");
}
@Test
@@ -496,27 +483,37 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
final String knownKey2 = "myKnownKey2";
final String knownValue2 = "myKnownValue2";
final SoftwareModule ah = testdataFactory.createSoftwareModuleApp();
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleApp();
assertThat(ah.getOptLockRevision()).isEqualTo(1);
assertThat(softwareModule.getOptLockRevision()).isEqualTo(1);
final SoftwareModuleMetadataCreate swMetadata1 = entityFactory.softwareModuleMetadata().create(ah.getId())
.key(knownKey1).value(knownValue1);
final SoftwareModuleMetadataCreate swMetadata1 = entityFactory.softwareModuleMetadata()
.create(softwareModule.getId())
.key(knownKey1)
.value(knownValue1)
.targetVisible(true);
final SoftwareModuleMetadataCreate swMetadata2 = entityFactory.softwareModuleMetadata().create(ah.getId())
.key(knownKey2).value(knownValue2);
final SoftwareModuleMetadataCreate swMetadata2 = entityFactory.softwareModuleMetadata()
.create(softwareModule.getId())
.key(knownKey2)
.value(knownValue2);
final List<SoftwareModuleMetadata> softwareModuleMetadata = softwareModuleManagement
.putMetaData(Arrays.asList(swMetadata1, swMetadata2));
softwareModuleManagement.createMetadata(Arrays.asList(swMetadata1, swMetadata2));
final SoftwareModule changedLockRevisionModule = softwareModuleManagement.get(ah.getId()).get();
final SoftwareModule changedLockRevisionModule = softwareModuleManagement.get(softwareModule.getId()).get();
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(2);
assertThat(softwareModuleMetadata).hasSize(2);
assertThat(softwareModuleMetadata.get(0)).isNotNull();
assertThat(softwareModuleMetadata.get(0).getValue()).isEqualTo(knownValue1);
assertThat(((JpaSoftwareModuleMetadata) softwareModuleMetadata.get(0)).getId().getKey()).isEqualTo(knownKey1);
assertThat(softwareModuleMetadata.get(0).getEntityId()).isEqualTo(ah.getId());
assertThat(softwareModuleManagement.getMetadata(softwareModule.getId(), knownKey1)).satisfies(metadata -> {
assertThat(metadata.getKey()).isEqualTo(knownKey1);
assertThat(metadata.getValue()).isEqualTo(knownValue1);
assertThat(metadata.isTargetVisible()).isTrue();
});
assertThat(softwareModuleManagement.getMetadata(softwareModule.getId(), knownKey2)).satisfies(metadata -> {
assertThat(metadata.getKey()).isEqualTo(knownKey2);
assertThat(metadata.getValue()).isEqualTo(knownValue2);
assertThat(metadata.isTargetVisible()).isFalse();
});
}
@Test
@@ -527,7 +524,7 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
final SoftwareModule module = testdataFactory.createSoftwareModuleApp("m1");
final int maxMetaData = quotaManagement.getMaxMetaDataEntriesPerSoftwareModule();
for (int i = 0; i < maxMetaData; ++i) {
softwareModuleManagement.updateMetaData(
softwareModuleManagement.updateMetadata(
entityFactory.softwareModuleMetadata().create(module.getId()).key("k" + i).value("v" + i));
}
@@ -535,7 +532,7 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
final SoftwareModuleMetadataCreate metadata = entityFactory.softwareModuleMetadata().create(module.getId())
.key("k" + maxMetaData).value("v" + maxMetaData);
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> softwareModuleManagement.updateMetaData(metadata));
.isThrownBy(() -> softwareModuleManagement.updateMetadata(metadata));
// add multiple meta data entries at once
final SoftwareModule module2 = testdataFactory.createSoftwareModuleApp("m2");
@@ -545,13 +542,13 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
}
// quota exceeded
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> softwareModuleManagement.putMetaData(create));
.isThrownBy(() -> softwareModuleManagement.createMetadata(create));
// add some meta data entries
final SoftwareModule module3 = testdataFactory.createSoftwareModuleApp("m3");
final int firstHalf = Math.round((maxMetaData) / 2.f);
for (int i = 0; i < firstHalf; ++i) {
softwareModuleManagement.updateMetaData(
softwareModuleManagement.updateMetadata(
entityFactory.softwareModuleMetadata().create(module3.getId()).key("k" + i).value("v" + i));
}
// add too many data entries
@@ -562,7 +559,7 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
}
// quota exceeded
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> softwareModuleManagement.putMetaData(create2));
.isThrownBy(() -> softwareModuleManagement.createMetadata(create2));
}
@@ -576,21 +573,21 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
final SoftwareModuleMetadataCreate metadata = entityFactory.softwareModuleMetadata()
.create(ah.getId()).key(knownKey1).value(knownValue1).targetVisible(true);
softwareModuleManagement.updateMetaData(metadata);
softwareModuleManagement.updateMetadata(metadata);
assertThatExceptionOfType(EntityAlreadyExistsException.class)
.isThrownBy(() -> softwareModuleManagement.updateMetaData(metadata))
.isThrownBy(() -> softwareModuleManagement.updateMetadata(metadata))
.withMessageContaining("Metadata").withMessageContaining(knownKey1);
final String knownKey2 = "myKnownKey2";
softwareModuleManagement.updateMetaData(entityFactory.softwareModuleMetadata().create(ah.getId()).key(knownKey2)
softwareModuleManagement.updateMetadata(entityFactory.softwareModuleMetadata().create(ah.getId()).key(knownKey2)
.value(knownValue1).targetVisible(false));
final SoftwareModuleMetadataCreate metadata2 = entityFactory.softwareModuleMetadata().create(ah.getId())
.key(knownKey2).value(knownValue1).targetVisible(true);
assertThatExceptionOfType(EntityAlreadyExistsException.class)
.isThrownBy(() -> softwareModuleManagement.updateMetaData(metadata2))
.isThrownBy(() -> softwareModuleManagement.updateMetadata(metadata2))
.withMessageContaining("Metadata").withMessageContaining(knownKey2);
}
@@ -608,7 +605,7 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
assertThat(ah.getOptLockRevision()).isEqualTo(1);
// create an software module meta data entry
final SoftwareModuleMetadata softwareModuleMetadata = softwareModuleManagement.updateMetaData(
final SoftwareModuleMetadata softwareModuleMetadata = softwareModuleManagement.updateMetadata(
entityFactory.softwareModuleMetadata().create(ah.getId()).key(knownKey).value(knownValue));
assertThat(softwareModuleMetadata.isTargetVisible()).isFalse();
assertThat(softwareModuleMetadata.getValue()).isEqualTo(knownValue);
@@ -619,7 +616,7 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(2);
// update the software module metadata
final SoftwareModuleMetadata updated = softwareModuleManagement.updateMetaData(entityFactory
final SoftwareModuleMetadata updated = softwareModuleManagement.updateMetadata(entityFactory
.softwareModuleMetadata().update(ah.getId(), knownKey).value(knownUpdateValue).targetVisible(true));
// we are updating the sw metadata so also modifying the base software
@@ -632,7 +629,7 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
assertThat(updated.getValue()).isEqualTo(knownUpdateValue);
assertThat(updated.isTargetVisible()).isTrue();
assertThat(((JpaSoftwareModuleMetadata) updated).getId().getKey()).isEqualTo(knownKey);
assertThat(updated.getEntityId()).isEqualTo(ah.getId());
assertThat(((JpaSoftwareModuleMetadata) updated).getSoftwareModule().getId()).isEqualTo(ah.getId());
}
@Test
@@ -643,19 +640,18 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
final SoftwareModule swModule = testdataFactory.createSoftwareModuleApp();
softwareModuleManagement.updateMetaData(
softwareModuleManagement.updateMetadata(
entityFactory.softwareModuleMetadata().create(swModule.getId()).key(knownKey1).value(knownValue1));
assertThat(softwareModuleManagement.findMetaDataBySoftwareModuleId(PageRequest.of(0, 10), swModule.getId())
.getContent()).as("Contains the created metadata element").allSatisfy(metadata -> {
assertThat(metadata.getSoftwareModule().getId()).isEqualTo(swModule.getId());
assertThat(metadata.getKey()).isEqualTo(knownKey1);
assertThat(metadata.getValue()).isEqualTo(knownValue1);
});
assertThat(softwareModuleManagement.getMetadata(swModule.getId()))
.as("Contains the created metadata element").allSatisfy(metadata -> {
assertThat(((JpaSoftwareModuleMetadata) metadata).getSoftwareModule().getId()).isEqualTo(swModule.getId());
assertThat(metadata.getKey()).isEqualTo(knownKey1);
assertThat(metadata.getValue()).isEqualTo(knownValue1);
});
softwareModuleManagement.deleteMetaData(swModule.getId(), knownKey1);
assertThat(softwareModuleManagement.findMetaDataBySoftwareModuleId(PageRequest.of(0, 10), swModule.getId())
.getContent()).as("Metadata elements are").isEmpty();
softwareModuleManagement.deleteMetadata(swModule.getId(), knownKey1);
assertThat(softwareModuleManagement.getMetadata(swModule.getId())).as("Metadata elements are").isEmpty();
}
@Test
@@ -666,16 +662,16 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
final SoftwareModule ah = testdataFactory.createSoftwareModuleApp();
softwareModuleManagement.updateMetaData(
softwareModuleManagement.updateMetadata(
entityFactory.softwareModuleMetadata().create(ah.getId()).key(knownKey1).value(knownValue1));
assertThat(softwareModuleManagement.findMetaDataBySoftwareModuleId(ah.getId(), "doesnotexist")).isNotPresent();
assertThatExceptionOfType(EntityNotFoundException.class)
.isThrownBy(() -> softwareModuleManagement.getMetadata(ah.getId(), "doesnotexist"));
}
@Test
@Description("Queries and loads the metadata related to a given software module.")
void findAllSoftwareModuleMetadataBySwId() {
final SoftwareModule sw1 = testdataFactory.createSoftwareModuleApp();
final int metadataCountSw1 = 8;
@@ -683,38 +679,28 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
final int metadataCountSw2 = 10;
for (int index = 0; index < metadataCountSw1; index++) {
softwareModuleManagement.updateMetaData(entityFactory.softwareModuleMetadata().create(sw1.getId())
softwareModuleManagement.updateMetadata(entityFactory.softwareModuleMetadata().create(sw1.getId())
.key("key" + index).value("value" + index).targetVisible(true));
}
for (int index = 0; index < metadataCountSw2; index++) {
softwareModuleManagement.updateMetaData(entityFactory.softwareModuleMetadata().create(sw2.getId())
softwareModuleManagement.updateMetadata(entityFactory.softwareModuleMetadata().create(sw2.getId())
.key("key" + index).value("value" + index).targetVisible(false));
}
Page<SoftwareModuleMetadata> metadataSw1 = softwareModuleManagement
.findMetaDataBySoftwareModuleId(PageRequest.of(0, 100), sw1.getId());
final List<SoftwareModuleMetadata> metadataSw1 = softwareModuleManagement.getMetadata(sw1.getId());
final List<SoftwareModuleMetadata> metadataSw2 = softwareModuleManagement.getMetadata(sw2.getId());
assertThat(metadataSw1).hasSize(metadataCountSw1);
assertThat(metadataSw2).hasSize(metadataCountSw2);
Page<SoftwareModuleMetadata> metadataSw2 = softwareModuleManagement
.findMetaDataBySoftwareModuleId(PageRequest.of(0, 100), sw2.getId());
assertThat(metadataSw1.getNumberOfElements()).isEqualTo(metadataCountSw1);
assertThat(metadataSw1.getTotalElements()).isEqualTo(metadataCountSw1);
assertThat(metadataSw2.getNumberOfElements()).isEqualTo(metadataCountSw2);
assertThat(metadataSw2.getTotalElements()).isEqualTo(metadataCountSw2);
metadataSw1 = softwareModuleManagement.findMetaDataBySoftwareModuleIdAndTargetVisible(PageRequest.of(0, 100),
sw1.getId());
metadataSw2 = softwareModuleManagement.findMetaDataBySoftwareModuleIdAndTargetVisible(PageRequest.of(0, 100),
sw2.getId());
assertThat(metadataSw1.getNumberOfElements()).isEqualTo(metadataCountSw1);
assertThat(metadataSw1.getTotalElements()).isEqualTo(metadataCountSw1);
assertThat(metadataSw2.getNumberOfElements()).isZero();
assertThat(metadataSw2.getTotalElements()).isZero();
final Page<SoftwareModuleMetadata> metadataSw1V = softwareModuleManagement.findMetaDataBySoftwareModuleIdAndTargetVisible(
PAGE_REQUEST_100, sw1.getId());
final Page<SoftwareModuleMetadata> metadataSw2V = softwareModuleManagement.findMetaDataBySoftwareModuleIdAndTargetVisible(
PAGE_REQUEST_100, sw2.getId());
assertThat(metadataSw1V.getNumberOfElements()).isEqualTo(metadataCountSw1);
assertThat(metadataSw1V.getTotalElements()).isEqualTo(metadataCountSw1);
assertThat(metadataSw2V.getNumberOfElements()).isZero();
assertThat(metadataSw2V.getTotalElements()).isZero();
}
@Test
@@ -757,7 +743,8 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
.isTrue();
// try add
final ArtifactUpload artifactUpload = new ArtifactUpload(new ByteArrayInputStream(new byte[] { 2 }), softwareModuleId, "artifact2", false, 1);
final ArtifactUpload artifactUpload = new ArtifactUpload(new ByteArrayInputStream(new byte[] { 2 }), softwareModuleId, "artifact2",
false, 1);
assertThatExceptionOfType(LockedException.class)
.as("Attempt to modify a locked SM artifacts should throw an exception")
.isThrownBy(() -> artifactManagement.create(artifactUpload));

View File

@@ -51,11 +51,11 @@ class RSQLSoftwareModuleFieldTest extends AbstractJpaIntegrationTest {
final SoftwareModuleMetadataCreate softwareModuleMetadata = entityFactory.softwareModuleMetadata()
.create(ah.getId()).key("metaKey").value("metaValue");
softwareModuleManagement.updateMetaData(softwareModuleMetadata);
softwareModuleManagement.updateMetadata(softwareModuleMetadata);
final SoftwareModuleMetadataCreate softwareModuleMetadata2 = entityFactory.softwareModuleMetadata()
.create(ah2.getId()).key("metaKey").value("value");
softwareModuleManagement.updateMetaData(softwareModuleMetadata2);
softwareModuleManagement.updateMetadata(softwareModuleMetadata2);
}
@Test

View File

@@ -1,95 +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.rsql;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
@Feature("Component Tests - Repository")
@Story("RSQL filter software module metadata")
class RSQLSoftwareModuleMetadataFieldsTest extends AbstractJpaIntegrationTest {
private Long softwareModuleId;
@BeforeEach
void setupBeforeTest() {
final SoftwareModule softwareModule = testdataFactory.createSoftwareModule(TestdataFactory.SM_TYPE_APP);
softwareModuleId = softwareModule.getId();
final List<SoftwareModuleMetadataCreate> metadata = new ArrayList<>(5);
for (int i = 0; i < 5; i++) {
metadata.add(
entityFactory.softwareModuleMetadata().create(softwareModule.getId()).key("" + i).value("" + i));
}
metadata.add(entityFactory.softwareModuleMetadata().create(softwareModule.getId()).key("targetVisible")
.value("targetVisible").targetVisible(true));
metadata.add(entityFactory.softwareModuleMetadata().create(softwareModule.getId()).key("emptyMd")
.targetVisible(true));
softwareModuleManagement.putMetaData(metadata);
}
@Test
@Description("Test filter software module metadata by key")
void testFilterByParameterKey() {
assertRSQLQuery(SoftwareModuleMetadataFields.KEY.name() + "==1", 1);
assertRSQLQuery(SoftwareModuleMetadataFields.KEY.name() + "!=1", 6);
assertRSQLQuery(SoftwareModuleMetadataFields.KEY.name() + "=in=(1,2)", 2);
assertRSQLQuery(SoftwareModuleMetadataFields.KEY.name() + "=out=(1,2)", 5);
}
@Test
@Description("Test fitler software module metadata by value")
void testFilterByParameterValue() {
assertRSQLQuery(SoftwareModuleMetadataFields.VALUE.name() + "==''", 1);
assertRSQLQuery(SoftwareModuleMetadataFields.VALUE.name() + "!=''", 6);
assertRSQLQuery(SoftwareModuleMetadataFields.VALUE.name() + "==1", 1);
assertRSQLQuery(SoftwareModuleMetadataFields.VALUE.name() + "!=1", 6);
assertRSQLQuery(SoftwareModuleMetadataFields.VALUE.name() + "=in=(1,2)", 2);
assertRSQLQuery(SoftwareModuleMetadataFields.VALUE.name() + "=out=(1,2)", 5);
}
@Test
@Description("Test fitler software module metadata by target visible")
void testFilterByParameterTargetVisible() {
assertRSQLQuery(SoftwareModuleMetadataFields.TARGETVISIBLE.name() + "==true", 2);
assertRSQLQuery(SoftwareModuleMetadataFields.TARGETVISIBLE.name() + "==false", 5);
assertRSQLQuery(SoftwareModuleMetadataFields.TARGETVISIBLE.name() + "!=false", 2);
assertRSQLQuery(SoftwareModuleMetadataFields.TARGETVISIBLE.name() + "!=true", 5);
}
private void assertRSQLQuery(final String rsqlParam, final long expectedEntities) {
final Page<SoftwareModuleMetadata> findEnitity = softwareModuleManagement
.findMetaDataByRsql(softwareModuleId, rsqlParam, PageRequest.of(0, 100));
final long countAllEntities = findEnitity.getTotalElements();
assertThat(findEnitity).isNotNull();
assertThat(countAllEntities).isEqualTo(expectedEntities);
}
}