Remove swagger and minor feature extensions and bug fixes
- Various Bug fixes and improvements - Management API extended - Swagger removed - Guava Upgraded to 19
This commit is contained in:
0
hawkbit-repository/src/fbExcludeFilter.xml
Executable file → Normal file
0
hawkbit-repository/src/fbExcludeFilter.xml
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/Constants.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/Constants.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/MultiTenantJpaTransactionManager.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/MultiTenantJpaTransactionManager.java
Executable file → Normal file
8
hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java
Executable file → Normal file
8
hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java
Executable file → Normal file
@@ -11,7 +11,7 @@ package org.eclipse.hawkbit;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.hawkbit.aspects.SpExceptionMappingAspect;
|
||||
import org.eclipse.hawkbit.aspects.ExceptionMappingAspectHandler;
|
||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||
import org.eclipse.hawkbit.repository.model.helper.CacheManagerHolder;
|
||||
import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper;
|
||||
@@ -123,11 +123,11 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link SpExceptionMappingAspect} aspect bean
|
||||
* @return {@link ExceptionMappingAspectHandler} aspect bean
|
||||
*/
|
||||
@Bean
|
||||
public SpExceptionMappingAspect createRepositoryExceptionHandlerAdvice() {
|
||||
return new SpExceptionMappingAspect();
|
||||
public ExceptionMappingAspectHandler createRepositoryExceptionHandlerAdvice() {
|
||||
return new ExceptionMappingAspectHandler();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* 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.aspects;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.transaction.TransactionManager;
|
||||
|
||||
import org.aspectj.lang.annotation.AfterThrowing;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.eclipse.hawkbit.exception.GenericSpServerException;
|
||||
import org.eclipse.hawkbit.repository.exception.ConcurrentModificationException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.dao.ConcurrencyFailureException;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
|
||||
import org.springframework.orm.jpa.JpaSystemException;
|
||||
import org.springframework.orm.jpa.JpaVendorAdapter;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.transaction.TransactionSystemException;
|
||||
|
||||
/**
|
||||
* {@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 {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ExceptionMappingAspectHandler.class);
|
||||
|
||||
private static final Map<String, String> EXCEPTION_MAPPING = new HashMap<>();
|
||||
|
||||
/**
|
||||
* this is required to enable a certain order of exception and to select the
|
||||
* most specific mappable exception according to the type hierarchy of the
|
||||
* exception.
|
||||
*/
|
||||
private static final List<Class<?>> MAPPED_EXCEPTION_ORDER = new ArrayList<>();
|
||||
|
||||
@Autowired
|
||||
private JpaVendorAdapter jpaVendorAdapter;
|
||||
|
||||
private final SQLStateSQLExceptionTranslator sqlStateExceptionTranslator = new SQLStateSQLExceptionTranslator();
|
||||
|
||||
static {
|
||||
MAPPED_EXCEPTION_ORDER.add(DuplicateKeyException.class);
|
||||
MAPPED_EXCEPTION_ORDER.add(DataIntegrityViolationException.class);
|
||||
MAPPED_EXCEPTION_ORDER.add(ConcurrencyFailureException.class);
|
||||
MAPPED_EXCEPTION_ORDER.add(AccessDeniedException.class);
|
||||
|
||||
EXCEPTION_MAPPING.put(DuplicateKeyException.class.getName(), EntityAlreadyExistsException.class.getName());
|
||||
EXCEPTION_MAPPING.put(DataIntegrityViolationException.class.getName(),
|
||||
EntityAlreadyExistsException.class.getName());
|
||||
|
||||
EXCEPTION_MAPPING.put(ConcurrencyFailureException.class.getName(),
|
||||
ConcurrentModificationException.class.getName());
|
||||
EXCEPTION_MAPPING.put(AccessDeniedException.class.getName(), InsufficientPermissionException.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* catch exceptions of the {@link TransactionManager} and wrap them to
|
||||
* custom exceptions.
|
||||
*
|
||||
* @param ex
|
||||
* the thrown and catched exception
|
||||
* @throws Throwable
|
||||
*/
|
||||
@AfterThrowing(pointcut = "( execution( * org.springframework.transaction..*.*(..)) "
|
||||
+ " || execution( * org.eclipse.hawkbit.repository.*.*(..)) "
|
||||
+ " || execution( * org.eclipse.hawkbit.controller.*.*(..)) "
|
||||
+ " || execution( * org.eclipse.hawkbit.rest.resource.*.*(..)) "
|
||||
+ " || execution( * org.eclipse.hawkbit.service.*.*(..)) )", throwing = "ex")
|
||||
public void catchAndWrapJpaExceptionsService(final Exception ex) throws Throwable {
|
||||
LOG.trace("exception occured", ex);
|
||||
Exception translatedAccessException = translateEclipseLinkExceptionIfPossible(ex);
|
||||
|
||||
if (translatedAccessException == null && ex instanceof TransactionSystemException) {
|
||||
final TransactionSystemException systemException = (TransactionSystemException) ex;
|
||||
translatedAccessException = translateEclipseLinkExceptionIfPossible((Exception) systemException
|
||||
.getOriginalException());
|
||||
}
|
||||
|
||||
if (translatedAccessException == null) {
|
||||
translatedAccessException = ex;
|
||||
}
|
||||
|
||||
Exception mappingException = translatedAccessException;
|
||||
|
||||
LOG.trace("translated excpetion is", translatedAccessException);
|
||||
for (final Class<?> mappedEx : MAPPED_EXCEPTION_ORDER) {
|
||||
|
||||
if (mappedEx.isAssignableFrom(translatedAccessException.getClass())) {
|
||||
if (!EXCEPTION_MAPPING.containsKey(mappedEx.getName())) {
|
||||
LOG.error("there is no mapping configured for exception class {}", mappedEx.getName());
|
||||
mappingException = new GenericSpServerException(ex);
|
||||
} else {
|
||||
mappingException = (Exception) Class.forName(EXCEPTION_MAPPING.get(mappedEx.getName()))
|
||||
.getConstructor(Throwable.class).newInstance(ex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
LOG.trace("mapped exception {} to {}", translatedAccessException.getClass(), mappingException.getClass());
|
||||
throw mappingException;
|
||||
}
|
||||
|
||||
private DataAccessException translateEclipseLinkExceptionIfPossible(final Exception exception) {
|
||||
final DataAccessException translatedAccessException = jpaVendorAdapter.getJpaDialect()
|
||||
.translateExceptionIfPossible((RuntimeException) exception);
|
||||
return translateSQLStateExceptionIfPossible(translatedAccessException);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* There is no EclipseLinkExceptionTranslator. So we have to check and
|
||||
* translate the exception by the sql error code. Luckily, there we can use
|
||||
* {@link SQLStateSQLExceptionTranslator} if we can get a
|
||||
* {@link SQLException}.
|
||||
*
|
||||
* @param accessException
|
||||
* the base access exception from jpa
|
||||
* @return the translated accessException
|
||||
*/
|
||||
private DataAccessException translateSQLStateExceptionIfPossible(final DataAccessException accessException) {
|
||||
if (!(accessException instanceof JpaSystemException)) {
|
||||
return accessException;
|
||||
}
|
||||
|
||||
final SQLException ex = findSqlException((JpaSystemException) accessException);
|
||||
|
||||
if (ex == null) {
|
||||
return accessException;
|
||||
}
|
||||
|
||||
return sqlStateExceptionTranslator.translate(null, null, ex);
|
||||
}
|
||||
|
||||
private static SQLException findSqlException(final JpaSystemException jpaSystemException) {
|
||||
Throwable exception = jpaSystemException.getCause();
|
||||
while (exception != null) {
|
||||
final Throwable cause = exception.getCause();
|
||||
if (cause instanceof SQLException) {
|
||||
return (SQLException) cause;
|
||||
}
|
||||
exception = cause;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.core.Ordered#getOrder()
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1,108 +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.aspects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.transaction.TransactionManager;
|
||||
|
||||
import org.aspectj.lang.annotation.AfterThrowing;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.eclipse.hawkbit.exception.GenericSpServerException;
|
||||
import org.eclipse.hawkbit.repository.exception.ConcurrentModificationException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.dao.ConcurrencyFailureException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
|
||||
/**
|
||||
* {@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 SpExceptionMappingAspect implements Ordered {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SpExceptionMappingAspect.class);
|
||||
|
||||
private static final Map<String, String> EXCEPTION_MAPPING = new HashMap<String, String>();
|
||||
|
||||
/**
|
||||
* this is required to enable a certain order of exception and to select the
|
||||
* most specific mappable exception according to the type hierarchy of the
|
||||
* exception.
|
||||
*/
|
||||
private static final List<Class<?>> MAPPED_EXCEPTION_ORDER = new ArrayList<Class<?>>();
|
||||
|
||||
static {
|
||||
MAPPED_EXCEPTION_ORDER.add(DuplicateKeyException.class);
|
||||
MAPPED_EXCEPTION_ORDER.add(DataIntegrityViolationException.class);
|
||||
MAPPED_EXCEPTION_ORDER.add(ConcurrencyFailureException.class);
|
||||
MAPPED_EXCEPTION_ORDER.add(AccessDeniedException.class);
|
||||
|
||||
EXCEPTION_MAPPING.put(DuplicateKeyException.class.getName(), EntityAlreadyExistsException.class.getName());
|
||||
|
||||
EXCEPTION_MAPPING.put(ConcurrencyFailureException.class.getName(),
|
||||
ConcurrentModificationException.class.getName());
|
||||
EXCEPTION_MAPPING.put(AccessDeniedException.class.getName(), InsufficientPermissionException.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* catch exceptions of the {@link TransactionManager} and wrap them to
|
||||
* custom exceptions.
|
||||
*
|
||||
* @param ex
|
||||
* the thrown and catched exception
|
||||
* @throws Throwable
|
||||
*/
|
||||
@AfterThrowing(pointcut = "( execution( * org.springframework.transaction..*.*(..)) "
|
||||
+ " || execution( * org.eclipse.hawkbit.repository.*.*(..)) "
|
||||
+ " || execution( * org.eclipse.hawkbit.controller.*.*(..)) "
|
||||
+ " || execution( * org.eclipse.hawkbit.service.*.*(..)) )", throwing = "ex")
|
||||
public void catchAndWrapJpaExceptionsService(final Exception ex) throws Throwable {
|
||||
final Class<? extends Exception> exClass = ex.getClass();
|
||||
Exception newEx = ex;
|
||||
LOG.trace("exception occured", ex);
|
||||
for (final Class<?> mappedEx : MAPPED_EXCEPTION_ORDER) {
|
||||
|
||||
if (mappedEx.isAssignableFrom(exClass)) {
|
||||
if (!EXCEPTION_MAPPING.containsKey(mappedEx.getName())) {
|
||||
LOG.error("there is no mapping configured for exception class {}", mappedEx.getName());
|
||||
newEx = new GenericSpServerException(ex);
|
||||
} else {
|
||||
newEx = (Exception) Class.forName(EXCEPTION_MAPPING.get(mappedEx.getName()))
|
||||
.getConstructor(Throwable.class).newInstance(ex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
LOG.trace("mapped exception {} to {}", ex.getClass(), newEx.getClass());
|
||||
throw newEx;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.core.Ordered#getOrder()
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/cache/CacheField.java
vendored
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/cache/CacheField.java
vendored
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/cache/CacheKeys.java
vendored
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/cache/CacheKeys.java
vendored
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/cache/CacheWriteNotify.java
vendored
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/cache/CacheWriteNotify.java
vendored
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/CacheFieldEntityListener.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/CacheFieldEntityListener.java
Executable file → Normal file
15
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/EntityChangeEventListener.java
Executable file → Normal file
15
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/EntityChangeEventListener.java
Executable file → Normal file
@@ -18,6 +18,7 @@ import org.aspectj.lang.annotation.Aspect;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent;
|
||||
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
|
||||
import org.eclipse.hawkbit.repository.TargetRepository;
|
||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
@@ -49,6 +50,9 @@ public class EntityChangeEventListener {
|
||||
@Autowired
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private AfterTransactionCommitExecutor afterCommit;
|
||||
|
||||
/**
|
||||
* In case the a {@link Target} is created a corresponding
|
||||
* {@link TargetInfo} is created as well. We need the {@link TargetInfo}
|
||||
@@ -68,10 +72,6 @@ public class EntityChangeEventListener {
|
||||
final Object result = joinpoint.proceed();
|
||||
if (result instanceof TargetInfo) {
|
||||
if (isNew) {
|
||||
// we need to flush here because seems like eclipselink
|
||||
// implementation setting the ID of the target no immediately
|
||||
// otherwise.
|
||||
entityManager.flush();
|
||||
notifyTargetCreated(entityManager.merge(entityManager.merge(((TargetInfo) result).getTarget())));
|
||||
} else {
|
||||
notifyTargetInfoChanged((TargetInfo) result);
|
||||
@@ -129,15 +129,16 @@ public class EntityChangeEventListener {
|
||||
}
|
||||
|
||||
private void notifyTargetCreated(final Target t) {
|
||||
eventBus.post(new TargetCreatedEvent(t));
|
||||
afterCommit.afterCommit(() -> eventBus.post(new TargetCreatedEvent(t)));
|
||||
|
||||
}
|
||||
|
||||
private void notifyTargetInfoChanged(final TargetInfo targetInfo) {
|
||||
eventBus.post(new TargetInfoUpdateEvent(targetInfo));
|
||||
afterCommit.afterCommit(() -> eventBus.post(new TargetInfoUpdateEvent(targetInfo)));
|
||||
}
|
||||
|
||||
private void notifyTargetDeleted(final String tenant, final Long targetId) {
|
||||
eventBus.post(new TargetDeletedEvent(tenant, targetId));
|
||||
afterCommit.afterCommit(() -> eventBus.post(new TargetDeletedEvent(tenant, targetId)));
|
||||
}
|
||||
|
||||
private boolean isTargetInfoNew(final Object targetInfo) {
|
||||
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractBaseEntityEvent.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractBaseEntityEvent.java
Executable file → Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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.eventbus.event;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||
|
||||
/**
|
||||
*
|
||||
* A abstract typesafe bulkevent which contains all changed base entities.
|
||||
*
|
||||
* @param <E>
|
||||
*/
|
||||
public abstract class AbstractEntityBulkEvent<E extends BaseEntity> implements EntityBulkEvent<E> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<E> entities;
|
||||
|
||||
private String tenant;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant
|
||||
* @param entities
|
||||
* the changed entities
|
||||
*/
|
||||
public AbstractEntityBulkEvent(final String tenant, final List<E> entities) {
|
||||
this.entities = entities;
|
||||
this.tenant = tenant;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant
|
||||
* @param entitiy
|
||||
* the changed entity
|
||||
*/
|
||||
public AbstractEntityBulkEvent(final String tenant, final E entitiy) {
|
||||
this(tenant, Arrays.asList(entitiy));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<E> getEntities() {
|
||||
return entities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRevision() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTenant() {
|
||||
return tenant;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.eventbus.event;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssigmentResult;
|
||||
|
||||
/**
|
||||
* A event for assignment target tag.
|
||||
*/
|
||||
public class DistributionSetTagAssigmentResultEvent {
|
||||
|
||||
private final DistributionSetTagAssigmentResult assigmentResult;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param assigmentResult
|
||||
* the assignment result-
|
||||
*/
|
||||
public DistributionSetTagAssigmentResultEvent(final DistributionSetTagAssigmentResult assigmentResult) {
|
||||
this.assigmentResult = assigmentResult;
|
||||
}
|
||||
|
||||
public DistributionSetTagAssigmentResult getAssigmentResult() {
|
||||
return assigmentResult;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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.eventbus.event;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
|
||||
/**
|
||||
* * A bulk event which contains one or many new ds tag after creating.
|
||||
*/
|
||||
public class DistributionSetTagCreatedBulkEvent extends AbstractEntityBulkEvent<DistributionSetTag> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant
|
||||
* @param entities
|
||||
* the new ds tags
|
||||
*/
|
||||
public DistributionSetTagCreatedBulkEvent(final String tenant, final List<DistributionSetTag> entities) {
|
||||
super(tenant, entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant.
|
||||
* @param entity
|
||||
* the new ds tag
|
||||
*/
|
||||
public DistributionSetTagCreatedBulkEvent(final String tenant, final DistributionSetTag entity) {
|
||||
super(tenant, entity);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.eventbus.event;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
|
||||
/**
|
||||
* Defines the {@link AbstractBaseEntityEvent} for update a
|
||||
* {@link DistributionSetTag}.
|
||||
*
|
||||
*/
|
||||
public class DistributionSetTagUpdateEvent extends AbstractBaseEntityEvent<DistributionSetTag> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tag
|
||||
* the tag which is updated
|
||||
*/
|
||||
public DistributionSetTagUpdateEvent(final DistributionSetTag tag) {
|
||||
super(tag);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.eventbus.event;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||
|
||||
/**
|
||||
* An event interface which declares event types that an entities has been
|
||||
* changed.
|
||||
*
|
||||
* @param <E>
|
||||
* the entity type
|
||||
*/
|
||||
public interface EntityBulkEvent<E extends BaseEntity> extends Serializable, Event {
|
||||
|
||||
/**
|
||||
* A typesafe way to retrieve the the entities from the event, which might
|
||||
* be loaded lazy in case the event has been distributed from another node.
|
||||
*
|
||||
* @return the entities might be lazy loaded. Might be {@code null} in case
|
||||
* the entity e.g. is queried lazy on a different node and has been
|
||||
* already deleted from the database
|
||||
*/
|
||||
List<E> getEntities();
|
||||
}
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetAssignDistributionSetEvent.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetAssignDistributionSetEvent.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetCreatedEvent.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetCreatedEvent.java
Executable file → Normal file
6
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetInfoUpdateEvent.java
Executable file → Normal file
6
hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetInfoUpdateEvent.java
Executable file → Normal file
@@ -11,9 +11,7 @@ package org.eclipse.hawkbit.eventbus.event;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
* Event for update the targets info.
|
||||
*/
|
||||
public class TargetInfoUpdateEvent implements EntityEvent {
|
||||
|
||||
@@ -24,6 +22,8 @@ public class TargetInfoUpdateEvent implements EntityEvent {
|
||||
private String nodeId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param targetInfo
|
||||
* the target info entity
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.eventbus.event;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.TargetTagAssigmentResult;
|
||||
|
||||
/**
|
||||
* A event for assignment target tag.
|
||||
*/
|
||||
public class TargetTagAssigmentResultEvent {
|
||||
|
||||
private final TargetTagAssigmentResult assigmentResult;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param assigmentResult
|
||||
* the assignment result-
|
||||
*/
|
||||
public TargetTagAssigmentResultEvent(final TargetTagAssigmentResult assigmentResult) {
|
||||
this.assigmentResult = assigmentResult;
|
||||
}
|
||||
|
||||
public TargetTagAssigmentResult getAssigmentResult() {
|
||||
return assigmentResult;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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.eventbus.event;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
|
||||
/**
|
||||
* A bulk event which contains one or many new target tags after creating.
|
||||
*/
|
||||
public class TargetTagCreatedBulkEvent extends AbstractEntityBulkEvent<TargetTag> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant
|
||||
* @param entities
|
||||
* the new targets
|
||||
*/
|
||||
public TargetTagCreatedBulkEvent(final String tenant, final List<TargetTag> entities) {
|
||||
super(tenant, entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant
|
||||
* @param entity
|
||||
* one new target
|
||||
*/
|
||||
public TargetTagCreatedBulkEvent(final String tenant, final TargetTag entity) {
|
||||
super(tenant, entity);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.eventbus.event;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
|
||||
/**
|
||||
* Defines the {@link AbstractBaseEntityEvent} of update a {@link TargetTag}.
|
||||
*
|
||||
*/
|
||||
public class TargetTagDeletedEvent extends AbstractBaseEntityEvent<TargetTag> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tag
|
||||
* the tag which is deleted
|
||||
*/
|
||||
public TargetTagDeletedEvent(final TargetTag tag) {
|
||||
super(tag);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.eventbus.event;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
|
||||
/**
|
||||
* Defines the {@link AbstractBaseEntityEvent} for update a {@link TargetTag}.
|
||||
*
|
||||
*/
|
||||
public class TargetTagUpdateEvent extends AbstractBaseEntityEvent<TargetTag> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tag
|
||||
* the tag which is updated
|
||||
*/
|
||||
public TargetTagUpdateEvent(final TargetTag tag) {
|
||||
super(tag);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* 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.executor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* A Service which calls register runnable. This runnables will executed after a
|
||||
* successful spring transaction commit.The class is thread safe.
|
||||
*/
|
||||
@Service
|
||||
public class AfterTransactionCommitDefaultServiceExecutor extends TransactionSynchronizationAdapter implements
|
||||
AfterTransactionCommitExecutor {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AfterTransactionCommitDefaultServiceExecutor.class);
|
||||
private static final ThreadLocal<List<Runnable>> THREAD_LOCAL_RUNNABLES = new ThreadLocal<>();
|
||||
|
||||
@Override
|
||||
public void afterCommit() {
|
||||
final List<Runnable> afterCommitRunnables = THREAD_LOCAL_RUNNABLES.get();
|
||||
LOGGER.debug("Transaction successfully committed, executing {} runnables", afterCommitRunnables.size());
|
||||
for (final Runnable afterCommitRunnable : afterCommitRunnables) {
|
||||
LOGGER.debug("Executing runnable {}", afterCommitRunnable);
|
||||
try {
|
||||
afterCommitRunnable.run();
|
||||
} catch (final RuntimeException e) {
|
||||
LOGGER.error("Failed to execute runnable " + afterCommitRunnable, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCommit(final Runnable runnable) {
|
||||
LOGGER.debug("Submitting new runnable {} to run after transaction commit", runnable);
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
List<Runnable> localRunnables = THREAD_LOCAL_RUNNABLES.get();
|
||||
if (localRunnables == null) {
|
||||
localRunnables = new ArrayList<>();
|
||||
THREAD_LOCAL_RUNNABLES.set(localRunnables);
|
||||
TransactionSynchronizationManager.registerSynchronization(this);
|
||||
}
|
||||
localRunnables.add(runnable);
|
||||
return;
|
||||
}
|
||||
LOGGER.info("Transaction synchronization is NOT ACTIVE/ INACTIVE. Executing right now runnable {}", runnable);
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(final int status) {
|
||||
final String transactionStatus = status == STATUS_COMMITTED ? "COMMITTED" : "ROLLEDBACK";
|
||||
LOGGER.debug("Transaction completed after commit with status {}", transactionStatus);
|
||||
THREAD_LOCAL_RUNNABLES.remove();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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.executor;
|
||||
|
||||
/**
|
||||
*
|
||||
* A interface to register a runnable, which will be executed after a successful
|
||||
* spring transaction.
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface AfterTransactionCommitExecutor {
|
||||
|
||||
/**
|
||||
* Register a runnable which will be executed after a successful spring
|
||||
* transaction.
|
||||
*
|
||||
* @param runnable
|
||||
* the after commit runnable
|
||||
*/
|
||||
void afterCommit(Runnable runnable);
|
||||
}
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/AbstractReportSeries.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/AbstractReportSeries.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/DataReportSeries.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/DataReportSeries.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/DataReportSeriesItem.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/DataReportSeriesItem.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/InnerOuterDataReportSeries.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/InnerOuterDataReportSeries.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/ListReportSeries.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/ListReportSeries.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/SeriesTime.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/report/model/SeriesTime.java
Executable file → Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* 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.report.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Bean for holding the system usage stats.
|
||||
*
|
||||
*/
|
||||
public class SystemUsageReport {
|
||||
private final long overallTargets;
|
||||
private final long overallArtifacts;
|
||||
private final long overallArtifactVolumeInBytes;
|
||||
private final long overallActions;
|
||||
|
||||
private final List<TenantUsage> tenants = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param overallTargets
|
||||
* of the system
|
||||
* @param overallArtifacts
|
||||
* of the system
|
||||
* @param overallActions
|
||||
* of the system
|
||||
* @param overallArtifactVolumeInBytes
|
||||
* of the system
|
||||
*/
|
||||
public SystemUsageReport(final long overallTargets, final long overallArtifacts, final long overallActions,
|
||||
final long overallArtifactVolumeInBytes) {
|
||||
super();
|
||||
this.overallTargets = overallTargets;
|
||||
this.overallArtifacts = overallArtifacts;
|
||||
this.overallActions = overallActions;
|
||||
|
||||
this.overallArtifactVolumeInBytes = overallArtifactVolumeInBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return overallTargets in the system
|
||||
*/
|
||||
public long getOverallTargets() {
|
||||
return overallTargets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return overallArtifacts in the system
|
||||
*/
|
||||
public long getOverallArtifacts() {
|
||||
return overallArtifacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return overallArtifactVolumeInBytes of the system
|
||||
*/
|
||||
public long getOverallArtifactVolumeInBytes() {
|
||||
return overallArtifactVolumeInBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tenantUsage
|
||||
* of one tenant
|
||||
* @return updated bean
|
||||
*/
|
||||
public SystemUsageReport addTenantData(final TenantUsage tenantUsage) {
|
||||
tenants.add(tenantUsage);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return actions of system
|
||||
*/
|
||||
public long getOverallActions() {
|
||||
return overallActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tenant data
|
||||
*/
|
||||
public List<TenantUsage> getTenants() {
|
||||
return ImmutableList.copyOf(tenants);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* 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.report.model;
|
||||
|
||||
/**
|
||||
* System usage stats element for a tenant.
|
||||
*
|
||||
*/
|
||||
public class TenantUsage {
|
||||
|
||||
private final String tenantName;
|
||||
private long targets;
|
||||
private long artifacts;
|
||||
private long actions;
|
||||
private long overallArtifactVolumeInBytes;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tenantName
|
||||
*/
|
||||
public TenantUsage(final String tenantName) {
|
||||
super();
|
||||
this.tenantName = tenantName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return name of the tenant
|
||||
*/
|
||||
public String getTenantName() {
|
||||
return tenantName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of targets of the tenant
|
||||
*/
|
||||
public long getTargets() {
|
||||
return targets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param targets
|
||||
* of the tenant
|
||||
* @return updated tenant stats element
|
||||
*/
|
||||
public TenantUsage setTargets(final long targets) {
|
||||
this.targets = targets;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of undeleted artifacts of the tenant
|
||||
*/
|
||||
public long getArtifacts() {
|
||||
return artifacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param artifacts
|
||||
* of tenant
|
||||
* @return updated tenant stats element
|
||||
*/
|
||||
public TenantUsage setArtifacts(final long artifacts) {
|
||||
this.artifacts = artifacts;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current overallArtifactVolumeInBytes
|
||||
*/
|
||||
public long getOverallArtifactVolumeInBytes() {
|
||||
return overallArtifactVolumeInBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param overallArtifactVolumeInBytes
|
||||
* of the tenant in bytes
|
||||
* @return updated tenant stats element
|
||||
*/
|
||||
public TenantUsage setOverallArtifactVolumeInBytes(final long overallArtifactVolumeInBytes) {
|
||||
this.overallArtifactVolumeInBytes = overallArtifactVolumeInBytes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of actions of tenant
|
||||
*/
|
||||
public long getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actions
|
||||
* of the tenant
|
||||
* @return updated tenant stats element
|
||||
*/
|
||||
public TenantUsage setActions(final long actions) {
|
||||
this.actions = actions;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() { // NOSONAR - as this is generated code
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (int) (actions ^ (actions >>> 32));
|
||||
result = prime * result + (int) (artifacts ^ (artifacts >>> 32));
|
||||
result = prime * result + (int) (overallArtifactVolumeInBytes ^ (overallArtifactVolumeInBytes >>> 32));
|
||||
result = prime * result + (int) (targets ^ (targets >>> 32));
|
||||
result = prime * result + ((tenantName == null) ? 0 : tenantName.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) { // NOSONAR - as this is generated
|
||||
// code
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final TenantUsage other = (TenantUsage) obj;
|
||||
if (actions != other.actions) {
|
||||
return false;
|
||||
}
|
||||
if (artifacts != other.artifacts) {
|
||||
return false;
|
||||
}
|
||||
if (overallArtifactVolumeInBytes != other.overallArtifactVolumeInBytes) {
|
||||
return false;
|
||||
}
|
||||
if (targets != other.targets) {
|
||||
return false;
|
||||
}
|
||||
if (tenantName == null) {
|
||||
if (other.tenantName != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!tenantName.equals(other.tenantName)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SystemUsage [tenantName=" + tenantName + ", targets=" + targets + ", artifacts=" + artifacts
|
||||
+ ", actions=" + actions + ", overallArtifactVolumeInBytes=" + overallArtifactVolumeInBytes + "]";
|
||||
}
|
||||
|
||||
}
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionStatusRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionStatusRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/BaseEntityRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/BaseEntityRepository.java
Executable file → Normal file
59
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java
Executable file → Normal file
59
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java
Executable file → Normal file
@@ -11,7 +11,6 @@ package org.eclipse.hawkbit.repository;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
@@ -135,8 +134,8 @@ public class ControllerManagement implements EnvironmentAware {
|
||||
final List<Action> action = actionRepository.findActionByTargetAndSoftwareModule(targetId, module);
|
||||
|
||||
if (action.isEmpty() || action.get(0).isCancelingOrCanceled()) {
|
||||
throw new EntityNotFoundException("No assigment found for module " + module.getId() + " to target "
|
||||
+ targetId);
|
||||
throw new EntityNotFoundException(
|
||||
"No assigment found for module " + module.getId() + " to target " + targetId);
|
||||
}
|
||||
|
||||
return action.get(0);
|
||||
@@ -270,22 +269,20 @@ public class ControllerManagement implements EnvironmentAware {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports an {@link ActionStatus} for a {@link CancelAction}.
|
||||
*
|
||||
* @param actionStatusMessages
|
||||
* Adds an {@link ActionStatus} for a {@link UpdateAction} and cancels the
|
||||
* {@link UpdateAction} if necessary.
|
||||
*
|
||||
* @param actionStatus
|
||||
* to be updated
|
||||
* @param target2
|
||||
*
|
||||
* @throws EntityAlreadyExistsException
|
||||
* if a given entity already exists
|
||||
* @throws ToManyStatusEntriesException
|
||||
* if more than the allowed number of status entries are
|
||||
* inserted
|
||||
* @param action
|
||||
* the status is for
|
||||
* @return the persisted {@link Action}
|
||||
*
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
|
||||
public void addCancelActionStatus(@NotNull final ActionStatus actionStatus, final Action action) {
|
||||
public Action addCancelActionStatus(@NotNull final ActionStatus actionStatus, final Action action) {
|
||||
|
||||
checkForToManyStatusEntries(action);
|
||||
action.setStatus(actionStatus.getStatus());
|
||||
@@ -298,12 +295,9 @@ public class ControllerManagement implements EnvironmentAware {
|
||||
case CANCELED:
|
||||
case FINISHED:
|
||||
// in case of successful cancelation we also report the success at
|
||||
// the canceled action
|
||||
// itself.
|
||||
// the canceled action itself.
|
||||
actionStatus.addMessage("Cancelation completion is finished sucessfully.");
|
||||
// set action inactive
|
||||
action.setActive(false);
|
||||
successCancellation(action);
|
||||
deploymentManagement.successCancellation(action);
|
||||
break;
|
||||
case RETRIEVED:
|
||||
actionStatus.addMessage("Cancelation request retrieved");
|
||||
@@ -312,30 +306,18 @@ public class ControllerManagement implements EnvironmentAware {
|
||||
}
|
||||
actionRepository.save(action);
|
||||
actionStatusRepository.save(actionStatus);
|
||||
}
|
||||
|
||||
private void successCancellation(final Action action) {
|
||||
final Target target = action.getTarget();
|
||||
final List<Action> nextActiveActions = actionRepository.findByTargetAndActiveOrderByIdAsc(target, true)
|
||||
.stream().filter(a -> !a.getId().equals(action.getId())).collect(Collectors.toList());
|
||||
|
||||
if (nextActiveActions.isEmpty()) {
|
||||
target.setAssignedDistributionSet(target.getTargetInfo().getInstalledDistributionSet());
|
||||
deploymentManagement.updateTargetInfo(target, TargetUpdateStatus.IN_SYNC, false);
|
||||
} else {
|
||||
target.setAssignedDistributionSet(nextActiveActions.get(0).getDistributionSet());
|
||||
}
|
||||
targetManagement.updateTarget(target);
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports an {@link ActionStatus} for a {@link UpdateAction}.
|
||||
* Updates an {@link ActionStatus} for a {@link UpdateAction}.
|
||||
*
|
||||
* @param actionStatus
|
||||
* to be updated
|
||||
* @param action
|
||||
* the update is for
|
||||
* @return the persisted {@link ActionStatus}
|
||||
* @return the persisted {@link Action}
|
||||
*
|
||||
* @throws EntityAlreadyExistsException
|
||||
* if a given entity already exists
|
||||
@@ -420,8 +402,8 @@ public class ControllerManagement implements EnvironmentAware {
|
||||
final TargetInfo targetInfo = target.getTargetInfo();
|
||||
final DistributionSet ds = entityManager.merge(action.getDistributionSet());
|
||||
targetInfo.setInstalledDistributionSet(ds);
|
||||
if (target.getAssignedDistributionSet() != null && targetInfo.getInstalledDistributionSet() != null
|
||||
&& target.getAssignedDistributionSet().getId().equals(targetInfo.getInstalledDistributionSet().getId())) {
|
||||
if (target.getAssignedDistributionSet() != null && targetInfo.getInstalledDistributionSet() != null && target
|
||||
.getAssignedDistributionSet().getId().equals(targetInfo.getInstalledDistributionSet().getId())) {
|
||||
targetInfo.setUpdateStatus(TargetUpdateStatus.IN_SYNC);
|
||||
targetInfo.setInstallationDate(System.currentTimeMillis());
|
||||
} else {
|
||||
@@ -461,8 +443,7 @@ public class ControllerManagement implements EnvironmentAware {
|
||||
target.getTargetInfo().getControllerAttributes().putAll(data);
|
||||
|
||||
if (target.getTargetInfo().getControllerAttributes().size() > maxAttributes) {
|
||||
LOG_DOS.info(
|
||||
"Target tries to insert more than the allowed number of entries ({}). DOS attack anticipated!",
|
||||
LOG_DOS.info("Target tries to insert more than the allowed number of entries ({}). DOS attack anticipated!",
|
||||
maxAttributes);
|
||||
throw new ToManyAttributeEntriesException(String.valueOf(maxAttributes));
|
||||
}
|
||||
@@ -474,7 +455,7 @@ public class ControllerManagement implements EnvironmentAware {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.springframework.context.EnvironmentAware#setEnvironment(org.
|
||||
* springframework.core.env. Environment)
|
||||
*/
|
||||
|
||||
236
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java
Executable file → Normal file
236
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java
Executable file → Normal file
@@ -28,10 +28,14 @@ import javax.persistence.criteria.Root;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.Constants;
|
||||
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent;
|
||||
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.event.DeploymentManagementEvents;
|
||||
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
|
||||
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
@@ -65,6 +69,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Business service facade for managing all deployment related data and actions.
|
||||
@@ -105,11 +110,14 @@ public class DeploymentManagement {
|
||||
private AuditorAware<String> auditorProvider;
|
||||
|
||||
@Autowired
|
||||
private DeploymentManagementEvents deploymentManagementEvents;
|
||||
private EventBus eventBus;
|
||||
|
||||
@Autowired
|
||||
private AfterTransactionCommitExecutor afterCommit;
|
||||
|
||||
/**
|
||||
* method assigns the {@link DistributionSet} to all {@link Target}s.
|
||||
*
|
||||
*
|
||||
* @param pset
|
||||
* {@link DistributionSet} which is assigned to the
|
||||
* {@link Target}s
|
||||
@@ -139,7 +147,7 @@ public class DeploymentManagement {
|
||||
/**
|
||||
* method assigns the {@link DistributionSet} to all {@link Target}s by
|
||||
* their IDs.
|
||||
*
|
||||
*
|
||||
* @param dsID
|
||||
* {@link DistributionSet} which is assigned to the
|
||||
* {@link Target}s
|
||||
@@ -168,7 +176,7 @@ public class DeploymentManagement {
|
||||
/**
|
||||
* method assigns the {@link DistributionSet} to all {@link Target}s by
|
||||
* their IDs with a specific {@link ActionType} and {@code forcetime}.
|
||||
*
|
||||
*
|
||||
* @param dsID
|
||||
* the ID of the distribution set to assign
|
||||
* @param actionType
|
||||
@@ -190,14 +198,16 @@ public class DeploymentManagement {
|
||||
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
|
||||
public DistributionSetAssignmentResult assignDistributionSet(@NotNull final Long dsID, final ActionType actionType,
|
||||
final long forcedTimestamp, @NotEmpty final String... targetIDs) {
|
||||
return assignDistributionSet(dsID, Arrays.stream(targetIDs)
|
||||
.map(t -> new TargetWithActionType(t, actionType, forcedTimestamp)).collect(Collectors.toList()));
|
||||
return assignDistributionSet(
|
||||
dsID,
|
||||
Arrays.stream(targetIDs).map(t -> new TargetWithActionType(t, actionType, forcedTimestamp))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* method assigns the {@link DistributionSet} to all {@link Target}s by
|
||||
* their IDs with a specific {@link ActionType} and {@code forcetime}.
|
||||
*
|
||||
*
|
||||
* @param dsID
|
||||
* the ID of the distribution set to assign
|
||||
* @param targets
|
||||
@@ -216,8 +226,8 @@ public class DeploymentManagement {
|
||||
final List<TargetWithActionType> targets) {
|
||||
final DistributionSet set = distributoinSetRepository.findOne(dsID);
|
||||
if (set == null) {
|
||||
throw new EntityNotFoundException(
|
||||
String.format("no %s with id %d found", DistributionSet.class.getSimpleName(), dsID));
|
||||
throw new EntityNotFoundException(String.format("no %s with id %d found",
|
||||
DistributionSet.class.getSimpleName(), dsID));
|
||||
}
|
||||
|
||||
return assignDistributionSetToTargets(set, targets);
|
||||
@@ -226,7 +236,7 @@ public class DeploymentManagement {
|
||||
/**
|
||||
* method assigns the {@link DistributionSet} to all {@link Target}s by
|
||||
* their IDs with a specific {@link ActionType} and {@code forcetime}.
|
||||
*
|
||||
*
|
||||
* @param dsID
|
||||
* the ID of the distribution set to assign
|
||||
* @param targetsWithActionType
|
||||
@@ -241,8 +251,8 @@ public class DeploymentManagement {
|
||||
final List<TargetWithActionType> targetsWithActionType) {
|
||||
|
||||
if (!set.isComplete()) {
|
||||
throw new IncompleteDistributionSetException(
|
||||
"Distribution set of type " + set.getType().getKey() + " is incomplete: " + set.getId());
|
||||
throw new IncompleteDistributionSetException("Distribution set of type " + set.getType().getKey()
|
||||
+ " is incomplete: " + set.getId());
|
||||
}
|
||||
|
||||
final List<String> controllerIDs = targetsWithActionType.stream().map(TargetWithActionType::getTargetId)
|
||||
@@ -250,8 +260,8 @@ public class DeploymentManagement {
|
||||
|
||||
LOG.debug("assignDistribution({}) to {} targets", set, controllerIDs.size());
|
||||
|
||||
final Map<String, TargetWithActionType> targetsWithActionMap = targetsWithActionType.stream()
|
||||
.collect(Collectors.toMap(TargetWithActionType::getTargetId, Function.identity()));
|
||||
final Map<String, TargetWithActionType> targetsWithActionMap = targetsWithActionType.stream().collect(
|
||||
Collectors.toMap(TargetWithActionType::getTargetId, Function.identity()));
|
||||
|
||||
// split tIDs length into max entries in-statement because many database
|
||||
// have constraint of
|
||||
@@ -261,10 +271,12 @@ public class DeploymentManagement {
|
||||
// we take the target only into account if the requested operation is no
|
||||
// duplicate of a
|
||||
// previous one
|
||||
final List<Target> targets = Lists.partition(controllerIDs, Constants.MAX_ENTRIES_IN_STATEMENT).stream()
|
||||
.map(ids -> targetRepository
|
||||
.findAll(TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, set.getId())))
|
||||
.flatMap(t -> t.stream()).collect(Collectors.toList());
|
||||
final List<Target> targets = Lists
|
||||
.partition(controllerIDs, Constants.MAX_ENTRIES_IN_STATEMENT)
|
||||
.stream()
|
||||
.map(ids -> targetRepository.findAll(TargetSpecifications
|
||||
.hasControllerIdAndAssignedDistributionSetIdNot(ids, set.getId()))).flatMap(t -> t.stream())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (targets.isEmpty()) {
|
||||
// detaching as it is not necessary to persist the set itself
|
||||
@@ -327,8 +339,8 @@ public class DeploymentManagement {
|
||||
});
|
||||
|
||||
// select updated targets in order to return them
|
||||
final DistributionSetAssignmentResult result = new DistributionSetAssignmentResult(
|
||||
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList()), targets.size(),
|
||||
final DistributionSetAssignmentResult result = new DistributionSetAssignmentResult(targets.stream()
|
||||
.map(target -> target.getControllerId()).collect(Collectors.toList()), targets.size(),
|
||||
controllerIDs.size() - targets.size(), Lists.newArrayList(targetIdsToActions.values()),
|
||||
targetManagement);
|
||||
|
||||
@@ -340,16 +352,40 @@ public class DeploymentManagement {
|
||||
entityManager.detach(set);
|
||||
|
||||
// send distribution set assignment event
|
||||
targets.stream().filter(t -> !!!targetIdsCancellList.contains(t.getId()))
|
||||
.forEach(t -> deploymentManagementEvents.assignDistributionSet(t,
|
||||
targetIdsToActions.get(t.getControllerId()).getId(), softwareModules));
|
||||
|
||||
targets.stream()
|
||||
.filter(t -> !!!targetIdsCancellList.contains(t.getId()))
|
||||
.forEach(
|
||||
t -> assignDistributionSetEvent(t, targetIdsToActions.get(t.getControllerId()).getId(),
|
||||
softwareModules));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the {@link TargetAssignDistributionSetEvent} for a specific target
|
||||
* to the {@link EventBus}.
|
||||
*
|
||||
* @param target
|
||||
* the Target which has been assigned to a distribution set
|
||||
* @param actionId
|
||||
* the action id of the assignment
|
||||
* @param softwareModules
|
||||
* the software modules which have been assigned
|
||||
*/
|
||||
private void assignDistributionSetEvent(final Target target, final Long actionId,
|
||||
final List<SoftwareModule> softwareModules) {
|
||||
target.getTargetInfo().setUpdateStatus(TargetUpdateStatus.PENDING);
|
||||
afterCommit.afterCommit(() -> {
|
||||
eventBus.post(new TargetInfoUpdateEvent(target.getTargetInfo()));
|
||||
eventBus.post(new TargetAssignDistributionSetEvent(target.getControllerId(), actionId, softwareModules,
|
||||
target.getTargetInfo().getAddress()));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes {@link UpdateAction}s that are no longer necessary and sends
|
||||
* cancelations to the controller.
|
||||
* cancellations to the controller.
|
||||
*
|
||||
* @param myTarget
|
||||
* to override {@link UpdateAction}s
|
||||
@@ -360,18 +396,20 @@ public class DeploymentManagement {
|
||||
|
||||
// Figure out if there are potential target/action combinations that
|
||||
// need to be considered
|
||||
// for cancelation
|
||||
// for cancellation
|
||||
final List<Action> activeActions = actionRepository
|
||||
.findByActiveAndTargetIdInAndActionStatusNotEqualToAndDistributionSetRequiredMigrationStep(targetsIds,
|
||||
Action.Status.CANCELING);
|
||||
activeActions.forEach(action -> {
|
||||
action.setStatus(Status.CANCELING);
|
||||
// document that the status has been retrieved
|
||||
actionStatusRepository.save(new ActionStatus(action, Status.CANCELING, System.currentTimeMillis(),
|
||||
"manual cancelation requested"));
|
||||
deploymentManagementEvents.cancalAssignDistributionSet(action.getTarget(), action.getId());
|
||||
cancelledTargetIds.add(action.getTarget().getId());
|
||||
});
|
||||
actionStatusRepository.save(new ActionStatus(action, Status.CANCELING, System.currentTimeMillis(),
|
||||
"manual cancelation requested"));
|
||||
|
||||
cancelAssignDistributionSetEvent(action.getTarget(), action.getId());
|
||||
|
||||
cancelledTargetIds.add(action.getTarget().getId());
|
||||
});
|
||||
actionRepository.save(activeActions);
|
||||
|
||||
return cancelledTargetIds;
|
||||
@@ -379,8 +417,9 @@ public class DeploymentManagement {
|
||||
|
||||
private DistributionSetAssignmentResult assignDistributionSetByTargetId(@NotNull final DistributionSet set,
|
||||
@NotEmpty final List<String> tIDs, final ActionType actionType, final long forcedTime) {
|
||||
return assignDistributionSetToTargets(set, tIDs.stream()
|
||||
.map(t -> new TargetWithActionType(t, actionType, forcedTime)).collect(Collectors.toList()));
|
||||
return assignDistributionSetToTargets(set,
|
||||
tIDs.stream().map(t -> new TargetWithActionType(t, actionType, forcedTime))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -442,19 +481,77 @@ public class DeploymentManagement {
|
||||
// document that the status has been retrieved
|
||||
actionStatusRepository.save(new ActionStatus(myAction, Status.CANCELING, System.currentTimeMillis(),
|
||||
"manual cancelation requested"));
|
||||
final Action saveAction = actionRepository.save(myAction);
|
||||
|
||||
deploymentManagementEvents.cancalAssignDistributionSet(target, myAction.getId());
|
||||
cancelAssignDistributionSetEvent(target, myAction.getId());
|
||||
|
||||
return actionRepository.save(myAction);
|
||||
return saveAction;
|
||||
} else {
|
||||
throw new CancelActionNotAllowedException(
|
||||
"Action [id: " + action.getId() + "] is not active and cannot be canceled");
|
||||
throw new CancelActionNotAllowedException("Action [id: " + action.getId()
|
||||
+ "] is not active and cannot be canceled");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Action} entity for given actionId.
|
||||
* Sends the {@link CancelTargetAssignmentEvent} for a specific target to
|
||||
* the {@link EventBus}.
|
||||
*
|
||||
* @param target
|
||||
* the Target which has been assigned to a distribution set
|
||||
* @param actionId
|
||||
* the action id of the assignment
|
||||
*/
|
||||
private void cancelAssignDistributionSetEvent(final Target target, final Long actionId) {
|
||||
afterCommit.afterCommit(() -> eventBus.post(new CancelTargetAssignmentEvent(target.getControllerId(), actionId,
|
||||
target.getTargetInfo().getAddress())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Force cancels given {@link Action} for given {@link Target}. Force
|
||||
* canceling means that the action is marked as canceled on the SP server
|
||||
* and a cancel request is sent to the target. But however it's not tracked,
|
||||
* if the targets handles the cancel request or not.
|
||||
*
|
||||
* @param action
|
||||
* to be canceled
|
||||
* @param target
|
||||
* for which the action needs cancellation
|
||||
*
|
||||
* @return generated {@link CancelAction} or <code>null</code> if not in
|
||||
* {@link Target#getActiveActions()}.
|
||||
* @throws CancelActionNotAllowedException
|
||||
* in case the given action is not active
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||
public Action forceQuitAction(@NotNull final Action action, @NotNull final Target target) {
|
||||
final Action mergedAction = entityManager.merge(action);
|
||||
|
||||
if (!mergedAction.isCancelingOrCanceled()) {
|
||||
throw new ForceQuitActionNotAllowedException("Action [id: " + action.getId()
|
||||
+ "] is not canceled yet and cannot be force quit");
|
||||
}
|
||||
|
||||
if (!mergedAction.isActive()) {
|
||||
throw new ForceQuitActionNotAllowedException("Action [id: " + action.getId()
|
||||
+ "] is not active and cannot be force quit");
|
||||
}
|
||||
|
||||
LOG.warn("action ({}) was still activ and has been force quite.", action);
|
||||
|
||||
// document that the status has been retrieved
|
||||
actionStatusRepository.save(new ActionStatus(mergedAction, Status.CANCELED, System.currentTimeMillis(),
|
||||
"A force quit has been performed."));
|
||||
|
||||
successCancellation(mergedAction);
|
||||
|
||||
return actionRepository.save(mergedAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Action} entity for given actionId.
|
||||
*
|
||||
* @param actionId
|
||||
* to be id of the action
|
||||
* @return the corresponding {@link Action}
|
||||
@@ -467,7 +564,7 @@ public class DeploymentManagement {
|
||||
/**
|
||||
* Get the {@link Action} entity for given actionId with all lazy
|
||||
* attributes.
|
||||
*
|
||||
*
|
||||
* @param actionId
|
||||
* to be id of the action
|
||||
* @return the corresponding {@link Action}
|
||||
@@ -493,7 +590,7 @@ public class DeploymentManagement {
|
||||
|
||||
/**
|
||||
* Retrieves all {@link Action}s of a specific target ordered by action ID.
|
||||
*
|
||||
*
|
||||
* @param target
|
||||
* the target associated with the actions
|
||||
* @return a list of actions associated with the given target ordered by
|
||||
@@ -506,7 +603,7 @@ public class DeploymentManagement {
|
||||
|
||||
/**
|
||||
* Retrieves all {@link Action}s of a specific target ordered by action ID.
|
||||
*
|
||||
*
|
||||
* @param target
|
||||
* the target associated with the actions
|
||||
* @return a list of actions associated with the given target ordered by
|
||||
@@ -536,7 +633,7 @@ public class DeploymentManagement {
|
||||
/**
|
||||
* Retrieves all {@link Action}s assigned to a specific {@link Target} and a
|
||||
* given specification.
|
||||
*
|
||||
*
|
||||
* @param specifiction
|
||||
* the specification to narrow down the search
|
||||
* @param target
|
||||
@@ -553,17 +650,21 @@ public class DeploymentManagement {
|
||||
return actionRepository.findAll(new Specification<Action>() {
|
||||
|
||||
@Override
|
||||
public Predicate toPredicate(final Root<Action> root, final CriteriaQuery<?> query,
|
||||
final CriteriaBuilder cb) {
|
||||
public Predicate toPredicate(final Root<Action> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
|
||||
return cb.and(specifiction.toPredicate(root, query, cb), cb.equal(root.get(Action_.target), target));
|
||||
}
|
||||
}, pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param foundTarget
|
||||
* Retrieves all {@link Action}s which are referring the given
|
||||
* {@link Target}.
|
||||
*
|
||||
* @param pageable
|
||||
* @return
|
||||
* page parameters
|
||||
* @param foundTarget
|
||||
* the target to find assigned actions
|
||||
* @return the found {@link Action}s
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
public Slice<Action> findActionsByTarget(final Target foundTarget, final Pageable pageable) {
|
||||
@@ -573,7 +674,7 @@ public class DeploymentManagement {
|
||||
/**
|
||||
* Retrieves all active {@link Action}s of a specific target ordered by
|
||||
* action ID.
|
||||
*
|
||||
*
|
||||
* @param pageable
|
||||
* the pagination parameter
|
||||
* @param target
|
||||
@@ -588,7 +689,7 @@ public class DeploymentManagement {
|
||||
/**
|
||||
* Retrieves all active {@link Action}s of a specific target ordered by
|
||||
* action ID.
|
||||
*
|
||||
*
|
||||
* @param target
|
||||
* the target associated with the actions
|
||||
* @return a list of actions associated with the given target
|
||||
@@ -601,7 +702,7 @@ public class DeploymentManagement {
|
||||
/**
|
||||
* Retrieves all inactive {@link Action}s of a specific target ordered by
|
||||
* action ID.
|
||||
*
|
||||
*
|
||||
* @param target
|
||||
* the target associated with the actions
|
||||
* @return a list of actions associated with the given target
|
||||
@@ -614,7 +715,7 @@ public class DeploymentManagement {
|
||||
/**
|
||||
* Retrieves all inactive {@link Action}s of a specific target ordered by
|
||||
* action ID.
|
||||
*
|
||||
*
|
||||
* @param pageable
|
||||
* the pagination parameter
|
||||
* @param target
|
||||
@@ -628,7 +729,7 @@ public class DeploymentManagement {
|
||||
|
||||
/**
|
||||
* counts all actions associated to a specific target.
|
||||
*
|
||||
*
|
||||
* @param target
|
||||
* the target associated to the actions to count
|
||||
* @return the count value of found actions associated to the target
|
||||
@@ -640,7 +741,7 @@ public class DeploymentManagement {
|
||||
|
||||
/**
|
||||
* counts all actions associated to a specific target.
|
||||
*
|
||||
*
|
||||
* @param spec
|
||||
* the specification to filter the count result
|
||||
* @param target
|
||||
@@ -651,8 +752,7 @@ public class DeploymentManagement {
|
||||
public Long countActionsByTarget(@NotNull final Specification<Action> spec, @NotNull final Target target) {
|
||||
return actionRepository.count(new Specification<Action>() {
|
||||
@Override
|
||||
public Predicate toPredicate(final Root<Action> root, final CriteriaQuery<?> query,
|
||||
final CriteriaBuilder cb) {
|
||||
public Predicate toPredicate(final Root<Action> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
|
||||
return cb.and(spec.toPredicate(root, query, cb), cb.equal(root.get(Action_.target), target));
|
||||
}
|
||||
});
|
||||
@@ -683,7 +783,7 @@ public class DeploymentManagement {
|
||||
/**
|
||||
* retrieves all the {@link ActionStatus} entries of the given
|
||||
* {@link Action} and {@link Target} in the order latest first.
|
||||
*
|
||||
*
|
||||
* @param pageReq
|
||||
* pagination parameter
|
||||
* @param action
|
||||
@@ -703,4 +803,30 @@ public class DeploymentManagement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called, when cancellation has been successful. It sets the
|
||||
* action to canceled, resets the meta data of the target and in case there
|
||||
* is a new action this action is triggered.
|
||||
*
|
||||
* @param action
|
||||
* the action which is set to canceled
|
||||
*/
|
||||
void successCancellation(final Action action) {
|
||||
|
||||
// set action inactive
|
||||
action.setActive(false);
|
||||
action.setStatus(Status.CANCELED);
|
||||
|
||||
final Target target = action.getTarget();
|
||||
final List<Action> nextActiveActions = actionRepository.findByTargetAndActiveOrderByIdAsc(target, true)
|
||||
.stream().filter(a -> !a.getId().equals(action.getId())).collect(Collectors.toList());
|
||||
|
||||
if (nextActiveActions.isEmpty()) {
|
||||
target.setAssignedDistributionSet(target.getTargetInfo().getInstalledDistributionSet());
|
||||
updateTargetInfo(target, TargetUpdateStatus.IN_SYNC, false);
|
||||
} else {
|
||||
target.setAssignedDistributionSet(nextActiveActions.get(0).getDistributionSet());
|
||||
}
|
||||
targetManagement.updateTarget(target);
|
||||
}
|
||||
}
|
||||
|
||||
1
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetAssignmentResult.java
Executable file → Normal file
1
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetAssignmentResult.java
Executable file → Normal file
@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.AssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
|
||||
/**
|
||||
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetFilter.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetFilter.java
Executable file → Normal file
133
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java
Executable file → Normal file
133
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java
Executable file → Normal file
@@ -11,7 +11,9 @@ package org.eclipse.hawkbit.repository;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -26,6 +28,8 @@ import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.eventbus.event.DistributionSetTagAssigmentResultEvent;
|
||||
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetFilter.DistributionSetFilterBuilder;
|
||||
import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMissingMandatoryModuleException;
|
||||
@@ -38,6 +42,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata_;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssigmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTypeElement;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet_;
|
||||
@@ -62,6 +67,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Business facade for managing the {@link DistributionSet}s.
|
||||
@@ -96,6 +102,12 @@ public class DistributionSetManagement {
|
||||
@Autowired
|
||||
private ActionRepository actionRepository;
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
|
||||
@Autowired
|
||||
private AfterTransactionCommitExecutor afterCommit;
|
||||
|
||||
/**
|
||||
* Find {@link DistributionSet} based on given ID including (lazy loaded)
|
||||
* details, e.g. {@link DistributionSet#getAgentHub()}.
|
||||
@@ -183,13 +195,16 @@ public class DistributionSetManagement {
|
||||
allDSs.add(set);
|
||||
}
|
||||
}
|
||||
result = new DistributionSetTagAssigmentResult(dsIds.size() - allDSs.size(), 0, allDSs.size(), null,
|
||||
distributionSetRepository.save(allDSs));
|
||||
result = new DistributionSetTagAssigmentResult(dsIds.size() - allDSs.size(), 0, allDSs.size(),
|
||||
Collections.emptyList(), distributionSetRepository.save(allDSs), myTag);
|
||||
} else {
|
||||
result = new DistributionSetTagAssigmentResult(dsIds.size() - allDSs.size(), allDSs.size(), 0,
|
||||
distributionSetRepository.save(allDSs), null);
|
||||
distributionSetRepository.save(allDSs), Collections.emptyList(), myTag);
|
||||
}
|
||||
|
||||
final DistributionSetTagAssigmentResult resultAssignment = result;
|
||||
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagAssigmentResultEvent(resultAssignment)));
|
||||
|
||||
// no reason to persist the tag
|
||||
entityManager.detach(myTag);
|
||||
return result;
|
||||
@@ -204,8 +219,7 @@ public class DistributionSetManagement {
|
||||
* @return the found {@link DistributionSet}s
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||
public List<DistributionSet> findDistributionSetListWithDetails(
|
||||
@NotEmpty final Collection<Long> distributionIdSet) {
|
||||
public List<DistributionSet> findDistributionSetListWithDetails(@NotEmpty final Collection<Long> distributionIdSet) {
|
||||
return distributionSetRepository.findAll(DistributionSetSpecification.byIds(distributionIdSet));
|
||||
}
|
||||
|
||||
@@ -383,8 +397,7 @@ public class DistributionSetManagement {
|
||||
@Modifying
|
||||
@Transactional
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
||||
public DistributionSet unassignSoftwareModule(@NotNull final DistributionSet ds,
|
||||
final SoftwareModule softwareModule) {
|
||||
public DistributionSet unassignSoftwareModule(@NotNull final DistributionSet ds, final SoftwareModule softwareModule) {
|
||||
final Set<SoftwareModule> softwareModules = new HashSet<SoftwareModule>();
|
||||
softwareModules.add(softwareModule);
|
||||
ds.removeModule(softwareModule);
|
||||
@@ -416,9 +429,9 @@ public class DistributionSetManagement {
|
||||
// throw exception if user tries to update a DS type that is already in
|
||||
// use
|
||||
if (!persisted.areModuleEntriesIdentical(dsType) && distributionSetRepository.countByType(persisted) > 0) {
|
||||
throw new EntityReadOnlyException(
|
||||
String.format("distribution set type %s set is already assigned to targets and cannot be changed",
|
||||
dsType.getName()));
|
||||
throw new EntityReadOnlyException(String.format(
|
||||
"distribution set type %s set is already assigned to targets and cannot be changed",
|
||||
dsType.getName()));
|
||||
}
|
||||
|
||||
return distributionSetTypeRepository.save(dsType);
|
||||
@@ -584,16 +597,14 @@ public class DistributionSetManagement {
|
||||
|
||||
final DistributionSetFilter filterWithInstalledTargets = distributionSetFilterBuilder
|
||||
.setInstalledTargetId(assignedOrInstalled).setAssignedTargetId(null).build();
|
||||
final DistributionSet installedDS = findDistributionSetsByFiltersAndInstalledOrAssignedTarget(
|
||||
filterWithInstalledTargets);
|
||||
final DistributionSet installedDS = findDistributionSetsByFiltersAndInstalledOrAssignedTarget(filterWithInstalledTargets);
|
||||
|
||||
final DistributionSetFilter filterWithAssignedTargets = distributionSetFilterBuilder.setInstalledTargetId(null)
|
||||
.setAssignedTargetId(assignedOrInstalled).build();
|
||||
final DistributionSet assignedDS = findDistributionSetsByFiltersAndInstalledOrAssignedTarget(
|
||||
filterWithAssignedTargets);
|
||||
final DistributionSet assignedDS = findDistributionSetsByFiltersAndInstalledOrAssignedTarget(filterWithAssignedTargets);
|
||||
|
||||
final DistributionSetFilter dsFilterWithNoTargetLinked = distributionSetFilterBuilder.setInstalledTargetId(null)
|
||||
.setAssignedTargetId(null).build();
|
||||
final DistributionSetFilter dsFilterWithNoTargetLinked = distributionSetFilterBuilder
|
||||
.setInstalledTargetId(null).setAssignedTargetId(null).build();
|
||||
// first fine the distribution sets filtered by the given filter
|
||||
// parameters
|
||||
final Page<DistributionSet> findDistributionSetsByFilters = findDistributionSetsByFilters(pageable,
|
||||
@@ -643,8 +654,8 @@ public class DistributionSetManagement {
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||
public DistributionSet findDistributionSetByNameAndVersion(@NotEmpty final String distributionName,
|
||||
@NotEmpty final String version) {
|
||||
final Specification<DistributionSet> spec = DistributionSetSpecification
|
||||
.equalsNameAndVersionIgnoreCase(distributionName, version);
|
||||
final Specification<DistributionSet> spec = DistributionSetSpecification.equalsNameAndVersionIgnoreCase(
|
||||
distributionName, version);
|
||||
return distributionSetRepository.findOne(spec);
|
||||
|
||||
}
|
||||
@@ -998,17 +1009,17 @@ public class DistributionSetManagement {
|
||||
final Set<SoftwareModule> softwareModules) {
|
||||
if (!new HashSet<SoftwareModule>(distributionSet.getModules()).equals(softwareModules)
|
||||
&& actionRepository.countByDistributionSet(distributionSet) > 0) {
|
||||
throw new EntityLockedException(
|
||||
String.format("distribution set %s:%s is already assigned to targets and cannot be changed",
|
||||
distributionSet.getName(), distributionSet.getVersion()));
|
||||
throw new EntityLockedException(String.format(
|
||||
"distribution set %s:%s is already assigned to targets and cannot be changed",
|
||||
distributionSet.getName(), distributionSet.getVersion()));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkDistributionSetSoftwareModulesIsAllowedToModify(final DistributionSet distributionSet) {
|
||||
if (actionRepository.countByDistributionSet(distributionSet) > 0) {
|
||||
throw new EntityLockedException(
|
||||
String.format("distribution set %s:%s is already assigned to targets and cannot be changed",
|
||||
distributionSet.getName(), distributionSet.getVersion()));
|
||||
throw new EntityLockedException(String.format(
|
||||
"distribution set %s:%s is already assigned to targets and cannot be changed",
|
||||
distributionSet.getName(), distributionSet.getVersion()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1057,8 +1068,8 @@ public class DistributionSetManagement {
|
||||
|
||||
private void checkAndThrowAlreadyIfDistributionSetMetadataExists(final DsMetadataCompositeKey metadataId) {
|
||||
if (distributionSetMetadataRepository.exists(metadataId)) {
|
||||
throw new EntityAlreadyExistsException(
|
||||
"Metadata entry with key '" + metadataId.getKey() + "' already exists");
|
||||
throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataId.getKey()
|
||||
+ "' already exists");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1066,4 +1077,74 @@ public class DistributionSetManagement {
|
||||
throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists");
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a {@link DistributionSetTag} assignment to given
|
||||
* {@link DistributionSet}s.
|
||||
*
|
||||
* @param dsIds
|
||||
* to assign for
|
||||
* @param tag
|
||||
* to assign
|
||||
* @return list of assigned ds
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@NotNull
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||
public List<DistributionSet> assignTag(@NotEmpty final Collection<Long> dsIds, @NotNull final DistributionSetTag tag) {
|
||||
final List<DistributionSet> allDs = findDistributionSetListWithDetails(dsIds);
|
||||
|
||||
allDs.forEach(ds -> ds.getTags().add(tag));
|
||||
final List<DistributionSet> save = distributionSetRepository.save(allDs);
|
||||
|
||||
afterCommit.afterCommit(() -> {
|
||||
|
||||
final DistributionSetTagAssigmentResult result = new DistributionSetTagAssigmentResult(0, save.size(), 0,
|
||||
save, Collections.emptyList(), tag);
|
||||
eventBus.post(new DistributionSetTagAssigmentResultEvent(result));
|
||||
});
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign all {@link DistributionSet} from a given
|
||||
* {@link DistributionSetTag} .
|
||||
*
|
||||
* @param tag
|
||||
* to unassign all ds
|
||||
* @return list of unassigned ds
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@NotNull
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||
public List<DistributionSet> unAssignAllDistributionSetsByTag(@NotNull final DistributionSetTag tag) {
|
||||
return unAssignTag(tag.getAssignedToDistributionSet(), tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign a {@link DistributionSetTag} assignment to given
|
||||
* {@link DistributionSet}.
|
||||
*
|
||||
* @param dsId
|
||||
* to unassign for
|
||||
* @param distributionSetTag
|
||||
* to unassign
|
||||
* @return the unassigned ds or <null> if no ds is unassigned
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||
public DistributionSet unAssignTag(@NotNull final Long dsId, @NotNull final DistributionSetTag distributionSetTag) {
|
||||
final List<DistributionSet> allDs = findDistributionSetListWithDetails(Arrays.asList(dsId));
|
||||
final List<DistributionSet> unAssignTag = unAssignTag(allDs, distributionSetTag);
|
||||
return unAssignTag.isEmpty() ? null : unAssignTag.get(0);
|
||||
}
|
||||
|
||||
private List<DistributionSet> unAssignTag(final Collection<DistributionSet> distributionSets,
|
||||
final DistributionSetTag tag) {
|
||||
distributionSets.forEach(ds -> ds.getTags().remove(tag));
|
||||
return distributionSetRepository.save(distributionSets);
|
||||
}
|
||||
}
|
||||
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetMetadataRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetMetadataRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetRepository.java
Executable file → Normal file
7
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagRepository.java
Executable file → Normal file
7
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagRepository.java
Executable file → Normal file
@@ -13,6 +13,7 @@ import java.util.List;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -23,7 +24,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
*
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public interface DistributionSetTagRepository extends BaseEntityRepository<DistributionSetTag, Long> {
|
||||
public interface DistributionSetTagRepository extends BaseEntityRepository<DistributionSetTag, Long>,
|
||||
JpaSpecificationExecutor<DistributionSetTag> {
|
||||
/**
|
||||
* deletes the {@link DistributionSet} with the given name.
|
||||
*
|
||||
@@ -51,4 +53,7 @@ public interface DistributionSetTagRepository extends BaseEntityRepository<Distr
|
||||
*/
|
||||
@Override
|
||||
List<DistributionSetTag> findAll();
|
||||
|
||||
@Override
|
||||
<S extends DistributionSetTag> List<S> save(Iterable<S> entities);
|
||||
}
|
||||
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/EclipseLinkTargetInfoRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/EclipseLinkTargetInfoRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactProviderRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactProviderRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactRepository.java
Executable file → Normal file
24
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/LocalArtifactRepository.java
Executable file → Normal file
24
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/LocalArtifactRepository.java
Executable file → Normal file
@@ -9,20 +9,40 @@
|
||||
package org.eclipse.hawkbit.repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* {@link LocalArtifact} repository.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public interface LocalArtifactRepository extends BaseEntityRepository<LocalArtifact, Long> {
|
||||
|
||||
/**
|
||||
* Counts artifacts size where the related software module is not
|
||||
* deleted/archived.
|
||||
*
|
||||
* @return sum of artifacts size in bytes
|
||||
*/
|
||||
@Query("SELECT SUM(la.size) FROM LocalArtifact la WHERE la.softwareModule.deleted = 0")
|
||||
Optional<Long> getSumOfUndeletedArtifactSize();
|
||||
|
||||
/**
|
||||
* Counts artifacts where the related software module is deleted/archived.
|
||||
*
|
||||
* @param deleted
|
||||
* to true for counting the deleted artifacts
|
||||
*
|
||||
* @return number of artifacts
|
||||
*/
|
||||
Long countBySoftwareModuleDeleted(boolean deleted);
|
||||
|
||||
/**
|
||||
* Searches for a {@link LocalArtifact} based on given gridFsFileName.
|
||||
*
|
||||
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/NoCountPagingRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/NoCountPagingRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ReportManagement.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ReportManagement.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleMetadataRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleMetadataRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeRepository.java
Executable file → Normal file
113
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java
Executable file → Normal file
113
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java
Executable file → Normal file
@@ -9,6 +9,7 @@
|
||||
package org.eclipse.hawkbit.repository;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -17,13 +18,13 @@ import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.cache.TenancyCacheManager;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.report.model.SystemUsageReport;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
|
||||
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware.TenantRunner;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||
import org.eclipse.persistence.config.PersistenceUnitProperties;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -48,9 +49,6 @@ import org.springframework.validation.annotation.Validated;
|
||||
/**
|
||||
* Central system management operations of the SP server.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
@Validated
|
||||
@@ -101,6 +99,9 @@ public class SystemManagement implements EnvironmentAware {
|
||||
@Autowired
|
||||
private TenantAware tenantAware;
|
||||
|
||||
@Autowired
|
||||
private TenantStatsManagement systemStatsManagement;
|
||||
|
||||
@Autowired
|
||||
private TenancyCacheManager cacheManager;
|
||||
|
||||
@@ -110,12 +111,61 @@ public class SystemManagement implements EnvironmentAware {
|
||||
|
||||
private Environment environment;
|
||||
|
||||
/**
|
||||
* Calculated system usage statistics, both overall for the entire system
|
||||
* and per tenant;
|
||||
*
|
||||
* @return SystemUsageReport of the current system
|
||||
*/
|
||||
@NotNull
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN)
|
||||
public SystemUsageReport getSystemUsageStatistics() {
|
||||
|
||||
BigDecimal sumOfArtifacts = (BigDecimal) entityManager
|
||||
.createNativeQuery(
|
||||
"select SUM(file_size) from sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = 0")
|
||||
.getSingleResult();
|
||||
|
||||
if (sumOfArtifacts == null) {
|
||||
sumOfArtifacts = new BigDecimal(0);
|
||||
}
|
||||
|
||||
// we use native queries to punch through the tenant boundaries. This
|
||||
// has to be used with care!
|
||||
final Long targets = (Long) entityManager.createNativeQuery("SELECT COUNT(id) FROM sp_target")
|
||||
.getSingleResult();
|
||||
|
||||
final Long artifacts = (Long) entityManager
|
||||
.createNativeQuery(
|
||||
"SELECT COUNT(a.id) FROM sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = 0")
|
||||
.getSingleResult();
|
||||
|
||||
final Long actions = (Long) entityManager.createNativeQuery("SELECT COUNT(id) FROM sp_action")
|
||||
.getSingleResult();
|
||||
|
||||
final SystemUsageReport result = new SystemUsageReport(targets, artifacts, actions,
|
||||
sumOfArtifacts.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
|
||||
|
||||
usageStatsPerTenant(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void usageStatsPerTenant(final SystemUsageReport report) {
|
||||
final List<String> tenants = findTenants();
|
||||
|
||||
tenants.forEach(tenant -> tenantAware.runAsTenant(tenant, () -> {
|
||||
report.addTenantData(systemStatsManagement.getStatsOfTenant(tenant));
|
||||
return null;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the key generator for the {@link #currentTenant()} method
|
||||
* because this key generator is aware of the {@link #createInitialTenant}
|
||||
* thread local in case we are currently creating a tenant and insert the
|
||||
* default distribution set types.
|
||||
*
|
||||
*
|
||||
* @return the {@link CurrentTenantKeyGenerator}
|
||||
*/
|
||||
@Bean
|
||||
@@ -127,8 +177,8 @@ public class SystemManagement implements EnvironmentAware {
|
||||
* Returns {@link TenantMetaData} of given and current tenant.
|
||||
*
|
||||
* DISCLAIMER: this variant is used during initial login (where the tenant
|
||||
* is not yet in teh session). Please user {@link #getTenantMetadata()} for
|
||||
* reluar requests.
|
||||
* is not yet in the session). Please user {@link #getTenantMetadata()} for
|
||||
* regular requests.
|
||||
*
|
||||
* @param tenant
|
||||
* @return
|
||||
@@ -179,25 +229,22 @@ public class SystemManagement implements EnvironmentAware {
|
||||
public void deleteTenant(@NotNull final String tenant) {
|
||||
cacheManager.evictCaches(tenant);
|
||||
cacheManager.getCache("currentTenant").evict(currentTenantKeyGenerator().generate(null, null));
|
||||
tenantAware.runAsTenant(tenant, new TenantRunner<Void>() {
|
||||
@Override
|
||||
public Void run() {
|
||||
entityManager.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, tenant.toUpperCase());
|
||||
tenantMetaDataRepository.deleteByTenantIgnoreCase(tenant);
|
||||
tenantConfigurationRepository.deleteByTenantIgnoreCase(tenant);
|
||||
targetRepository.deleteByTenantIgnoreCase(tenant);
|
||||
artifactRepository.deleteByTenantIgnoreCase(tenant);
|
||||
externalArtifactRepository.deleteByTenantIgnoreCase(tenant);
|
||||
externalArtifactProviderRepository.deleteByTenantIgnoreCase(tenant);
|
||||
targetTagRepository.deleteByTenantIgnoreCase(tenant);
|
||||
actionRepository.deleteByTenantIgnoreCase(tenant);
|
||||
distributionSetTagRepository.deleteByTenantIgnoreCase(tenant);
|
||||
distributionSetRepository.deleteByTenantIgnoreCase(tenant);
|
||||
distributionSetTypeRepository.deleteByTenantIgnoreCase(tenant);
|
||||
softwareModuleRepository.deleteByTenantIgnoreCase(tenant);
|
||||
softwareModuleTypeRepository.deleteByTenantIgnoreCase(tenant);
|
||||
return null;
|
||||
}
|
||||
tenantAware.runAsTenant(tenant, () -> {
|
||||
entityManager.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, tenant.toUpperCase());
|
||||
tenantMetaDataRepository.deleteByTenantIgnoreCase(tenant);
|
||||
tenantConfigurationRepository.deleteByTenantIgnoreCase(tenant);
|
||||
targetRepository.deleteByTenantIgnoreCase(tenant);
|
||||
artifactRepository.deleteByTenantIgnoreCase(tenant);
|
||||
externalArtifactRepository.deleteByTenantIgnoreCase(tenant);
|
||||
externalArtifactProviderRepository.deleteByTenantIgnoreCase(tenant);
|
||||
targetTagRepository.deleteByTenantIgnoreCase(tenant);
|
||||
actionRepository.deleteByTenantIgnoreCase(tenant);
|
||||
distributionSetTagRepository.deleteByTenantIgnoreCase(tenant);
|
||||
distributionSetRepository.deleteByTenantIgnoreCase(tenant);
|
||||
distributionSetTypeRepository.deleteByTenantIgnoreCase(tenant);
|
||||
softwareModuleRepository.deleteByTenantIgnoreCase(tenant);
|
||||
softwareModuleTypeRepository.deleteByTenantIgnoreCase(tenant);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -218,7 +265,7 @@ public class SystemManagement implements EnvironmentAware {
|
||||
|
||||
/**
|
||||
* Checks if a specific tenant exists. The tenant will not be created lazy.
|
||||
*
|
||||
*
|
||||
* @param tenant
|
||||
* the tenant to check
|
||||
* @return {@code true} in case the tenant exits or {@code false} if not
|
||||
@@ -268,7 +315,7 @@ public class SystemManagement implements EnvironmentAware {
|
||||
* Retrieves a configuration value from the e.g. tenant overwritten
|
||||
* configuration values or in case the tenant does not a have a specific
|
||||
* configuration the global default value hold in the {@link Environment}.
|
||||
*
|
||||
*
|
||||
* @param configurationKey
|
||||
* the key of the configuration
|
||||
* @param propertyType
|
||||
@@ -298,7 +345,7 @@ public class SystemManagement implements EnvironmentAware {
|
||||
|
||||
/**
|
||||
* Adds or updates a specific configuration for a specific tenant.
|
||||
*
|
||||
*
|
||||
* @param tenantConf
|
||||
* the tenant configuration object which contains the key and
|
||||
* value of the specific configuration to update
|
||||
@@ -319,7 +366,7 @@ public class SystemManagement implements EnvironmentAware {
|
||||
|
||||
/**
|
||||
* Deletes a specific configuration for the current tenant.
|
||||
*
|
||||
*
|
||||
* @param configurationKey
|
||||
* the configuration key to be deleted
|
||||
*/
|
||||
@@ -337,7 +384,7 @@ public class SystemManagement implements EnvironmentAware {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.springframework.context.EnvironmentAware#setEnvironment(org.
|
||||
* springframework.core.env. Environment)
|
||||
*/
|
||||
@@ -379,7 +426,7 @@ public class SystemManagement implements EnvironmentAware {
|
||||
* {@link TenantAware}, but in case we are in a tenant creation with its
|
||||
* default types we need to use the tenant the current tenant which is
|
||||
* currently created and not the one currently in the {@link TenantAware}.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@@ -387,7 +434,7 @@ public class SystemManagement implements EnvironmentAware {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* org.springframework.cache.interceptor.KeyGenerator#generate(java.lang
|
||||
* .Object, java.lang.reflect.Method, java.lang.Object[])
|
||||
|
||||
108
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TagManagement.java
Executable file → Normal file
108
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TagManagement.java
Executable file → Normal file
@@ -15,6 +15,13 @@ import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.eventbus.event.DistributionSetTagCreatedBulkEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.DistributionSetTagDeletedEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.DistributionSetTagUpdateEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetTagCreatedBulkEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetTagDeletedEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetTagUpdateEvent;
|
||||
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
@@ -22,16 +29,20 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.Tag;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
*
|
||||
* Mangement service class for {@link Tag}s.
|
||||
@@ -58,6 +69,15 @@ public class TagManagement {
|
||||
@Autowired
|
||||
private DistributionSetRepository distributionSetRepository;
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
|
||||
@Autowired
|
||||
private TenantAware tenantAware;
|
||||
|
||||
@Autowired
|
||||
private AfterTransactionCommitExecutor afterCommit;
|
||||
|
||||
/**
|
||||
* Find {@link TargetTag} based on given Name.
|
||||
*
|
||||
@@ -94,7 +114,12 @@ public class TagManagement {
|
||||
throw new EntityAlreadyExistsException();
|
||||
}
|
||||
|
||||
return targetTagRepository.save(targetTag);
|
||||
final TargetTag save = targetTagRepository.save(targetTag);
|
||||
|
||||
afterCommit
|
||||
.afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,8 +142,10 @@ public class TagManagement {
|
||||
throw new EntityAlreadyExistsException();
|
||||
}
|
||||
});
|
||||
|
||||
return targetTagRepository.save(targetTags);
|
||||
final List<TargetTag> save = targetTagRepository.save(targetTags);
|
||||
afterCommit
|
||||
.afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
|
||||
return save;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,6 +171,9 @@ public class TagManagement {
|
||||
|
||||
// finally delete the tag itself
|
||||
targetTagRepository.deleteByName(targetTagName);
|
||||
|
||||
afterCommit.afterCommit(() -> eventBus.post(new TargetTagDeletedEvent(tag)));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,6 +187,31 @@ public class TagManagement {
|
||||
return targetTagRepository.findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all target tags based on the given specification.
|
||||
*
|
||||
* @param spec
|
||||
* the specification for the query
|
||||
* @param pageable
|
||||
* pagination parameter
|
||||
* @return the found {@link Target}s, never {@code null}
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
public Page<TargetTag> findAllTargetTags(@NotNull final Specification<TargetTag> spec,
|
||||
@NotNull final Pageable pageable) {
|
||||
return targetTagRepository.findAll(spec, pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* count {@link TargetTag}s.
|
||||
*
|
||||
* @return size of {@link TargetTag}s
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
public long countTargetTags() {
|
||||
return targetTagRepository.count();
|
||||
}
|
||||
|
||||
/**
|
||||
* updates the {@link TargetTag}.
|
||||
*
|
||||
@@ -171,7 +226,9 @@ public class TagManagement {
|
||||
public TargetTag updateTargetTag(@NotNull final TargetTag targetTag) {
|
||||
checkNotNull(targetTag.getName());
|
||||
checkNotNull(targetTag.getId());
|
||||
return targetTagRepository.save(targetTag);
|
||||
final TargetTag save = targetTagRepository.save(targetTag);
|
||||
afterCommit.afterCommit(() -> eventBus.post(new TargetTagUpdateEvent(save)));
|
||||
return save;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,7 +265,11 @@ public class TagManagement {
|
||||
throw new EntityAlreadyExistsException();
|
||||
}
|
||||
|
||||
return distributionSetTagRepository.save(distributionSetTag);
|
||||
final DistributionSetTag save = distributionSetTagRepository.save(distributionSetTag);
|
||||
|
||||
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware
|
||||
.getCurrentTenant(), save)));
|
||||
return save;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,15 +284,18 @@ public class TagManagement {
|
||||
@Modifying
|
||||
@Transactional
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY)
|
||||
public Iterable<DistributionSetTag> createDistributionSetTags(
|
||||
public List<DistributionSetTag> createDistributionSetTags(
|
||||
@NotNull final Iterable<DistributionSetTag> distributionSetTags) {
|
||||
for (final DistributionSetTag dsTag : distributionSetTags) {
|
||||
if (dsTag.getId() != null) {
|
||||
throw new EntityAlreadyExistsException();
|
||||
}
|
||||
}
|
||||
final List<DistributionSetTag> save = distributionSetTagRepository.save(distributionSetTags);
|
||||
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware
|
||||
.getCurrentTenant(), save)));
|
||||
|
||||
return distributionSetTagRepository.save(distributionSetTags);
|
||||
return save;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,6 +321,8 @@ public class TagManagement {
|
||||
distributionSetRepository.save(changed);
|
||||
|
||||
distributionSetTagRepository.deleteByName(tagName);
|
||||
|
||||
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagDeletedEvent(tag)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,7 +341,10 @@ public class TagManagement {
|
||||
public DistributionSetTag updateDistributionSetTag(@NotNull final DistributionSetTag distributionSetTag) {
|
||||
checkNotNull(distributionSetTag.getName());
|
||||
checkNotNull(distributionSetTag.getId());
|
||||
return distributionSetTagRepository.save(distributionSetTag);
|
||||
final DistributionSetTag save = distributionSetTagRepository.save(distributionSetTag);
|
||||
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagUpdateEvent(save)));
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -284,7 +353,7 @@ public class TagManagement {
|
||||
* @return all {@link DistributionTag}s
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||
public List<DistributionSetTag> findDistributionSetTagsAll() {
|
||||
public List<DistributionSetTag> findAllDistributionSetTags() {
|
||||
return distributionSetTagRepository.findAll();
|
||||
}
|
||||
|
||||
@@ -328,16 +397,31 @@ public class TagManagement {
|
||||
}
|
||||
|
||||
/**
|
||||
* returns all {@link TargetTag}s.
|
||||
* returns all {@link DistributionSetTag}s.
|
||||
*
|
||||
* @param pageReq
|
||||
* page parameter
|
||||
* @return all {@link TargetTag}s
|
||||
* @return all {@link DistributionSetTag}s
|
||||
*/
|
||||
@NotNull
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||
public Page<DistributionSetTag> findDistributionSetTagsAll(@NotNull final Pageable pageReq) {
|
||||
public Page<DistributionSetTag> findAllDistributionSetTags(@NotNull final Pageable pageReq) {
|
||||
return distributionSetTagRepository.findAll(pageReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all DistributionSet tags based on the given specification.
|
||||
*
|
||||
* @param spec
|
||||
* the specification for the query
|
||||
* @param pageable
|
||||
* pagination parameter
|
||||
* @return the found {@link DistributionSetTag}s, never {@code null}
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
public Page<DistributionSetTag> findAllDistributionSetTags(@NotNull final Specification<DistributionSetTag> spec,
|
||||
@NotNull final Pageable pageable) {
|
||||
return distributionSetTagRepository.findAll(spec, pageable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagement.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagement.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetInfoRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetInfoRepository.java
Executable file → Normal file
289
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java
Executable file → Normal file
289
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java
Executable file → Normal file
@@ -10,7 +10,9 @@ package org.eclipse.hawkbit.repository;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -28,6 +30,8 @@ import javax.persistence.criteria.Root;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.Constants;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetTagAssigmentResultEvent;
|
||||
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
@@ -39,6 +43,7 @@ import org.eclipse.hawkbit.repository.model.TargetIdName;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo_;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTagAssigmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Target_;
|
||||
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
|
||||
@@ -86,9 +91,6 @@ public class TargetManagement {
|
||||
@Autowired
|
||||
private TargetTagRepository targetTagRepository;
|
||||
|
||||
@Autowired
|
||||
private TargetFilterQueryRepository targetFilterQueryRepository;
|
||||
|
||||
@Autowired
|
||||
private TargetInfoRepository targetInfoRepository;
|
||||
|
||||
@@ -98,6 +100,9 @@ public class TargetManagement {
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
|
||||
@Autowired
|
||||
private AfterTransactionCommitExecutor afterCommit;
|
||||
|
||||
/**
|
||||
* Find {@link Target} based on given ID returns found Target without
|
||||
* details, i.e. NO {@link Target#getTags()} and
|
||||
@@ -179,14 +184,11 @@ public class TargetManagement {
|
||||
// workarround - no join fetch allowed that is why we need specification
|
||||
// instead of query for
|
||||
// count() of Pageable
|
||||
final Specification<Target> spec = new Specification<Target>() {
|
||||
@Override
|
||||
public Predicate toPredicate(final Root<Target> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
|
||||
if (!query.getResultType().isAssignableFrom(Long.class)) {
|
||||
root.fetch(Target_.targetInfo);
|
||||
}
|
||||
return cb.conjunction();
|
||||
final Specification<Target> spec = (root, query, cb) -> {
|
||||
if (!query.getResultType().isAssignableFrom(Long.class)) {
|
||||
root.fetch(Target_.targetInfo);
|
||||
}
|
||||
return cb.conjunction();
|
||||
};
|
||||
return criteriaNoCountDao.findAll(spec, pageable, Target.class);
|
||||
}
|
||||
@@ -223,7 +225,7 @@ public class TargetManagement {
|
||||
|
||||
/**
|
||||
* Retrieves all targets based on the given specification.
|
||||
*
|
||||
*
|
||||
* @param spec
|
||||
* the specification for the query
|
||||
* @param pageable
|
||||
@@ -256,7 +258,7 @@ public class TargetManagement {
|
||||
|
||||
/**
|
||||
* updates the {@link Target}.
|
||||
*
|
||||
*
|
||||
* @param target
|
||||
* to be updated
|
||||
* @return the updated {@link Target}
|
||||
@@ -274,7 +276,7 @@ public class TargetManagement {
|
||||
|
||||
/**
|
||||
* updates multiple {@link Target}s.
|
||||
*
|
||||
*
|
||||
* @param targets
|
||||
* to be updated
|
||||
* @return the updated {@link Target}s
|
||||
@@ -291,7 +293,7 @@ public class TargetManagement {
|
||||
|
||||
/**
|
||||
* Deletes all targets with the given IDs.
|
||||
*
|
||||
*
|
||||
* @param targetIDs
|
||||
* the technical IDs of the targets to be deleted
|
||||
*/
|
||||
@@ -336,7 +338,7 @@ public class TargetManagement {
|
||||
* details, i.e. NO {@link Target#getTags()} and
|
||||
* {@link Target#getActiveActions()} possible including the filtering based
|
||||
* on the given {@code spec}.
|
||||
*
|
||||
*
|
||||
* @param distributionSetID
|
||||
* the ID of the {@link DistributionSet}
|
||||
* @param spec
|
||||
@@ -349,14 +351,9 @@ public class TargetManagement {
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
|
||||
public Page<Target> findTargetByAssignedDistributionSet(@NotNull final Long distributionSetID,
|
||||
final Specification<Target> spec, @NotNull final Pageable pageReq) {
|
||||
return targetRepository.findAll(new Specification<Target>() {
|
||||
@Override
|
||||
public Predicate toPredicate(final Root<Target> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
|
||||
return cb
|
||||
.and(TargetSpecifications.hasAssignedDistributionSet(distributionSetID).toPredicate(root,
|
||||
query, cb), spec.toPredicate(root, query, cb));
|
||||
}
|
||||
}, pageReq);
|
||||
return targetRepository.findAll((Specification<Target>) (root, query, cb) -> cb.and(
|
||||
TargetSpecifications.hasAssignedDistributionSet(distributionSetID).toPredicate(root, query, cb),
|
||||
spec.toPredicate(root, query, cb)), pageReq);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -393,14 +390,9 @@ public class TargetManagement {
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
|
||||
public Page<Target> findTargetByInstalledDistributionSet(final Long distributionSetId,
|
||||
final Specification<Target> spec, final Pageable pageable) {
|
||||
return targetRepository.findAll(new Specification<Target>() {
|
||||
@Override
|
||||
public Predicate toPredicate(final Root<Target> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
|
||||
return cb.and(
|
||||
TargetSpecifications.hasInstalledDistributionSet(distributionSetId)
|
||||
.toPredicate(root, query, cb), spec.toPredicate(root, query, cb));
|
||||
}
|
||||
}, pageable);
|
||||
return targetRepository.findAll((Specification<Target>) (root, query, cb) -> cb.and(
|
||||
TargetSpecifications.hasInstalledDistributionSet(distributionSetId).toPredicate(root, query, cb),
|
||||
spec.toPredicate(root, query, cb)), pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -487,16 +479,16 @@ public class TargetManagement {
|
||||
return countByCriteriaAPI(specList);
|
||||
}
|
||||
|
||||
private List<Specification<Target>> buildSpecificationList(final Collection<TargetUpdateStatus> status,
|
||||
private static List<Specification<Target>> buildSpecificationList(final Collection<TargetUpdateStatus> status,
|
||||
final String searchText, final Long installedOrAssignedDistributionSetId,
|
||||
final Boolean selectTargetWithNoTag, final boolean fetch, final String... tagNames) {
|
||||
final List<Specification<Target>> specList = new ArrayList<Specification<Target>>();
|
||||
final List<Specification<Target>> specList = new ArrayList<>();
|
||||
if (status != null && !status.isEmpty()) {
|
||||
specList.add(TargetSpecifications.hasTargetUpdateStatus(status, fetch));
|
||||
}
|
||||
if (installedOrAssignedDistributionSetId != null) {
|
||||
specList.add(TargetSpecifications
|
||||
.hasInstalledOrAssignedDistributionSet(installedOrAssignedDistributionSetId));
|
||||
specList.add(
|
||||
TargetSpecifications.hasInstalledOrAssignedDistributionSet(installedOrAssignedDistributionSetId));
|
||||
}
|
||||
if (!Strings.isNullOrEmpty(searchText)) {
|
||||
specList.add(TargetSpecifications.likeNameOrDescriptionOrIp(searchText));
|
||||
@@ -509,7 +501,7 @@ public class TargetManagement {
|
||||
|
||||
/**
|
||||
* executes findAll with the given {@link Target} {@link Specification}s.
|
||||
*
|
||||
*
|
||||
* @param pageable
|
||||
* paging parameter
|
||||
* @param specList
|
||||
@@ -538,7 +530,7 @@ public class TargetManagement {
|
||||
|
||||
}
|
||||
|
||||
private Specifications<Target> creatingTargetSpecifications(final List<Specification<Target>> specList) {
|
||||
private static Specifications<Target> creatingTargetSpecifications(final List<Specification<Target>> specList) {
|
||||
Specifications<Target> specs = null;
|
||||
if (!specList.isEmpty()) {
|
||||
specs = Specifications.where(specList.get(0));
|
||||
@@ -568,8 +560,8 @@ public class TargetManagement {
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||
public TargetTagAssigmentResult toggleTagAssignment(@NotEmpty final List<Target> targets,
|
||||
@NotNull final TargetTag tag) {
|
||||
return toggleTagAssignment(targets.stream().map(target -> target.getControllerId())
|
||||
.collect(Collectors.toList()), tag.getName());
|
||||
return toggleTagAssignment(
|
||||
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList()), tag.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -592,25 +584,107 @@ public class TargetManagement {
|
||||
@NotNull final String tagName) {
|
||||
final TargetTag tag = targetTagRepository.findByNameEquals(tagName);
|
||||
final List<Target> alreadyAssignedTargets = targetRepository.findByTagNameAndControllerIdIn(tagName, targetIds);
|
||||
final List<Target> allTargets = targetRepository.findAll(TargetSpecifications
|
||||
.byControllerIdWithStatusAndTagsInJoin(targetIds));
|
||||
final List<Target> allTargets = targetRepository
|
||||
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds));
|
||||
|
||||
// all are already assigned -> unassign
|
||||
if (alreadyAssignedTargets.size() == allTargets.size()) {
|
||||
alreadyAssignedTargets.forEach(target -> target.getTags().remove(tag));
|
||||
return new TargetTagAssigmentResult(0, 0, alreadyAssignedTargets.size(), null, alreadyAssignedTargets);
|
||||
final TargetTagAssigmentResult result = new TargetTagAssigmentResult(0, 0, alreadyAssignedTargets.size(),
|
||||
Collections.emptyList(), alreadyAssignedTargets, tag);
|
||||
|
||||
afterCommit.afterCommit(() -> eventBus.post(new TargetTagAssigmentResultEvent(result)));
|
||||
return result;
|
||||
}
|
||||
|
||||
allTargets.removeAll(alreadyAssignedTargets);
|
||||
// some or none are assigned -> assign
|
||||
allTargets.forEach(target -> target.getTags().add(tag));
|
||||
final TargetTagAssigmentResult result = new TargetTagAssigmentResult(alreadyAssignedTargets.size(),
|
||||
allTargets.size(), 0, targetRepository.save(allTargets), null);
|
||||
allTargets.size(), 0, targetRepository.save(allTargets), Collections.emptyList(), tag);
|
||||
|
||||
afterCommit.afterCommit(() -> eventBus.post(new TargetTagAssigmentResultEvent(result)));
|
||||
|
||||
// no reason to persist the tag
|
||||
entityManager.detach(tag);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a {@link TargetTag} assignment to given {@link Target}s.
|
||||
*
|
||||
* @param targetIds
|
||||
* to assign for
|
||||
* @param tagName
|
||||
* to assign
|
||||
* @return list of assigned targets
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@NotNull
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||
public List<Target> assignTag(@NotEmpty final Collection<String> targetIds, @NotNull final TargetTag tag) {
|
||||
final List<Target> allTargets = targetRepository.findAll(TargetSpecifications
|
||||
.byControllerIdWithStatusAndTagsInJoin(targetIds));
|
||||
|
||||
allTargets.forEach(target -> target.getTags().add(tag));
|
||||
final List<Target> save = targetRepository.save(allTargets);
|
||||
|
||||
afterCommit.afterCommit(() -> {
|
||||
final TargetTagAssigmentResult assigmentResult = new TargetTagAssigmentResult(0, save.size(), 0, save,
|
||||
Collections.emptyList(), tag);
|
||||
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult));
|
||||
});
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
private List<Target> unAssignTag(@NotEmpty final Collection<Target> targets, @NotNull final TargetTag tag) {
|
||||
targets.forEach(target -> target.getTags().remove(tag));
|
||||
|
||||
final List<Target> save = targetRepository.save(targets);
|
||||
afterCommit.afterCommit(() -> {
|
||||
final TargetTagAssigmentResult assigmentResult = new TargetTagAssigmentResult(0, 0, save.size(),
|
||||
Collections.emptyList(), save, tag);
|
||||
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult));
|
||||
});
|
||||
return save;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign all {@link Target} from a given {@link TargetTag} .
|
||||
*
|
||||
* @param tag
|
||||
* to unassign all targets
|
||||
* @return list of unassigned targets
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@NotNull
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||
public List<Target> unAssignAllTargetsByTag(@NotNull final TargetTag tag) {
|
||||
return unAssignTag(tag.getAssignedToTargets(), tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassign a {@link TargetTag} assignment to given {@link Target}.
|
||||
*
|
||||
* @param controllerID
|
||||
* to unassign for
|
||||
* @param targetTag
|
||||
* to unassign
|
||||
* @return the unassigned target or <null> if no target is unassigned
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||
public Target unAssignTag(@NotNull final String controllerID, @NotNull final TargetTag targetTag) {
|
||||
final List<Target> allTargets = targetRepository.findAll(TargetSpecifications
|
||||
.byControllerIdWithStatusAndTagsInJoin(Arrays.asList(controllerID)));
|
||||
final List<Target> unAssignTag = unAssignTag(allTargets, targetTag);
|
||||
return unAssignTag.isEmpty() ? null : unAssignTag.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* method retrieves all {@link Target}s from the repo in the following
|
||||
* order:
|
||||
@@ -624,7 +698,7 @@ public class TargetManagement {
|
||||
* <p>
|
||||
* 3) {@link Target}s which have no connection to the given
|
||||
* {@link DistributionSet}.
|
||||
*
|
||||
*
|
||||
* @param pageable
|
||||
* the page request to page the result set
|
||||
* @param orderByDistributionId
|
||||
@@ -667,19 +741,20 @@ public class TargetManagement {
|
||||
// select case expression to retrieve the case value as a column to be
|
||||
// able to order based on
|
||||
// this column, installed first,...
|
||||
final Expression<Object> selectCase = cb
|
||||
.selectCase()
|
||||
final Expression<Object> selectCase = cb.selectCase()
|
||||
.when(cb.equal(targetInfo.get(TargetInfo_.installedDistributionSet).get(DistributionSet_.id),
|
||||
orderByDistributionId), 1)
|
||||
.when(cb.equal(targetRoot.get(Target_.assignedDistributionSet).get(DistributionSet_.id),
|
||||
orderByDistributionId), 2).otherwise(100);
|
||||
orderByDistributionId), 2)
|
||||
.otherwise(100);
|
||||
// multiselect statement order by the select case and controllerId
|
||||
query.distinct(true);
|
||||
// build the specifications and then to predicates necessary by the
|
||||
// given filters
|
||||
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
|
||||
buildSpecificationList(filterByStatus, filterBySearchText, filterByDistributionId,
|
||||
selectTargetWithNoTag, true, filterByTagNames), targetRoot, query, cb);
|
||||
selectTargetWithNoTag, true, filterByTagNames),
|
||||
targetRoot, query, cb);
|
||||
|
||||
// if we have some predicates then add it to the where clause of the
|
||||
// multiselect
|
||||
@@ -706,7 +781,7 @@ public class TargetManagement {
|
||||
/**
|
||||
* @param specifications
|
||||
*/
|
||||
private Predicate[] specificationsToPredicate(final List<Specification<Target>> specifications,
|
||||
private static Predicate[] specificationsToPredicate(final List<Specification<Target>> specifications,
|
||||
final Root<Target> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
|
||||
final Predicate[] predicates = new Predicate[specifications.size()];
|
||||
for (int index = 0; index < predicates.length; index++) {
|
||||
@@ -745,7 +820,7 @@ public class TargetManagement {
|
||||
/**
|
||||
* finds all {@link Target#getControllerId()} which are currently in the
|
||||
* database.
|
||||
*
|
||||
*
|
||||
* @return all IDs of all {@link Target} in the system
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
@@ -753,9 +828,8 @@ public class TargetManagement {
|
||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<TargetIdName> query = cb.createQuery(TargetIdName.class);
|
||||
final Root<Target> targetRoot = query.from(Target.class);
|
||||
return entityManager.createQuery(
|
||||
query.multiselect(targetRoot.get(Target_.id), targetRoot.get(Target_.controllerId),
|
||||
targetRoot.get(Target_.name))).getResultList();
|
||||
return entityManager.createQuery(query.multiselect(targetRoot.get(Target_.id),
|
||||
targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name))).getResultList();
|
||||
|
||||
}
|
||||
|
||||
@@ -790,14 +864,15 @@ public class TargetManagement {
|
||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
|
||||
final Root<Target> targetRoot = query.from(Target.class);
|
||||
List<Object[]> resultList = null;
|
||||
List<Object[]> resultList;
|
||||
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(Target_.id),
|
||||
targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name),
|
||||
targetRoot.get(pageRequest.getSort().iterator().next().getProperty()));
|
||||
|
||||
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
|
||||
buildSpecificationList(filterByStatus, filterBySearchText, filterByDistributionId,
|
||||
selectTargetWithNoTag, false, filterByTagNames), targetRoot, multiselect, cb);
|
||||
selectTargetWithNoTag, false, filterByTagNames),
|
||||
targetRoot, multiselect, cb);
|
||||
|
||||
// if we have some predicates then add it to the where clause of the
|
||||
// multiselect
|
||||
@@ -805,25 +880,47 @@ public class TargetManagement {
|
||||
multiselect.where(specificationsForMultiSelect);
|
||||
}
|
||||
|
||||
if (pageRequest.getSort() != null) {
|
||||
final List<Order> orders = new ArrayList<>();
|
||||
final Sort sort = pageRequest.getSort();
|
||||
for (final Sort.Order sortOrder : sort) {
|
||||
if (sortOrder.getDirection() == Direction.ASC) {
|
||||
orders.add(cb.asc(targetRoot.get(sortOrder.getProperty())));
|
||||
} else {
|
||||
orders.add(cb.desc(targetRoot.get(sortOrder.getProperty())));
|
||||
}
|
||||
}
|
||||
multiselect.orderBy(orders);
|
||||
resultList = entityManager.createQuery(multiselect).setFirstResult(pageRequest.getOffset())
|
||||
.setMaxResults(pageRequest.getPageSize()).getResultList();
|
||||
} else {
|
||||
resultList = entityManager.createQuery(multiselect).getResultList();
|
||||
}
|
||||
resultList = getTargetIdNameResultSet(pageRequest, cb, targetRoot, multiselect);
|
||||
return resultList.parallelStream().map(o -> new TargetIdName((long) o[0], o[1].toString(), o[2].toString()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all {@link Target#getControllerId()} for all the given parameter
|
||||
* {@link TargetFilterQuery}.
|
||||
*
|
||||
* @param pageRequest
|
||||
* the pageRequest to enhance the query for paging and sorting
|
||||
* @param targetFilterQuery
|
||||
* {@link TargetFilterQuery}
|
||||
* @return the found {@link Target}s
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
public List<TargetIdName> findAllTargetIdsByTargetFilterQuery(final PageRequest pageRequest,
|
||||
@NotNull final TargetFilterQuery targetFilterQuery) {
|
||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
|
||||
final Root<Target> targetRoot = query.from(Target.class);
|
||||
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(Target_.id),
|
||||
targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name),
|
||||
targetRoot.get(pageRequest.getSort().iterator().next().getProperty()));
|
||||
|
||||
final Specification<Target> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
|
||||
entityManager);
|
||||
final List<Specification<Target>> specList = new ArrayList<>();
|
||||
specList.add(spec);
|
||||
|
||||
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(specList, targetRoot, multiselect,
|
||||
cb);
|
||||
|
||||
// if we have some predicates then add it to the where clause of the
|
||||
// multiselect
|
||||
if (specificationsForMultiSelect.length > 0) {
|
||||
multiselect.where(specificationsForMultiSelect);
|
||||
}
|
||||
final List<Object[]> resultList = getTargetIdNameResultSet(pageRequest, cb, targetRoot, multiselect);
|
||||
return resultList.parallelStream().map(o -> new TargetIdName((long) o[0], o[1].toString(), o[2].toString()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
@@ -880,7 +977,7 @@ public class TargetManagement {
|
||||
|
||||
/**
|
||||
* creating a new {@link Target}.
|
||||
*
|
||||
*
|
||||
* @param target
|
||||
* to be created
|
||||
* @return the created {@link Target}
|
||||
@@ -901,24 +998,25 @@ public class TargetManagement {
|
||||
* already exists in the DB a {@link EntityAlreadyExistsException} is
|
||||
* thrown. {@link Target}s contain all objects of the parameter targets,
|
||||
* including duplicates.
|
||||
*
|
||||
*
|
||||
* @param targets
|
||||
* to be created.
|
||||
* @return the created {@link Target}s
|
||||
*
|
||||
* @throws {@link EntityAlreadyExistsException} of one of the given targets
|
||||
* already exist.
|
||||
* @throws {@link
|
||||
* EntityAlreadyExistsException} of one of the given targets
|
||||
* already exist.
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@NotNull
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
|
||||
public List<Target> createTargets(@NotNull final List<Target> targets) {
|
||||
if (targetRepository.countByControllerIdIn(targets.stream().map(target -> target.getControllerId())
|
||||
.collect(Collectors.toList())) > 0) {
|
||||
if (targetRepository.countByControllerIdIn(
|
||||
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())) > 0) {
|
||||
throw new EntityAlreadyExistsException();
|
||||
}
|
||||
final List<Target> savedTargets = new ArrayList<Target>();
|
||||
final List<Target> savedTargets = new ArrayList<>();
|
||||
for (final Target t : targets) {
|
||||
final Target myTarget = createTarget(t);
|
||||
savedTargets.add(myTarget);
|
||||
@@ -947,11 +1045,11 @@ public class TargetManagement {
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
|
||||
public List<Target> createTargets(@NotNull final Collection<Target> targets,
|
||||
@NotNull final TargetUpdateStatus status, final long lastTargetQuery, final URI address) {
|
||||
if (targetRepository.countByControllerIdIn(targets.stream().map(target -> target.getControllerId())
|
||||
.collect(Collectors.toList())) > 0) {
|
||||
if (targetRepository.countByControllerIdIn(
|
||||
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())) > 0) {
|
||||
throw new EntityAlreadyExistsException();
|
||||
}
|
||||
final List<Target> savedTargets = new ArrayList<Target>();
|
||||
final List<Target> savedTargets = new ArrayList<>();
|
||||
for (final Target t : targets) {
|
||||
final Target myTarget = createTarget(t, status, lastTargetQuery, address);
|
||||
savedTargets.add(myTarget);
|
||||
@@ -970,13 +1068,12 @@ public class TargetManagement {
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||
public List<Target> findTargetsByTag(@NotNull final String tagName) {
|
||||
final TargetTag tag = targetTagRepository.findByNameEquals(tagName);
|
||||
final List<Target> assignedTargets = targetRepository.findByTag(tag);
|
||||
return assignedTargets;
|
||||
return targetRepository.findByTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count {@link TargetFilterQuery}s for given filter parameter.
|
||||
*
|
||||
*
|
||||
* @param targetFilterQuery
|
||||
* {link TargetFilterQuery}
|
||||
* @return the found number {@link TargetFilterQuery}s
|
||||
@@ -990,7 +1087,7 @@ public class TargetManagement {
|
||||
|
||||
/**
|
||||
* Count {@link TargetFilterQuery}s for given target filter query.
|
||||
*
|
||||
*
|
||||
* @param targetFilterQuery
|
||||
* {link TargetFilterQuery}
|
||||
* @return the found number {@link TargetFilterQuery}s
|
||||
@@ -1000,4 +1097,26 @@ public class TargetManagement {
|
||||
final Specification<Target> specs = RSQLUtility.parse(targetFilterQuery, TargetFields.class, entityManager);
|
||||
return targetRepository.count(specs);
|
||||
}
|
||||
|
||||
private List<Object[]> getTargetIdNameResultSet(final PageRequest pageRequest, final CriteriaBuilder cb,
|
||||
final Root<Target> targetRoot, final CriteriaQuery<Object[]> multiselect) {
|
||||
List<Object[]> resultList;
|
||||
if (pageRequest.getSort() != null) {
|
||||
final List<Order> orders = new ArrayList<>();
|
||||
final Sort sort = pageRequest.getSort();
|
||||
for (final Sort.Order sortOrder : sort) {
|
||||
if (sortOrder.getDirection() == Direction.ASC) {
|
||||
orders.add(cb.asc(targetRoot.get(sortOrder.getProperty())));
|
||||
} else {
|
||||
orders.add(cb.desc(targetRoot.get(sortOrder.getProperty())));
|
||||
}
|
||||
}
|
||||
multiselect.orderBy(orders);
|
||||
resultList = entityManager.createQuery(multiselect).setFirstResult(pageRequest.getOffset())
|
||||
.setMaxResults(pageRequest.getPageSize()).getResultList();
|
||||
} else {
|
||||
resultList = entityManager.createQuery(multiselect).getResultList();
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetRepository.java
Executable file → Normal file
3
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetTagRepository.java
Executable file → Normal file
3
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetTagRepository.java
Executable file → Normal file
@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -21,7 +22,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
*
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public interface TargetTagRepository extends BaseEntityRepository<TargetTag, Long> {
|
||||
public interface TargetTagRepository extends BaseEntityRepository<TargetTag, Long>, JpaSpecificationExecutor<TargetTag> {
|
||||
|
||||
/**
|
||||
* deletes the {@link TargetTag}s with the given tag names.
|
||||
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetWithActionType.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetWithActionType.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantKeyGenerator.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantKeyGenerator.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantMetaDataRepository.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantMetaDataRepository.java
Executable file → Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.hawkbit.report.model.TenantUsage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
* Management service for stats of a single tenant.
|
||||
*
|
||||
*/
|
||||
@Validated
|
||||
@Service
|
||||
public class TenantStatsManagement {
|
||||
|
||||
@Autowired
|
||||
private TargetRepository targetRepository;
|
||||
|
||||
@Autowired
|
||||
private LocalArtifactRepository artifactRepository;
|
||||
|
||||
@Autowired
|
||||
private ActionRepository actionRepository;
|
||||
|
||||
/**
|
||||
* Service for stats of a single tenant. Opens a new transaction and as a
|
||||
* result can an be used for multiple tenants, i.e. to allow in one session
|
||||
* to collect data of all tenants in the system.
|
||||
*
|
||||
* @param tenant
|
||||
* to collect for
|
||||
* @return collected statistics
|
||||
*/
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public TenantUsage getStatsOfTenant(final String tenant) {
|
||||
final TenantUsage result = new TenantUsage(tenant);
|
||||
|
||||
result.setTargets(targetRepository.count());
|
||||
|
||||
final Long artifacts = artifactRepository.countBySoftwareModuleDeleted(false);
|
||||
result.setArtifacts(artifacts);
|
||||
|
||||
final Optional<Long> artifactsSize = artifactRepository.getSumOfUndeletedArtifactSize();
|
||||
if (artifactsSize.isPresent()) {
|
||||
result.setOverallArtifactVolumeInBytes(artifactsSize.get());
|
||||
}
|
||||
|
||||
result.setActions(actionRepository.count());
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.event;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Defines all events which are sent from the {@link DeploymentManagement}.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class DeploymentManagementEvents {
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
|
||||
/**
|
||||
* Sends the {@link TargetAssignDistributionSetEvent} for a specific target
|
||||
* to the {@link EventBus}.
|
||||
*
|
||||
* @param target
|
||||
* the Target which has been assigned to a distribution set
|
||||
* @param actionId
|
||||
* the action id of the assignment
|
||||
* @param softwareModules
|
||||
* the software modules which have been assigned
|
||||
*/
|
||||
public void assignDistributionSet(final Target target, final Long actionId,
|
||||
final List<SoftwareModule> softwareModules) {
|
||||
target.getTargetInfo().setUpdateStatus(TargetUpdateStatus.PENDING);
|
||||
eventBus.post(new TargetInfoUpdateEvent(target.getTargetInfo()));
|
||||
eventBus.post(new TargetAssignDistributionSetEvent(target.getControllerId(), actionId, softwareModules,
|
||||
target.getTargetInfo().getAddress()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the {@link CancelTargetAssignmentEvent} for a specific target to
|
||||
* the {@link EventBus}.
|
||||
*
|
||||
* @param target
|
||||
* the Target which has been assigned to a distribution set
|
||||
* @param actionId
|
||||
* the action id of the assignment
|
||||
*/
|
||||
public void cancalAssignDistributionSet(final Target target, final Long actionId) {
|
||||
eventBus.post(new CancelTargetAssignmentEvent(target.getControllerId(), actionId,
|
||||
target.getTargetInfo().getAddress()));
|
||||
}
|
||||
}
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactDeleteFailedException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactDeleteFailedException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactUploadFailedException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactUploadFailedException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/CancelActionNotAllowedException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/CancelActionNotAllowedException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/ConcurrentModificationException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/ConcurrentModificationException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/DistributionSetTypeUndefinedException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/DistributionSetTypeUndefinedException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/EntityAlreadyExistsException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/EntityAlreadyExistsException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/EntityLockedException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/EntityLockedException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/EntityNotFoundException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/EntityNotFoundException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/EntityReadOnlyException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/EntityReadOnlyException.java
Executable file → Normal 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.exception;
|
||||
|
||||
import org.eclipse.hawkbit.exception.SpServerError;
|
||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
||||
|
||||
/**
|
||||
* Thrown when force quitting an actions is not allowed. e.g. the action is not
|
||||
* active or it is not canceled before.
|
||||
*
|
||||
*/
|
||||
public final class ForceQuitActionNotAllowedException extends SpServerRtException {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new CancelActionNotAllowed with
|
||||
* {@link SpServerError#SP_ACTION_NOT_CANCELABLE} error.
|
||||
*/
|
||||
public ForceQuitActionNotAllowedException() {
|
||||
super(SpServerError.SP_ACTION_NOT_FORCE_QUITABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cause
|
||||
* for the exception
|
||||
*/
|
||||
public ForceQuitActionNotAllowedException(final Throwable cause) {
|
||||
super(SpServerError.SP_ACTION_NOT_FORCE_QUITABLE, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* of the error
|
||||
*/
|
||||
public ForceQuitActionNotAllowedException(final String message) {
|
||||
super(message, SpServerError.SP_ACTION_NOT_FORCE_QUITABLE);
|
||||
}
|
||||
}
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/GridFSDBFileNotFoundException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/GridFSDBFileNotFoundException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/IncompleteDistributionSetException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/IncompleteDistributionSetException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InsufficientPermissionException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InsufficientPermissionException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidMD5HashException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidMD5HashException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidSHA1HashException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidSHA1HashException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/TenantNotExistException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/TenantNotExistException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyAttributeEntriesException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyAttributeEntriesException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyStatusEntriesException.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyStatusEntriesException.java
Executable file → Normal file
12
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Action.java
Executable file → Normal file
12
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Action.java
Executable file → Normal file
@@ -116,6 +116,10 @@ public class Action extends BaseEntity implements Comparable<Action> {
|
||||
this.distributionSet = distributionSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true when action is in state {@link Status#CANCELING} or
|
||||
* {@link Status#CANCELED}, false otherwise
|
||||
*/
|
||||
public boolean isCancelingOrCanceled() {
|
||||
return status == Status.CANCELING || status == Status.CANCELED;
|
||||
}
|
||||
@@ -262,7 +266,7 @@ public class Action extends BaseEntity implements Comparable<Action> {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the forced
|
||||
* @return true when action is forced, false otherwise
|
||||
*/
|
||||
public boolean isForced() {
|
||||
return actionType == ActionType.FORCED;
|
||||
@@ -331,14 +335,10 @@ public class Action extends BaseEntity implements Comparable<Action> {
|
||||
/**
|
||||
* Action status as reported by the controller.
|
||||
*
|
||||
* Be aware that JPA is persiting the ordnial number of the enum by means
|
||||
* Be aware that JPA is persisting the ordinal number of the enum by means
|
||||
* the ordered number in the enum. So don't re-order the enums within the
|
||||
* Status enum declaration!
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public enum Status {
|
||||
/**
|
||||
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionStatus.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionStatus.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionWithStatusCount.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/ActionWithStatusCount.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Artifact.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Artifact.java
Executable file → Normal 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;
|
||||
package org.eclipse.hawkbit.repository.model;
|
||||
|
||||
/**
|
||||
* Generic assigment result bean.
|
||||
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/BaseEntity.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/BaseEntity.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/CustomSoftwareModule.java
Executable file → Normal file
0
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/CustomSoftwareModule.java
Executable file → Normal file
18
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSet.java
Executable file → Normal file
18
hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSet.java
Executable file → Normal file
@@ -69,13 +69,13 @@ public class DistributionSet extends NamedVersionedEntity {
|
||||
@JoinTable(name = "sp_ds_module", joinColumns = {
|
||||
@JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds") ) }, inverseJoinColumns = {
|
||||
@JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module") ) })
|
||||
private final Set<SoftwareModule> modules = new HashSet<SoftwareModule>();
|
||||
private final Set<SoftwareModule> modules = new HashSet<>();
|
||||
|
||||
@ManyToMany(targetEntity = DistributionSetTag.class)
|
||||
@JoinTable(name = "sp_ds_dstag", joinColumns = {
|
||||
@JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds") ) }, inverseJoinColumns = {
|
||||
@JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag") ) })
|
||||
private Set<DistributionSetTag> tags = new HashSet<DistributionSetTag>();
|
||||
private Set<DistributionSetTag> tags = new HashSet<>();
|
||||
|
||||
@Column(name = "deleted")
|
||||
private boolean deleted = false;
|
||||
@@ -110,7 +110,7 @@ public class DistributionSet extends NamedVersionedEntity {
|
||||
|
||||
/**
|
||||
* Parameterized constructor.
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
* of the {@link DistributionSet}
|
||||
* @param version
|
||||
@@ -128,7 +128,7 @@ public class DistributionSet extends NamedVersionedEntity {
|
||||
|
||||
this.type = type;
|
||||
if (moduleList != null) {
|
||||
moduleList.forEach(module -> addModule(module));
|
||||
moduleList.forEach(this::addModule);
|
||||
}
|
||||
complete = type.checkComplete(this);
|
||||
}
|
||||
@@ -160,7 +160,7 @@ public class DistributionSet extends NamedVersionedEntity {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
@@ -173,7 +173,7 @@ public class DistributionSet extends NamedVersionedEntity {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@@ -234,7 +234,7 @@ public class DistributionSet extends NamedVersionedEntity {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
@@ -322,8 +322,8 @@ public class DistributionSet extends NamedVersionedEntity {
|
||||
* Searches through modules for the given type.
|
||||
*
|
||||
* @param type
|
||||
* to serach for
|
||||
* @return SoftwareModule of giben type or <code>null</code> if not in the
|
||||
* to seach for
|
||||
* @return SoftwareModule of given type or <code>null</code> if not in the
|
||||
* list.
|
||||
*/
|
||||
public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user