Feature horizontal scalability (#305)

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Dennis Melzer
2016-11-03 15:53:53 +01:00
committed by Kai Zimmermann
parent 07cb62a3dd
commit 866bc72114
287 changed files with 4219 additions and 5046 deletions

View File

@@ -8,7 +8,8 @@
http://www.eclipse.org/legal/epl-v10.html
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.hawkbit</groupId>
@@ -36,6 +37,10 @@
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
<!-- Optional -->
<dependency>

View File

@@ -16,7 +16,7 @@ import java.util.Optional;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
@@ -25,7 +25,6 @@ import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
@@ -34,8 +33,6 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.security.access.prepost.PreAuthorize;
import com.google.common.eventbus.EventBus;
/**
* Service layer for all operations of the DDI API (with access permissions only
* for the controller).
@@ -59,7 +56,7 @@ public interface ControllerManagement {
Action addCancelActionStatus(@NotNull ActionStatus actionStatus);
/**
* Sends the download progress and notifies the {@link EventBus} with a
* Sends the download progress and notifies the event publisher with a
* {@link DownloadProgressEvent}.
*
* @param statusId
@@ -148,19 +145,6 @@ public interface ControllerManagement {
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
Target findOrRegisterTargetIfItDoesNotexist(@NotEmpty String controllerId, URI address);
/**
* Retrieves all {@link SoftwareModule}s which are assigned to the given
* {@link DistributionSet}.
*
* @param distributionSet
* the distribution set which should be assigned to the returned
* {@link SoftwareModule}s
* @return a list of {@link SoftwareModule}s assigned to given
* {@code distributionSet}
*/
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
List<SoftwareModule> findSoftwareModulesByDistributionSet(@NotNull DistributionSet distributionSet);
/**
* Retrieves last {@link Action} for a download of an artifact of given
* module and target.

View File

@@ -24,6 +24,7 @@ import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.ActionWithStatusCount;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;

View File

@@ -11,7 +11,7 @@ package org.eclipse.hawkbit.repository;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupCreatedEvent;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;

View File

@@ -8,6 +8,8 @@
*/
package org.eclipse.hawkbit.repository;
import java.io.Serializable;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
@@ -40,7 +42,8 @@ public interface TenantConfigurationManagement {
* if the property cannot be converted to the given
*/
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
<T> TenantConfigurationValue<T> addOrUpdateConfiguration(TenantConfigurationKey configurationKey, T value);
<T extends Serializable> TenantConfigurationValue<T> addOrUpdateConfiguration(
TenantConfigurationKey configurationKey, T value);
/**
* Build the tenant configuration by the given key
@@ -55,8 +58,8 @@ public interface TenantConfigurationManagement {
* or returns the tenant configuration value
*/
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
<T> TenantConfigurationValue<T> buildTenantConfigurationValueByKey(TenantConfigurationKey configurationKey,
Class<T> propertyType, TenantConfiguration tenantConfiguration);
<T extends Serializable> TenantConfigurationValue<T> buildTenantConfigurationValueByKey(
TenantConfigurationKey configurationKey, Class<T> propertyType, TenantConfiguration tenantConfiguration);
/**
* Deletes a specific configuration for the current tenant. Does nothing in
@@ -87,7 +90,7 @@ public interface TenantConfigurationManagement {
* {@code propertyType}
*/
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
<T> TenantConfigurationValue<T> getConfigurationValue(TenantConfigurationKey configurationKey);
<T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(TenantConfigurationKey configurationKey);
/**
* Retrieves a configuration value from the e.g. tenant overwritten
@@ -113,7 +116,7 @@ public interface TenantConfigurationManagement {
* {@code propertyType}
*/
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
<T> TenantConfigurationValue<T> getConfigurationValue(TenantConfigurationKey configurationKey,
<T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(TenantConfigurationKey configurationKey,
Class<T> propertyType);
/**

View File

@@ -0,0 +1,24 @@
/**
* 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.event;
/**
* Events to be published to refresh data on UI.
*
*
*
*
*/
public enum CustomEvents {
TARGETS_CREATED_EVENT,
DISTRIBUTION_CREATED_EVENT
}

View File

@@ -0,0 +1,23 @@
/**
* 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.event;
/**
* An event declaration which holds an revision for each event so consumers have
* the chance to know if they might already retrieved a newer event.
*
*/
@FunctionalInterface
public interface TenantAwareEvent {
/**
* @return the tenant of the event.
*/
String getTenant();
}

View File

@@ -0,0 +1,40 @@
/**
* 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.event.remote;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
* Defines the remote event for deletion of {@link DistributionSet}.
*/
public class DistributionSetDeletedEvent extends RemoteIdEvent {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public DistributionSetDeletedEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param tenant
* the tenant
* @param entityId
* the entity id
* @param applicationId
* the origin application id
*/
public DistributionSetDeletedEvent(final String tenant, final Long entityId, final String applicationId) {
super(entityId, tenant, applicationId);
}
}

View File

@@ -0,0 +1,41 @@
/**
* 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.event.remote;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
/**
* Defines the the remote event of delete a {@link DistributionSetTag}.
*/
public class DistributionSetTagDeletedEvent extends RemoteIdEvent {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public DistributionSetTagDeletedEvent() {
// for serialization libs like jackson
}
/**
* Constructor for json serialization.
*
* @param tenant
* the tenant
* @param entityId
* the entity id
* @param applicationId
* the origin application id
*/
public DistributionSetTagDeletedEvent(final String tenant, final Long entityId, final String applicationId) {
super(entityId, tenant, applicationId);
}
}

View File

@@ -0,0 +1,48 @@
/**
* 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.event.remote;
/**
* TenantAwareEvent that contains an updated download progress for a given
* ActionStatus that was written for a download request.
*
*/
public class DownloadProgressEvent extends RemoteTenantAwareEvent {
private static final long serialVersionUID = 1L;
private Long shippedBytesSinceLast;
/**
* Default constructor.
*/
public DownloadProgressEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param tenant
* the tenant
* @param shippedBytesSinceLast
* the shippedBytesSinceLast
* @param applicationId
* the application id.
*/
public DownloadProgressEvent(final String tenant, final Long shippedBytesSinceLast, final String applicationId) {
super(shippedBytesSinceLast, tenant, applicationId);
this.shippedBytesSinceLast = shippedBytesSinceLast;
}
public long getShippedBytesSinceLast() {
return shippedBytesSinceLast;
}
}

View File

@@ -0,0 +1,32 @@
/**
* 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.event.remote;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
/**
* Loads an entity e.g. if a remote event is received.
*/
@FunctionalInterface
public interface EventEntityManager {
/**
* Find an entity by given id and return it.
*
* @param tenant
* the tenant
* @param id
* the id
* @param entityType
* the entity type
* @return the entity
*/
<E extends TenantAwareBaseEntity> E findEntity(String tenant, Long id, Class<E> entityType);
}

View File

@@ -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.event.remote;
import org.springframework.beans.factory.annotation.Autowired;
/**
* A singleton bean which holds the event entity manager to have autowiring in
* the events.
*
*/
public final class EventEntityManagerHolder {
private static final EventEntityManagerHolder SINGLETON = new EventEntityManagerHolder();
@Autowired
private EventEntityManager eventEntityManager;
private EventEntityManagerHolder() {
}
/**
* @return the cache manager holder singleton instance
*/
public static EventEntityManagerHolder getInstance() {
return SINGLETON;
}
/**
* @return the eventEntityManager
*/
public EventEntityManager getEventEntityManager() {
return eventEntityManager;
}
}

View File

@@ -0,0 +1,47 @@
/**
* 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.event.remote;
/**
* An base definition class for an event which contains an id.
*
*/
public class RemoteIdEvent extends RemoteTenantAwareEvent {
private static final long serialVersionUID = 1L;
private Long entityId;
/**
* Default constructor.
*/
protected RemoteIdEvent() {
// for serialization libs like jackson
}
/**
* Constructor for json serialization.
*
* @param entityId
* the entity Id
* @param tenant
* the tenant
* @param applicationId
* the origin application id
*/
protected RemoteIdEvent(final Long entityId, final String tenant, final String applicationId) {
super(entityId, tenant, applicationId);
this.entityId = entityId;
}
public Long getEntityId() {
return entityId;
}
}

View File

@@ -0,0 +1,52 @@
/**
* 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.event.remote;
import org.eclipse.hawkbit.repository.event.TenantAwareEvent;
import org.springframework.cloud.bus.event.RemoteApplicationEvent;
/**
* A distributed tenant aware event. It's the base class of the other
* distributed events. All the necessary information of distributing events to
* other nodes.
*
*/
public class RemoteTenantAwareEvent extends RemoteApplicationEvent implements TenantAwareEvent {
private static final long serialVersionUID = 1L;
private String tenant;
/**
* Default constructor.
*/
protected RemoteTenantAwareEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param source
* the for the remote event.
* @param tenant
* the tenant
* @param applicationId
* the applicationId
*/
public RemoteTenantAwareEvent(final Object source, final String tenant, final String applicationId) {
super(source, applicationId, "**");
this.tenant = tenant;
}
@Override
public String getTenant() {
return tenant;
}
}

View File

@@ -0,0 +1,88 @@
/**
* 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.event.remote;
import java.util.Collection;
import java.util.Collections;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* TenantAwareEvent that gets sent when a distribution set gets assigned to a
* target.
*/
public class TargetAssignDistributionSetEvent extends RemoteTenantAwareEvent {
private static final long serialVersionUID = 1L;
private Long actionId;
private Long distributionSetId;
private String controllerId;
private transient Collection<SoftwareModule> modules;
/**
* Default constructor.
*/
public TargetAssignDistributionSetEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param action
* the action
* @param applicationId
* the application id.
*/
public TargetAssignDistributionSetEvent(final Action action, final String applicationId) {
this(action.getTenant(), action.getId(), action.getDistributionSet().getId(),
action.getTarget().getControllerId(), applicationId);
this.modules = action.getDistributionSet().getModules();
}
private TargetAssignDistributionSetEvent(final String tenant, final Long actionId, final Long distributionSetId,
final String controllerId, final String applicationId) {
super(actionId, tenant, applicationId);
this.actionId = actionId;
this.distributionSetId = distributionSetId;
this.controllerId = controllerId;
}
public Long getActionId() {
return actionId;
}
public String getControllerId() {
return controllerId;
}
public Long getDistributionSetId() {
return distributionSetId;
}
/**
* @return modules if Event has been published by same node otherwise empty.
*/
@JsonIgnore
public Collection<SoftwareModule> getModules() {
if (modules == null) {
return Collections.emptyList();
}
return modules;
}
}

View File

@@ -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.event.remote;
import org.eclipse.hawkbit.repository.model.Target;
/**
*
* Defines the remote event of deleting a {@link Target}.
*/
public class TargetDeletedEvent extends RemoteIdEvent {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public TargetDeletedEvent() {
// for serialization libs like jackson
}
/**
* Constructor for json serialization.
*
* @param tenant
* the tenant
* @param entityId
* the entity id
* @param applicationId
* the origin application id
*/
public TargetDeletedEvent(final String tenant, final Long entityId, final String applicationId) {
super(entityId, tenant, applicationId);
}
}

View File

@@ -0,0 +1,41 @@
/**
* 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.event.remote;
import org.eclipse.hawkbit.repository.model.TargetTag;
/**
* Defines the remote event of delete a {@link TargetTag}.
*
*/
public class TargetTagDeletedEvent extends RemoteIdEvent {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public TargetTagDeletedEvent() {
// for serialization libs like jackson
}
/**
* Constructor for json serialization.
*
* @param tenant
* the tenant
* @param entityId
* the entity id
* @param applicationId
* the origin application id
*/
public TargetTagDeletedEvent(final String tenant, final Long entityId, final String applicationId) {
super(entityId, tenant, applicationId);
}
}

View File

@@ -0,0 +1,38 @@
/**
* 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.event.remote.entity;
import org.eclipse.hawkbit.repository.model.Action;
/**
* Defines the remote event of creating a new {@link Action}.
*/
public class ActionCreatedEvent extends RemoteEntityEvent<Action> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public ActionCreatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor
*
* @param action
* the created action
* @param applicationId
* the origin application id
*/
public ActionCreatedEvent(final Action action, final String applicationId) {
super(action, applicationId);
}
}

View File

@@ -0,0 +1,38 @@
/**
* 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.event.remote.entity;
import org.eclipse.hawkbit.repository.model.Action;
/**
* Defines the remote event of updated a {@link Action}.
*/
public class ActionUpdatedEvent extends RemoteEntityEvent<Action> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public ActionUpdatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor
*
* @param action
* the updated action
* @param applicationId
* the origin application id
*/
public ActionUpdatedEvent(final Action action, final String applicationId) {
super(action, applicationId);
}
}

View File

@@ -0,0 +1,52 @@
/**
* 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.event.remote.entity;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Event that gets sent when the assignment of a distribution set to a target
* gets canceled.
*/
public class CancelTargetAssignmentEvent extends RemoteEntityEvent<Target> {
private static final long serialVersionUID = 1L;
private Long actionId;
/**
* Default constructor.
*/
public CancelTargetAssignmentEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param baseEntity
* the target
* @param actionId
* the actionId
* @param applicationId
* the origin application id
*/
public CancelTargetAssignmentEvent(final Target baseEntity, final Long actionId, final String applicationId) {
super(baseEntity, applicationId);
this.actionId = actionId;
}
/**
* @return the action id of the assignment
*/
public Long getActionId() {
return actionId;
}
}

View File

@@ -0,0 +1,40 @@
/**
* 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.event.remote.entity;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
* Defines the the remote of creating a new {@link DistributionSet}.
*
*/
public class DistributionSetCreatedEvent extends RemoteEntityEvent<DistributionSet> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public DistributionSetCreatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param distributionSet
* the created distributionSet
* @param applicationId
* the origin application id
*/
public DistributionSetCreatedEvent(final DistributionSet distributionSet, final String applicationId) {
super(distributionSet, applicationId);
}
}

View File

@@ -6,26 +6,35 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.eventbus.event;
package org.eclipse.hawkbit.repository.event.remote.entity;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
/**
* Defines the {@link AbstractBaseEntityEvent} for creation of a new
* Defines the {@link RemoteEntityEvent} for creation of a new
* {@link DistributionSetTag}.
*
*/
public class DistributionSetTagCreatedEvent extends AbstractBaseEntityEvent<DistributionSetTag> {
public class DistributionSetTagCreatedEvent extends RemoteEntityEvent<DistributionSetTag> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public DistributionSetTagCreatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param tag
* the tag which is updated
* the tag which is deleted
* @param applicationId
* the origin application id
*/
public DistributionSetTagCreatedEvent(final DistributionSetTag tag) {
super(tag);
public DistributionSetTagCreatedEvent(final DistributionSetTag tag, final String applicationId) {
super(tag, applicationId);
}
}

View File

@@ -6,26 +6,34 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.eventbus.event;
package org.eclipse.hawkbit.repository.event.remote.entity;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
/**
* Defines the {@link AbstractBaseEntityEvent} for update a
* {@link DistributionSetTag}.
* Defines the remote event for update a {@link DistributionSetTag}.
*
*/
public class DistributionSetTagUpdateEvent extends AbstractBaseEntityEvent<DistributionSetTag> {
public class DistributionSetTagUpdateEvent extends RemoteEntityEvent<DistributionSetTag> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public DistributionSetTagUpdateEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param tag
* the tag which is updated
* tag the tag which is updated
* @param applicationId
* the applicationID
*/
public DistributionSetTagUpdateEvent(final DistributionSetTag tag) {
super(tag);
public DistributionSetTagUpdateEvent(final DistributionSetTag tag, final String applicationId) {
super(tag, applicationId);
}
}

View File

@@ -0,0 +1,39 @@
/**
* 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.event.remote.entity;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
* Defines the remote event for updating a {@link DistributionSet}.
*
*/
public class DistributionSetUpdateEvent extends RemoteEntityEvent<DistributionSet> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public DistributionSetUpdateEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param ds
* Distribution Set
* @param applicationId
* the origin application id
*/
public DistributionSetUpdateEvent(final DistributionSet ds, final String applicationId) {
super(ds, applicationId);
}
}

View File

@@ -0,0 +1,85 @@
/**
* 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.event.remote.entity;
import org.apache.commons.lang3.ClassUtils;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManagerHolder;
import org.eclipse.hawkbit.repository.event.remote.RemoteIdEvent;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* A base definition class for remote events which contain a tenant aware base
* entity.
*
* @param <E>
* the type of the entity
*/
public class RemoteEntityEvent<E extends TenantAwareBaseEntity> extends RemoteIdEvent {
private static final Logger LOG = LoggerFactory.getLogger(RemoteEntityEvent.class);
private static final long serialVersionUID = 1L;
private String entityClass;
private transient E entity;
/**
* Default constructor.
*/
protected RemoteEntityEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param baseEntity
* the base entity
* @param applicationId
* the origin application id
*/
protected RemoteEntityEvent(final E baseEntity, final String applicationId) {
super(baseEntity.getId(), baseEntity.getTenant(), applicationId);
this.entityClass = baseEntity.getClass().getName();
this.entity = baseEntity;
}
/**
* @return the entityClass
*/
public String getEntityClass() {
return entityClass;
}
@JsonIgnore
public E getEntity() {
if (entity == null) {
entity = reloadEntityFromRepository();
}
return entity;
}
@SuppressWarnings("unchecked")
private E reloadEntityFromRepository() {
try {
final Class<E> clazz = (Class<E>) ClassUtils.getClass(entityClass);
return EventEntityManagerHolder.getInstance().getEventEntityManager().findEntity(getTenant(), getEntityId(),
clazz);
} catch (final ClassNotFoundException e) {
LOG.error("Cannot reload entity because class is not found", e);
}
return null;
}
}

View File

@@ -0,0 +1,48 @@
/**
* 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.event.remote.entity;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
/**
* TenantAwareEvent definition which is been published in case a rollout group
* has been created for a specific rollout.
*
*/
public class RolloutGroupCreatedEvent extends RemoteEntityEvent<RolloutGroup> {
private static final long serialVersionUID = 1L;
private Long rolloutId;
/**
* Default constructor.
*/
public RolloutGroupCreatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor
*
* @param rolloutGroup
* the updated rolloutGroup
* @param applicationId
* the origin application id
*/
public RolloutGroupCreatedEvent(final RolloutGroup rolloutGroup, final String applicationId) {
super(rolloutGroup, applicationId);
this.rolloutId = rolloutGroup.getRollout().getId();
}
public Long getRolloutId() {
return rolloutId;
}
}

View File

@@ -0,0 +1,39 @@
/**
* 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.event.remote.entity;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
/**
* Defines the remote event of updated a {@link RolloutGroup}.
*/
public class RolloutGroupUpdatedEvent extends RemoteEntityEvent<RolloutGroup> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public RolloutGroupUpdatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor
*
* @param rolloutGroup
* the updated rolloutGroup
* @param applicationId
* the origin application id
*/
public RolloutGroupUpdatedEvent(final RolloutGroup rolloutGroup, final String applicationId) {
super(rolloutGroup, applicationId);
}
}

View File

@@ -0,0 +1,38 @@
/**
* 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.event.remote.entity;
import org.eclipse.hawkbit.repository.model.Rollout;
/**
* Defines the remote event of updated a {@link Rollout}.
*/
public class RolloutUpdatedEvent extends RemoteEntityEvent<Rollout> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public RolloutUpdatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor
*
* @param rollout
* the updated rollout
* @param applicationId
* the origin application id
*/
public RolloutUpdatedEvent(final Rollout rollout, final String applicationId) {
super(rollout, applicationId);
}
}

View File

@@ -0,0 +1,39 @@
/**
* 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.event.remote.entity;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Defines the remote event of creating a new {@link Target}.
*
*/
public class TargetCreatedEvent extends RemoteEntityEvent<Target> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public TargetCreatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param baseEntity
* the target
* @param applicationId
* the origin application id
*/
public TargetCreatedEvent(final Target baseEntity, final String applicationId) {
super(baseEntity, applicationId);
}
}

View File

@@ -6,25 +6,34 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.eventbus.event;
package org.eclipse.hawkbit.repository.event.remote.entity;
import org.eclipse.hawkbit.repository.model.TargetTag;
/**
* Defines the {@link AbstractBaseEntityEvent} of update a {@link TargetTag}.
* Defines the remote event for the creation of a new {@link TargetTag}.
*
*/
public class TargetTagDeletedEvent extends AbstractBaseEntityEvent<TargetTag> {
public class TargetTagCreatedEvent extends RemoteEntityEvent<TargetTag> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public TargetTagCreatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param tag
* the tag which is deleted
* @param applicationId
* the origin application id
*/
public TargetTagDeletedEvent(final TargetTag tag) {
super(tag);
public TargetTagCreatedEvent(final TargetTag tag, final String applicationId) {
super(tag, applicationId);
}
}

View File

@@ -6,25 +6,34 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.eventbus.event;
package org.eclipse.hawkbit.repository.event.remote.entity;
import org.eclipse.hawkbit.repository.model.TargetTag;
/**
* Defines the {@link AbstractBaseEntityEvent} for update a {@link TargetTag}.
* Defines the remote event for updating a {@link TargetTag}.
*
*/
public class TargetTagUpdateEvent extends AbstractBaseEntityEvent<TargetTag> {
public class TargetTagUpdateEvent extends RemoteEntityEvent<TargetTag> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public TargetTagUpdateEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param tag
* the tag which is updated
* @param applicationId
* the origin application id
*/
public TargetTagUpdateEvent(final TargetTag tag) {
super(tag);
public TargetTagUpdateEvent(final TargetTag tag, final String applicationId) {
super(tag, applicationId);
}
}

View File

@@ -0,0 +1,40 @@
/**
* 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.event.remote.entity;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Defines the remote event for updating a {@link Target}.
*
*/
public class TargetUpdatedEvent extends RemoteEntityEvent<Target> {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public TargetUpdatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param baseEntity
* Target entity
* @param applicationId
* the origin application id
*/
public TargetUpdatedEvent(final Target baseEntity, final String applicationId) {
super(baseEntity, applicationId);
}
}

View File

@@ -1,57 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent;
import org.eclipse.hawkbit.eventbus.event.EntityEvent;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
/**
* An abstract definition class for {@link EntityEvent} for
* {@link TenantAwareBaseEntity}s, which holds the {@link TenantAwareBaseEntity}
* .
*
*
*
* @param <E>
* the type of the {@link TenantAwareBaseEntity}
*/
public abstract class AbstractBaseEntityEvent<E extends TenantAwareBaseEntity> extends AbstractDistributedEvent
implements EntityEvent {
/**
*
*/
private static final long serialVersionUID = 1L;
private final E entity;
/**
* @param baseEntity
* the entity which has been created or modified
*/
public AbstractBaseEntityEvent(final E baseEntity) {
super(baseEntity.getOptLockRevision(), baseEntity.getTenant());
this.entity = baseEntity;
}
@Override
public E getEntity() {
return entity;
}
@Override
public <T> T getEntity(final Class<T> entityClass) {
return entityClass.cast(entity);
}
@Override
public String getTenant() {
return entity.getTenant();
}
}

View File

@@ -1,82 +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.eventbus.event;
import java.util.Map;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
/**
* Property change event.
*
* @param <E>
*/
public class AbstractPropertyChangeEvent<E extends TenantAwareBaseEntity> extends AbstractBaseEntityEvent<E> {
private static final long serialVersionUID = -3671601415138242311L;
private final transient Map<String, PropertyChange> changeSet;
/**
* Initialize base entity and property changed with old and new value.
*
* @param baseEntity
* entity changed
* @param changeSetValues
* details of properties changed and old value and new value of
* the changed properties
*/
public AbstractPropertyChangeEvent(final E baseEntity, final Map<String, PropertyChange> changeSetValues) {
super(baseEntity);
this.changeSet = changeSetValues;
}
/**
* @return the changeSet
*/
public Map<String, PropertyChange> getChangeSet() {
return changeSet;
}
/**
* Carries old value and new value of a property .
*/
public static class PropertyChange {
private final Object oldValue;
private final Object newValue;
/**
* Initialize old value and new changes value of property.
*
* @param oldValue
* old value before change
* @param newValue
* new value after change
*/
public PropertyChange(final Object oldValue, final Object newValue) {
super();
this.oldValue = oldValue;
this.newValue = newValue;
}
/**
* @return the oldValue
*/
public Object getOldValue() {
return oldValue;
}
/**
* @return the newValue
*/
public Object getNewValue() {
return newValue;
}
}
}

View File

@@ -1,26 +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.eventbus.event;
import org.eclipse.hawkbit.repository.model.Action;
/**
* Defines the {@link AbstractBaseEntityEvent} of creating a new {@link Action}.
*/
public class ActionCreatedEvent extends AbstractBaseEntityEvent<Action> {
private static final long serialVersionUID = 181780358321768629L;
/**
* @param action
*/
public ActionCreatedEvent(final Action action) {
super(action);
}
}

View File

@@ -1,29 +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.eventbus.event;
import java.util.Map;
import org.eclipse.hawkbit.repository.model.Action;
/**
* Defines the {@link AbstractPropertyChangeEvent} of {@link Action}.
*/
public class ActionPropertyChangeEvent extends AbstractPropertyChangeEvent<Action> {
private static final long serialVersionUID = 181780358321768629L;
/**
* @param action
* @param changeSetValues
*/
public ActionPropertyChangeEvent(final Action action, final Map<String, PropertyChange> changeSetValues) {
super(action, changeSetValues);
}
}

View File

@@ -1,63 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Event that gets sent when the assignment of a distribution set to a target
* gets canceled.
*
*
*
*/
public class CancelTargetAssignmentEvent implements Event {
private final Target target;
private final Long actionId;
/**
* Creates a new {@link CancelTargetAssignmentEvent}.
*
* @param target
* entity
* @param actionId
* the action id of the assignment
*/
public CancelTargetAssignmentEvent(final Target target, final Long actionId) {
this.target = target;
this.actionId = actionId;
}
/**
* @return the action id of the assignment
*/
public Long getActionId() {
return actionId;
}
/**
* @return target where the action got canceled
*/
public Target getTarget() {
return target;
}
@Override
public long getRevision() {
return -1;
}
@Override
public String getTenant() {
return target.getTenant();
}
}

View File

@@ -1,28 +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.eventbus.event;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
* Defines the {@link AbstractBaseEntityEvent} of creating a new {@link DistributionSet}.
*
*/
public class DistributionCreatedEvent extends AbstractBaseEntityEvent<DistributionSet> {
private static final long serialVersionUID = 1L;
/**
* @param distributionSet
* the distributionSet which has been created
*/
public DistributionCreatedEvent(final DistributionSet distributionSet) {
super(distributionSet);
}
}

View File

@@ -1,36 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
* Defines the {@link AbstractDistributedEvent} for deletion of
* {@link DistributionSet}.
*/
public class DistributionDeletedEvent extends AbstractDistributedEvent {
private static final long serialVersionUID = -3308850381757843098L;
private final Long distributionId;
/**
* @param tenant
* the tenant for this event
* @param distributionId
* the ID of the distribution set which has been deleted
*/
public DistributionDeletedEvent(final String tenant, final Long distributionId) {
super(-1, tenant);
this.distributionId = distributionId;
}
public Long getDistributionSetId() {
return distributionId;
}
}

View File

@@ -1,50 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
/**
* A event for assignment target tag.
*/
public class DistributionSetTagAssigmentResultEvent implements Event {
private final DistributionSetTagAssignmentResult assigmentResult;
private final String tenant;
/**
* Constructor.
*
* @param assigmentResult
* the assignment result
* @param tenant
* current
*/
public DistributionSetTagAssigmentResultEvent(final DistributionSetTagAssignmentResult assigmentResult,
final String tenant) {
this.assigmentResult = assigmentResult;
this.tenant = tenant;
}
public DistributionSetTagAssignmentResult getAssigmentResult() {
return assigmentResult;
}
@Override
public long getRevision() {
return -1;
}
@Override
public String getTenant() {
return tenant;
}
}

View File

@@ -1,31 +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.eventbus.event;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
/**
* Defines the {@link AbstractBaseEntityEvent} of update a
* {@link DistributionSetTag}.
*
*/
public class DistributionSetTagDeletedEvent extends AbstractBaseEntityEvent<DistributionSetTag> {
private static final long serialVersionUID = 1L;
/**
* Constructor.
*
* @param tag
* the tag which is deleted
*/
public DistributionSetTagDeletedEvent(final DistributionSetTag tag) {
super(tag);
}
}

View File

@@ -1,29 +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.eventbus.event;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
* Defines the {@link AbstractBaseEntityEvent} for update a {@link DistributionSet}.
*
*/
public class DistributionSetUpdateEvent extends AbstractBaseEntityEvent<DistributionSet> {
private static final long serialVersionUID = 1L;
/**
* Constructor
* @param ds Distribution Set
*/
public DistributionSetUpdateEvent(final DistributionSet ds) {
super(ds);
}
}

View File

@@ -1,67 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent;
/**
* Event that contains an updated download progress for a given ActionStatus
* that was written for a download request.
*
*/
public class DownloadProgressEvent extends AbstractDistributedEvent {
private static final long serialVersionUID = 1L;
private final Long statusId;
private final long requestedBytes;
private final long shippedBytesSinceLast;
private final long shippedBytesOverall;
/**
* Constructor.
*
* @param tenant
* the tenant for this event
* @param statusId
* of ActionStatus that was written for the download request
* @param requestedBytes
* bytes requested
* @param shippedBytesSinceLast
* bytes since last event
* @param shippedBytesOverall
* on the download request
*/
public DownloadProgressEvent(final String tenant, final Long statusId, final Long requestedBytes,
final Long shippedBytesSinceLast, final Long shippedBytesOverall) {
// the revision of the DownloadProgressEvent is just equal the
// shippedBytesOverall as this is a growing number.
super(shippedBytesOverall, tenant);
this.statusId = statusId;
this.requestedBytes = requestedBytes;
this.shippedBytesSinceLast = shippedBytesSinceLast;
this.shippedBytesOverall = shippedBytesOverall;
}
public Long getStatusId() {
return statusId;
}
public long getRequestedBytes() {
return requestedBytes;
}
public long getShippedBytesSinceLast() {
return shippedBytesSinceLast;
}
public long getShippedBytesOverall() {
return shippedBytesOverall;
}
}

View File

@@ -1,40 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.DefaultEvent;
/**
* Event declaration for the UI to notify the UI that a rollout has been
* changed.
*
* @author Michael Hirsch
*
*/
public class RolloutChangeEvent extends DefaultEvent {
private final Long rolloutId;
/**
* @param revision
* the revision of the event
* @param tenant
* the tenant of the event
* @param rolloutId
* the ID of the rollout which has been changed
*/
public RolloutChangeEvent(final long revision, final String tenant, final Long rolloutId) {
super(revision, tenant);
this.rolloutId = rolloutId;
}
public Long getRolloutId() {
return rolloutId;
}
}

View File

@@ -1,49 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.DefaultEvent;
/**
* Event declaration for the UI to notify the UI that a rollout has been
* changed.
*
* @author Michael Hirsch
*
*/
public class RolloutGroupChangeEvent extends DefaultEvent {
private final Long rolloutId;
private final Long rolloutGroupId;
/**
* @param revision
* the revision of the event
* @param tenant
* the tenant of the event
* @param rolloutId
* the ID of the rollout which has been changed
* @param rolloutGroupId
* the ID of the rollout group which has been changed
*/
public RolloutGroupChangeEvent(final long revision, final String tenant, final Long rolloutId,
final Long rolloutGroupId) {
super(revision, tenant);
this.rolloutId = rolloutId;
this.rolloutGroupId = rolloutGroupId;
}
public Long getRolloutId() {
return rolloutId;
}
public Long getRolloutGroupId() {
return rolloutGroupId;
}
}

View File

@@ -1,69 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent;
/**
* Event definition which is been published in case a rollout group has been
* created for a specific rollout.
*
* @author Michael Hirsch
*
*/
public class RolloutGroupCreatedEvent extends AbstractDistributedEvent {
private static final long serialVersionUID = 1L;
private final Long rolloutId;
private final Long rolloutGroupId;
private final int totalRolloutGroup;
private final int createdRolloutGroup;
/**
* Creating a new rollout group created event for a specific rollout.
*
* @param tenant
* the tenant of this event
* @param revision
* the revision of the event
* @param rolloutId
* the ID of the rollout the group has been created
* @param rolloutGroupId
* identifier of this group
* @param totalRolloutGroup
* the total number of rollout groups for this rollout
* @param createdRolloutGroup
* the number of already created groups of the rollout
*/
public RolloutGroupCreatedEvent(final String tenant, final long revision, final Long rolloutId,
final Long rolloutGroupId, final int totalRolloutGroup, final int createdRolloutGroup) {
super(revision, tenant);
this.rolloutId = rolloutId;
this.rolloutGroupId = rolloutGroupId;
this.totalRolloutGroup = totalRolloutGroup;
this.createdRolloutGroup = createdRolloutGroup;
}
public Long getRolloutId() {
return rolloutId;
}
public int getTotalRolloutGroup() {
return totalRolloutGroup;
}
public int getCreatedRolloutGroup() {
return createdRolloutGroup;
}
public Long getRolloutGroupId() {
return rolloutGroupId;
}
}

View File

@@ -1,32 +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.eventbus.event;
import java.util.Map;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
/**
* Defines the {@link AbstractPropertyChangeEvent} of {@link RolloutGroup}.
*/
public class RolloutGroupPropertyChangeEvent extends AbstractPropertyChangeEvent<RolloutGroup> {
private static final long serialVersionUID = 4026477044419472686L;
/**
*
* @param rolloutGroup
* @param changeSetValues
*/
public RolloutGroupPropertyChangeEvent(final RolloutGroup rolloutGroup,
final Map<String, PropertyChange> changeSetValues) {
super(rolloutGroup, changeSetValues);
}
}

View File

@@ -1,30 +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.eventbus.event;
import java.util.Map;
import org.eclipse.hawkbit.repository.model.Rollout;
/**
* Defines the {@link AbstractPropertyChangeEvent} of {@link Rollout}.
*/
public class RolloutPropertyChangeEvent extends AbstractPropertyChangeEvent<Rollout> {
private static final long serialVersionUID = 1056221355466373514L;
/**
*
* @param rollout
* @param changeSetValues
*/
public RolloutPropertyChangeEvent(final Rollout rollout, final Map<String, PropertyChange> changeSetValues) {
super(rollout, changeSetValues);
}
}

View File

@@ -1,70 +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.eventbus.event;
import java.util.Collection;
import org.eclipse.hawkbit.eventbus.event.DefaultEvent;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Event that gets sent when a distribution set gets assigned to a target.
*
*/
public class TargetAssignDistributionSetEvent extends DefaultEvent {
private final Collection<SoftwareModule> softwareModules;
private final Target target;
private final Long actionId;
/**
* Creates a new {@link TargetAssignDistributionSetEvent}.
*
* @param revision
* the revision of the event
* @param tenant
* the tenant of the event
* @param target
* the assigned {@link Target}
* @param actionId
* the action id of the assignment
* @param softwareModules
* the software modules which have been assigned to the target
*/
public TargetAssignDistributionSetEvent(final long revision, final String tenant, final Target target,
final Long actionId, final Collection<SoftwareModule> softwareModules) {
super(revision, tenant);
this.target = target;
this.actionId = actionId;
this.softwareModules = softwareModules;
}
/**
* @return the action id of the assignment
*/
public Long getActionId() {
return actionId;
}
/**
* @return the {@link Target} which has been assigned to the distribution
* set
*/
public Target getTarget() {
return target;
}
/**
* @return the software modules which have been assigned to the target
*/
public Collection<SoftwareModule> getSoftwareModules() {
return softwareModules;
}
}

View File

@@ -1,29 +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.eventbus.event;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Defines the {@link AbstractBaseEntityEvent} of creating a new {@link Target}.
*
*
*/
public class TargetCreatedEvent extends AbstractBaseEntityEvent<Target> {
private static final long serialVersionUID = 1L;
/**
* @param target
* the target which has been created
*/
public TargetCreatedEvent(final Target target) {
super(target);
}
}

View File

@@ -1,41 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent;
import org.eclipse.hawkbit.repository.model.Target;
/**
*
* Defines the {@link AbstractBaseEntityEvent} of deleting a {@link Target}.
*/
public class TargetDeletedEvent extends AbstractDistributedEvent {
private static final long serialVersionUID = 1L;
private final long targetId;
/**
* @param tenant
* the tenant for this event
* @param targetId
* the ID of the target which has been deleted
*/
public TargetDeletedEvent(final String tenant, final long targetId) {
super(-1, tenant);
this.targetId = targetId;
}
/**
* @return the targetId
*/
public long getTargetId() {
return targetId;
}
}

View File

@@ -1,78 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.EntityEvent;
import org.eclipse.hawkbit.repository.model.TargetInfo;
/**
* Event for update the targets info.
*/
public class TargetInfoUpdateEvent implements EntityEvent {
private final long revision;
private final TargetInfo targetInfo;
private final String tenant;
private String originNodeId;
private String nodeId;
/**
* Constructor.
*
* @param targetInfo
* the target info entity
*/
public TargetInfoUpdateEvent(final TargetInfo targetInfo) {
this.targetInfo = targetInfo;
this.tenant = targetInfo.getTarget().getTenant();
this.revision = -1;
}
@Override
public void setOriginNodeId(final String originNodeId) {
this.originNodeId = originNodeId;
}
@Override
public void setNodeId(final String nodeId) {
this.nodeId = nodeId;
}
@Override
public String getOriginNodeId() {
return this.originNodeId;
}
@Override
public String getNodeId() {
return this.nodeId;
}
@Override
public long getRevision() {
return revision;
}
@Override
public <E> E getEntity(final Class<E> entityClass) {
return entityClass.cast(targetInfo);
}
@Override
public TargetInfo getEntity() {
return targetInfo;
}
@Override
public String getTenant() {
return tenant;
}
}

View File

@@ -1,49 +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.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
/**
* A event for assignment target tag.
*/
public class TargetTagAssigmentResultEvent implements Event {
private final TargetTagAssignmentResult assigmentResult;
private final String tenant;
/**
* Constructor.
*
* @param assigmentResult
* the assignment result-
* @param tenant
* current
*/
public TargetTagAssigmentResultEvent(final TargetTagAssignmentResult assigmentResult, final String tenant) {
this.tenant = tenant;
this.assigmentResult = assigmentResult;
}
public TargetTagAssignmentResult getAssigmentResult() {
return assigmentResult;
}
@Override
public long getRevision() {
return -1;
}
@Override
public String getTenant() {
return tenant;
}
}

View File

@@ -1,31 +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.eventbus.event;
import org.eclipse.hawkbit.repository.model.TargetTag;
/**
* Defines the {@link AbstractBaseEntityEvent} for creation of a new
* {@link TargetTag}.
*
*/
public class TargetTagCreatedEvent extends AbstractBaseEntityEvent<TargetTag> {
private static final long serialVersionUID = 1L;
/**
* Constructor.
*
* @param tag
* the tag which has been created
*/
public TargetTagCreatedEvent(final TargetTag tag) {
super(tag);
}
}

View File

@@ -1,31 +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.eventbus.event;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Defines the {@link AbstractBaseEntityEvent} of updating a {@link Target}.
*
*/
public class TargetUpdatedEvent extends AbstractBaseEntityEvent<Target> {
private static final long serialVersionUID = 5665118668865832477L;
/**
* Constructor
*
* @param baseEntity
* Target entity
*/
public TargetUpdatedEvent(final Target baseEntity) {
super(baseEntity);
}
}

View File

@@ -43,12 +43,6 @@ public interface ActionStatus extends TenantAwareBaseEntity {
*/
void addMessage(String message);
/**
* @return current {@link Status#DOWNLOAD} progress if known by the update
* server.
*/
short getDownloadProgressPercent();
/**
* @return immutable list of message entries that in the
* {@link ActionStatus}.

View File

@@ -6,13 +6,12 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository;
package org.eclipse.hawkbit.repository.model;
import java.util.Collections;
import java.util.List;
import org.eclipse.hawkbit.repository.model.AssignmentResult;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.springframework.util.CollectionUtils;
/**

View File

@@ -10,16 +10,13 @@ package org.eclipse.hawkbit.repository.model;
import java.util.List;
import org.eclipse.hawkbit.eventbus.event.Event;
/**
* Result object for {@link DistributionSetTag} assignments.
*
*/
public class DistributionSetTagAssignmentResult extends AssignmentResult<DistributionSet> implements Event {
public class DistributionSetTagAssignmentResult extends AssignmentResult<DistributionSet> {
private final DistributionSetTag distributionSetTag;
private final String tenant;
/**
* Constructor.
@@ -39,24 +36,13 @@ public class DistributionSetTagAssignmentResult extends AssignmentResult<Distrib
*/
public DistributionSetTagAssignmentResult(final int alreadyAssigned, final int assigned, final int unassigned,
final List<DistributionSet> assignedDs, final List<DistributionSet> unassignedDs,
final DistributionSetTag distributionSetTag, final String tenant) {
final DistributionSetTag distributionSetTag) {
super(assigned, alreadyAssigned, unassigned, assignedDs, unassignedDs);
this.distributionSetTag = distributionSetTag;
this.tenant = tenant;
}
public DistributionSetTag getDistributionSetTag() {
return distributionSetTag;
}
@Override
public long getRevision() {
return 0;
}
@Override
public String getTenant() {
return tenant;
}
}

View File

@@ -8,14 +8,17 @@
*/
package org.eclipse.hawkbit.repository.model;
import java.io.Serializable;
/**
* represents a tenant configuration value including some meta data
*
* @param <T>
* type of the configuration value
*/
public final class TenantConfigurationValue<T> {
public final class TenantConfigurationValue<T extends Serializable> implements Serializable {
private static final long serialVersionUID = 1L;
private T value;
private Long lastModifiedAt;
private String lastModifiedBy;
@@ -87,7 +90,7 @@ public final class TenantConfigurationValue<T> {
* the key type
* @return the tenant configuration value builder
*/
public static <K> TenantConfigurationValueBuilder<K> builder() {
public static <K extends Serializable> TenantConfigurationValueBuilder<K> builder() {
return new TenantConfigurationValueBuilder<>();
}
@@ -98,7 +101,7 @@ public final class TenantConfigurationValue<T> {
* @param <T>
* type of the configuration value
*/
public static class TenantConfigurationValueBuilder<T> {
public static class TenantConfigurationValueBuilder<T extends Serializable> {
private final TenantConfigurationValue<T> configuration = new TenantConfigurationValue<>();

View File

@@ -19,8 +19,9 @@ import java.io.Serializable;
* @param <T>
* The type parameter for the report series data
*/
public class InnerOuterDataReportSeries<T extends Serializable> {
public class InnerOuterDataReportSeries<T extends Serializable> implements Serializable {
private static final long serialVersionUID = 1L;
private final DataReportSeries<T> innerSeries;
private final DataReportSeries<T> outerSeries;

View File

@@ -24,6 +24,16 @@
<artifactId>hawkbit-repository-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,108 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.event;
import org.apache.commons.lang3.ClassUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.bus.event.RemoteApplicationEvent;
import org.springframework.integration.support.MutableMessageHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.converter.AbstractMessageConverter;
import org.springframework.messaging.converter.MessageConversionException;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.util.MimeType;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtobufIOUtil;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
/**
* A customize message converter for the spring cloud events. The converter is
* registered for the application/binary+protostuff type.
*
*/
public class BusProtoStuffMessageConverter extends AbstractMessageConverter {
public static final MimeType APPLICATION_BINARY_PROTOSTUFF = new MimeType("application", "binary+protostuff");
private static final Logger LOG = LoggerFactory.getLogger(BusProtoStuffMessageConverter.class);
private static final String DEFAULT_CLASS_FIELD_NAME = "__Class__";
/**
* Constructor.
*/
public BusProtoStuffMessageConverter() {
super(APPLICATION_BINARY_PROTOSTUFF);
}
@Override
protected boolean supports(final Class<?> aClass) {
return RemoteApplicationEvent.class.isAssignableFrom(aClass);
}
@Override
public Object convertFromInternal(final Message<?> message, final Class<?> targetClass,
final Object conversionHint) {
final Object payload = message.getPayload();
try {
final Class<?> deserializeClass = ClassUtils
.getClass(message.getHeaders().get(DEFAULT_CLASS_FIELD_NAME).toString());
if (payload instanceof byte[]) {
@SuppressWarnings("unchecked")
final Schema<Object> schema = (Schema<Object>) RuntimeSchema.getSchema(deserializeClass);
final Object deserializeEvent = schema.newMessage();
ProtobufIOUtil.mergeFrom((byte[]) message.getPayload(), deserializeEvent, schema);
return deserializeEvent;
}
} catch (final ClassNotFoundException e) {
LOG.error("Protostuff cannot find derserialize class", e);
throw new MessageConversionException(message, "Failed to read payload", e);
}
return null;
}
@Override
protected Object convertToInternal(final Object payload, final MessageHeaders headers,
final Object conversionHint) {
checkIfHeaderMutable(headers);
final Class<? extends Object> serializeClass = payload.getClass();
@SuppressWarnings("unchecked")
final Schema<Object> schema = (Schema<Object>) RuntimeSchema.getSchema(serializeClass);
final LinkedBuffer buffer = LinkedBuffer.allocate();
final byte[] serializeByte;
try {
serializeByte = ProtostuffIOUtil.toByteArray(payload, schema, buffer);
} finally {
buffer.clear();
}
headers.put(DEFAULT_CLASS_FIELD_NAME, serializeClass.getName());
return serializeByte;
}
private static void checkIfHeaderMutable(final MessageHeaders headers) {
if (isAccessorMutable(headers) || headers instanceof MutableMessageHeaders) {
return;
}
LOG.error("Protostuff cannot set serializae class because message header is not mutable");
throw new MessageConversionException(
"Cannot set the serialize class to message header. Need Mutable message header");
}
private static boolean isAccessorMutable(final MessageHeaders headers) {
final MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(headers, MessageHeaderAccessor.class);
return accessor != null && accessor.isMutable();
}
}

View File

@@ -6,13 +6,13 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa;
package org.eclipse.hawkbit.repository;
import java.time.Duration;
import java.time.Instant;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;

View File

@@ -1,54 +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.helper;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.eventbus.EventBus;
/**
* A singleton bean which holds the {@link EventBus} to have to the cache
* manager in beans not instantiated by spring e.g. JPA entities or
* CacheFieldEntityListener which cannot be autowired.
*
*/
public final class EventBusHolder {
private static final EventBusHolder SINGLETON = new EventBusHolder();
@Autowired
private EventBus eventBus;
private EventBusHolder() {
}
/**
* @return the cache manager holder singleton instance
*/
public static EventBusHolder getInstance() {
return SINGLETON;
}
/**
* @return the eventBus
*/
public EventBus getEventBus() {
return eventBus;
}
/**
* @param eventBus
* the eventBus to set
*/
public void setEventBus(final EventBus eventBus) {
this.eventBus = eventBus;
}
}

View File

@@ -0,0 +1,53 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.model.helper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
/**
* A singleton bean which holds the event publisher to have to the cache manager
* in beans not instantiated by spring e.g. JPA entities or
* CacheFieldEntityListener which cannot be autowired.
*
*/
public final class EventPublisherHolder {
private static final EventPublisherHolder SINGLETON = new EventPublisherHolder();
@Autowired
private ApplicationEventPublisher eventPublisher;
@Autowired
private ApplicationContext applicationContext;
private EventPublisherHolder() {
}
/**
* @return the cache manager holder singleton instance
*/
public static EventPublisherHolder getInstance() {
return SINGLETON;
}
/**
* @return the eventPublisher
*/
public ApplicationEventPublisher getEventPublisher() {
return eventPublisher;
}
public String getApplicationId() {
return applicationContext.getId();
}
}

View File

@@ -6,7 +6,7 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.model.helper;
package org.eclipse.hawkbit.repository.model.helper;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -6,7 +6,7 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.model.helper;
package org.eclipse.hawkbit.repository.model.helper;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -6,19 +6,14 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.rsql;
package org.eclipse.hawkbit.repository.rsql;
import java.time.Duration;
import java.time.Instant;
import org.apache.commons.lang3.text.StrLookup;
import org.apache.commons.lang3.text.StrSubstitutor;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.jpa.TimestampCalculator;
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.repository.TimestampCalculator;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
/**
* Adds macro capabilities to RSQL expressions that are used to filter for

View File

@@ -56,14 +56,6 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
@@ -101,16 +93,6 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
@@ -188,17 +170,7 @@
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -10,6 +10,8 @@ package org.eclipse.hawkbit;
import java.util.Map;
import javax.persistence.EntityManager;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.DeploymentManagement;
@@ -26,6 +28,8 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.TenantStatsManagement;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManager;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManagerHolder;
import org.eclipse.hawkbit.repository.jpa.JpaArtifactManagement;
import org.eclipse.hawkbit.repository.jpa.JpaControllerManagement;
import org.eclipse.hawkbit.repository.jpa.JpaDeploymentManagement;
@@ -45,20 +49,19 @@ import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler;
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignChecker;
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignScheduler;
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
import org.eclipse.hawkbit.repository.jpa.event.JpaEventEntityManager;
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
import org.eclipse.hawkbit.repository.jpa.model.helper.CacheManagerHolder;
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder;
import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder;
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemManagementHolder;
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder;
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlParserValidationOracle;
import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder;
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.repository.rsql.RsqlValidationOracle;
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -77,7 +80,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import com.google.common.collect.Maps;
import com.google.common.eventbus.EventBus;
/**
* General configuration for hawkBit's Repository.
@@ -93,8 +95,6 @@ import com.google.common.eventbus.EventBus;
@EnableScheduling
@EntityScan("org.eclipse.hawkbit.repository.jpa.model")
public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
@Autowired
private EventBus eventBus;
@Bean
@ConditionalOnMissingBean
@@ -163,14 +163,6 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
return EntityInterceptorHolder.getInstance();
}
/**
* @return the singleton instance of the {@link CacheManagerHolder}
*/
@Bean
public CacheManagerHolder cacheManagerHolder() {
return CacheManagerHolder.getInstance();
}
/**
*
* @return the singleton instance of the
@@ -273,9 +265,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
@Bean
@ConditionalOnMissingBean
public TenantStatsManagement tenantStatsManagement() {
final TenantStatsManagement mgmt = new JpaTenantStatsManagement();
eventBus.register(mgmt);
return mgmt;
return new JpaTenantStatsManagement();
}
/**
@@ -400,6 +390,32 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
return new JpaEntityFactory();
}
/**
* {@link EventEntityManagerHolder} bean.
*
* @return a new {@link EventEntityManagerHolder}
*/
@Bean
@ConditionalOnMissingBean
public EventEntityManagerHolder eventEntityManagerHolder() {
return EventEntityManagerHolder.getInstance();
}
/**
* {@link EventEntityManager} bean.
*
* @param aware
* the tenant aware
* @param entityManager
* the entitymanager
* @return a new {@link EventEntityManager}
*/
@Bean
@ConditionalOnMissingBean
public EventEntityManager eventEntityManager(final TenantAware aware, final EntityManager entityManager) {
return new JpaEventEntityManager(aware, entityManager);
}
/**
* {@link AutoAssignChecker} bean.
*
@@ -415,9 +431,9 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
*/
@Bean
@ConditionalOnMissingBean
public AutoAssignChecker autoAssignChecker(TargetFilterQueryManagement targetFilterQueryManagement,
TargetManagement targetManagement, DeploymentManagement deploymentManagement,
PlatformTransactionManager transactionManager) {
public AutoAssignChecker autoAssignChecker(final TargetFilterQueryManagement targetFilterQueryManagement,
final TargetManagement targetManagement, final DeploymentManagement deploymentManagement,
final PlatformTransactionManager transactionManager) {
return new AutoAssignChecker(targetFilterQueryManagement, targetManagement, deploymentManagement,
transactionManager);
}
@@ -437,8 +453,10 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
*/
@Bean
@ConditionalOnMissingBean
public AutoAssignScheduler autoAssignScheduler(TenantAware tenantAware, SystemManagement systemManagement,
SystemSecurityContext systemSecurityContext, AutoAssignChecker autoAssignChecker) {
public AutoAssignScheduler autoAssignScheduler(final TenantAware tenantAware,
final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext,
final AutoAssignChecker autoAssignChecker) {
return new AutoAssignScheduler(tenantAware, systemManagement, systemSecurityContext, autoAssignChecker);
}
}

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.repository.jpa;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -24,10 +23,10 @@ import org.eclipse.hawkbit.repository.RepositoryConstants;
import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
import org.eclipse.hawkbit.repository.exception.TooManyStatusEntriesException;
import org.eclipse.hawkbit.repository.jpa.cache.CacheWriteNotify;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus_;
@@ -41,7 +40,6 @@ import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
@@ -49,10 +47,13 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
@@ -86,9 +87,6 @@ public class JpaControllerManagement implements ControllerManagement {
@Autowired
private TargetInfoRepository targetInfoRepository;
@Autowired
private SoftwareModuleRepository softwareModuleRepository;
@Autowired
private ActionStatusRepository actionStatusRepository;
@@ -105,11 +103,17 @@ public class JpaControllerManagement implements ControllerManagement {
private TenantConfigurationManagement tenantConfigurationManagement;
@Autowired
private CacheWriteNotify cacheWriteNotify;
private TenantAware tenantAware;
@Autowired
private SystemSecurityContext systemSecurityContext;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Autowired
private ApplicationContext applicationContext;
@Override
public String getPollingTime() {
final TenantConfigurationKey configurationKey = TenantConfigurationKey.POLLING_TIME_INTERVAL;
@@ -178,12 +182,6 @@ public class JpaControllerManagement implements ControllerManagement {
return actionRepository.findFirstByTargetAndActive(new Sort(Direction.ASC, "id"), (JpaTarget) target, true);
}
@Override
public List<SoftwareModule> findSoftwareModulesByDistributionSet(final DistributionSet distributionSet) {
return Collections
.unmodifiableList(softwareModuleRepository.findByAssignedTo((JpaDistributionSet) distributionSet));
}
@Override
public Action findActionWithDetails(final Long actionId) {
return actionRepository.findById(actionId);
@@ -480,7 +478,8 @@ public class JpaControllerManagement implements ControllerManagement {
@Override
public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast,
final Long shippedBytesOverall) {
cacheWriteNotify.downloadProgress(statusId, requestedBytes, shippedBytesSinceLast, shippedBytesOverall);
eventPublisher.publishEvent(new DownloadProgressEvent(tenantAware.getCurrentTenant(), shippedBytesSinceLast,
applicationContext.getId()));
}
@Override

View File

@@ -30,12 +30,10 @@ import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.ActionFields;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.RepositoryConstants;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
@@ -51,11 +49,9 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
@@ -63,20 +59,22 @@ import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.ActionWithStatusCount;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
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.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
@@ -90,7 +88,6 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
/**
* JPA implementation for {@link DeploymentManagement}.
@@ -110,9 +107,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Autowired
private DistributionSetRepository distributoinSetRepository;
@Autowired
private SoftwareModuleRepository softwareModuleRepository;
@Autowired
private TargetRepository targetRepository;
@@ -129,14 +123,14 @@ public class JpaDeploymentManagement implements DeploymentManagement {
private AuditorAware<String> auditorProvider;
@Autowired
private EventBus eventBus;
private ApplicationEventPublisher eventPublisher;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private AfterTransactionCommitExecutor afterCommit;
@Autowired
private SystemSecurityContext systemSecurityContext;
@Autowired
private VirtualPropertyReplacer virtualPropertyReplacer;
@@ -316,21 +310,18 @@ public class JpaDeploymentManagement implements DeploymentManagement {
LOG.debug("assignDistribution({}) finished {}", set, result);
final List<JpaSoftwareModule> softwareModules = softwareModuleRepository.findByAssignedTo(set);
// detaching as it is not necessary to persist the set itself
entityManager.detach(set);
sendDistributionSetAssignmentEvent(targets, targetIdsCancellList, targetIdsToActions, softwareModules);
sendDistributionSetAssignmentEvent(targets, targetIdsCancellList, targetIdsToActions);
return result;
}
private void sendDistributionSetAssignmentEvent(final List<JpaTarget> targets, final Set<Long> targetIdsCancellList,
final Map<String, JpaAction> targetIdsToActions, final List<JpaSoftwareModule> softwareModules) {
final Map<String, JpaAction> targetIdsToActions) {
targets.stream().filter(t -> !!!targetIdsCancellList.contains(t.getId()))
.forEach(t -> assignDistributionSetEvent(t, targetIdsToActions.get(t.getControllerId()).getId(),
softwareModules));
.forEach(t -> assignDistributionSetEvent(targetIdsToActions.get(t.getControllerId())));
}
private static JpaAction createTargetAction(final Map<String, TargetWithActionType> targetsWithActionMap,
@@ -349,17 +340,11 @@ public class JpaDeploymentManagement implements DeploymentManagement {
return actionForTarget;
}
private void assignDistributionSetEvent(final JpaTarget target, final Long actionId,
final List<JpaSoftwareModule> modules) {
((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING);
private void assignDistributionSetEvent(final Action action) {
((JpaTargetInfo) action.getTarget().getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING);
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<SoftwareModule> softwareModules = (Collection) modules;
afterCommit.afterCommit(() -> {
eventBus.post(new TargetInfoUpdateEvent(target.getTargetInfo()));
eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(), target,
actionId, softwareModules));
});
afterCommit.afterCommit(() -> eventPublisher
.publishEvent(new TargetAssignDistributionSetEvent(action, applicationContext.getId())));
}
/**
@@ -431,7 +416,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
/**
* Sends the {@link CancelTargetAssignmentEvent} for a specific target to
* the {@link EventBus}.
* the eventPublisher.
*
* @param target
* the Target which has been assigned to a distribution set
@@ -439,7 +424,8 @@ public class JpaDeploymentManagement implements DeploymentManagement {
* the action id of the assignment
*/
private void cancelAssignDistributionSetEvent(final Target target, final Long actionId) {
afterCommit.afterCommit(() -> eventBus.post(new CancelTargetAssignmentEvent(target, actionId)));
afterCommit.afterCommit(() -> eventPublisher
.publishEvent(new CancelTargetAssignmentEvent(target, actionId, applicationContext.getId())));
}
@Override
@@ -534,11 +520,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
// in case we canceled an action before for this target, then don't fire
// assignment event
if (!overrideObsoleteUpdateActions.contains(savedAction.getId())) {
final List<JpaSoftwareModule> softwareModules = softwareModuleRepository
.findByAssignedTo((JpaDistributionSet) savedAction.getDistributionSet());
// send distribution set assignment event
assignDistributionSetEvent((JpaTarget) savedAction.getTarget(), savedAction.getId(), softwareModules);
assignDistributionSetEvent(savedAction);
}
return savedAction;
}

View File

@@ -27,8 +27,7 @@ import org.eclipse.hawkbit.repository.DistributionSetMetadataFields;
import org.eclipse.hawkbit.repository.DistributionSetTypeFields;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityLockedException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
@@ -57,6 +56,8 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
@@ -68,7 +69,6 @@ import org.springframework.validation.annotation.Validated;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
/**
* JPA implementation of {@link DistributionSetManagement}.
@@ -103,7 +103,10 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
private ActionRepository actionRepository;
@Autowired
private EventBus eventBus;
private ApplicationEventPublisher eventPublisher;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private AfterTransactionCommitExecutor afterCommit;
@@ -146,18 +149,13 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
}
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), 0,
toBeChangedDSs.size(), Collections.emptyList(),
Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)), myTag,
tenantAware.getCurrentTenant());
Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)), myTag);
} else {
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), toBeChangedDSs.size(),
0, Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)),
Collections.emptyList(), myTag, tenantAware.getCurrentTenant());
Collections.emptyList(), myTag);
}
final DistributionSetTagAssignmentResult resultAssignment = result;
afterCommit.afterCommit(() -> eventBus
.post(new DistributionSetTagAssigmentResultEvent(resultAssignment, tenantAware.getCurrentTenant())));
// no reason to persist the tag
entityManager.detach(myTag);
return result;
@@ -187,7 +185,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
// soft delete assigned
if (!assigned.isEmpty()) {
Long[] dsIds = assigned.toArray(new Long[assigned.size()]);
final Long[] dsIds = assigned.toArray(new Long[assigned.size()]);
distributionSetRepository.deleteDistributionSet(dsIds);
targetFilterQueryRepository.unsetAutoAssignDistributionSet(dsIds);
}
@@ -203,8 +201,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
distributionSetRepository.deleteByIdIn(toHardDelete);
}
Arrays.stream(distributionSetIDs)
.forEach(dsId -> eventBus.post(new DistributionDeletedEvent(tenantAware.getCurrentTenant(), dsId)));
Arrays.stream(distributionSetIDs).forEach(dsId -> eventPublisher.publishEvent(
new DistributionSetDeletedEvent(tenantAware.getCurrentTenant(), dsId, applicationContext.getId())));
}
@Override
@@ -710,16 +708,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
allDs.forEach(ds -> ds.addTag(tag));
final List<DistributionSet> save = Collections.unmodifiableList(distributionSetRepository.save(allDs));
afterCommit.afterCommit(() -> {
final DistributionSetTagAssignmentResult result = new DistributionSetTagAssignmentResult(0, save.size(), 0,
save, Collections.emptyList(), tag, tenantAware.getCurrentTenant());
eventBus.post(new DistributionSetTagAssigmentResultEvent(result, tenantAware.getCurrentTenant()));
});
return save;
return Collections.unmodifiableList(distributionSetRepository.save(allDs));
}
@Override

View File

@@ -44,7 +44,6 @@ import org.eclipse.hawkbit.repository.report.model.SeriesTime;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -81,7 +80,6 @@ public class JpaReportManagement implements ReportManagement {
private TenantAware tenantAware;
@Override
@Cacheable("targetStatus")
public DataReportSeries<TargetUpdateStatus> targetStatus() {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
@@ -106,7 +104,44 @@ public class JpaReportManagement implements ReportManagement {
}
@Override
@Cacheable("distributionUsageAssigned")
public DataReportSeries<SeriesTime> targetsLastPoll() {
final LocalDateTime now = LocalDateTime.now();
final LocalDateTime beforeHour = now.minusHours(1);
final LocalDateTime beforeDay = now.minusDays(1);
final LocalDateTime beforeWeek = now.minusWeeks(1);
final LocalDateTime beforeMonth = now.minusMonths(1);
final LocalDateTime beforeYear = now.minusYears(1);
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final List<DataReportSeriesItem<SeriesTime>> resultList = new ArrayList<>();
// hours
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.HOUR,
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, beforeHour, now)).getSingleResult()));
// days
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.DAY, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeDay, beforeHour)).getSingleResult()));
// weeks
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.WEEK, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeWeek, beforeDay)).getSingleResult()));
// months
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.MONTH, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeMonth, beforeWeek)).getSingleResult()));
// years
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.YEAR, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeYear, beforeMonth)).getSingleResult()));
// years
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.MORE_THAN_YEAR,
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, null, beforeYear)).getSingleResult()));
// never
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.NEVER,
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, null, null)).getSingleResult()));
return new DataReportSeries<>("TargetLastPoll", resultList);
}
@Override
public List<InnerOuterDataReportSeries<String>> distributionUsageAssigned(final int topXEntries) {
// top X entries distribution usage
@@ -132,7 +167,6 @@ public class JpaReportManagement implements ReportManagement {
}
@Override
@Cacheable("distributionUsageInstalled")
public List<InnerOuterDataReportSeries<String>> distributionUsageInstalled(final int topXEntries) {
// top X entries distribution usage
final CriteriaBuilder cbTopX = entityManager.getCriteriaBuilder();
@@ -157,7 +191,6 @@ public class JpaReportManagement implements ReportManagement {
}
@Override
@Cacheable("targetsCreatedOverPeriod")
public <T extends Serializable> DataReportSeries<T> targetsCreatedOverPeriod(final DateType<T> dateType,
final LocalDateTime from, final LocalDateTime to) {
final Query createNativeQuery = entityManager
@@ -208,7 +241,6 @@ public class JpaReportManagement implements ReportManagement {
}
@Override
@Cacheable("feedbackReceivedOverTime")
public <T extends Serializable> DataReportSeries<T> feedbackReceivedOverTime(final DateType<T> dateType,
final LocalDateTime from, final LocalDateTime to) {
final Query createNativeQuery = entityManager
@@ -223,47 +255,8 @@ public class JpaReportManagement implements ReportManagement {
return new DataReportSeries<>("FeedbackRecieved", reportItems);
}
@Override
@Cacheable("targetsLastPoll")
public DataReportSeries<SeriesTime> targetsLastPoll() {
final LocalDateTime now = LocalDateTime.now();
final LocalDateTime beforeHour = now.minusHours(1);
final LocalDateTime beforeDay = now.minusDays(1);
final LocalDateTime beforeWeek = now.minusWeeks(1);
final LocalDateTime beforeMonth = now.minusMonths(1);
final LocalDateTime beforeYear = now.minusYears(1);
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final List<DataReportSeriesItem<SeriesTime>> resultList = new ArrayList<>();
// hours
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.HOUR,
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, beforeHour, now)).getSingleResult()));
// days
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.DAY, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeDay, beforeHour)).getSingleResult()));
// weeks
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.WEEK, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeWeek, beforeDay)).getSingleResult()));
// months
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.MONTH, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeMonth, beforeWeek)).getSingleResult()));
// years
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.YEAR, entityManager
.createQuery(createCountSelectTargetsLastPoll(cb, beforeYear, beforeMonth)).getSingleResult()));
// years
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.MORE_THAN_YEAR,
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, null, beforeYear)).getSingleResult()));
// never
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.NEVER,
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, null, null)).getSingleResult()));
return new DataReportSeries<>("TargetLastPoll", resultList);
}
private CriteriaQuery<Long> createCountSelectTargetsLastPoll(final CriteriaBuilder cb, final LocalDateTime from,
final LocalDateTime to) {
private static CriteriaQuery<Long> createCountSelectTargetsLastPoll(final CriteriaBuilder cb,
final LocalDateTime from, final LocalDateTime to) {
Long start = null;
Long end = null;
@@ -289,8 +282,8 @@ public class JpaReportManagement implements ReportManagement {
return countSelect;
}
private List<InnerOuterDataReportSeries<String>> mapDistirbutionUsageResultToDataReport(final int topXEntries,
final List<Object[]> resultListTop) {
private static List<InnerOuterDataReportSeries<String>> mapDistirbutionUsageResultToDataReport(
final int topXEntries, final List<Object[]> resultListTop) {
final List<InnerOuterDataReportSeries<String>> innerOuterReport = new ArrayList<>();
final Map<DSName, InnerOuter> map = new LinkedHashMap<>();

View File

@@ -24,8 +24,8 @@ import org.eclipse.hawkbit.repository.RolloutFields;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupCreatedEvent;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.jpa.cache.CacheWriteNotify;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
@@ -54,6 +54,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
@@ -110,15 +111,15 @@ public class JpaRolloutManagement implements RolloutManagement {
@Autowired
private ApplicationContext context;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Autowired
private NoCountPagingRepository criteriaNoCountDao;
@Autowired
private PlatformTransactionManager txManager;
@Autowired
private CacheWriteNotify cacheWriteNotify;
@Autowired
private VirtualPropertyReplacer virtualPropertyReplacer;
@@ -249,13 +250,6 @@ public class JpaRolloutManagement implements RolloutManagement {
int groupIndex = 0;
final Long totalCount = savedRollout.getTotalTargets();
final int groupSize = (int) Math.ceil((double) totalCount / (double) amountOfGroups);
// validate if the amount of groups that will be created are the amount
// of groups that the client what's to have created.
int amountGroupValidated = amountOfGroups;
final int amountGroupCreation = (int) (Math.ceil((double) totalCount / (double) groupSize));
if (amountGroupCreation == (amountOfGroups - 1)) {
amountGroupValidated--;
}
RolloutGroup lastSavedGroup = null;
while (pageIndex < totalCount) {
groupIndex++;
@@ -282,11 +276,11 @@ public class JpaRolloutManagement implements RolloutManagement {
targetGroup
.forEach(target -> rolloutTargetGroupRepository.save(new RolloutTargetGroup(savedGroup, target)));
cacheWriteNotify.rolloutGroupCreated(groupIndex, savedRollout.getId(), savedGroup.getId(),
amountGroupValidated, groupIndex);
eventPublisher.publishEvent(new RolloutGroupCreatedEvent(group, context.getId()));
pageIndex += groupSize;
}
savedRollout.setRolloutGroupsCreated(groupIndex);
savedRollout.setStatus(RolloutStatus.READY);
return rolloutRepository.save(savedRollout);
}

View File

@@ -598,12 +598,10 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
public List<SoftwareModuleMetadata> findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) {
return Collections
.unmodifiableList(softwareModuleMetadataRepository
.findAll((Specification<JpaSoftwareModuleMetadata>) (root, query,
cb) -> cb.and(cb.equal(
root.get(JpaSoftwareModuleMetadata_.softwareModule).get(JpaSoftwareModule_.id),
softwareModuleId))));
return Collections.unmodifiableList(softwareModuleMetadataRepository
.findAll((Specification<JpaSoftwareModuleMetadata>) (root, query, cb) -> cb
.and(cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule).get(JpaSoftwareModule_.id),
softwareModuleId))));
}
@Override

View File

@@ -17,12 +17,12 @@ import java.util.List;
import org.eclipse.hawkbit.repository.TagFields;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdateEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
@@ -33,8 +33,11 @@ import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
@@ -44,8 +47,6 @@ import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import com.google.common.eventbus.EventBus;
/**
* JP>A implementation of {@link TagManagement}.
*
@@ -67,14 +68,17 @@ public class JpaTagManagement implements TagManagement {
private DistributionSetRepository distributionSetRepository;
@Autowired
private EventBus eventBus;
private ApplicationEventPublisher eventPublisher;
@Autowired
private TenantAware tenantAware;
private ApplicationContext applicationContext;
@Autowired
private AfterTransactionCommitExecutor afterCommit;
@Autowired
private TenantAware tenantAware;
@Autowired
private VirtualPropertyReplacer virtualPropertyReplacer;
@@ -96,7 +100,8 @@ public class JpaTagManagement implements TagManagement {
final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag);
afterCommit.afterCommit(() -> eventBus.post(new TargetTagCreatedEvent(save)));
afterCommit.afterCommit(
() -> eventPublisher.publishEvent(new TargetTagCreatedEvent(save, applicationContext.getId())));
return save;
}
@@ -115,7 +120,8 @@ public class JpaTagManagement implements TagManagement {
});
final List<TargetTag> save = Collections.unmodifiableList(targetTagRepository.save(targetTags));
afterCommit.afterCommit(() -> save.forEach(tag -> eventBus.post(new TargetTagCreatedEvent(tag))));
afterCommit.afterCommit(() -> save.forEach(
tag -> eventPublisher.publishEvent(new TargetTagCreatedEvent(tag, applicationContext.getId()))));
return save;
}
@@ -137,7 +143,8 @@ public class JpaTagManagement implements TagManagement {
// finally delete the tag itself
targetTagRepository.deleteByName(targetTagName);
afterCommit.afterCommit(() -> eventBus.post(new TargetTagDeletedEvent(tag)));
afterCommit.afterCommit(() -> eventPublisher.publishEvent(
new TargetTagDeletedEvent(tenantAware.getCurrentTenant(), tag.getId(), applicationContext.getId())));
}
@@ -174,7 +181,8 @@ public class JpaTagManagement implements TagManagement {
checkNotNull(targetTag.getName());
checkNotNull(targetTag.getId());
final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag);
afterCommit.afterCommit(() -> eventBus.post(new TargetTagUpdateEvent(save)));
afterCommit.afterCommit(() -> eventPublisher
.publishEvent(new TargetTagUpdateEvent(save, EventPublisherHolder.getInstance().getApplicationId())));
return save;
}
@@ -197,7 +205,8 @@ public class JpaTagManagement implements TagManagement {
final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag);
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagCreatedEvent(save)));
afterCommit.afterCommit(() -> eventPublisher
.publishEvent(new DistributionSetTagCreatedEvent(save, applicationContext.getId())));
return save;
}
@@ -216,8 +225,8 @@ public class JpaTagManagement implements TagManagement {
}
final List<DistributionSetTag> save = Collections
.unmodifiableList(distributionSetTagRepository.save(distributionSetTags));
afterCommit.afterCommit(() -> save.forEach(tag -> eventBus.post(new DistributionSetTagCreatedEvent(tag))));
afterCommit.afterCommit(() -> save.forEach(tag -> eventPublisher
.publishEvent(new DistributionSetTagCreatedEvent(tag, applicationContext.getId()))));
return save;
}
@@ -238,7 +247,9 @@ public class JpaTagManagement implements TagManagement {
distributionSetTagRepository.deleteByName(tagName);
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagDeletedEvent(tag)));
afterCommit.afterCommit(
() -> eventPublisher.publishEvent(new DistributionSetTagDeletedEvent(tenantAware.getCurrentTenant(),
tag.getId(), applicationContext.getId())));
}
@Override
@@ -248,7 +259,8 @@ public class JpaTagManagement implements TagManagement {
checkNotNull(distributionSetTag.getName());
checkNotNull(distributionSetTag.getId());
final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag);
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagUpdateEvent(save)));
afterCommit.afterCommit(() -> eventPublisher.publishEvent(
new DistributionSetTagUpdateEvent(save, EventPublisherHolder.getInstance().getApplicationId())));
return save;
}

View File

@@ -16,7 +16,6 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.PreDestroy;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
@@ -32,8 +31,8 @@ import org.apache.commons.lang3.StringUtils;
import org.eclipse.hawkbit.repository.FilterParams;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagAssigmentResultEvent;
import org.eclipse.hawkbit.repository.TimestampCalculator;
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
@@ -56,6 +55,8 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
@@ -71,7 +72,6 @@ import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
/**
* JPA implementation of {@link TargetManagement}.
@@ -97,7 +97,10 @@ public class JpaTargetManagement implements TargetManagement {
private NoCountPagingRepository criteriaNoCountDao;
@Autowired
private EventBus eventBus;
private ApplicationEventPublisher eventPublisher;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private TenantAware tenantAware;
@@ -218,7 +221,8 @@ public class JpaTargetManagement implements TargetManagement {
public void deleteTargets(final Collection<Long> targetIDs) {
targetRepository.deleteByIdIn(targetIDs);
targetIDs.forEach(targetId -> eventBus.post(new TargetDeletedEvent(tenantAware.getCurrentTenant(), targetId)));
targetIDs.forEach(targetId -> eventPublisher.publishEvent(
new TargetDeletedEvent(tenantAware.getCurrentTenant(), targetId, applicationContext.getId())));
}
@Override
@@ -368,8 +372,6 @@ public class JpaTargetManagement implements TargetManagement {
final TargetTagAssignmentResult result = new TargetTagAssignmentResult(0, 0, alreadyAssignedTargets.size(),
Collections.emptyList(), alreadyAssignedTargets, tag);
afterCommit.afterCommit(
() -> eventBus.post(new TargetTagAssigmentResultEvent(result, tenantAware.getCurrentTenant())));
return result;
}
@@ -380,9 +382,6 @@ public class JpaTargetManagement implements TargetManagement {
allTargets.size(), 0, Collections.unmodifiableList(targetRepository.save(allTargets)),
Collections.emptyList(), tag);
afterCommit.afterCommit(
() -> eventBus.post(new TargetTagAssigmentResultEvent(result, tenantAware.getCurrentTenant())));
// no reason to persist the tag
entityManager.detach(tag);
return result;
@@ -396,15 +395,7 @@ public class JpaTargetManagement implements TargetManagement {
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(controllerIds));
allTargets.forEach(target -> target.addTag(tag));
final List<Target> save = Collections.unmodifiableList(targetRepository.save(allTargets));
afterCommit.afterCommit(() -> {
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, save.size(), 0, save,
Collections.emptyList(), tag);
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult, tenantAware.getCurrentTenant()));
});
return save;
return Collections.unmodifiableList(targetRepository.save(allTargets));
}
private List<Target> unAssignTag(final Collection<Target> targets, final TargetTag tag) {
@@ -413,13 +404,7 @@ public class JpaTargetManagement implements TargetManagement {
toUnassign.forEach(target -> target.removeTag(tag));
final List<Target> save = Collections.unmodifiableList(targetRepository.save(toUnassign));
afterCommit.afterCommit(() -> {
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, 0, save.size(),
Collections.emptyList(), save, tag);
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult, tenantAware.getCurrentTenant()));
});
return save;
return Collections.unmodifiableList(targetRepository.save(toUnassign));
}
@Override
@@ -612,11 +597,6 @@ public class JpaTargetManagement implements TargetManagement {
return countByCriteriaAPI(specList);
}
@PreDestroy
void destroy() {
eventBus.unregister(this);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)

View File

@@ -8,6 +8,8 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.io.Serializable;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
@@ -46,8 +48,8 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
@Override
@Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()")
public <T> TenantConfigurationValue<T> getConfigurationValue(final TenantConfigurationKey configurationKey,
final Class<T> propertyType) {
public <T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(
final TenantConfigurationKey configurationKey, final Class<T> propertyType) {
validateTenantConfigurationDataType(configurationKey, propertyType);
final TenantConfiguration tenantConfiguration = tenantConfigurationRepository
@@ -75,7 +77,7 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
}
@Override
public <T> TenantConfigurationValue<T> buildTenantConfigurationValueByKey(
public <T extends Serializable> TenantConfigurationValue<T> buildTenantConfigurationValueByKey(
final TenantConfigurationKey configurationKey, final Class<T> propertyType,
final TenantConfiguration tenantConfiguration) {
if (tenantConfiguration != null) {
@@ -95,7 +97,8 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
}
@Override
public <T> TenantConfigurationValue<T> getConfigurationValue(final TenantConfigurationKey configurationKey) {
public <T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(
final TenantConfigurationKey configurationKey) {
return getConfigurationValue(configurationKey, configurationKey.getDataType());
}
@@ -122,8 +125,8 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
@CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()")
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public <T> TenantConfigurationValue<T> addOrUpdateConfiguration(final TenantConfigurationKey configurationKey,
final T value) {
public <T extends Serializable> TenantConfigurationValue<T> addOrUpdateConfiguration(
final TenantConfigurationKey configurationKey, final T value) {
if (!configurationKey.getDataType().isAssignableFrom(value.getClass())) {
throw new TenantConfigurationValidatorException(String.format(

View File

@@ -20,6 +20,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
@@ -43,7 +44,7 @@ public interface RolloutRepository
* @return the count of the updated rows. Zero if no row has been updated
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
@Query("UPDATE JpaRollout r SET r.lastCheck = :lastCheck WHERE r.lastCheck < (:lastCheck - :delay) AND r.status=:status")
int updateLastCheck(@Param("lastCheck") final long lastCheck, @Param("delay") final long delay,
@Param("status") final RolloutStatus status);

View File

@@ -89,13 +89,13 @@ public interface SoftwareModuleRepository
/**
*
*
* @param set
* @param setId
* to search for
* @return all {@link SoftwareModule}s that are assigned to given
* {@link DistributionSet}
*/
@EntityGraph(value = "SoftwareModule.artifacts", type = EntityGraphType.LOAD)
List<JpaSoftwareModule> findByAssignedTo(JpaDistributionSet set);
List<JpaSoftwareModule> findByAssignedToId(Long setId);
/**
* @param pageable

View File

@@ -15,7 +15,6 @@ import javax.persistence.Entity;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
@@ -53,6 +52,5 @@ public interface TargetInfoRepository {
*
* @return persisted or updated {@link Entity}
*/
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
<S extends JpaTargetInfo> S save(S entity);
}

View File

@@ -41,9 +41,6 @@ import com.google.common.collect.Maps;
* {@link Aspect} catches persistence exceptions and wraps them to custom
* specific exceptions Additionally it checks and prevents access to certain
* packages. Logging aspect which logs the call stack
*
*
*
*/
@Aspect
public class ExceptionMappingAspectHandler implements Ordered {

View File

@@ -1,41 +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.cache;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.eclipse.hawkbit.repository.jpa.model.CacheFieldEntityListener;
import org.springframework.cache.CacheManager;
import org.springframework.data.annotation.Transient;
/**
* Marks an field within a JPA entity as transient and this field should be
* loaded from a configured {@link CacheManager} by using the JPA entity
* listeners.
*
*
*
* @see CacheFieldEntityListener
*/
@Target({ FIELD })
@Retention(RUNTIME)
@Transient
public @interface CacheField {
/**
* @return the cache key name for this cacheable field which is used to
* store the value.
*/
String key();
}

View File

@@ -1,56 +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.cache;
import org.eclipse.hawkbit.repository.jpa.model.CacheFieldEntityListener;
/**
* RepositoryConstants for cache keys used in multiple classes.
*
*
*
*
* @see CacheFieldEntityListener
* @see CacheWriteNotify
* @see CacheField
*
*/
public final class CacheKeys {
/**
* The cache key name for the {@link UpdateActionStatus} download progress
* event.
*/
public static final String DOWNLOAD_PROGRESS_PERCENT = "download.progress.percent";
public static final String ROLLOUT_GROUP_CREATED = "rollout.group.created";
public static final String ROLLOUT_GROUP_TOTAL = "rollout.group.total";
/**
* utility class only private constructor.
*/
private CacheKeys() {
}
/**
* calculates the cache key for a specific entity. The cache key must be
* different for each different identifiable entity by its ID.
*
* @param entityId
* the ID of the entity to build the specific cache key for this
* entity
* @param cacheKey
* the cache key for the field to be cached
* @return the combined cache key based on the given {@code entityId} and
* {@code cacheKey}
*/
public static String entitySpecificCacheKey(final String entityId, final String cacheKey) {
return entityId + "." + cacheKey;
}
}

View File

@@ -1,143 +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.cache;
import java.math.RoundingMode;
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import com.google.common.eventbus.EventBus;
import com.google.common.math.DoubleMath;
/**
* An service which combines the functionality for functional use cases to write
* into the cache an notify the writing to the cache to the {@link EventBus}.
*
*
*
*/
@Service
public class CacheWriteNotify {
private static final int DOWNLOAD_PROGRESS_MAX = 100;
@Autowired
private CacheManager cacheManager;
@Autowired
private EventBus eventBus;
@Autowired
private TenantAware tenantAware;
/**
* writes the download progress into the cache
* {@link CacheKeys#DOWNLOAD_PROGRESS_PERCENT} and notifies the
* {@link EventBus} with a {@link DownloadProgressEvent}.
*
* @param statusId
* the ID of the {@link ActionStatus}
* @param requestedBytes
* requested bytes of the request
* @param shippedBytesSinceLast
* since last event
* @param shippedBytesOverall
* for the download request
*/
public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast,
final Long shippedBytesOverall) {
final Cache cache = cacheManager.getCache(ActionStatus.class.getName());
final String cacheKey = CacheKeys.entitySpecificCacheKey(String.valueOf(statusId),
CacheKeys.DOWNLOAD_PROGRESS_PERCENT);
final int progressPercent = DoubleMath.roundToInt(shippedBytesOverall * 100.0 / requestedBytes,
RoundingMode.DOWN);
if (progressPercent < DOWNLOAD_PROGRESS_MAX) {
cache.put(cacheKey, progressPercent);
} else {
// in case we reached progress 100 delete the cache value again
// because otherwise he will
// keep there forever
cache.evict(cacheKey);
}
eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, requestedBytes,
shippedBytesSinceLast, shippedBytesOverall));
}
/**
* Writes the {@link CacheKeys#ROLLOUT_GROUP_CREATED} and
* {@link CacheKeys#ROLLOUT_GROUP_TOTAL} into the cache and notfies the
* {@link EventBus} with a {@link RolloutGroupCreatedEvent}.
*
* @param revision
* the revision of the event
* @param rolloutId
* the ID of the rollout the group has been created
* @param rolloutGroupId
* the ID of the rollout group which has been created
* @param totalRolloutGroup
* the total number of rollout groups for this rollout
* @param createdRolloutGroup
* the number of already created groups of the rollout
*/
public void rolloutGroupCreated(final long revision, final Long rolloutId, final Long rolloutGroupId,
final int totalRolloutGroup, final int createdRolloutGroup) {
final Cache cache = cacheManager.getCache(Rollout.class.getName());
final String cacheKeyGroupTotal = CacheKeys.entitySpecificCacheKey(String.valueOf(rolloutId),
CacheKeys.ROLLOUT_GROUP_TOTAL);
final String cacheKeyGroupCreated = CacheKeys.entitySpecificCacheKey(String.valueOf(rolloutId),
CacheKeys.ROLLOUT_GROUP_CREATED);
if (createdRolloutGroup < totalRolloutGroup) {
cache.put(cacheKeyGroupTotal, totalRolloutGroup);
cache.put(cacheKeyGroupCreated, createdRolloutGroup);
} else {
// in case we reached progress 100 delete the cache value again
// because otherwise he will keep there forever
cache.evict(cacheKeyGroupTotal);
cache.evict(cacheKeyGroupCreated);
}
eventBus.post(new RolloutGroupCreatedEvent(tenantAware.getCurrentTenant(), revision, rolloutId, rolloutGroupId,
totalRolloutGroup, createdRolloutGroup));
}
/**
* @param cacheManager
* the cacheManager to set
*/
void setCacheManager(final CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
/**
* @param eventBus
* the eventBus to set
*/
void setEventBus(final EventBus eventBus) {
this.eventBus = eventBus;
}
/**
* @param tenantAware
* the tenantAware to set
*/
void setTenantAware(final TenantAware tenantAware) {
this.tenantAware = tenantAware;
}
}

View File

@@ -0,0 +1,49 @@
/**
* 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.event;
import javax.persistence.EntityManager;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManager;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
/**
* A TenantAwareEvent entity manager, which loads an entity by id and type for
* remote events.
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public class JpaEventEntityManager implements EventEntityManager {
private final TenantAware tenantAware;
private final EntityManager entityManager;
/**
* Constructor.
*
* @param tenantAware
* the tenant aware
* @param entityManager
* the entity manager
*/
public JpaEventEntityManager(final TenantAware tenantAware, final EntityManager entityManager) {
this.tenantAware = tenantAware;
this.entityManager = entityManager;
}
@Override
public <E extends TenantAwareBaseEntity> E findEntity(final String tenant, final Long id,
final Class<E> entityType) {
return tenantAware.runAsTenant(tenant, () -> entityManager.find(entityType, id));
}
}

View File

@@ -1,193 +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.eventbus;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.hawkbit.eventbus.EventSubscriber;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutChangeEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupChangeEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
/**
* Collects and merges fine grained events to more generic events and push them
* in a fixed delay on the events bus. This helps for code which are not
* interested in all fine grained events, e.g. UI code. The UI code is not
* interested in handling the flood of events, so collecting the events and
* merge them to one event together and post them in a fixed interval is easier
* to consume e.g. for push notifications on UI.
*
*/
@EventSubscriber
@Service
public class EventMerger {
private static final Set<RolloutEventKey> rolloutEvents = ConcurrentHashMap.newKeySet();
private static final Set<RolloutEventKey> rolloutGroupEvents = ConcurrentHashMap.newKeySet();
@Autowired
private EventBus eventBus;
/**
* Checks if there are events to publish in the fixed interval.
*/
@Scheduled(initialDelay = 10000, fixedDelay = 2000)
public void rolloutEventScheduler() {
final Iterator<RolloutEventKey> rolloutIterator = rolloutEvents.iterator();
while (rolloutIterator.hasNext()) {
final RolloutEventKey eventKey = rolloutIterator.next();
eventBus.post(new RolloutChangeEvent(1, eventKey.tenant, eventKey.rolloutId));
rolloutIterator.remove();
}
final Iterator<RolloutEventKey> rolloutGroupIterator = rolloutGroupEvents.iterator();
while (rolloutGroupIterator.hasNext()) {
final RolloutEventKey eventKey = rolloutGroupIterator.next();
eventBus.post(new RolloutGroupChangeEvent(1, eventKey.tenant, eventKey.rolloutId, eventKey.rolloutGroupId));
rolloutGroupIterator.remove();
}
}
/**
* Called by the event bus to retrieve all necessary events to collect and
* merge.
*
* @param event
* the event on the event bus
*/
@Subscribe
@AllowConcurrentEvents
public void onEvent(final Event event) {
Long rolloutId = null;
Long rolloutGroupId = null;
if (event instanceof ActionCreatedEvent) {
rolloutId = getRolloutId(((ActionCreatedEvent) event).getEntity().getRollout());
rolloutGroupId = getRolloutGroupId(((ActionCreatedEvent) event).getEntity().getRolloutGroup());
} else if (event instanceof ActionPropertyChangeEvent) {
rolloutId = getRolloutId(((ActionPropertyChangeEvent) event).getEntity().getRollout());
rolloutGroupId = getRolloutGroupId(((ActionPropertyChangeEvent) event).getEntity().getRolloutGroup());
} else if (event instanceof RolloutPropertyChangeEvent) {
rolloutId = ((RolloutPropertyChangeEvent) event).getEntity().getId();
} else if (event instanceof RolloutGroupCreatedEvent) {
rolloutId = ((RolloutGroupCreatedEvent) event).getRolloutId();
rolloutGroupId = ((RolloutGroupCreatedEvent) event).getRolloutGroupId();
} else if (event instanceof RolloutGroupPropertyChangeEvent) {
final RolloutGroup rolloutGroup = ((RolloutGroupPropertyChangeEvent) event).getEntity();
rolloutId = rolloutGroup.getRollout().getId();
rolloutGroupId = rolloutGroup.getId();
}
if (rolloutId != null) {
rolloutEvents.add(new RolloutEventKey(rolloutId, event.getTenant()));
if (rolloutGroupId != null) {
rolloutGroupEvents.add(new RolloutEventKey(rolloutId, rolloutGroupId, event.getTenant()));
}
}
}
private Long getRolloutGroupId(final RolloutGroup rolloutGroup) {
if (rolloutGroup != null) {
return rolloutGroup.getId();
}
return null;
}
private Long getRolloutId(final Rollout rollout) {
if (rollout != null) {
return rollout.getId();
}
return null;
}
/**
* The rollout key in the concurrent set to be hold.
*
* @author Michael Hirsch
*
*/
private static final class RolloutEventKey {
private final Long rolloutId;
private final String tenant;
private final Long rolloutGroupId;
private RolloutEventKey(final Long rolloutId, final Long rolloutGroupId, final String tenant) {
this.rolloutGroupId = rolloutGroupId;
this.rolloutId = rolloutId;
this.tenant = tenant;
}
private RolloutEventKey(final Long rolloutId, final String tenant) {
this(rolloutId, null, tenant);
}
@Override
public int hashCode() {// NOSONAR - as this is generated
final int prime = 31;
int result = 1;
result = prime * result + ((rolloutGroupId == null) ? 0 : rolloutGroupId.hashCode());
result = prime * result + ((rolloutId == null) ? 0 : rolloutId.hashCode());
result = prime * result + ((tenant == null) ? 0 : tenant.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {// NOSONAR - as this is
// generated
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final RolloutEventKey other = (RolloutEventKey) obj;
if (rolloutGroupId == null) {
if (other.rolloutGroupId != null) {
return false;
}
} else if (!rolloutGroupId.equals(other.rolloutGroupId)) {
return false;
}
if (rolloutId == null) {
if (other.rolloutId != null) {
return false;
}
} else if (!rolloutId.equals(other.rolloutId)) {
return false;
}
if (tenant == null) {
if (other.tenant != null) {
return false;
}
} else if (!tenant.equals(other.tenant)) {
return false;
}
return true;
}
}
}

View File

@@ -31,8 +31,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
*/
@MappedSuperclass
@Access(AccessType.FIELD)
@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class,
EntityInterceptorListener.class })
@EntityListeners({ AuditingEntityListener.class, EntityPropertyChangeListener.class, EntityInterceptorListener.class })
public abstract class AbstractJpaBaseEntity implements BaseEntity {
private static final long serialVersionUID = 1L;

View File

@@ -14,9 +14,9 @@ import javax.persistence.PrePersist;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.exception.TenantNotExistException;
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemManagementHolder;
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder;
import org.eclipse.persistence.annotations.Multitenant;
import org.eclipse.persistence.annotations.MultitenantType;
import org.eclipse.persistence.annotations.TenantDiscriminatorColumn;

View File

@@ -1,123 +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.io.Serializable;
import java.lang.reflect.Field;
import javax.persistence.PostLoad;
import javax.persistence.PostRemove;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
import org.eclipse.hawkbit.repository.jpa.model.helper.CacheManagerHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.CacheManager;
import org.springframework.hateoas.Identifiable;
/**
* An JPA entity listener which enriches the JPA entity fields which are
* annotated with {@link CacheField} with values from the {@link CacheManager}.
* Only JPA entities which are implementing {@link Identifiable} can be handled
* by this entity listener cause the cache keys are calculated with the ID of
* the entity.
*
*
*
*
*/
public class CacheFieldEntityListener {
private static final Logger LOGGER = LoggerFactory.getLogger(CacheFieldEntityListener.class);
/**
* enriches the JPA entities after loading the entity from the SQL database.
*
* @param target
* the target which has been loaded from the database
*/
@PostLoad
public void postLoad(final Object target) {
if (target instanceof Identifiable) {
final CacheManager cacheManager = CacheManagerHolder.getInstance().getCacheManager();
@SuppressWarnings("rawtypes")
final String id = ((Identifiable) target).getId().toString();
final Class<? extends Object> type = target.getClass();
findCacheFields(type, id, (field, cacheKey, id1) -> {
final Cache cache = cacheManager.getCache(type.getName());
final ValueWrapper valueWrapper = cache.get(CacheKeys.entitySpecificCacheKey(id1.toString(), cacheKey));
if (valueWrapper != null && valueWrapper.get() != null) {
FieldUtils.writeField(field, target, valueWrapper.get(), true);
}
});
}
}
/**
* deletes the associated cache fields from the cache when deleted the
* entity from the database.
*
* @param target
* the entity which has been deleted
*/
@PostRemove
public void postDelete(final Object target) {
if (target instanceof Identifiable) {
final CacheManager cacheManager = CacheManagerHolder.getInstance().getCacheManager();
@SuppressWarnings("rawtypes")
final String id = ((Identifiable) target).getId().toString();
final Class<? extends Object> type = target.getClass();
findCacheFields(type, id, (field, cacheKey, id1) -> {
final Cache cache = cacheManager.getCache(type.getName());
cache.evict(CacheKeys.entitySpecificCacheKey(id1.toString(), cacheKey));
});
}
}
private void findCacheFields(final Class<? extends Object> type, final Serializable id,
final CacheFieldCallback callback) {
final Field[] declaredFields = type.getDeclaredFields();
for (final Field field : declaredFields) {
if (field.getAnnotation(CacheField.class) != null) {
try {
final CacheField annotation = field.getAnnotation(CacheField.class);
callback.fromCache(field, annotation.key(), id);
} catch (final IllegalAccessException e) {
LOGGER.error("cannot access the field {} for the entity {}, ignoring the cacheable field", field,
type, e);
}
}
}
}
@FunctionalInterface
private interface CacheFieldCallback {
/**
* callback methods which is called by the
* {@link CacheFieldEntityListener#findCacheFields(Class, Serializable, CacheFieldCallback)}
* in case a field is annotated with {@link CacheField}.
*
* @param field
* the field which is annotaed with {@link CacheField}
* @param cacheKey
* the configured cache key in the annotation
* {@link CacheField#key()}
* @param id
* the ID of the entity
* @throws IllegalAccessException
* in case the field cannot be accessed
*/
void fromCache(final Field field, final String cacheKey, Serializable id) throws IllegalAccessException;
}
}

View File

@@ -30,16 +30,15 @@ import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent;
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper;
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
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.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.persistence.annotations.CascadeOnDelete;
import org.eclipse.persistence.descriptors.DescriptorEvent;
@@ -187,13 +186,14 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
@Override
public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(this));
EventPublisherHolder.getInstance().getEventPublisher()
.publishEvent(new ActionCreatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
}
@Override
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
EventBusHolder.getInstance().getEventBus()
.post(new ActionPropertyChangeEvent(this, EntityPropertyChangeHelper.getChangeSet(descriptorEvent)));
EventPublisherHolder.getInstance().getEventPublisher()
.publishEvent(new ActionUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
}
@Override

View File

@@ -25,11 +25,8 @@ import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus;
@@ -72,13 +69,6 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
@Column(name = "detail_message", length = 512)
private List<String> messages;
/**
* Note: filled only in {@link Status#DOWNLOAD}.
*/
@Transient
@CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT)
private short downloadProgressPercent;
/**
* Creates a new {@link ActionStatus} object.
*
@@ -121,11 +111,6 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
// JPA default constructor.
}
@Override
public short getDownloadProgressPercent() {
return downloadProgressPercent;
}
@Override
public Long getOccurredAt() {
return occurredAt;

View File

@@ -12,9 +12,9 @@ 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 java.util.stream.Collectors;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@@ -34,14 +34,11 @@ import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent.PropertyChange;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdateEvent;
import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException;
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
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;
@@ -52,8 +49,13 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.persistence.annotations.CascadeOnDelete;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.eclipse.persistence.queries.UpdateObjectQuery;
import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord;
import org.eclipse.persistence.sessions.changesets.ObjectChangeSet;
import org.springframework.context.ApplicationEvent;
/**
* Jpa implementation of {@link DistributionSet}.
@@ -347,27 +349,40 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@Override
public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(this));
publishEventWithEventPublisher(
new DistributionSetCreatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
}
@Override
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
final Map<String, PropertyChange> changeSet = EntityPropertyChangeHelper.getChangeSet(descriptorEvent);
EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(this));
publishEventWithEventPublisher(
new DistributionSetUpdateEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
if (changeSet.containsKey(DELETED_PROPERTY)) {
final Boolean newDeleted = (Boolean) changeSet.get(DELETED_PROPERTY).getNewValue();
if (newDeleted) {
EventBusHolder.getInstance().getEventBus().post(new DistributionDeletedEvent(getTenant(), getId()));
}
if (isSoftDeleted(descriptorEvent)) {
publishEventWithEventPublisher(new DistributionSetDeletedEvent(getTenant(), getId(),
EventPublisherHolder.getInstance().getApplicationId()));
}
}
@Override
public void fireDeleteEvent(final DescriptorEvent descriptorEvent) {
EventBusHolder.getInstance().getEventBus().post(new DistributionDeletedEvent(getTenant(), getId()));
publishEventWithEventPublisher(new DistributionSetDeletedEvent(getTenant(), getId(),
EventPublisherHolder.getInstance().getApplicationId()));
}
private static void publishEventWithEventPublisher(final ApplicationEvent event) {
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(event);
}
private static boolean isSoftDeleted(final DescriptorEvent event) {
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
.filter(record -> record instanceof DirectToFieldChangeRecord)
.map(record -> (DirectToFieldChangeRecord) record).collect(Collectors.toList());
return changes.stream().filter(record -> DELETED_PROPERTY.equals(record.getAttribute())
&& Boolean.parseBoolean(record.getNewValue().toString())).count() > 0;
}
}

View File

@@ -28,12 +28,9 @@ import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
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.EntityPropertyChangeHelper;
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutUpdatedEvent;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
@@ -86,12 +83,7 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
@Column(name = "total_targets")
private long totalTargets;
@Transient
@CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL)
private int rolloutGroupsTotal;
@Transient
@CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED)
@Column(name = "rollout_groups_created")
private int rolloutGroupsCreated;
@Transient
@@ -172,14 +164,6 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
this.totalTargets = totalTargets;
}
public int getRolloutGroupsTotal() {
return rolloutGroupsTotal;
}
public void setRolloutGroupsTotal(final int rolloutGroupsTotal) {
this.rolloutGroupsTotal = rolloutGroupsTotal;
}
@Override
public int getRolloutGroupsCreated() {
return rolloutGroupsCreated;
@@ -215,8 +199,8 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
@Override
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
EventBusHolder.getInstance().getEventBus()
.post(new RolloutPropertyChangeEvent(this, EntityPropertyChangeHelper.getChangeSet(descriptorEvent)));
EventPublisherHolder.getInstance().getEventPublisher()
.publishEvent(new RolloutUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
}

View File

@@ -26,12 +26,11 @@ import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent;
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper;
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupUpdatedEvent;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.persistence.descriptors.DescriptorEvent;
/**
@@ -256,8 +255,9 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
@Override
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
EventBusHolder.getInstance().getEventBus().post(
new RolloutGroupPropertyChangeEvent(this, EntityPropertyChangeHelper.getChangeSet(descriptorEvent)));
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(new RolloutGroupUpdatedEvent(this,
EventPublisherHolder.getInstance().getApplicationId()));
}
@Override

View File

@@ -37,10 +37,9 @@ 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.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
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;
@@ -49,6 +48,7 @@ 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.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.persistence.annotations.CascadeOnDelete;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.springframework.data.domain.Persistable;
@@ -278,16 +278,19 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
@Override
public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(this));
EventPublisherHolder.getInstance().getEventPublisher()
.publishEvent(new TargetCreatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
}
@Override
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(this));
EventPublisherHolder.getInstance().getEventPublisher()
.publishEvent(new TargetUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
}
@Override
public void fireDeleteEvent(final DescriptorEvent descriptorEvent) {
EventBusHolder.getInstance().getEventBus().post(new TargetDeletedEvent(getTenant(), getId()));
EventPublisherHolder.getInstance().getEventPublisher()
.publishEvent(new TargetDeletedEvent(getTenant(), getId(), EventPublisherHolder.getInstance().getApplicationId()));
}
}

View File

@@ -40,16 +40,16 @@ import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException;
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.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.eclipse.persistence.annotations.CascadeOnDelete;
@@ -338,7 +338,8 @@ public class JpaTargetInfo implements Persistable<Long>, TargetInfo, EventAwareE
@Override
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(this));
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
new TargetUpdatedEvent(this.getTarget(), EventPublisherHolder.getInstance().getApplicationId()));
}
@Override

View File

@@ -1,58 +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.helper;
import org.eclipse.hawkbit.repository.jpa.model.CacheFieldEntityListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
/**
* A singleton bean which holds the {@link CacheManager} to have to the cache
* manager in beans not instantiated by spring e.g. JPA entities or
* {@link CacheFieldEntityListener} which cannot be autowired.
*
*
*
*/
public final class CacheManagerHolder {
private static final CacheManagerHolder SINGLETON = new CacheManagerHolder();
@Autowired
private CacheManager cacheManager;
private CacheManagerHolder() {
}
/**
* @return the cache manager holder singleton instance
*/
public static CacheManagerHolder getInstance() {
return SINGLETON;
}
/**
* @return the cacheManager
*/
public CacheManager getCacheManager() {
return cacheManager;
}
/**
* Normally not used when using spring-boot then the cachemanager is
* autowired to the CacheManagerHolder, but for testing purposes.
*
* @param cacheManager
* the cache manager to set for the cache manager holder.
*/
public void setCacheManager(final CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
}

View File

@@ -1,44 +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.helper;
import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent.PropertyChange;
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;
/**
* Helper class to get the change set for the property changes in the Entity.
*
*/
public final class EntityPropertyChangeHelper {
private EntityPropertyChangeHelper() {
// noop
}
/**
* To get the map of entity property change set
*
* @param clazz
* @param event
* @return the map of the changeSet
*/
public static Map<String, PropertyChange> getChangeSet(final DescriptorEvent event) {
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 PropertyChange(record.getOldValue(), record.getNewValue())));
}
}

Some files were not shown because too many files have changed in this diff Show More