[#1509] Sync Target type with SW and DS types (#1512)

Unifies Target type with the other types
* _TargetType_ made to inhert type, thus
* _TargetType_ now has immutable _key_
* add _AbstractJpaTypeEntity_ abstraction that implement the common 'type' JPA functionallity

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2023-12-12 15:24:57 +02:00
committed by GitHub
parent 4289f464c5
commit 71a5319019
12 changed files with 157 additions and 119 deletions

View File

@@ -16,11 +16,17 @@ import java.util.Set;
* {@link Target} * {@link Target}
* *
*/ */
public interface TargetType extends NamedEntity { public interface TargetType extends Type {
/** /**
* Maximum length of color in Management UI. * Target type doesn't support soft-delete so all target type instandces re not deleted.
*
* @return <code>false</code>
*/ */
int COLOUR_MAX_SIZE = 16; @Override
default boolean isDeleted() {
return false;
}
/** /**
* @return immutable set of optional {@link DistributionSetType}s * @return immutable set of optional {@link DistributionSetType}s
@@ -32,18 +38,6 @@ public interface TargetType extends NamedEntity {
*/ */
Set<Target> getTargets(); Set<Target> getTargets();
/**
* Checks if the given {@link DistributionSetType} is in
* {@link #getCompatibleDistributionSetTypes()}.
*
* @param distributionSetType
* search for
* @return <code>true</code> if found
*/
default boolean containsCompatibleDistributionSetType(final DistributionSetType distributionSetType) {
return containsCompatibleDistributionSetType(distributionSetType.getId());
}
/** /**
* Checks if the given {@link DistributionSetType} is in * Checks if the given {@link DistributionSetType} is in
* {@link #getCompatibleDistributionSetTypes()}. * {@link #getCompatibleDistributionSetTypes()}.
@@ -64,9 +58,4 @@ public interface TargetType extends NamedEntity {
* @return the resulting target type * @return the resulting target type
*/ */
TargetType removeDistributionSetType(final Long dsTypeId); TargetType removeDistributionSetType(final Long dsTypeId);
/**
* @return get color code to be used in management UI views.
*/
String getColour();
} }

View File

@@ -17,6 +17,8 @@ import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import java.io.Serial;
/** /**
* {@link TenantAwareBaseEntity} extension for all entities that are named in * {@link TenantAwareBaseEntity} extension for all entities that are named in
* addition to their technical ID. * addition to their technical ID.
@@ -26,15 +28,17 @@ import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
// sub entities // sub entities
@SuppressWarnings("squid:S2160") @SuppressWarnings("squid:S2160")
public abstract class AbstractJpaNamedEntity extends AbstractJpaTenantAwareBaseEntity implements NamedEntity { public abstract class AbstractJpaNamedEntity extends AbstractJpaTenantAwareBaseEntity implements NamedEntity {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Column(name = "name", nullable = false, length = NamedEntity.NAME_MAX_SIZE) @Column(name = "name", nullable = false, length = NAME_MAX_SIZE)
@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @Size(min = 1, max = NAME_MAX_SIZE)
@NotNull @NotNull
private String name; private String name;
@Column(name = "description", length = NamedEntity.DESCRIPTION_MAX_SIZE) @Column(name = "description", length = DESCRIPTION_MAX_SIZE)
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) @Size(max = DESCRIPTION_MAX_SIZE)
private String description; private String description;
/** /**

View File

@@ -0,0 +1,80 @@
/**
* 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 org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.eclipse.hawkbit.repository.model.Type;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serial;
/**
* {@link TenantAwareBaseEntity} extension for all entities that are named in
* addition to their technical ID.
*/
@MappedSuperclass
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities
@SuppressWarnings("squid:S2160")
public abstract class AbstractJpaTypeEntity extends AbstractJpaNamedEntity implements Type {
@Serial
private static final long serialVersionUID = 1L;
@Column(name = "type_key", nullable = false, updatable = false, length = KEY_MAX_SIZE)
@Size(min = 1, max = KEY_MAX_SIZE)
@NotNull
private String key;
@Column(name = "colour", length = COLOUR_MAX_SIZE)
@Size(max = COLOUR_MAX_SIZE)
private String colour;
/**
* Default constructor.
*/
protected AbstractJpaTypeEntity() {
// Default constructor needed for JPA entities
}
/**
* Parameterized constructor.
*
* @param key
* of the {@link Type}
* @param colour
* of the {@link Type}
*/
AbstractJpaTypeEntity(final String name, final String description, final String key, final String colour) {
super(name, description);
this.key = key;
this.colour = colour;
}
@Override
public String getKey() {
return key;
}
@Override
public String getColour() {
return colour;
}
public void setKey(final String key) {
this.key = key;
}
public void setColour(final String colour) {
this.colour = colour;
}
}

View File

@@ -31,8 +31,7 @@ import javax.persistence.ManyToMany;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull; import java.io.Serial;
import javax.validation.constraints.Size;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -54,7 +53,9 @@ import java.util.stream.Collectors;
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
// sub entities // sub entities
@SuppressWarnings("squid:S2160") @SuppressWarnings("squid:S2160")
public class JpaDistributionSetType extends AbstractJpaNamedEntity implements DistributionSetType, EventAwareEntity { public class JpaDistributionSetType extends AbstractJpaTypeEntity implements DistributionSetType, EventAwareEntity {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@CascadeOnDelete @CascadeOnDelete
@@ -62,15 +63,6 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
CascadeType.PERSIST }, fetch = FetchType.EAGER, orphanRemoval = true) CascadeType.PERSIST }, fetch = FetchType.EAGER, orphanRemoval = true)
private Set<DistributionSetTypeElement> elements; private Set<DistributionSetTypeElement> elements;
@Column(name = "type_key", nullable = false, updatable = false, length = DistributionSetType.KEY_MAX_SIZE)
@Size(min = 1, max = DistributionSetType.KEY_MAX_SIZE)
@NotNull
private String key;
@Column(name = "colour", nullable = true, length = DistributionSetType.COLOUR_MAX_SIZE)
@Size(max = DistributionSetType.COLOUR_MAX_SIZE)
private String colour;
@Column(name = "deleted") @Column(name = "deleted")
private boolean deleted; private boolean deleted;
@@ -109,9 +101,7 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
* of the type. It will be null by default * of the type. It will be null by default
*/ */
public JpaDistributionSetType(final String key, final String name, final String description, final String colour) { public JpaDistributionSetType(final String key, final String name, final String description, final String colour) {
super(name, description); super(name, description, key, colour);
this.key = key;
this.colour = colour;
} }
@Override @Override
@@ -205,15 +195,6 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
return this; return this;
} }
@Override
public String getKey() {
return key;
}
public void setKey(final String key) {
this.key = key;
}
@Override @Override
public boolean checkComplete(final DistributionSet distributionSet) { public boolean checkComplete(final DistributionSet distributionSet) {
final List<SoftwareModuleType> smTypes = distributionSet.getModules().stream().map(SoftwareModule::getType) final List<SoftwareModuleType> smTypes = distributionSet.getModules().stream().map(SoftwareModule::getType)
@@ -224,15 +205,6 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
return smTypes.containsAll(getMandatoryModuleTypes()); return smTypes.containsAll(getMandatoryModuleTypes());
} }
@Override
public String getColour() {
return colour;
}
public void setColour(final String colour) {
this.colour = colour;
}
public Set<DistributionSetTypeElement> getElements() { public Set<DistributionSetTypeElement> getElements() {
if (elements == null) { if (elements == null) {
return Collections.emptySet(); return Collections.emptySet();
@@ -243,7 +215,7 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
@Override @Override
public String toString() { public String toString() {
return "DistributionSetType [key=" + key + ", isDeleted()=" + isDeleted() + ", getId()=" + getId() + "]"; return "DistributionSetType [key=" + getKey() + ", isDeleted()=" + isDeleted() + ", getId()=" + getId() + "]";
} }
@Override @Override

View File

@@ -15,8 +15,6 @@ import javax.persistence.Index;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Min; import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.event.remote.SoftwareModuleTypeDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.SoftwareModuleTypeDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleTypeCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleTypeCreatedEvent;
@@ -25,6 +23,8 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder; import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEvent;
import java.io.Serial;
/** /**
* Type of a software modules. * Type of a software modules.
* *
@@ -38,22 +38,15 @@ import org.eclipse.persistence.descriptors.DescriptorEvent;
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
// sub entities // sub entities
@SuppressWarnings("squid:S2160") @SuppressWarnings("squid:S2160")
public class JpaSoftwareModuleType extends AbstractJpaNamedEntity implements SoftwareModuleType, EventAwareEntity { public class JpaSoftwareModuleType extends AbstractJpaTypeEntity implements SoftwareModuleType, EventAwareEntity {
private static final long serialVersionUID = 1L;
@Column(name = "type_key", nullable = false, length = SoftwareModuleType.KEY_MAX_SIZE) @Serial
@Size(min = 1, max = SoftwareModuleType.KEY_MAX_SIZE) private static final long serialVersionUID = 1L;
@NotNull
private String key;
@Column(name = "max_ds_assignments", nullable = false) @Column(name = "max_ds_assignments", nullable = false)
@Min(1) @Min(1)
private int maxAssignments; private int maxAssignments;
@Column(name = "colour", nullable = true, length = SoftwareModuleType.COLOUR_MAX_SIZE)
@Size(max = SoftwareModuleType.COLOUR_MAX_SIZE)
private String colour;
@Column(name = "deleted") @Column(name = "deleted")
private boolean deleted; private boolean deleted;
@@ -90,11 +83,8 @@ public class JpaSoftwareModuleType extends AbstractJpaNamedEntity implements Sof
*/ */
public JpaSoftwareModuleType(final String key, final String name, final String description, public JpaSoftwareModuleType(final String key, final String name, final String description,
final int maxAssignments, final String colour) { final int maxAssignments, final String colour) {
this.key = key; super(name, description, key, colour);
this.maxAssignments = maxAssignments; this.maxAssignments = maxAssignments;
setDescription(description);
setName(name);
this.colour = colour;
} }
/** /**
@@ -108,11 +98,6 @@ public class JpaSoftwareModuleType extends AbstractJpaNamedEntity implements Sof
this.maxAssignments = maxAssignments; this.maxAssignments = maxAssignments;
} }
@Override
public String getKey() {
return key;
}
@Override @Override
public int getMaxAssignments() { public int getMaxAssignments() {
return maxAssignments; return maxAssignments;
@@ -127,22 +112,9 @@ public class JpaSoftwareModuleType extends AbstractJpaNamedEntity implements Sof
this.deleted = deleted; this.deleted = deleted;
} }
@Override
public String getColour() {
return colour;
}
public void setColour(final String colour) {
this.colour = colour;
}
@Override @Override
public String toString() { public String toString() {
return "SoftwareModuleType [key=" + key + ", getName()=" + getName() + ", getId()=" + getId() + "]"; return "SoftwareModuleType [key=" + getKey() + ", getName()=" + getName() + ", getId()=" + getId() + "]";
}
public void setKey(final String key) {
this.key = key;
} }
@Override @Override

View File

@@ -19,7 +19,6 @@ import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.persistence.annotations.CascadeOnDelete; import org.eclipse.persistence.annotations.CascadeOnDelete;
import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEvent;
import javax.persistence.Column;
import javax.persistence.ConstraintMode; import javax.persistence.ConstraintMode;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.FetchType; import javax.persistence.FetchType;
@@ -31,7 +30,7 @@ import javax.persistence.ManyToMany;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Size; import java.io.Serial;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@@ -45,14 +44,11 @@ import java.util.Set;
@Table(name = "sp_target_type", indexes = { @Table(name = "sp_target_type", indexes = {
@Index(name = "sp_idx_target_type_prim", columnList = "tenant,id") }, uniqueConstraints = { @Index(name = "sp_idx_target_type_prim", columnList = "tenant,id") }, uniqueConstraints = {
@UniqueConstraint(columnNames = { "name", "tenant" }, name = "uk_target_type_name")}) @UniqueConstraint(columnNames = { "name", "tenant" }, name = "uk_target_type_name")})
public class JpaTargetType extends AbstractJpaNamedEntity implements TargetType, EventAwareEntity{ public class JpaTargetType extends AbstractJpaTypeEntity implements TargetType, EventAwareEntity {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Column(name = "colour", nullable = true, length = TargetType.COLOUR_MAX_SIZE)
@Size(max = TargetType.COLOUR_MAX_SIZE)
private String colour;
@CascadeOnDelete @CascadeOnDelete
@ManyToMany(targetEntity = JpaDistributionSetType.class) @ManyToMany(targetEntity = JpaDistributionSetType.class)
@JoinTable(name = "sp_target_type_ds_type_relation", joinColumns = { @JoinTable(name = "sp_target_type_ds_type_relation", joinColumns = {
@@ -74,15 +70,30 @@ public class JpaTargetType extends AbstractJpaNamedEntity implements TargetType,
* Constructor * Constructor
* *
* @param name * @param name
* Type name * of the type
* @param description * @param description
* Description * of the type
* @param colour * @param colour
* Colour * of the type
*/ */
public JpaTargetType(String name, String description, String colour) { public JpaTargetType(final String name, final String description, final String colour) {
super(name,description); this(name, name, description, colour);
this.colour = colour; }
/**
* Constructor.
*
* @param key
* of the type
* @param name
* of the type
* @param description
* of the type
* @param colour
* of the type. It will be null by default
*/
public JpaTargetType(final String key, final String name, final String description, final String colour) {
super(name, description, key, colour);
} }
/** /**
@@ -90,13 +101,12 @@ public class JpaTargetType extends AbstractJpaNamedEntity implements TargetType,
* Distribution set type * Distribution set type
* @return Target type * @return Target type
*/ */
public JpaTargetType addCompatibleDistributionSetType(final DistributionSetType dsSetType) { public void addCompatibleDistributionSetType(final DistributionSetType dsSetType) {
if (distributionSetTypes == null) { if (distributionSetTypes == null) {
distributionSetTypes = new HashSet<>(); distributionSetTypes = new HashSet<>();
} }
distributionSetTypes.add(dsSetType); distributionSetTypes.add(dsSetType);
return this;
} }
/** /**
@@ -129,28 +139,24 @@ public class JpaTargetType extends AbstractJpaNamedEntity implements TargetType,
} }
@Override @Override
public String getColour() { public String toString() {
return colour; return "TargetType [key=" + getKey() + ", isDeleted()=" + isDeleted() + ", getId()=" + getId() + "]";
}
public void setColour(final String colour) {
this.colour = colour;
} }
@Override @Override
public void fireCreateEvent(DescriptorEvent descriptorEvent) { public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
EventPublisherHolder.getInstance().getEventPublisher().publishEvent( EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
new TargetTypeCreatedEvent(this, EventPublisherHolder.getInstance().getApplicationId())); new TargetTypeCreatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
} }
@Override @Override
public void fireUpdateEvent(DescriptorEvent descriptorEvent) { public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
EventPublisherHolder.getInstance().getEventPublisher().publishEvent( EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
new TargetTypeUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId())); new TargetTypeUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
} }
@Override @Override
public void fireDeleteEvent(DescriptorEvent descriptorEvent) { public void fireDeleteEvent(final DescriptorEvent descriptorEvent) {
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(new TargetTypeDeletedEvent( EventPublisherHolder.getInstance().getEventPublisher().publishEvent(new TargetTypeDeletedEvent(
getTenant(), getId(), getClass(), EventPublisherHolder.getInstance().getApplicationId())); getTenant(), getId(), getClass(), EventPublisherHolder.getInstance().getApplicationId()));
} }

View File

@@ -0,0 +1,3 @@
ALTER TABLE sp_target_type ADD COLUMN type_key VARCHAR (64) NOT NULL DEFAULT ('_');
UPDATE sp_target_type SET type_key = name;
ALTER TABLE sp_target_type ADD CONSTRAINT uk_target_type_key UNIQUE (type_key, tenant);

View File

@@ -0,0 +1,3 @@
ALTER TABLE sp_target_type ADD COLUMN type_key VARCHAR (64) NOT NULL DEFAULT ('_');
UPDATE sp_target_type SET type_key = name;
ALTER TABLE sp_target_type ADD CONSTRAINT uk_target_type_key UNIQUE (type_key, tenant);

View File

@@ -0,0 +1,3 @@
ALTER TABLE sp_target_type ADD COLUMN type_key VARCHAR (64) NOT NULL DEFAULT ('_');
UPDATE sp_target_type SET type_key = name;
ALTER TABLE sp_target_type ADD CONSTRAINT uk_target_type_key UNIQUE (type_key, tenant);

View File

@@ -0,0 +1,3 @@
ALTER TABLE sp_target_type ADD COLUMN type_key VARCHAR (64) NOT NULL DEFAULT ('_');
UPDATE sp_target_type SET type_key = name;
ALTER TABLE sp_target_type ADD CONSTRAINT uk_target_type_key UNIQUE (type_key, tenant);

View File

@@ -0,0 +1,3 @@
ALTER TABLE sp_target_type ADD type_key VARCHAR (64) NOT NULL DEFAULT ('_');
UPDATE sp_target_type SET type_key = name;
ALTER TABLE sp_target_type ADD CONSTRAINT uk_target_type_key UNIQUE (type_key, tenant);

View File

@@ -74,14 +74,14 @@ public class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest
@Test @Test
@Description("Calling update for changed fields results in change in the repository.") @Description("Calling update for changed fields results in change in the repository.")
public void updateSoftareModuleTypeFieldsToNewValue() { public void updateSoftwareModuleTypeFieldsToNewValue() {
final SoftwareModuleType created = softwareModuleTypeManagement final SoftwareModuleType created = softwareModuleTypeManagement
.create(entityFactory.softwareModuleType().create().key("test-key").name("test-name")); .create(entityFactory.softwareModuleType().create().key("test-key").name("test-name"));
final SoftwareModuleType updated = softwareModuleTypeManagement.update( final SoftwareModuleType updated = softwareModuleTypeManagement.update(
entityFactory.softwareModuleType().update(created.getId()).description("changed").colour("changed")); entityFactory.softwareModuleType().update(created.getId()).description("changed").colour("changed"));
assertThat(updated.getOptLockRevision()).as("Expected version number of updated entitity is") assertThat(updated.getOptLockRevision()).as("Expected version number of updated entities is")
.isEqualTo(created.getOptLockRevision() + 1); .isEqualTo(created.getOptLockRevision() + 1);
assertThat(updated.getDescription()).as("Updated description is").isEqualTo("changed"); assertThat(updated.getDescription()).as("Updated description is").isEqualTo("changed");
assertThat(updated.getColour()).as("Updated vendor is").isEqualTo("changed"); assertThat(updated.getColour()).as("Updated vendor is").isEqualTo("changed");