Removed the extra level of abstraction and modified the code
accordingly.
This commit is contained in:
@@ -1,189 +0,0 @@
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.DescriptorEventDetails.ActionType;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
|
||||
import org.eclipse.persistence.queries.UpdateObjectQuery;
|
||||
import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Implementation of @link{AbstractDescriptorEventVisitor} .Publishes the
|
||||
* appropriate event after any action on entity like create/update.
|
||||
*
|
||||
*/
|
||||
public class AbstractDescriptorEventVisitorImpl implements
|
||||
AbstractDescriptorEventVisitor {
|
||||
|
||||
private static final String COMPLETE = "complete";
|
||||
private static final Logger LOG = LoggerFactory
|
||||
.getLogger(AbstractDescriptorEventVisitorImpl.class);
|
||||
|
||||
@Override
|
||||
public void publishEventPostAction(final DescriptorEventDetails event) {
|
||||
Method method = null;
|
||||
DescriptorEvent descriptorEvent = event.getDescriptorEvent();
|
||||
ActionType actiontype = event.getActiontype();
|
||||
try {
|
||||
method = getMethod(descriptorEvent, actiontype);
|
||||
if (method != null) {
|
||||
method.invoke(this, descriptorEvent.getObject(),
|
||||
descriptorEvent);
|
||||
}
|
||||
} catch (NoSuchMethodException | SecurityException
|
||||
| IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException e) {
|
||||
LOG.info(
|
||||
"Exception when invoking approriate method to publis event {}",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
private Method getMethod(DescriptorEvent descriptorEvent,
|
||||
ActionType actiontype) throws NoSuchMethodException {
|
||||
if (actiontype == ActionType.UPDATE) {
|
||||
return this.getClass().getMethod("publishEventAfterUpdate",
|
||||
descriptorEvent.getObject().getClass(),
|
||||
DescriptorEvent.class);
|
||||
} else if (actiontype == ActionType.CREATE) {
|
||||
return this.getClass().getMethod("publishEventAfterCreate",
|
||||
descriptorEvent.getObject().getClass(),
|
||||
DescriptorEvent.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void publishEventAfterCreate(JpaAction action, DescriptorEvent event) {
|
||||
if (action.getRollout() != null) {
|
||||
getAfterTransactionCommmitExecutor().afterCommit(
|
||||
() -> getEventBus().post(new ActionCreatedEvent(action)));
|
||||
}
|
||||
}
|
||||
|
||||
public void publishEventAfterCreate(JpaTarget target, DescriptorEvent event) {
|
||||
getAfterTransactionCommmitExecutor().afterCommit(
|
||||
() -> getEventBus().post(new TargetCreatedEvent(target)));
|
||||
}
|
||||
|
||||
public void publishEventAfterCreate(JpaDistributionSet ds,
|
||||
DescriptorEvent event) {
|
||||
getAfterTransactionCommmitExecutor().afterCommit(
|
||||
() -> getEventBus().post(new DistributionCreatedEvent(ds)));
|
||||
|
||||
}
|
||||
|
||||
public void publishEventAfterUpdate(JpaAction action, DescriptorEvent event) {
|
||||
getAfterTransactionCommmitExecutor().afterCommit(
|
||||
() -> getEventBus().post(
|
||||
new ActionPropertyChangeEvent(action, getChangeSet(
|
||||
Action.class, event))));
|
||||
}
|
||||
|
||||
public void publishEventAfterUpdate(JpaTarget target, DescriptorEvent event) {
|
||||
getAfterTransactionCommmitExecutor().afterCommit(
|
||||
() -> getEventBus().post(new TargetUpdatedEvent(target)));
|
||||
}
|
||||
|
||||
public void publishEventAfterUpdate(JpaTargetInfo targetInfo,
|
||||
DescriptorEvent event) {
|
||||
getAfterTransactionCommmitExecutor()
|
||||
.afterCommit(
|
||||
() -> getEventBus().post(
|
||||
new TargetInfoUpdateEvent(targetInfo)));
|
||||
}
|
||||
|
||||
public void publishEventAfterUpdate(JpaRollout entity, DescriptorEvent event) {
|
||||
getAfterTransactionCommmitExecutor().afterCommit(
|
||||
() -> getEventBus().post(
|
||||
new RolloutPropertyChangeEvent(entity, getChangeSet(
|
||||
Rollout.class, event))));
|
||||
}
|
||||
|
||||
public void publishEventAfterUpdate(JpaRolloutGroup entity,
|
||||
DescriptorEvent event) {
|
||||
getAfterTransactionCommmitExecutor().afterCommit(
|
||||
() -> getEventBus().post(
|
||||
new RolloutGroupPropertyChangeEvent(entity,
|
||||
getChangeSet(RolloutGroup.class, event))));
|
||||
|
||||
}
|
||||
|
||||
public void publishEventAfterUpdate(JpaDistributionSet entity,
|
||||
DescriptorEvent event) {
|
||||
Map<String, AbstractPropertyChangeEvent<JpaDistributionSet>.Values> changeSet = getChangeSet(
|
||||
JpaDistributionSet.class, event);
|
||||
if (changeSet.containsKey(COMPLETE)
|
||||
&& changeSet.get(COMPLETE).getOldValue().equals(false)
|
||||
&& changeSet.get(COMPLETE).getNewValue().equals(true)) {
|
||||
getAfterTransactionCommmitExecutor().afterCommit(
|
||||
() -> getEventBus().post(
|
||||
new DistributionCreatedEvent(entity)));
|
||||
}
|
||||
|
||||
getAfterTransactionCommmitExecutor().afterCommit(
|
||||
() -> getEventBus()
|
||||
.post(new DistributionSetUpdateEvent(entity)));
|
||||
|
||||
}
|
||||
|
||||
private <T extends TenantAwareBaseEntity> Map<String, AbstractPropertyChangeEvent<T>.Values> getChangeSet(
|
||||
final Class<T> clazz, final DescriptorEvent event) {
|
||||
final T rolloutGroup = clazz.cast(event.getObject());
|
||||
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery())
|
||||
.getObjectChangeSet();
|
||||
return changeSet
|
||||
.getChanges()
|
||||
.stream()
|
||||
.filter(record -> record instanceof DirectToFieldChangeRecord)
|
||||
.map(record -> (DirectToFieldChangeRecord) record)
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
record -> record.getAttribute(),
|
||||
record -> new AbstractPropertyChangeEvent<T>(
|
||||
rolloutGroup, null).new Values(record
|
||||
.getOldValue(), record.getNewValue())));
|
||||
}
|
||||
|
||||
private AfterTransactionCommitExecutor getAfterTransactionCommmitExecutor() {
|
||||
return AfterTransactionCommitExecutorHolder.getInstance()
|
||||
.getAfterCommit();
|
||||
}
|
||||
|
||||
private EventBus getEventBus() {
|
||||
return EventBusHolder.getInstance().getEventBus();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,7 +32,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
@MappedSuperclass
|
||||
@Access(AccessType.FIELD)
|
||||
@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class })
|
||||
public abstract class AbstractJpaBaseEntity implements BaseEntity,AcceptVisitor {
|
||||
public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@@ -179,8 +179,4 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity,AcceptVisitor
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void postActionOnEntity(AbstractDescriptorEventVisitor visitor, DescriptorEventDetails eventDetails){
|
||||
visitor.publishEventPostAction(eventDetails);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
/**
|
||||
* Interface to accept visitor @link{AbstractDescriptorEventVisitor}.
|
||||
*
|
||||
*/
|
||||
public interface AcceptVisitor {
|
||||
public void postActionOnEntity(AbstractDescriptorEventVisitor visitor,
|
||||
DescriptorEventDetails eventDetails);
|
||||
}
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.DescriptorEventDetails.ActionType;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEventAdapter;
|
||||
|
||||
@@ -18,19 +17,23 @@ import org.eclipse.persistence.descriptors.DescriptorEventAdapter;
|
||||
*/
|
||||
public class EntityPropertyChangeListener extends DescriptorEventAdapter {
|
||||
|
||||
@Override
|
||||
public void postInsert(final DescriptorEvent event) {
|
||||
AbstractDescriptorEventVisitor visitor = new AbstractDescriptorEventVisitorImpl();
|
||||
((AbstractJpaBaseEntity) event.getObject()).postActionOnEntity(visitor,
|
||||
new DescriptorEventDetails(ActionType.CREATE, event));
|
||||
@Override
|
||||
public void postInsert(final DescriptorEvent event) {
|
||||
|
||||
final Object object = event.getObject();
|
||||
if (object instanceof EventAwareEntity) {
|
||||
((EventAwareEntity) object).fireCreateEvent(object,event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postUpdate(final DescriptorEvent event) {
|
||||
|
||||
final Object object = event.getObject();
|
||||
if (object instanceof EventAwareEntity) {
|
||||
((EventAwareEntity) object).fireUpdateEvent(object,event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postUpdate(final DescriptorEvent event) {
|
||||
AbstractDescriptorEventVisitor visitor = new AbstractDescriptorEventVisitorImpl();
|
||||
((AbstractJpaBaseEntity) event.getObject()).postActionOnEntity(visitor,
|
||||
new DescriptorEventDetails(ActionType.UPDATE, event));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
/**
|
||||
*
|
||||
* Interface defining the action to be performed after entity is
|
||||
* created/updated.
|
||||
*
|
||||
*/
|
||||
public interface AbstractDescriptorEventVisitor {
|
||||
void publishEventPostAction(DescriptorEventDetails eventDetails);
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
|
||||
public interface EventAwareEntity<T> {
|
||||
|
||||
public void fireCreateEvent(T t,DescriptorEvent descriptorEvent);
|
||||
|
||||
public void fireUpdateEvent(T t,DescriptorEvent descriptorEvent);
|
||||
|
||||
public void fireDeleteEvent(T t,DescriptorEvent descriptorEvent);
|
||||
}
|
||||
@@ -1,174 +1,199 @@
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.NamedEntityGraphs;
|
||||
import javax.persistence.NamedSubgraph;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
|
||||
/**
|
||||
* JPA implementation of {@link Action}.
|
||||
*/
|
||||
@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"),
|
||||
@Index(name = "sp_idx_action_02", columnList = "tenant,target,active"),
|
||||
@Index(name = "sp_idx_action_prim", columnList = "tenant,id") })
|
||||
@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }),
|
||||
@NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"),
|
||||
@NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) })
|
||||
@Entity
|
||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||
// sub entities
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds"))
|
||||
private JpaDistributionSet distributionSet;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target"))
|
||||
private JpaTarget target;
|
||||
|
||||
@Column(name = "active")
|
||||
private boolean active;
|
||||
|
||||
@Column(name = "action_type", nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private ActionType actionType;
|
||||
|
||||
@Column(name = "forced_time")
|
||||
private long forcedTime;
|
||||
|
||||
@Column(name = "status")
|
||||
private Status status;
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = {
|
||||
CascadeType.REMOVE })
|
||||
private List<ActionStatus> actionStatus;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup"))
|
||||
private JpaRolloutGroup rolloutGroup;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout"))
|
||||
private JpaRollout rollout;
|
||||
|
||||
@Override
|
||||
public DistributionSet getDistributionSet() {
|
||||
return distributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDistributionSet(final DistributionSet distributionSet) {
|
||||
this.distributionSet = (JpaDistributionSet) distributionSet;
|
||||
}
|
||||
|
||||
public void setActive(final boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(final Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setActionType(final ActionType actionType) {
|
||||
this.actionType = actionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionType getActionType() {
|
||||
return actionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActionStatus> getActionStatus() {
|
||||
return actionStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTarget(final Target target) {
|
||||
this.target = (JpaTarget) target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Target getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getForcedTime() {
|
||||
return forcedTime;
|
||||
}
|
||||
|
||||
public void setForcedTime(final long forcedTime) {
|
||||
this.forcedTime = forcedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroup getRolloutGroup() {
|
||||
return rolloutGroup;
|
||||
}
|
||||
|
||||
public void setRolloutGroup(final RolloutGroup rolloutGroup) {
|
||||
this.rolloutGroup = (JpaRolloutGroup) rolloutGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rollout getRollout() {
|
||||
return rollout;
|
||||
}
|
||||
|
||||
public void setRollout(final Rollout rollout) {
|
||||
this.rollout = (JpaRollout) rollout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.NamedEntityGraphs;
|
||||
import javax.persistence.NamedSubgraph;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
|
||||
/**
|
||||
* JPA implementation of {@link Action}.
|
||||
*/
|
||||
@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"),
|
||||
@Index(name = "sp_idx_action_02", columnList = "tenant,target,active"),
|
||||
@Index(name = "sp_idx_action_prim", columnList = "tenant,id") })
|
||||
@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }),
|
||||
@NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"),
|
||||
@NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) })
|
||||
@Entity
|
||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||
// sub entities
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action,EventAwareEntity<JpaAction> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds"))
|
||||
private JpaDistributionSet distributionSet;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target"))
|
||||
private JpaTarget target;
|
||||
|
||||
@Column(name = "active")
|
||||
private boolean active;
|
||||
|
||||
@Column(name = "action_type", nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private ActionType actionType;
|
||||
|
||||
@Column(name = "forced_time")
|
||||
private long forcedTime;
|
||||
|
||||
@Column(name = "status")
|
||||
private Status status;
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = {
|
||||
CascadeType.REMOVE })
|
||||
private List<ActionStatus> actionStatus;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup"))
|
||||
private JpaRolloutGroup rolloutGroup;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout"))
|
||||
private JpaRollout rollout;
|
||||
|
||||
@Override
|
||||
public DistributionSet getDistributionSet() {
|
||||
return distributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDistributionSet(final DistributionSet distributionSet) {
|
||||
this.distributionSet = (JpaDistributionSet) distributionSet;
|
||||
}
|
||||
|
||||
public void setActive(final boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(final Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setActionType(final ActionType actionType) {
|
||||
this.actionType = actionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionType getActionType() {
|
||||
return actionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActionStatus> getActionStatus() {
|
||||
return actionStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTarget(final Target target) {
|
||||
this.target = (JpaTarget) target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Target getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getForcedTime() {
|
||||
return forcedTime;
|
||||
}
|
||||
|
||||
public void setForcedTime(final long forcedTime) {
|
||||
this.forcedTime = forcedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroup getRolloutGroup() {
|
||||
return rolloutGroup;
|
||||
}
|
||||
|
||||
public void setRolloutGroup(final RolloutGroup rolloutGroup) {
|
||||
this.rolloutGroup = (JpaRolloutGroup) rolloutGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rollout getRollout() {
|
||||
return rollout;
|
||||
}
|
||||
|
||||
public void setRollout(final Rollout rollout) {
|
||||
this.rollout = (JpaRollout) rollout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) {
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction)));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) {
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().
|
||||
post(new ActionPropertyChangeEvent(jpaAction, EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent))));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,282 +1,320 @@
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException;
|
||||
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
|
||||
/**
|
||||
* Jpa implementation of {@link DistributionSet}.
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "sp_distribution_set", uniqueConstraints = {
|
||||
@UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = {
|
||||
@Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"),
|
||||
@Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"),
|
||||
@Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") })
|
||||
@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"),
|
||||
@NamedAttributeNode("tags"), @NamedAttributeNode("type") })
|
||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||
// sub entities
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Column(name = "required_migration_step")
|
||||
private boolean requiredMigrationStep;
|
||||
|
||||
@ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY)
|
||||
@JoinTable(name = "sp_ds_module", joinColumns = {
|
||||
@JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = {
|
||||
@JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) })
|
||||
private final Set<SoftwareModule> modules = new HashSet<>();
|
||||
|
||||
@ManyToMany(targetEntity = JpaDistributionSetTag.class)
|
||||
@JoinTable(name = "sp_ds_dstag", joinColumns = {
|
||||
@JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = {
|
||||
@JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) })
|
||||
private Set<DistributionSetTag> tags = new HashSet<>();
|
||||
|
||||
@Column(name = "deleted")
|
||||
private boolean deleted;
|
||||
|
||||
@OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY)
|
||||
private List<Target> assignedToTargets;
|
||||
|
||||
@OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY)
|
||||
private List<TargetInfo> installedAtTargets;
|
||||
|
||||
@OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY)
|
||||
private List<Action> actions;
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = {
|
||||
CascadeType.REMOVE })
|
||||
@JoinColumn(name = "ds_id", insertable = false, updatable = false)
|
||||
private final List<DistributionSetMetadata> metadata = new ArrayList<>();
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class)
|
||||
@JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds"))
|
||||
private DistributionSetType type;
|
||||
|
||||
@Column(name = "complete")
|
||||
private boolean complete;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public JpaDistributionSet() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameterized constructor.
|
||||
*
|
||||
* @param name
|
||||
* of the {@link DistributionSet}
|
||||
* @param version
|
||||
* of the {@link DistributionSet}
|
||||
* @param description
|
||||
* of the {@link DistributionSet}
|
||||
* @param type
|
||||
* of the {@link DistributionSet}
|
||||
* @param moduleList
|
||||
* {@link SoftwareModule}s of the {@link DistributionSet}
|
||||
*/
|
||||
public JpaDistributionSet(final String name, final String version, final String description,
|
||||
final DistributionSetType type, final Collection<SoftwareModule> moduleList) {
|
||||
super(name, version, description);
|
||||
|
||||
this.type = type;
|
||||
if (moduleList != null) {
|
||||
moduleList.forEach(this::addModule);
|
||||
}
|
||||
if (this.type != null) {
|
||||
complete = this.type.checkComplete(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DistributionSetTag> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DistributionSetMetadata> getMetadata() {
|
||||
return Collections.unmodifiableList(metadata);
|
||||
}
|
||||
|
||||
public List<Action> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequiredMigrationStep() {
|
||||
return requiredMigrationStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSet setDeleted(final boolean deleted) {
|
||||
this.deleted = deleted;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) {
|
||||
requiredMigrationStep = isRequiredMigrationStep;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistributionSet setTags(final Set<DistributionSetTag> tags) {
|
||||
this.tags = tags;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Target> getAssignedTargets() {
|
||||
return assignedToTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TargetInfo> getInstalledTargets() {
|
||||
return installedAtTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision()
|
||||
+ ", getId()=" + getId() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SoftwareModule> getModules() {
|
||||
return Collections.unmodifiableSet(modules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addModule(final SoftwareModule softwareModule) {
|
||||
|
||||
// we cannot allow that modules are added without a type defined
|
||||
if (type == null) {
|
||||
throw new DistributionSetTypeUndefinedException();
|
||||
}
|
||||
|
||||
// check if it is allowed to such a module to this DS type
|
||||
if (!type.containsModuleType(softwareModule.getType())) {
|
||||
throw new UnsupportedSoftwareModuleForThisDistributionSetException();
|
||||
}
|
||||
|
||||
final Optional<SoftwareModule> found = modules.stream()
|
||||
.filter(module -> module.getId().equals(softwareModule.getId())).findFirst();
|
||||
|
||||
if (found.isPresent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final long allready = modules.stream()
|
||||
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count();
|
||||
|
||||
if (allready >= softwareModule.getType().getMaxAssignments()) {
|
||||
final Optional<SoftwareModule> sameKey = modules.stream()
|
||||
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst();
|
||||
modules.remove(sameKey.get());
|
||||
}
|
||||
|
||||
if (modules.add(softwareModule)) {
|
||||
complete = type.checkComplete(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeModule(final SoftwareModule softwareModule) {
|
||||
final Optional<SoftwareModule> found = modules.stream()
|
||||
.filter(module -> module.getId().equals(softwareModule.getId())).findFirst();
|
||||
|
||||
if (found.isPresent()) {
|
||||
modules.remove(found.get());
|
||||
complete = type.checkComplete(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) {
|
||||
final Optional<SoftwareModule> result = modules.stream().filter(module -> module.getType().equals(type))
|
||||
.findFirst();
|
||||
|
||||
if (result.isPresent()) {
|
||||
return result.get();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSetType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(final DistributionSetType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException;
|
||||
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
|
||||
/**
|
||||
* Jpa implementation of {@link DistributionSet}.
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "sp_distribution_set", uniqueConstraints = {
|
||||
@UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = {
|
||||
@Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"),
|
||||
@Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"),
|
||||
@Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") })
|
||||
@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"),
|
||||
@NamedAttributeNode("tags"), @NamedAttributeNode("type") })
|
||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||
// sub entities
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet,EventAwareEntity<JpaDistributionSet> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String COMPLETE = "complete";
|
||||
|
||||
@Column(name = "required_migration_step")
|
||||
private boolean requiredMigrationStep;
|
||||
|
||||
@ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY)
|
||||
@JoinTable(name = "sp_ds_module", joinColumns = {
|
||||
@JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = {
|
||||
@JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) })
|
||||
private final Set<SoftwareModule> modules = new HashSet<>();
|
||||
|
||||
@ManyToMany(targetEntity = JpaDistributionSetTag.class)
|
||||
@JoinTable(name = "sp_ds_dstag", joinColumns = {
|
||||
@JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = {
|
||||
@JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) })
|
||||
private Set<DistributionSetTag> tags = new HashSet<>();
|
||||
|
||||
@Column(name = "deleted")
|
||||
private boolean deleted;
|
||||
|
||||
@OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY)
|
||||
private List<Target> assignedToTargets;
|
||||
|
||||
@OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY)
|
||||
private List<TargetInfo> installedAtTargets;
|
||||
|
||||
@OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY)
|
||||
private List<Action> actions;
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = {
|
||||
CascadeType.REMOVE })
|
||||
@JoinColumn(name = "ds_id", insertable = false, updatable = false)
|
||||
private final List<DistributionSetMetadata> metadata = new ArrayList<>();
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class)
|
||||
@JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds"))
|
||||
private DistributionSetType type;
|
||||
|
||||
@Column(name = "complete")
|
||||
private boolean complete;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public JpaDistributionSet() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameterized constructor.
|
||||
*
|
||||
* @param name
|
||||
* of the {@link DistributionSet}
|
||||
* @param version
|
||||
* of the {@link DistributionSet}
|
||||
* @param description
|
||||
* of the {@link DistributionSet}
|
||||
* @param type
|
||||
* of the {@link DistributionSet}
|
||||
* @param moduleList
|
||||
* {@link SoftwareModule}s of the {@link DistributionSet}
|
||||
*/
|
||||
public JpaDistributionSet(final String name, final String version, final String description,
|
||||
final DistributionSetType type, final Collection<SoftwareModule> moduleList) {
|
||||
super(name, version, description);
|
||||
|
||||
this.type = type;
|
||||
if (moduleList != null) {
|
||||
moduleList.forEach(this::addModule);
|
||||
}
|
||||
if (this.type != null) {
|
||||
complete = this.type.checkComplete(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<DistributionSetTag> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DistributionSetMetadata> getMetadata() {
|
||||
return Collections.unmodifiableList(metadata);
|
||||
}
|
||||
|
||||
public List<Action> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequiredMigrationStep() {
|
||||
return requiredMigrationStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSet setDeleted(final boolean deleted) {
|
||||
this.deleted = deleted;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) {
|
||||
requiredMigrationStep = isRequiredMigrationStep;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistributionSet setTags(final Set<DistributionSetTag> tags) {
|
||||
this.tags = tags;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Target> getAssignedTargets() {
|
||||
return assignedToTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TargetInfo> getInstalledTargets() {
|
||||
return installedAtTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision()
|
||||
+ ", getId()=" + getId() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SoftwareModule> getModules() {
|
||||
return Collections.unmodifiableSet(modules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addModule(final SoftwareModule softwareModule) {
|
||||
|
||||
// we cannot allow that modules are added without a type defined
|
||||
if (type == null) {
|
||||
throw new DistributionSetTypeUndefinedException();
|
||||
}
|
||||
|
||||
// check if it is allowed to such a module to this DS type
|
||||
if (!type.containsModuleType(softwareModule.getType())) {
|
||||
throw new UnsupportedSoftwareModuleForThisDistributionSetException();
|
||||
}
|
||||
|
||||
final Optional<SoftwareModule> found = modules.stream()
|
||||
.filter(module -> module.getId().equals(softwareModule.getId())).findFirst();
|
||||
|
||||
if (found.isPresent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final long allready = modules.stream()
|
||||
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count();
|
||||
|
||||
if (allready >= softwareModule.getType().getMaxAssignments()) {
|
||||
final Optional<SoftwareModule> sameKey = modules.stream()
|
||||
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst();
|
||||
modules.remove(sameKey.get());
|
||||
}
|
||||
|
||||
if (modules.add(softwareModule)) {
|
||||
complete = type.checkComplete(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeModule(final SoftwareModule softwareModule) {
|
||||
final Optional<SoftwareModule> found = modules.stream()
|
||||
.filter(module -> module.getId().equals(softwareModule.getId())).findFirst();
|
||||
|
||||
if (found.isPresent()) {
|
||||
modules.remove(found.get());
|
||||
complete = type.checkComplete(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) {
|
||||
final Optional<SoftwareModule> result = modules.stream().filter(module -> module.getType().equals(type))
|
||||
.findFirst();
|
||||
|
||||
if (result.isPresent()) {
|
||||
return result.get();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSetType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(final DistributionSetType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) {
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet)));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) {
|
||||
final Map<String, AbstractPropertyChangeEvent<JpaDistributionSet>.Values> changeSet = EntityPropertyChangeHelper.getChangeSet(
|
||||
JpaDistributionSet.class, descriptorEvent);
|
||||
if (changeSet.containsKey(COMPLETE)
|
||||
&& changeSet.get(COMPLETE).getOldValue().equals(false)
|
||||
&& changeSet.get(COMPLETE).getNewValue().equals(true)) {
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(
|
||||
() -> EventBusHolder.getInstance().getEventBus().post(
|
||||
new DistributionCreatedEvent(jpaDistributionSet)));
|
||||
}
|
||||
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(
|
||||
() -> EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet)));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,200 +1,223 @@
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||
|
||||
/**
|
||||
* JPA implementation of a {@link Rollout}.
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "sp_rollout", indexes = {
|
||||
@Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = {
|
||||
"name", "tenant" }, name = "uk_rollout"))
|
||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||
// sub entities
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaRollout extends AbstractJpaNamedEntity implements Rollout {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@OneToMany(targetEntity = JpaRolloutGroup.class)
|
||||
@JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup"))
|
||||
private List<RolloutGroup> rolloutGroups;
|
||||
|
||||
@Column(name = "target_filter", length = 1024, nullable = false)
|
||||
private String targetFilterQuery;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds"))
|
||||
private JpaDistributionSet distributionSet;
|
||||
|
||||
@Column(name = "status")
|
||||
private RolloutStatus status = RolloutStatus.CREATING;
|
||||
|
||||
@Column(name = "last_check")
|
||||
private long lastCheck;
|
||||
|
||||
@Column(name = "action_type", nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private ActionType actionType = ActionType.FORCED;
|
||||
|
||||
@Column(name = "forced_time")
|
||||
private long forcedTime;
|
||||
|
||||
@Column(name = "total_targets")
|
||||
private long totalTargets;
|
||||
|
||||
@Transient
|
||||
@CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL)
|
||||
private int rolloutGroupsTotal;
|
||||
|
||||
@Transient
|
||||
@CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED)
|
||||
private int rolloutGroupsCreated;
|
||||
|
||||
@Transient
|
||||
private transient TotalTargetCountStatus totalTargetCountStatus;
|
||||
|
||||
@Override
|
||||
public DistributionSet getDistributionSet() {
|
||||
return distributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDistributionSet(final DistributionSet distributionSet) {
|
||||
this.distributionSet = (JpaDistributionSet) distributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RolloutGroup> getRolloutGroups() {
|
||||
return rolloutGroups;
|
||||
}
|
||||
|
||||
public void setRolloutGroups(final List<RolloutGroup> rolloutGroups) {
|
||||
this.rolloutGroups = rolloutGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetFilterQuery() {
|
||||
return targetFilterQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetFilterQuery(final String targetFilterQuery) {
|
||||
this.targetFilterQuery = targetFilterQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(final RolloutStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public long getLastCheck() {
|
||||
return lastCheck;
|
||||
}
|
||||
|
||||
public void setLastCheck(final long lastCheck) {
|
||||
this.lastCheck = lastCheck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionType getActionType() {
|
||||
return actionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionType(final ActionType actionType) {
|
||||
this.actionType = actionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getForcedTime() {
|
||||
return forcedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setForcedTime(final long forcedTime) {
|
||||
this.forcedTime = forcedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalTargets() {
|
||||
return totalTargets;
|
||||
}
|
||||
|
||||
public void setTotalTargets(final long totalTargets) {
|
||||
this.totalTargets = totalTargets;
|
||||
}
|
||||
|
||||
public int getRolloutGroupsTotal() {
|
||||
return rolloutGroupsTotal;
|
||||
}
|
||||
|
||||
public void setRolloutGroupsTotal(final int rolloutGroupsTotal) {
|
||||
this.rolloutGroupsTotal = rolloutGroupsTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRolloutGroupsCreated() {
|
||||
return rolloutGroupsCreated;
|
||||
}
|
||||
|
||||
public void setRolloutGroupsCreated(final int rolloutGroupsCreated) {
|
||||
this.rolloutGroupsCreated = rolloutGroupsCreated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TotalTargetCountStatus getTotalTargetCountStatus() {
|
||||
if (totalTargetCountStatus == null) {
|
||||
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets);
|
||||
}
|
||||
return totalTargetCountStatus;
|
||||
}
|
||||
|
||||
public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) {
|
||||
this.totalTargetCountStatus = totalTargetCountStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery
|
||||
+ ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck
|
||||
+ ", getName()=" + getName() + ", getId()=" + getId() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
|
||||
/**
|
||||
* JPA implementation of a {@link Rollout}.
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "sp_rollout", indexes = {
|
||||
@Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = {
|
||||
"name", "tenant" }, name = "uk_rollout"))
|
||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||
// sub entities
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventAwareEntity<JpaRollout> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@OneToMany(targetEntity = JpaRolloutGroup.class)
|
||||
@JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup"))
|
||||
private List<RolloutGroup> rolloutGroups;
|
||||
|
||||
@Column(name = "target_filter", length = 1024, nullable = false)
|
||||
private String targetFilterQuery;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds"))
|
||||
private JpaDistributionSet distributionSet;
|
||||
|
||||
@Column(name = "status")
|
||||
private RolloutStatus status = RolloutStatus.CREATING;
|
||||
|
||||
@Column(name = "last_check")
|
||||
private long lastCheck;
|
||||
|
||||
@Column(name = "action_type", nullable = false)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private ActionType actionType = ActionType.FORCED;
|
||||
|
||||
@Column(name = "forced_time")
|
||||
private long forcedTime;
|
||||
|
||||
@Column(name = "total_targets")
|
||||
private long totalTargets;
|
||||
|
||||
@Transient
|
||||
@CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL)
|
||||
private int rolloutGroupsTotal;
|
||||
|
||||
@Transient
|
||||
@CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED)
|
||||
private int rolloutGroupsCreated;
|
||||
|
||||
@Transient
|
||||
private transient TotalTargetCountStatus totalTargetCountStatus;
|
||||
|
||||
@Override
|
||||
public DistributionSet getDistributionSet() {
|
||||
return distributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDistributionSet(final DistributionSet distributionSet) {
|
||||
this.distributionSet = (JpaDistributionSet) distributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RolloutGroup> getRolloutGroups() {
|
||||
return rolloutGroups;
|
||||
}
|
||||
|
||||
public void setRolloutGroups(final List<RolloutGroup> rolloutGroups) {
|
||||
this.rolloutGroups = rolloutGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetFilterQuery() {
|
||||
return targetFilterQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetFilterQuery(final String targetFilterQuery) {
|
||||
this.targetFilterQuery = targetFilterQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(final RolloutStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public long getLastCheck() {
|
||||
return lastCheck;
|
||||
}
|
||||
|
||||
public void setLastCheck(final long lastCheck) {
|
||||
this.lastCheck = lastCheck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionType getActionType() {
|
||||
return actionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionType(final ActionType actionType) {
|
||||
this.actionType = actionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getForcedTime() {
|
||||
return forcedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setForcedTime(final long forcedTime) {
|
||||
this.forcedTime = forcedTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalTargets() {
|
||||
return totalTargets;
|
||||
}
|
||||
|
||||
public void setTotalTargets(final long totalTargets) {
|
||||
this.totalTargets = totalTargets;
|
||||
}
|
||||
|
||||
public int getRolloutGroupsTotal() {
|
||||
return rolloutGroupsTotal;
|
||||
}
|
||||
|
||||
public void setRolloutGroupsTotal(final int rolloutGroupsTotal) {
|
||||
this.rolloutGroupsTotal = rolloutGroupsTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRolloutGroupsCreated() {
|
||||
return rolloutGroupsCreated;
|
||||
}
|
||||
|
||||
public void setRolloutGroupsCreated(final int rolloutGroupsCreated) {
|
||||
this.rolloutGroupsCreated = rolloutGroupsCreated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TotalTargetCountStatus getTotalTargetCountStatus() {
|
||||
if (totalTargetCountStatus == null) {
|
||||
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets);
|
||||
}
|
||||
return totalTargetCountStatus;
|
||||
}
|
||||
|
||||
public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) {
|
||||
this.totalTargetCountStatus = totalTargetCountStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery
|
||||
+ ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck
|
||||
+ ", getName()=" + getName() + ", getId()=" + getId() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) {
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus().
|
||||
post(new RolloutPropertyChangeEvent(jpaRollout, EntityPropertyChangeHelper.getChangeSet(
|
||||
Rollout.class, descriptorEvent))));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,239 +1,261 @@
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||
|
||||
/**
|
||||
* JPA entity definition of persisting a group of an rollout.
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "sp_rolloutgroup", indexes = {
|
||||
@Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = {
|
||||
"name", "rollout", "tenant" }, name = "uk_rolloutgroup"))
|
||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||
// sub entities
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout"))
|
||||
private JpaRollout rollout;
|
||||
|
||||
@Column(name = "status")
|
||||
private RolloutGroupStatus status = RolloutGroupStatus.READY;
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class)
|
||||
@JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false)
|
||||
private final List<RolloutTargetGroup> rolloutTargetGroup = new ArrayList<>();
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
private JpaRolloutGroup parent;
|
||||
|
||||
@Column(name = "success_condition", nullable = false)
|
||||
private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD;
|
||||
|
||||
@Column(name = "success_condition_exp", length = 512, nullable = false)
|
||||
private String successConditionExp;
|
||||
|
||||
@Column(name = "success_action", nullable = false)
|
||||
private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP;
|
||||
|
||||
@Column(name = "success_action_exp", length = 512, nullable = false)
|
||||
private String successActionExp;
|
||||
|
||||
@Column(name = "error_condition")
|
||||
private RolloutGroupErrorCondition errorCondition;
|
||||
|
||||
@Column(name = "error_condition_exp", length = 512)
|
||||
private String errorConditionExp;
|
||||
|
||||
@Column(name = "error_action")
|
||||
private RolloutGroupErrorAction errorAction;
|
||||
|
||||
@Column(name = "error_action_exp", length = 512)
|
||||
private String errorActionExp;
|
||||
|
||||
@Column(name = "total_targets")
|
||||
private long totalTargets;
|
||||
|
||||
@Transient
|
||||
private transient TotalTargetCountStatus totalTargetCountStatus;
|
||||
|
||||
@Override
|
||||
public Rollout getRollout() {
|
||||
return rollout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRollout(final Rollout rollout) {
|
||||
this.rollout = (JpaRollout) rollout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroupStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(final RolloutGroupStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public List<RolloutTargetGroup> getRolloutTargetGroup() {
|
||||
return rolloutTargetGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroup getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(final RolloutGroup parent) {
|
||||
this.parent = (JpaRolloutGroup) parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroupSuccessCondition getSuccessCondition() {
|
||||
return successCondition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) {
|
||||
successCondition = finishCondition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuccessConditionExp() {
|
||||
return successConditionExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSuccessConditionExp(final String finishExp) {
|
||||
successConditionExp = finishExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroupErrorCondition getErrorCondition() {
|
||||
return errorCondition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) {
|
||||
this.errorCondition = errorCondition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorConditionExp() {
|
||||
return errorConditionExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorConditionExp(final String errorExp) {
|
||||
errorConditionExp = errorExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroupErrorAction getErrorAction() {
|
||||
return errorAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorAction(final RolloutGroupErrorAction errorAction) {
|
||||
this.errorAction = errorAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorActionExp() {
|
||||
return errorActionExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorActionExp(final String errorActionExp) {
|
||||
this.errorActionExp = errorActionExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroupSuccessAction getSuccessAction() {
|
||||
return successAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuccessActionExp() {
|
||||
return successActionExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalTargets() {
|
||||
return totalTargets;
|
||||
}
|
||||
|
||||
public void setTotalTargets(final long totalTargets) {
|
||||
this.totalTargets = totalTargets;
|
||||
}
|
||||
|
||||
public void setSuccessAction(final RolloutGroupSuccessAction successAction) {
|
||||
this.successAction = successAction;
|
||||
}
|
||||
|
||||
public void setSuccessActionExp(final String successActionExp) {
|
||||
this.successActionExp = successActionExp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the totalTargetCountStatus
|
||||
*/
|
||||
@Override
|
||||
public TotalTargetCountStatus getTotalTargetCountStatus() {
|
||||
if (totalTargetCountStatus == null) {
|
||||
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets);
|
||||
}
|
||||
return totalTargetCountStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param totalTargetCountStatus
|
||||
* the totalTargetCountStatus to set
|
||||
*/
|
||||
@Override
|
||||
public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) {
|
||||
this.totalTargetCountStatus = totalTargetCountStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup
|
||||
+ ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp
|
||||
+ ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName()
|
||||
+ ", getId()=" + getId() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
|
||||
/**
|
||||
* JPA entity definition of persisting a group of an rollout.
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "sp_rolloutgroup", indexes = {
|
||||
@Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = {
|
||||
"name", "rollout", "tenant" }, name = "uk_rolloutgroup"))
|
||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||
// sub entities
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup,EventAwareEntity<JpaRolloutGroup> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout"))
|
||||
private JpaRollout rollout;
|
||||
|
||||
@Column(name = "status")
|
||||
private RolloutGroupStatus status = RolloutGroupStatus.READY;
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class)
|
||||
@JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false)
|
||||
private final List<RolloutTargetGroup> rolloutTargetGroup = new ArrayList<>();
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
private JpaRolloutGroup parent;
|
||||
|
||||
@Column(name = "success_condition", nullable = false)
|
||||
private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD;
|
||||
|
||||
@Column(name = "success_condition_exp", length = 512, nullable = false)
|
||||
private String successConditionExp;
|
||||
|
||||
@Column(name = "success_action", nullable = false)
|
||||
private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP;
|
||||
|
||||
@Column(name = "success_action_exp", length = 512, nullable = false)
|
||||
private String successActionExp;
|
||||
|
||||
@Column(name = "error_condition")
|
||||
private RolloutGroupErrorCondition errorCondition;
|
||||
|
||||
@Column(name = "error_condition_exp", length = 512)
|
||||
private String errorConditionExp;
|
||||
|
||||
@Column(name = "error_action")
|
||||
private RolloutGroupErrorAction errorAction;
|
||||
|
||||
@Column(name = "error_action_exp", length = 512)
|
||||
private String errorActionExp;
|
||||
|
||||
@Column(name = "total_targets")
|
||||
private long totalTargets;
|
||||
|
||||
@Transient
|
||||
private transient TotalTargetCountStatus totalTargetCountStatus;
|
||||
|
||||
@Override
|
||||
public Rollout getRollout() {
|
||||
return rollout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRollout(final Rollout rollout) {
|
||||
this.rollout = (JpaRollout) rollout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroupStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(final RolloutGroupStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public List<RolloutTargetGroup> getRolloutTargetGroup() {
|
||||
return rolloutTargetGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroup getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(final RolloutGroup parent) {
|
||||
this.parent = (JpaRolloutGroup) parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroupSuccessCondition getSuccessCondition() {
|
||||
return successCondition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) {
|
||||
successCondition = finishCondition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuccessConditionExp() {
|
||||
return successConditionExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSuccessConditionExp(final String finishExp) {
|
||||
successConditionExp = finishExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroupErrorCondition getErrorCondition() {
|
||||
return errorCondition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) {
|
||||
this.errorCondition = errorCondition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorConditionExp() {
|
||||
return errorConditionExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorConditionExp(final String errorExp) {
|
||||
errorConditionExp = errorExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroupErrorAction getErrorAction() {
|
||||
return errorAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorAction(final RolloutGroupErrorAction errorAction) {
|
||||
this.errorAction = errorAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorActionExp() {
|
||||
return errorActionExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorActionExp(final String errorActionExp) {
|
||||
this.errorActionExp = errorActionExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroupSuccessAction getSuccessAction() {
|
||||
return successAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuccessActionExp() {
|
||||
return successActionExp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalTargets() {
|
||||
return totalTargets;
|
||||
}
|
||||
|
||||
public void setTotalTargets(final long totalTargets) {
|
||||
this.totalTargets = totalTargets;
|
||||
}
|
||||
|
||||
public void setSuccessAction(final RolloutGroupSuccessAction successAction) {
|
||||
this.successAction = successAction;
|
||||
}
|
||||
|
||||
public void setSuccessActionExp(final String successActionExp) {
|
||||
this.successActionExp = successActionExp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the totalTargetCountStatus
|
||||
*/
|
||||
@Override
|
||||
public TotalTargetCountStatus getTotalTargetCountStatus() {
|
||||
if (totalTargetCountStatus == null) {
|
||||
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets);
|
||||
}
|
||||
return totalTargetCountStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param totalTargetCountStatus
|
||||
* the totalTargetCountStatus to set
|
||||
*/
|
||||
@Override
|
||||
public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) {
|
||||
this.totalTargetCountStatus = totalTargetCountStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup
|
||||
+ ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp
|
||||
+ ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName()
|
||||
+ ", getId()=" + getId() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) {
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus().
|
||||
post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup,
|
||||
EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,234 +1,257 @@
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
import org.springframework.data.domain.Persistable;
|
||||
|
||||
/**
|
||||
* JPA implementation of {@link Target}.
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "sp_target", indexes = {
|
||||
@Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"),
|
||||
@Index(name = "sp_idx_target_02", columnList = "tenant,name"),
|
||||
@Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"),
|
||||
@Index(name = "sp_idx_target_04", columnList = "tenant,created_at"),
|
||||
@Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = {
|
||||
"controller_id", "tenant" }, name = "uk_tenant_controller_id"))
|
||||
@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"),
|
||||
@NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") })
|
||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||
// sub entities
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Long>, Target {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Column(name = "controller_id", length = 64)
|
||||
@Size(min = 1)
|
||||
@NotNull
|
||||
private String controllerId;
|
||||
|
||||
@Transient
|
||||
private boolean entityNew;
|
||||
|
||||
@ManyToMany(targetEntity = JpaTargetTag.class)
|
||||
@JoinTable(name = "sp_target_target_tag", joinColumns = {
|
||||
@JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = {
|
||||
@JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) })
|
||||
private Set<TargetTag> tags = new HashSet<>();
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = {
|
||||
CascadeType.REMOVE }, targetEntity = JpaAction.class)
|
||||
@JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ"))
|
||||
private final List<Action> actions = new ArrayList<>();
|
||||
|
||||
@ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class)
|
||||
@JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds"))
|
||||
private JpaDistributionSet assignedDistributionSet;
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class)
|
||||
@PrimaryKeyJoinColumn
|
||||
private JpaTargetInfo targetInfo;
|
||||
|
||||
/**
|
||||
* the security token of the target which allows if enabled to authenticate
|
||||
* with this security token.
|
||||
*/
|
||||
@Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128)
|
||||
private String securityToken;
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
|
||||
@JoinColumn(name = "target_Id", insertable = false, updatable = false)
|
||||
private final List<RolloutTargetGroup> rolloutTargetGroup = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param controllerId
|
||||
* controller ID of the {@link Target}
|
||||
*/
|
||||
public JpaTarget(final String controllerId) {
|
||||
this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param controllerId
|
||||
* controller ID of the {@link Target}
|
||||
* @param securityToken
|
||||
* for target authentication if enabled
|
||||
*/
|
||||
public JpaTarget(final String controllerId, final String securityToken) {
|
||||
this.controllerId = controllerId;
|
||||
setName(controllerId);
|
||||
this.securityToken = securityToken;
|
||||
targetInfo = new JpaTargetInfo(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* empty constructor for JPA.
|
||||
*/
|
||||
JpaTarget() {
|
||||
controllerId = null;
|
||||
securityToken = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSet getAssignedDistributionSet() {
|
||||
return assignedDistributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControllerId() {
|
||||
return controllerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TargetTag> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) {
|
||||
this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet;
|
||||
}
|
||||
|
||||
public void setControllerId(final String controllerId) {
|
||||
this.controllerId = controllerId;
|
||||
}
|
||||
|
||||
public void setTags(final Set<TargetTag> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Action> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
public boolean isNew() {
|
||||
return entityNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isNew
|
||||
* the isNew to set
|
||||
*/
|
||||
public void setNew(final boolean entityNew) {
|
||||
this.entityNew = entityNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the targetInfo
|
||||
*/
|
||||
@Override
|
||||
public TargetInfo getTargetInfo() {
|
||||
return targetInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param targetInfo
|
||||
* the targetInfo to set
|
||||
*/
|
||||
public void setTargetInfo(final TargetInfo targetInfo) {
|
||||
this.targetInfo = (JpaTargetInfo) targetInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the securityToken if the current security context contains the
|
||||
* necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN}
|
||||
* or the current context is executed as system code, otherwise
|
||||
* {@code null}.
|
||||
*/
|
||||
@Override
|
||||
public String getSecurityToken() {
|
||||
if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode()
|
||||
|| SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) {
|
||||
return securityToken;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param securityToken
|
||||
* the securityToken to set
|
||||
*/
|
||||
public void setSecurityToken(final String securityToken) {
|
||||
this.securityToken = securityToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
import org.springframework.data.domain.Persistable;
|
||||
|
||||
/**
|
||||
* JPA implementation of {@link Target}.
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "sp_target", indexes = {
|
||||
@Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"),
|
||||
@Index(name = "sp_idx_target_02", columnList = "tenant,name"),
|
||||
@Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"),
|
||||
@Index(name = "sp_idx_target_04", columnList = "tenant,created_at"),
|
||||
@Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = {
|
||||
"controller_id", "tenant" }, name = "uk_tenant_controller_id"))
|
||||
@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"),
|
||||
@NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") })
|
||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||
// sub entities
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Long>, Target, EventAwareEntity<JpaTarget> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Column(name = "controller_id", length = 64)
|
||||
@Size(min = 1)
|
||||
@NotNull
|
||||
private String controllerId;
|
||||
|
||||
@Transient
|
||||
private boolean entityNew;
|
||||
|
||||
@ManyToMany(targetEntity = JpaTargetTag.class)
|
||||
@JoinTable(name = "sp_target_target_tag", joinColumns = {
|
||||
@JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = {
|
||||
@JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) })
|
||||
private Set<TargetTag> tags = new HashSet<>();
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = {
|
||||
CascadeType.REMOVE }, targetEntity = JpaAction.class)
|
||||
@JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ"))
|
||||
private final List<Action> actions = new ArrayList<>();
|
||||
|
||||
@ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class)
|
||||
@JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds"))
|
||||
private JpaDistributionSet assignedDistributionSet;
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class)
|
||||
@PrimaryKeyJoinColumn
|
||||
private JpaTargetInfo targetInfo;
|
||||
|
||||
/**
|
||||
* the security token of the target which allows if enabled to authenticate
|
||||
* with this security token.
|
||||
*/
|
||||
@Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128)
|
||||
private String securityToken;
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
|
||||
@JoinColumn(name = "target_Id", insertable = false, updatable = false)
|
||||
private final List<RolloutTargetGroup> rolloutTargetGroup = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param controllerId
|
||||
* controller ID of the {@link Target}
|
||||
*/
|
||||
public JpaTarget(final String controllerId) {
|
||||
this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param controllerId
|
||||
* controller ID of the {@link Target}
|
||||
* @param securityToken
|
||||
* for target authentication if enabled
|
||||
*/
|
||||
public JpaTarget(final String controllerId, final String securityToken) {
|
||||
this.controllerId = controllerId;
|
||||
setName(controllerId);
|
||||
this.securityToken = securityToken;
|
||||
targetInfo = new JpaTargetInfo(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* empty constructor for JPA.
|
||||
*/
|
||||
JpaTarget() {
|
||||
controllerId = null;
|
||||
securityToken = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSet getAssignedDistributionSet() {
|
||||
return assignedDistributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControllerId() {
|
||||
return controllerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TargetTag> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) {
|
||||
this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet;
|
||||
}
|
||||
|
||||
public void setControllerId(final String controllerId) {
|
||||
this.controllerId = controllerId;
|
||||
}
|
||||
|
||||
public void setTags(final Set<TargetTag> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Action> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
public boolean isNew() {
|
||||
return entityNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isNew
|
||||
* the isNew to set
|
||||
*/
|
||||
public void setNew(final boolean entityNew) {
|
||||
this.entityNew = entityNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the targetInfo
|
||||
*/
|
||||
@Override
|
||||
public TargetInfo getTargetInfo() {
|
||||
return targetInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param targetInfo
|
||||
* the targetInfo to set
|
||||
*/
|
||||
public void setTargetInfo(final TargetInfo targetInfo) {
|
||||
this.targetInfo = (JpaTargetInfo) targetInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the securityToken if the current security context contains the
|
||||
* necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN}
|
||||
* or the current context is executed as system code, otherwise
|
||||
* {@code null}.
|
||||
*/
|
||||
@Override
|
||||
public String getSecurityToken() {
|
||||
if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode()
|
||||
|| SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) {
|
||||
return securityToken;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param securityToken
|
||||
* the securityToken to set
|
||||
*/
|
||||
@Override
|
||||
public void setSecurityToken(final String securityToken) {
|
||||
this.securityToken = securityToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCreateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) {
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final JpaTarget jpaTarget,final DescriptorEvent descriptorEvent) {
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget)));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,324 +1,344 @@
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.MapKeyColumn;
|
||||
import javax.persistence.MapsId;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.PollStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.domain.Persistable;
|
||||
|
||||
/**
|
||||
* A table which contains all the information inserted, updated by the
|
||||
* controller itself. So this entity does not provide audit information because
|
||||
* changes on this entity are mostly only done by controller requests. That's
|
||||
* the reason that we store these information in a separated table so we don't
|
||||
* modifying the {@link Target} itself when a controller reports it's
|
||||
* {@link #lastTargetQuery} for example.
|
||||
*
|
||||
*/
|
||||
@Table(name = "sp_target_info", indexes = {
|
||||
@Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") })
|
||||
@Entity
|
||||
public class JpaTargetInfo implements Persistable<Long>, TargetInfo {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class);
|
||||
|
||||
@Id
|
||||
private Long targetId;
|
||||
|
||||
@Transient
|
||||
private boolean entityNew;
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToOne(cascade = { CascadeType.MERGE,
|
||||
CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class)
|
||||
@JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ"))
|
||||
@MapsId
|
||||
private JpaTarget target;
|
||||
|
||||
@Column(name = "address", length = 512)
|
||||
private String address;
|
||||
|
||||
@Column(name = "last_target_query")
|
||||
private Long lastTargetQuery;
|
||||
|
||||
@Column(name = "install_date")
|
||||
private Long installationDate;
|
||||
|
||||
@Column(name = "update_status", nullable = false, length = 255)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN;
|
||||
|
||||
@ManyToOne(optional = true, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds"))
|
||||
private JpaDistributionSet installedDistributionSet;
|
||||
|
||||
/**
|
||||
* Read only on management API. Are commited by controller.
|
||||
*/
|
||||
@ElementCollection
|
||||
@Column(name = "attribute_value", length = 128)
|
||||
@MapKeyColumn(name = "attribute_key", nullable = false, length = 32)
|
||||
@CollectionTable(name = "sp_target_attributes", joinColumns = {
|
||||
@JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target"))
|
||||
|
||||
private final Map<String, String> controllerAttributes = Collections.synchronizedMap(new HashMap<String, String>());
|
||||
|
||||
// set default request controller attributes to true, because we want to
|
||||
// request them the first
|
||||
// time
|
||||
@Column(name = "request_controller_attributes", nullable = false)
|
||||
private boolean requestControllerAttributes = true;
|
||||
|
||||
/**
|
||||
* Constructor for {@link TargetStatus}.
|
||||
*
|
||||
* @param target
|
||||
* related to this status.
|
||||
*/
|
||||
public JpaTargetInfo(final JpaTarget target) {
|
||||
this.target = target;
|
||||
targetId = target.getId();
|
||||
}
|
||||
|
||||
JpaTargetInfo() {
|
||||
target = null;
|
||||
targetId = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return targetId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
public boolean isNew() {
|
||||
return entityNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isNew
|
||||
* the isNew to set
|
||||
*/
|
||||
public void setNew(final boolean entityNew) {
|
||||
this.entityNew = entityNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ipAddress
|
||||
*/
|
||||
@Override
|
||||
public URI getAddress() {
|
||||
if (address == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return URI.create(address);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
LOG.warn("Invalid address provided. Cloud not be configured to URI", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param address
|
||||
* the target address to set
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If the given string violates RFC 2396
|
||||
*/
|
||||
@Override
|
||||
public void setAddress(final String address) {
|
||||
// check if this is a real URI
|
||||
if (address != null) {
|
||||
try {
|
||||
URI.create(address);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
throw new InvalidTargetAddressException(
|
||||
"The given address " + address + " violates the RFC-2396 specification", e);
|
||||
}
|
||||
}
|
||||
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public Long getTargetId() {
|
||||
return targetId;
|
||||
}
|
||||
|
||||
public void setTargetId(final Long targetId) {
|
||||
this.targetId = targetId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Target getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(final JpaTarget target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLastTargetQuery() {
|
||||
return lastTargetQuery;
|
||||
}
|
||||
|
||||
public void setLastTargetQuery(final Long lastTargetQuery) {
|
||||
this.lastTargetQuery = lastTargetQuery;
|
||||
}
|
||||
|
||||
public void setRequestControllerAttributes(final boolean requestControllerAttributes) {
|
||||
this.requestControllerAttributes = requestControllerAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getControllerAttributes() {
|
||||
return controllerAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestControllerAttributes() {
|
||||
return requestControllerAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getInstallationDate() {
|
||||
return installationDate;
|
||||
}
|
||||
|
||||
public void setInstallationDate(final Long installationDate) {
|
||||
this.installationDate = installationDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetUpdateStatus getUpdateStatus() {
|
||||
return updateStatus;
|
||||
}
|
||||
|
||||
public void setUpdateStatus(final TargetUpdateStatus updateStatus) {
|
||||
this.updateStatus = updateStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSet getInstalledDistributionSet() {
|
||||
return installedDistributionSet;
|
||||
}
|
||||
|
||||
public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) {
|
||||
this.installedDistributionSet = installedDistributionSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the poll time which holds the last poll time of the target, the
|
||||
* next poll time and the overdue time. In case the
|
||||
* {@link #lastTargetQuery} is not set e.g. the target never polled
|
||||
* before this method returns {@code null}
|
||||
*/
|
||||
@Override
|
||||
public PollStatus getPollStatus() {
|
||||
if (lastTargetQuery == null) {
|
||||
return null;
|
||||
}
|
||||
return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> {
|
||||
final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder
|
||||
.getInstance().getTenantConfigurationManagement()
|
||||
.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue());
|
||||
final Duration overdueTime = DurationHelper.formattedStringToDuration(
|
||||
TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement()
|
||||
.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)
|
||||
.getValue());
|
||||
final LocalDateTime currentDate = LocalDateTime.now();
|
||||
final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery),
|
||||
ZoneId.systemDefault());
|
||||
final LocalDateTime nextPollDate = lastPollDate.plus(pollTime);
|
||||
final LocalDateTime overdueDate = nextPollDate.plus(overdueTime);
|
||||
return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((target == null) ? 0 : target.hashCode());
|
||||
result = prime * result + ((targetId == null) ? 0 : targetId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof TargetInfo)) {
|
||||
return false;
|
||||
}
|
||||
final JpaTargetInfo other = (JpaTargetInfo) obj;
|
||||
if (target == null) {
|
||||
if (other.target != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!target.equals(other.target)) {
|
||||
return false;
|
||||
}
|
||||
if (targetId == null) {
|
||||
if (other.targetId != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!targetId.equals(other.targetId)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.jpa.model;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ConstraintMode;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityListeners;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.ForeignKey;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.MapKeyColumn;
|
||||
import javax.persistence.MapsId;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.PollStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.domain.Persistable;
|
||||
|
||||
/**
|
||||
* A table which contains all the information inserted, updated by the
|
||||
* controller itself. So this entity does not provide audit information because
|
||||
* changes on this entity are mostly only done by controller requests. That's
|
||||
* the reason that we store these information in a separated table so we don't
|
||||
* modifying the {@link Target} itself when a controller reports it's
|
||||
* {@link #lastTargetQuery} for example.
|
||||
*
|
||||
*/
|
||||
@Table(name = "sp_target_info", indexes = {
|
||||
@Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") })
|
||||
@Entity
|
||||
@EntityListeners(EntityPropertyChangeListener.class)
|
||||
public class JpaTargetInfo implements Persistable<Long>, TargetInfo, EventAwareEntity<JpaTargetInfo> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class);
|
||||
|
||||
@Id
|
||||
private Long targetId;
|
||||
|
||||
@Transient
|
||||
private boolean entityNew;
|
||||
|
||||
@CascadeOnDelete
|
||||
@OneToOne(cascade = { CascadeType.MERGE,
|
||||
CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class)
|
||||
@JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ"))
|
||||
@MapsId
|
||||
private JpaTarget target;
|
||||
|
||||
@Column(name = "address", length = 512)
|
||||
private String address;
|
||||
|
||||
@Column(name = "last_target_query")
|
||||
private Long lastTargetQuery;
|
||||
|
||||
@Column(name = "install_date")
|
||||
private Long installationDate;
|
||||
|
||||
@Column(name = "update_status", nullable = false, length = 255)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN;
|
||||
|
||||
@ManyToOne(optional = true, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds"))
|
||||
private JpaDistributionSet installedDistributionSet;
|
||||
|
||||
/**
|
||||
* Read only on management API. Are commited by controller.
|
||||
*/
|
||||
@ElementCollection
|
||||
@Column(name = "attribute_value", length = 128)
|
||||
@MapKeyColumn(name = "attribute_key", nullable = false, length = 32)
|
||||
@CollectionTable(name = "sp_target_attributes", joinColumns = {
|
||||
@JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target"))
|
||||
|
||||
private final Map<String, String> controllerAttributes = Collections.synchronizedMap(new HashMap<String, String>());
|
||||
|
||||
// set default request controller attributes to true, because we want to
|
||||
// request them the first
|
||||
// time
|
||||
@Column(name = "request_controller_attributes", nullable = false)
|
||||
private boolean requestControllerAttributes = true;
|
||||
|
||||
/**
|
||||
* Constructor for {@link TargetStatus}.
|
||||
*
|
||||
* @param target
|
||||
* related to this status.
|
||||
*/
|
||||
public JpaTargetInfo(final JpaTarget target) {
|
||||
this.target = target;
|
||||
targetId = target.getId();
|
||||
}
|
||||
|
||||
JpaTargetInfo() {
|
||||
target = null;
|
||||
targetId = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return targetId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
public boolean isNew() {
|
||||
return entityNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isNew
|
||||
* the isNew to set
|
||||
*/
|
||||
public void setNew(final boolean entityNew) {
|
||||
this.entityNew = entityNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ipAddress
|
||||
*/
|
||||
@Override
|
||||
public URI getAddress() {
|
||||
if (address == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return URI.create(address);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
LOG.warn("Invalid address provided. Cloud not be configured to URI", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param address
|
||||
* the target address to set
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If the given string violates RFC 2396
|
||||
*/
|
||||
@Override
|
||||
public void setAddress(final String address) {
|
||||
// check if this is a real URI
|
||||
if (address != null) {
|
||||
try {
|
||||
URI.create(address);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
throw new InvalidTargetAddressException(
|
||||
"The given address " + address + " violates the RFC-2396 specification", e);
|
||||
}
|
||||
}
|
||||
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public Long getTargetId() {
|
||||
return targetId;
|
||||
}
|
||||
|
||||
public void setTargetId(final Long targetId) {
|
||||
this.targetId = targetId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Target getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(final JpaTarget target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLastTargetQuery() {
|
||||
return lastTargetQuery;
|
||||
}
|
||||
|
||||
public void setLastTargetQuery(final Long lastTargetQuery) {
|
||||
this.lastTargetQuery = lastTargetQuery;
|
||||
}
|
||||
|
||||
public void setRequestControllerAttributes(final boolean requestControllerAttributes) {
|
||||
this.requestControllerAttributes = requestControllerAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getControllerAttributes() {
|
||||
return controllerAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestControllerAttributes() {
|
||||
return requestControllerAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getInstallationDate() {
|
||||
return installationDate;
|
||||
}
|
||||
|
||||
public void setInstallationDate(final Long installationDate) {
|
||||
this.installationDate = installationDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetUpdateStatus getUpdateStatus() {
|
||||
return updateStatus;
|
||||
}
|
||||
|
||||
public void setUpdateStatus(final TargetUpdateStatus updateStatus) {
|
||||
this.updateStatus = updateStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributionSet getInstalledDistributionSet() {
|
||||
return installedDistributionSet;
|
||||
}
|
||||
|
||||
public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) {
|
||||
this.installedDistributionSet = installedDistributionSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the poll time which holds the last poll time of the target, the
|
||||
* next poll time and the overdue time. In case the
|
||||
* {@link #lastTargetQuery} is not set e.g. the target never polled
|
||||
* before this method returns {@code null}
|
||||
*/
|
||||
@Override
|
||||
public PollStatus getPollStatus() {
|
||||
if (lastTargetQuery == null) {
|
||||
return null;
|
||||
}
|
||||
return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> {
|
||||
final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder
|
||||
.getInstance().getTenantConfigurationManagement()
|
||||
.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue());
|
||||
final Duration overdueTime = DurationHelper.formattedStringToDuration(
|
||||
TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement()
|
||||
.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)
|
||||
.getValue());
|
||||
final LocalDateTime currentDate = LocalDateTime.now();
|
||||
final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery),
|
||||
ZoneId.systemDefault());
|
||||
final LocalDateTime nextPollDate = lastPollDate.plus(pollTime);
|
||||
final LocalDateTime overdueDate = nextPollDate.plus(overdueTime);
|
||||
return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((target == null) ? 0 : target.hashCode());
|
||||
result = prime * result + ((targetId == null) ? 0 : targetId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof TargetInfo)) {
|
||||
return false;
|
||||
}
|
||||
final JpaTargetInfo other = (JpaTargetInfo) obj;
|
||||
if (target == null) {
|
||||
if (other.target != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!target.equals(other.target)) {
|
||||
return false;
|
||||
}
|
||||
if (targetId == null) {
|
||||
if (other.targetId != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!targetId.equals(other.targetId)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo,final DescriptorEvent descriptorEvent) {
|
||||
// there is no target info created event
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) {
|
||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireDeleteEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 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.jpa.model.helper;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
|
||||
import org.eclipse.persistence.queries.UpdateObjectQuery;
|
||||
import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord;
|
||||
|
||||
public class EntityPropertyChangeHelper<T extends TenantAwareBaseEntity> {
|
||||
|
||||
|
||||
public static <T extends TenantAwareBaseEntity> Map<String, AbstractPropertyChangeEvent<T>.Values> getChangeSet(
|
||||
final Class<T> clazz, final DescriptorEvent event) {
|
||||
final T rolloutGroup = clazz.cast(event.getObject());
|
||||
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery())
|
||||
.getObjectChangeSet();
|
||||
return changeSet
|
||||
.getChanges()
|
||||
.stream()
|
||||
.filter(record -> record instanceof DirectToFieldChangeRecord)
|
||||
.map(record -> (DirectToFieldChangeRecord) record)
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
record -> record.getAttribute(),
|
||||
record -> new AbstractPropertyChangeEvent<T>(
|
||||
rolloutGroup, null).new Values(record
|
||||
.getOldValue(), record.getNewValue())));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user