Put BaseEntity below tenant aware and unaware entities

This commit is contained in:
Kai Zimmermann
2016-03-23 14:09:40 +01:00
parent 061159f259
commit 6ee66dc4e1
27 changed files with 178 additions and 383 deletions

View File

@@ -154,6 +154,7 @@ public class SimulatorView extends VerticalLayout implements View {
public void pollCounterUpdate(final NextPollCounterUpdate update) { public void pollCounterUpdate(final NextPollCounterUpdate update) {
final List<AbstractSimulatedDevice> devices = update.getDevices(); final List<AbstractSimulatedDevice> devices = update.getDevices();
this.getUI().access(new Runnable() { this.getUI().access(new Runnable() {
@Override @Override
public void run() { public void run() {
devices.forEach(device -> { devices.forEach(device -> {
@@ -176,6 +177,7 @@ public class SimulatorView extends VerticalLayout implements View {
public void initUpdate(final InitUpdate update) { public void initUpdate(final InitUpdate update) {
final AbstractSimulatedDevice device = update.getDevice(); final AbstractSimulatedDevice device = update.getDevice();
this.getUI().access(new Runnable() { this.getUI().access(new Runnable() {
@Override @Override
public void run() { public void run() {
final BeanItem<AbstractSimulatedDevice> item = beanContainer.getItem(device.getId()); final BeanItem<AbstractSimulatedDevice> item = beanContainer.getItem(device.getId());

View File

@@ -38,10 +38,7 @@ import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSFile; import com.mongodb.gridfs.GridFSFile;
/** /**
* The file management which looks up all the file in the filestore. * The file management which looks up all the file in the file tore.
*
*
*
* *
*/ */
public class ArtifactStore implements ArtifactRepository { public class ArtifactStore implements ArtifactRepository {
@@ -75,11 +72,10 @@ public class ArtifactStore implements ArtifactRepository {
/** /**
* Retrieves a {@link GridFSDBFile} from the store by it's SHA1 hash. * Retrieves a {@link GridFSDBFile} from the store by it's SHA1 hash.
* *
* @param tenant
* the tenant to retrieve the artifacts from, ignore case.
* @param sha1Hash * @param sha1Hash
* the sha1-hash of the file to lookup. * the sha1-hash of the file to lookup.
* @return The gridfs file object or {@code null} if no file exists. *
* @return The DbArtifact object or {@code null} if no file exists.
*/ */
@Override @Override
public DbArtifact getArtifactBySha1(final String sha1Hash) { public DbArtifact getArtifactBySha1(final String sha1Hash) {
@@ -226,8 +222,7 @@ public class ArtifactStore implements ArtifactRepository {
* @return a paged list of artifacts mapped from the given dbFiles * @return a paged list of artifacts mapped from the given dbFiles
*/ */
private List<DbArtifact> map(final List<GridFSDBFile> dbFiles) { private List<DbArtifact> map(final List<GridFSDBFile> dbFiles) {
final List<DbArtifact> collect = dbFiles.stream().map(dbFile -> map(dbFile)).collect(Collectors.toList()); return dbFiles.stream().map(dbFile -> map(dbFile)).collect(Collectors.toList());
return collect;
} }
/** /**
@@ -238,7 +233,7 @@ public class ArtifactStore implements ArtifactRepository {
* the tenant to retrieve the artifacts from, ignore case. * the tenant to retrieve the artifacts from, ignore case.
* @param sha1Hashes * @param sha1Hashes
* the sha1-hashes of the files to lookup. * the sha1-hashes of the files to lookup.
* @return list of artfiacts * @return list of artifacts
*/ */
@Override @Override
public List<DbArtifact> getArtifactsBySha1(final List<String> sha1Hashes) { public List<DbArtifact> getArtifactsBySha1(final List<String> sha1Hashes) {

View File

@@ -14,9 +14,6 @@ import java.io.OutputStream;
/** /**
* Database representation of artifact. * Database representation of artifact.
* *
*
*
*
*/ */
public class DbArtifact { public class DbArtifact {

View File

@@ -11,9 +11,6 @@ package org.eclipse.hawkbit.artifact.repository.model;
/** /**
* Database representation of artifact hash. * Database representation of artifact hash.
* *
*
*
*
*/ */
public class DbArtifactHash { public class DbArtifactHash {

View File

@@ -11,9 +11,6 @@ package org.eclipse.hawkbit;
/** /**
* A constant class which holds only static constants used within the SP server. * A constant class which holds only static constants used within the SP server.
* *
*
*
*
*/ */
public final class Constants { public final class Constants {
@@ -27,7 +24,7 @@ public final class Constants {
public static final int MAX_ENTRIES_IN_STATEMENT = 999; public static final int MAX_ENTRIES_IN_STATEMENT = 999;
/** /**
* constant class only private constructor. * Constant class only private constructor.
*/ */
private Constants() { private Constants() {

View File

@@ -20,7 +20,7 @@ import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent;
import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor; import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.TargetRepository; import org.eclipse.hawkbit.repository.TargetRepository;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
@@ -31,7 +31,7 @@ import com.google.common.eventbus.EventBus;
/** /**
* An aspect implementation which wraps the necessary repository services for * An aspect implementation which wraps the necessary repository services for
* saving {@link BaseEntity}s to publish create or update events. * saving {@link TenantAwareBaseEntity}s to publish create or update events.
* *
* *
* *

View File

@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.eventbus.event.RolloutGroupPropertyChangeEvent;
import org.eclipse.hawkbit.eventbus.event.RolloutPropertyChangeEvent; import org.eclipse.hawkbit.eventbus.event.RolloutPropertyChangeEvent;
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor; import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.model.helper.AfterTransactionCommitExecutorHolder;
@@ -83,7 +83,7 @@ public class EntityPropertyChangeListener extends DescriptorEventAdapter {
} }
} }
private <T extends BaseEntity> Map<String, AbstractPropertyChangeEvent<T>.Values> getChangeSet( private <T extends TenantAwareBaseEntity> Map<String, AbstractPropertyChangeEvent<T>.Values> getChangeSet(
final Class<T> clazz, final DescriptorEvent event) { final Class<T> clazz, final DescriptorEvent event) {
final T rolloutGroup = clazz.cast(event.getObject()); final T rolloutGroup = clazz.cast(event.getObject());
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet(); final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();

View File

@@ -8,18 +8,18 @@
*/ */
package org.eclipse.hawkbit.eventbus.event; package org.eclipse.hawkbit.eventbus.event;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
/** /**
* An abstract definition class for {@link EntityEvent} for {@link BaseEntity}s, * An abstract definition class for {@link EntityEvent} for {@link TenantAwareBaseEntity}s,
* which holds the {@link BaseEntity}. * which holds the {@link TenantAwareBaseEntity}.
* *
* *
* *
* @param <E> * @param <E>
* the type of the {@link BaseEntity} * the type of the {@link TenantAwareBaseEntity}
*/ */
public abstract class AbstractBaseEntityEvent<E extends BaseEntity> extends AbstractDistributedEvent public abstract class AbstractBaseEntityEvent<E extends TenantAwareBaseEntity> extends AbstractDistributedEvent
implements EntityEvent { implements EntityEvent {
/** /**

View File

@@ -11,7 +11,7 @@ package org.eclipse.hawkbit.eventbus.event;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
/** /**
* *
@@ -19,7 +19,7 @@ import org.eclipse.hawkbit.repository.model.BaseEntity;
* *
* @param <E> * @param <E>
*/ */
public abstract class AbstractEntityBulkEvent<E extends BaseEntity> implements EntityBulkEvent<E> { public abstract class AbstractEntityBulkEvent<E extends TenantAwareBaseEntity> implements EntityBulkEvent<E> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@@ -10,14 +10,14 @@ package org.eclipse.hawkbit.eventbus.event;
import java.util.Map; import java.util.Map;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
/** /**
* Property change event. * Property change event.
* *
* @param <E> * @param <E>
*/ */
public class AbstractPropertyChangeEvent<E extends BaseEntity> extends AbstractBaseEntityEvent<E> { public class AbstractPropertyChangeEvent<E extends TenantAwareBaseEntity> extends AbstractBaseEntityEvent<E> {
private static final long serialVersionUID = -3671601415138242311L; private static final long serialVersionUID = -3671601415138242311L;
private final transient Map<String, Values> changeSet; private final transient Map<String, Values> changeSet;

View File

@@ -11,7 +11,7 @@ package org.eclipse.hawkbit.eventbus.event;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
/** /**
* An event interface which declares event types that an entities has been * An event interface which declares event types that an entities has been
@@ -20,7 +20,7 @@ import org.eclipse.hawkbit.repository.model.BaseEntity;
* @param <E> * @param <E>
* the entity type * the entity type
*/ */
public interface EntityBulkEvent<E extends BaseEntity> extends Serializable, Event { public interface EntityBulkEvent<E extends TenantAwareBaseEntity> extends Serializable, Event {
/** /**
* A typesafe way to retrieve the the entities from the event, which might * A typesafe way to retrieve the the entities from the event, which might

View File

@@ -10,14 +10,14 @@ package org.eclipse.hawkbit.repository;
import java.io.Serializable; import java.io.Serializable;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Command repository operations for all {@link BaseEntity}s. * Command repository operations for all {@link TenantAwareBaseEntity}s.
* *
* *
* *
@@ -29,11 +29,11 @@ import org.springframework.transaction.annotation.Transactional;
*/ */
@NoRepositoryBean @NoRepositoryBean
@Transactional(readOnly = true) @Transactional(readOnly = true)
public interface BaseEntityRepository<T extends BaseEntity, I extends Serializable> public interface BaseEntityRepository<T extends TenantAwareBaseEntity, I extends Serializable>
extends PagingAndSortingRepository<T, I> { extends PagingAndSortingRepository<T, I> {
/** /**
* Deletes all {@link BaseEntity} of a given tenant. * Deletes all {@link TenantAwareBaseEntity} of a given tenant.
* *
* @param tenant * @param tenant
* to delete data from * to delete data from

View File

@@ -176,7 +176,7 @@ public class DistributionSetManagement {
final Iterable<DistributionSet> sets = findDistributionSetListWithDetails(dsIds); final Iterable<DistributionSet> sets = findDistributionSetListWithDetails(dsIds);
final DistributionSetTag myTag = tagManagement.findDistributionSetTag(tagName); final DistributionSetTag myTag = tagManagement.findDistributionSetTag(tagName);
DistributionSetTagAssigmentResult result = null; DistributionSetTagAssigmentResult result;
final List<DistributionSet> allDSs = new ArrayList<>(); final List<DistributionSet> allDSs = new ArrayList<>();
for (final DistributionSet set : sets) { for (final DistributionSet set : sets) {
if (set.getTags().add(myTag)) { if (set.getTags().add(myTag)) {
@@ -199,8 +199,7 @@ public class DistributionSetManagement {
} }
final DistributionSetTagAssigmentResult resultAssignment = result; final DistributionSetTagAssigmentResult resultAssignment = result;
afterCommit afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagAssigmentResultEvent(resultAssignment)));
.afterCommit(() -> eventBus.post(new DistributionSetTagAssigmentResultEvent(resultAssignment)));
// no reason to persist the tag // no reason to persist the tag
entityManager.detach(myTag); entityManager.detach(myTag);

View File

@@ -327,13 +327,11 @@ public class SystemManagement {
"Standard Edge Controller Linux distribution set type. OS only.").addMandatoryModuleType(eclOs) "Standard Edge Controller Linux distribution set type. OS only.").addMandatoryModuleType(eclOs)
.addOptionalModuleType(eclApp)); .addOptionalModuleType(eclApp));
final DistributionSetType defaultType = distributionSetTypeRepository return distributionSetTypeRepository
.save(new DistributionSetType("ecl_os_app_jvm", "OS with optional app and jvm", .save(new DistributionSetType("ecl_os_app_jvm", "OS with optional app and jvm",
"Standard Edge Controller Linux distribution set type. OS with optional application.") "Standard Edge Controller Linux distribution set type. OS with optional application.")
.addMandatoryModuleType(eclOs).addOptionalModuleType(eclApp) .addMandatoryModuleType(eclOs).addOptionalModuleType(eclApp)
.addOptionalModuleType(eclJvm)); .addOptionalModuleType(eclJvm));
return defaultType;
} }
/** /**

View File

@@ -52,7 +52,7 @@ import org.eclipse.persistence.annotations.CascadeOnDelete;
@NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"),
@NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet") ) ) }) @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet") ) ) })
@Entity @Entity
public class Action extends BaseEntity implements Comparable<Action> { public class Action extends TenantAwareBaseEntity implements Comparable<Action> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**

View File

@@ -41,7 +41,7 @@ import com.google.common.base.Splitter;
@Index(name = "sp_idx_action_status_prim", columnList = "tenant,id") }) @Index(name = "sp_idx_action_status_prim", columnList = "tenant,id") })
@NamedEntityGraph(name = "ActionStatus.withMessages", attributeNodes = { @NamedAttributeNode("messages") }) @NamedEntityGraph(name = "ActionStatus.withMessages", attributeNodes = { @NamedAttributeNode("messages") })
@Entity @Entity
public class ActionStatus extends BaseEntity { public class ActionStatus extends TenantAwareBaseEntity {
/** /**
* *
@@ -103,66 +103,46 @@ public class ActionStatus extends BaseEntity {
} }
/** /**
* * JPA default constructor.
*/ */
public ActionStatus() { public ActionStatus() {
// JPA default constructor.
} }
/**
* @return the occurredAt
*/
public Long getOccurredAt() { public Long getOccurredAt() {
return occurredAt; return occurredAt;
} }
/**
* @param occurredAt
* the occurredAt to set
*/
public void setOccurredAt(final Long occurredAt) { public void setOccurredAt(final Long occurredAt) {
this.occurredAt = occurredAt; this.occurredAt = occurredAt;
} }
/** /**
* Adds message. * Adds message including splitting in case it exceeds 512 length.
* *
* @param message * @param message
* to add * to add
*/ */
public final void addMessage(final String message) { public final void addMessage(final String message) {
Splitter.fixedLength(512).split(message).forEach(chunk -> messages.add(chunk)); Splitter.fixedLength(512).split(message).forEach(messages::add);
} }
public List<String> getMessages() { public List<String> getMessages() {
return messages; return messages;
} }
/**
* @return the action
*/
public Action getAction() { public Action getAction() {
return action; return action;
} }
/**
* @param action
* the action to set
*/
public void setAction(final Action action) { public void setAction(final Action action) {
this.action = action; this.action = action;
} }
/**
* @return the status
*/
public Status getStatus() { public Status getStatus() {
return status; return status;
} }
/**
* @param status
* the status to set
*/
public void setStatus(final Status status) { public void setStatus(final Status status) {
this.status = status; this.status = status;
} }

View File

@@ -20,7 +20,7 @@ import javax.persistence.MappedSuperclass;
* *
*/ */
@MappedSuperclass @MappedSuperclass
public abstract class Artifact extends BaseEntity { public abstract class Artifact extends TenantAwareBaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Column(name = "sha1_hash", length = 40, nullable = true) @Column(name = "sha1_hash", length = 40, nullable = true)

View File

@@ -18,17 +18,10 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.MappedSuperclass; import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.Version; import javax.persistence.Version;
import org.eclipse.hawkbit.eventbus.CacheFieldEntityListener; import org.eclipse.hawkbit.eventbus.CacheFieldEntityListener;
import org.eclipse.hawkbit.eventbus.EntityPropertyChangeListener; import org.eclipse.hawkbit.eventbus.EntityPropertyChangeListener;
import org.eclipse.hawkbit.repository.exception.TenantNotExistException;
import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder;
import org.eclipse.hawkbit.repository.model.helper.TenantAwareHolder;
import org.eclipse.persistence.annotations.Multitenant;
import org.eclipse.persistence.annotations.MultitenantType;
import org.eclipse.persistence.annotations.TenantDiscriminatorColumn;
import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedBy;
@@ -37,18 +30,12 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.hateoas.Identifiable; import org.springframework.hateoas.Identifiable;
/** /**
* Holder of all base attributes common to all entities. * Holder of the base attributes common to all entities.
*
*
*
*
* *
*/ */
@MappedSuperclass @MappedSuperclass
@Access(AccessType.FIELD) @Access(AccessType.FIELD)
@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class }) @EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class })
@TenantDiscriminatorColumn(name = "tenant", length = 40)
@Multitenant(MultitenantType.SINGLE_TABLE)
public abstract class BaseEntity implements Serializable, Identifiable<Long> { public abstract class BaseEntity implements Serializable, Identifiable<Long> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -66,44 +53,11 @@ public abstract class BaseEntity implements Serializable, Identifiable<Long> {
@Column(name = "optlock_revision") @Column(name = "optlock_revision")
private long optLockRevision; private long optLockRevision;
@Column(name = "tenant", nullable = false, insertable = false, updatable = false, length = 40)
private String tenant;
/** /**
* * Default constructor needed for JPA entities.
*/ */
public BaseEntity() { public BaseEntity() {
// Default constructor needed for JPA entities.
}
/**
* @param entity
* the entity to copy
*/
public BaseEntity(final BaseEntity entity) {
id = entity.id;
createdAt = entity.createdAt;
createdBy = entity.createdBy;
lastModifiedAt = entity.lastModifiedAt;
lastModifiedBy = entity.lastModifiedBy;
optLockRevision = entity.optLockRevision;
}
/**
* PrePersist listener method for all {@link BaseEntity} entities.
*/
@PrePersist
public void prePersist() {
// before persisting the entity check the current ID of the tenant by
// using the TenantAware
// service
final String currentTenant = SystemManagementHolder.getInstance().currentTenant();
if (currentTenant == null) {
throw new TenantNotExistException("Tenant "
+ TenantAwareHolder.getInstance().getTenantAware().getCurrentTenant()
+ " does not exists, cannot create entity " + this.getClass() + " with id " + id);
}
setTenant(currentTenant.toUpperCase());
} }
@Access(AccessType.PROPERTY) @Access(AccessType.PROPERTY)
@@ -130,37 +84,21 @@ public abstract class BaseEntity implements Serializable, Identifiable<Long> {
return lastModifiedBy; return lastModifiedBy;
} }
/**
* @param createdBy
* the createdBy to set
*/
@CreatedBy @CreatedBy
public void setCreatedBy(final String createdBy) { public void setCreatedBy(final String createdBy) {
this.createdBy = createdBy; this.createdBy = createdBy;
} }
/**
* @param lastModifiedBy
* the lastModifiedBy to set
*/
@LastModifiedBy @LastModifiedBy
public void setLastModifiedBy(final String lastModifiedBy) { public void setLastModifiedBy(final String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy; this.lastModifiedBy = lastModifiedBy;
} }
/**
* @param createdAt
* the createdAt to set
*/
@CreatedDate @CreatedDate
public void setCreatedAt(final Long createdAt) { public void setCreatedAt(final Long createdAt) {
this.createdAt = createdAt; this.createdAt = createdAt;
} }
/**
* @param lastModifiedAt
* the lastModifiedAt to set
*/
@LastModifiedDate @LastModifiedDate
public void setLastModifiedAt(final Long lastModifiedAt) { public void setLastModifiedAt(final Long lastModifiedAt) {
this.lastModifiedAt = lastModifiedAt; this.lastModifiedAt = lastModifiedAt;
@@ -170,52 +108,20 @@ public abstract class BaseEntity implements Serializable, Identifiable<Long> {
return optLockRevision; return optLockRevision;
} }
/**
* @return the tenant
*/
public String getTenant() {
return tenant;
}
/**
* @param tenant
* the tenant to set
*/
public void setTenant(final String tenant) {
this.tenant = tenant;
}
/**
* @return the id
*/
@Override @Override
public Long getId() { public Long getId() {
return id; return id;
} }
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override @Override
public String toString() { public String toString() {
return "BaseEntity [id=" + id + "]"; return "BaseEntity [id=" + id + "]";
} }
/**
* @param id
* the id to set
*/
public void setId(final Long id) { public void setId(final Long id) {
this.id = id; this.id = id;
} }
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override @Override
public int hashCode() { // NOSONAR - as this is generated code public int hashCode() { // NOSONAR - as this is generated code
final int prime = 31; final int prime = 31;
@@ -225,11 +131,6 @@ public abstract class BaseEntity implements Serializable, Identifiable<Long> {
return result; return result;
} }
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override @Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated public boolean equals(final Object obj) { // NOSONAR - as this is generated
// code // code

View File

@@ -12,7 +12,7 @@ import javax.persistence.Column;
import javax.persistence.MappedSuperclass; import javax.persistence.MappedSuperclass;
/** /**
* {@link BaseEntity} extension for all entities that are named in addition to * {@link TenantAwareBaseEntity} extension for all entities that are named in addition to
* their technical ID. * their technical ID.
* *
* *
@@ -22,7 +22,7 @@ import javax.persistence.MappedSuperclass;
* *
*/ */
@MappedSuperclass @MappedSuperclass
public abstract class NamedEntity extends BaseEntity { public abstract class NamedEntity extends TenantAwareBaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Column(name = "name", nullable = false, length = 64) @Column(name = "name", nullable = false, length = 64)

View File

@@ -22,7 +22,7 @@ import javax.persistence.UniqueConstraint;
@Table(name = "sp_target_filter_query", indexes = { @Table(name = "sp_target_filter_query", indexes = {
@Index(name = "sp_idx_target_filter_query_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { @Index(name = "sp_idx_target_filter_query_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = {
"name", "tenant" }, name = "uk_tenant_custom_filter_name") ) "name", "tenant" }, name = "uk_tenant_custom_filter_name") )
public class TargetFilterQuery extends BaseEntity { public class TargetFilterQuery extends TenantAwareBaseEntity {
/** /**
* *
* *

View File

@@ -0,0 +1,108 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.model;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import org.eclipse.hawkbit.eventbus.CacheFieldEntityListener;
import org.eclipse.hawkbit.eventbus.EntityPropertyChangeListener;
import org.eclipse.hawkbit.repository.exception.TenantNotExistException;
import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder;
import org.eclipse.hawkbit.repository.model.helper.TenantAwareHolder;
import org.eclipse.persistence.annotations.Multitenant;
import org.eclipse.persistence.annotations.MultitenantType;
import org.eclipse.persistence.annotations.TenantDiscriminatorColumn;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/**
* Holder of the base attributes common to all tenant aware entities.
*
*/
@MappedSuperclass
@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class })
@TenantDiscriminatorColumn(name = "tenant", length = 40)
@Multitenant(MultitenantType.SINGLE_TABLE)
public abstract class TenantAwareBaseEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
@Column(name = "tenant", nullable = false, insertable = false, updatable = false, length = 40)
private String tenant;
/**
* Default constructor needed for JPA entities.
*/
public TenantAwareBaseEntity() {
// Default constructor needed for JPA entities.
}
/**
* PrePersist listener method for all {@link TenantAwareBaseEntity}
* entities.
*/
@PrePersist
public void prePersist() {
// before persisting the entity check the current ID of the tenant by
// using the TenantAware
// service
final String currentTenant = SystemManagementHolder.getInstance().currentTenant();
if (currentTenant == null) {
throw new TenantNotExistException("Tenant "
+ TenantAwareHolder.getInstance().getTenantAware().getCurrentTenant()
+ " does not exists, cannot create entity " + this.getClass() + " with id " + super.getId());
}
setTenant(currentTenant.toUpperCase());
}
public String getTenant() {
return tenant;
}
public void setTenant(final String tenant) {
this.tenant = tenant;
}
@Override
public String toString() {
return "BaseEntity [id=" + super.getId() + "]";
}
@Override
public int hashCode() { // NOSONAR - as this is generated
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((tenant == null) ? 0 : tenant.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TenantAwareBaseEntity other = (TenantAwareBaseEntity) obj;
if (tenant == null) {
if (other.tenant != null) {
return false;
}
} else if (!tenant.equals(other.tenant)) {
return false;
}
return true;
}
}

View File

@@ -26,7 +26,7 @@ import javax.persistence.UniqueConstraint;
@Entity @Entity
@Table(name = "sp_tenant_configuration", uniqueConstraints = @UniqueConstraint(columnNames = { "conf_key", @Table(name = "sp_tenant_configuration", uniqueConstraints = @UniqueConstraint(columnNames = { "conf_key",
"tenant" }, name = "uk_tenant_key")) "tenant" }, name = "uk_tenant_key"))
public class TenantConfiguration extends BaseEntity implements Serializable { public class TenantConfiguration extends TenantAwareBaseEntity implements Serializable {
/** /**
* *
@@ -44,7 +44,7 @@ public class TenantConfiguration extends BaseEntity implements Serializable {
* JPA default constructor. * JPA default constructor.
*/ */
public TenantConfiguration() { public TenantConfiguration() {
// JPA default constructor.
} }
/** /**

View File

@@ -89,7 +89,7 @@ public class TenantConfigurationValue<T> {
*/ */
public static <K> TenantConfigurationValueBuilder<K> builder() { public static <K> TenantConfigurationValueBuilder<K> builder() {
return new TenantConfigurationValueBuilder<K>(); return new TenantConfigurationValueBuilder<>();
} }
/** /**

View File

@@ -8,76 +8,45 @@
*/ */
package org.eclipse.hawkbit.repository.model; package org.eclipse.hawkbit.repository.model;
import java.io.Serializable;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.ConstraintMode; import javax.persistence.ConstraintMode;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.FetchType; import javax.persistence.FetchType;
import javax.persistence.ForeignKey; import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Index; import javax.persistence.Index;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.OneToOne; import javax.persistence.OneToOne;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import javax.persistence.Version;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
/** /**
* Tenant metadata that is configured globally for the entire tenant. This * Tenant entity with meta data that is configured globally for the entire
* entity is * tenant. This entity is not tenant aware to allow the system to access it
* * through the {@link EntityManager} even before the actual tenant exists.
*
* *
* Entities owned by the tenant are based on {@link TenantAwareBaseEntity}.
* *
*/ */
@Access(AccessType.FIELD)
@Table(name = "sp_tenant", indexes = { @Table(name = "sp_tenant", indexes = {
@Index(name = "sp_idx_tenant_prim", columnList = "tenant,id") }, uniqueConstraints = { @Index(name = "sp_idx_tenant_prim", columnList = "tenant,id") }, uniqueConstraints = {
@UniqueConstraint(columnNames = { "tenant" }, name = "uk_tenantmd_tenant") }) @UniqueConstraint(columnNames = { "tenant" }, name = "uk_tenantmd_tenant") })
@Entity @Entity
public class TenantMetaData implements Serializable { public class TenantMetaData extends BaseEntity {
/**
*
*/
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "tenant", nullable = false, length = 40) @Column(name = "tenant", nullable = false, length = 40)
private String tenant; private String tenant;
private String createdBy;
private String lastModifiedBy;
private Long createdAt;
private Long lastModifiedAt;
@Version
@Column(name = "optlock_revision")
private long optLockRevision;
@OneToOne(fetch = FetchType.LAZY) @OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "default_ds_type", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_tenant_md_default_ds_type")) @JoinColumn(name = "default_ds_type", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_tenant_md_default_ds_type"))
// use deprecated annotation until HHH-8862 is fixed
@SuppressWarnings("deprecation")
// @org.hibernate.annotations.ForeignKey( name =
// "fk_tenant_md_default_ds_type" )
private DistributionSetType defaultDsType; private DistributionSetType defaultDsType;
/**
* Default constructor needed for JPA entities.
*/
public TenantMetaData() { public TenantMetaData() {
// Default constructor needed for JPA entities.
} }
/** /**
@@ -93,167 +62,20 @@ public class TenantMetaData implements Serializable {
this.tenant = tenant; this.tenant = tenant;
} }
/**
* @return the defaultDsType
*/
public DistributionSetType getDefaultDsType() { public DistributionSetType getDefaultDsType() {
return defaultDsType; return defaultDsType;
} }
/**
* Set the DistributionSet for a tenant.
*
* @param defaultDsType
* the new default DistributionSet
*/
public void setDefaultDsType(final DistributionSetType defaultDsType) { public void setDefaultDsType(final DistributionSetType defaultDsType) {
this.defaultDsType = defaultDsType; this.defaultDsType = defaultDsType;
} }
/**
* @return the id
*/
public Long getId() {
return id;
}
/**
* @param id
* the id to set
*/
public void setId(final Long id) {
this.id = id;
}
@Access(AccessType.PROPERTY)
@Column(name = "created_at", insertable = true, updatable = false)
public Long getCreatedAt() {
return createdAt;
}
@Access(AccessType.PROPERTY)
@Column(name = "created_by", insertable = true, updatable = false, length = 40)
public String getCreatedBy() {
return createdBy;
}
@Access(AccessType.PROPERTY)
@Column(name = "last_modified_at", insertable = false, updatable = true)
public Long getLastModifiedAt() {
return lastModifiedAt;
}
@Access(AccessType.PROPERTY)
@Column(name = "last_modified_by", insertable = false, updatable = true, length = 40)
public String getLastModifiedBy() {
return lastModifiedBy;
}
/**
* @param createdBy
* the createdBy to set
*/
@CreatedBy
public void setCreatedBy(final String createdBy) {
this.createdBy = createdBy;
}
/**
* @param lastModifiedBy
* the lastModifiedBy to set
*/
@LastModifiedBy
public void setLastModifiedBy(final String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
/**
* @param createdAt
* the createdAt to set
*/
@CreatedDate
public void setCreatedAt(final Long createdAt) {
this.createdAt = createdAt;
}
/**
* @param lastModifiedAt
* the lastModifiedAt to set
*/
@LastModifiedDate
public void setLastModifiedAt(final Long lastModifiedAt) {
this.lastModifiedAt = lastModifiedAt;
}
/**
* @return the optLockRevision
*/
public long getOptLockRevision() {
return optLockRevision;
}
/**
* @param optLockRevision
* the optLockRevision to set
*/
public void setOptLockRevision(final long optLockRevision) {
this.optLockRevision = optLockRevision;
}
/**
* @return the tenant
*/
public String getTenant() { public String getTenant() {
return tenant; return tenant;
} }
/**
* @param tenant
* the tenant to set
*/
public void setTenant(final String tenant) { public void setTenant(final String tenant) {
this.tenant = tenant; this.tenant = tenant;
} }
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated
// code
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TenantMetaData other = (TenantMetaData) obj;
if (id == null) {
if (other.id != null) {
return false;
}
} else if (!id.equals(other.id)) {
return false;
}
return true;
}
} }

View File

@@ -20,7 +20,7 @@ import org.eclipse.hawkbit.TestDataUtil;
import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
@@ -207,7 +207,7 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest {
final Slice<Target> result = targetManagement.findTargetsAllOrderByLinkedDistributionSet(pageReq, ds.getId(), final Slice<Target> result = targetManagement.findTargetsAllOrderByLinkedDistributionSet(pageReq, ds.getId(),
null, null, null, Boolean.FALSE, null); null, null, null, Boolean.FALSE, null);
final Comparator<BaseEntity> byId = (e1, e2) -> Long.compare(e2.getId(), e1.getId()); final Comparator<TenantAwareBaseEntity> byId = (e1, e2) -> Long.compare(e2.getId(), e1.getId());
assertThat(result.getNumberOfElements()).isEqualTo(9); assertThat(result.getNumberOfElements()).isEqualTo(9);
final List<Target> expected = new ArrayList<Target>(); final List<Target> expected = new ArrayList<Target>();

View File

@@ -13,7 +13,7 @@ spring.data.mongodb.port=28017
hawkbit.server.ddi.security.authentication.header.enabled=true hawkbit.server.ddi.security.authentication.header.enabled=true
hawkbit.server.ddi.security.authentication.gatewaytoken.name=TestToken hawkbit.server.ddi.security.authentication.gatewaytoken.name=TestToken
hawkbit.server.artifact.repo.upload.maxFileSize=5MB multipart.max-file-size=5MB
hawkbit.server.security.dos.maxStatusEntriesPerAction=100 hawkbit.server.security.dos.maxStatusEntriesPerAction=100
@@ -26,7 +26,6 @@ spring.datasource.username=sa
spring.datasource.password=sa spring.datasource.password=sa
flyway.enabled=true flyway.enabled=true
flyway.initOnMigrate=true
flyway.sqlMigrationSuffix=${spring.jpa.database}.sql flyway.sqlMigrationSuffix=${spring.jpa.database}.sql
#spring.jpa.show-sql=true #spring.jpa.show-sql=true

View File

@@ -8,7 +8,7 @@
*/ */
package org.eclipse.hawkbit.rest.resource; package org.eclipse.hawkbit.rest.resource;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.rest.resource.model.BaseEntityRest; import org.eclipse.hawkbit.rest.resource.model.BaseEntityRest;
import org.eclipse.hawkbit.rest.resource.model.NamedEntityRest; import org.eclipse.hawkbit.rest.resource.model.NamedEntityRest;
@@ -28,7 +28,7 @@ final class RestModelMapper {
} }
static void mapBaseToBase(final BaseEntityRest response, final BaseEntity base) { static void mapBaseToBase(final BaseEntityRest response, final TenantAwareBaseEntity base) {
response.setCreatedBy(base.getCreatedBy()); response.setCreatedBy(base.getCreatedBy());
response.setLastModifiedBy(base.getLastModifiedBy()); response.setLastModifiedBy(base.getLastModifiedBy());
if (base.getCreatedAt() != null) { if (base.getCreatedAt() != null) {