From 4f7bb98587972182977d81b894e80aa76edcb9b5 Mon Sep 17 00:00:00 2001 From: Asharani Date: Tue, 28 Jun 2016 12:07:26 +0530 Subject: [PATCH 01/42] Enable push for update target, create/update/delete ds Renamed constant MAX_TARGET_TABLE_ENTRIES Signed-off-by: Asharani --- .../eventbus/event/TargetDeletedEvent.java | 39 ---- .../event/DistributionCreatedEvent.java | 28 +++ .../event/DistributionDeletedEvent.java | 37 ++++ .../event/DistributionSetUpdateEvent.java | 30 +++ .../eventbus/event/TargetDeletedEvent.java | 41 ++++ .../eventbus/event/TargetUpdatedEvent.java | 25 +++ .../jpa/JpaDistributionSetManagement.java | 56 ++++-- .../repository/jpa/JpaTargetManagement.java | 22 +- .../eventbus/EntityChangeEventListener.java | 154 -------------- .../model/AbstractDescriptorEventVisitor.java | 19 ++ .../AbstractDescriptorEventVisitorImpl.java | 189 ++++++++++++++++++ .../jpa/model/AbstractJpaBaseEntity.java | 7 +- .../repository/jpa/model/AcceptVisitor.java | 18 ++ .../jpa/model/DescriptorEventDetails.java | 42 ++++ .../model/EntityPropertyChangeListener.java | 78 ++------ .../hawkbit/ui/HawkbitEventProvider.java | 14 +- .../dstable/DistributionSetTable.java | 108 +++++++++- .../dstable/ManageDistBeanQuery.java | 2 +- .../CustomTargetBeanQuery.java | 6 +- .../footer/TargetFilterCountMessageLabel.java | 6 +- .../DistributionAddUpdateWindowLayout.java | 17 +- .../dstable/DistributionBeanQuery.java | 2 +- .../management/dstable/DistributionTable.java | 97 +++++++++ .../management/footer/CountMessageLabel.java | 6 +- .../ManangementConfirmationWindowLayout.java | 1 - .../targettable/TargetBeanQuery.java | 6 +- .../management/targettable/TargetTable.java | 48 ++++- .../RolloutGroupTargetsBeanQuery.java | 6 +- .../RolloutGroupTargetsCountLabelMessage.java | 6 +- .../hawkbit/ui/utils/SPUIDefinitions.java | 15 +- 30 files changed, 788 insertions(+), 337 deletions(-) delete mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionCreatedEvent.java create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionSetUpdateEvent.java create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetDeletedEvent.java create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java delete mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/eventbus/EntityChangeEventListener.java create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java deleted file mode 100644 index e6fcac135..000000000 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java +++ /dev/null @@ -1,39 +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.eventbus.event; - -/** - * - * - * - */ -public class TargetDeletedEvent extends AbstractDistributedEvent { - - private static final long serialVersionUID = 1L; - private final long targetId; - - /** - * @param tenant - * the tenant for this event - * @param targetId - * the ID of the target which has been deleted - */ - public TargetDeletedEvent(final String tenant, final long targetId) { - super(-1, tenant); - this.targetId = targetId; - } - - /** - * @return the targetId - */ - public long getTargetId() { - return targetId; - } - -} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionCreatedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionCreatedEvent.java new file mode 100644 index 000000000..20515521d --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionCreatedEvent.java @@ -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.repository.eventbus.event; + +import org.eclipse.hawkbit.repository.model.DistributionSet; + +/** + * Defines the {@link AbstractBaseEntityEvent} of creating a new {@link DistributionSet}. + * + */ +public class DistributionCreatedEvent extends AbstractBaseEntityEvent { + + private static final long serialVersionUID = 1L; + + /** + * @param distributionSet + * the distributionSet which has been created + */ + public DistributionCreatedEvent(final DistributionSet distributionSet) { + super(distributionSet); + } +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java new file mode 100644 index 000000000..1edfb47ac --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.eventbus.event; + +import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent; +import org.eclipse.hawkbit.repository.model.DistributionSet; + + +/** + * * Defines the {@link AbstractDistributedEvent} for deletion of {@link DistributionSet}. + + * + */ +public class DistributionDeletedEvent extends AbstractDistributedEvent{ + private static final long serialVersionUID = -3308850381757843098L; + final Long[] distributionSetIDs; + /** + * @param tenant + * the tenant for this event + * @param distributionSetId + * the ID of the target which has been deleted + */ + public DistributionDeletedEvent(final String tenant, final Long...distributionIds) { + super(-1, tenant); + this.distributionSetIDs = distributionIds; + } + + public Long[] getDistributionSetIDs() { + return distributionSetIDs; + } +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionSetUpdateEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionSetUpdateEvent.java new file mode 100644 index 000000000..8d91d27f7 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionSetUpdateEvent.java @@ -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.repository.eventbus.event; + +import org.eclipse.hawkbit.repository.model.DistributionSet; + +/** + * Defines the {@link AbstractBaseEntityEvent} for update a {@link DistributionSet}. + * + */ +public class DistributionSetUpdateEvent extends AbstractBaseEntityEvent { + + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + * @param tag + * the tag which is updated + */ + public DistributionSetUpdateEvent(final DistributionSet ds) { + super(ds); + } +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetDeletedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetDeletedEvent.java new file mode 100644 index 000000000..637a0dcc5 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetDeletedEvent.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.eventbus.event; + +import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent; +import org.eclipse.hawkbit.repository.model.Target; + +/** + * + * Defines the {@link AbstractBaseEntityEvent} of deleting a {@link Target}. + */ +public class TargetDeletedEvent extends AbstractDistributedEvent { + + private static final long serialVersionUID = 1L; + private final long targetId; + + /** + * @param tenant + * the tenant for this event + * @param targetId + * the ID of the target which has been deleted + */ + public TargetDeletedEvent(final String tenant, final long targetId) { + super(-1, tenant); + this.targetId = targetId; + } + + /** + * @return the targetId + */ + public long getTargetId() { + return targetId; + } + +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java new file mode 100644 index 000000000..a30d96c69 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.eventbus.event; + +import org.eclipse.hawkbit.repository.model.Target; + +/** + * Defines the {@link AbstractBaseEntityEvent} of updating a {@link Target}. + * + */ +public class TargetUpdatedEvent extends AbstractBaseEntityEvent { + + private static final long serialVersionUID = 5665118668865832477L; + + public TargetUpdatedEvent(Target baseEntity) { + super(baseEntity); + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index 0e97d6ff5..b94677fb9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -28,6 +28,7 @@ import org.eclipse.hawkbit.repository.DistributionSetMetadataFields; import org.eclipse.hawkbit.repository.DistributionSetTypeFields; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TagManagement; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityLockedException; @@ -54,6 +55,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -102,6 +104,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; + @Autowired + private TenantAware tenantAware; + @Override public DistributionSet findDistributionSetByIdWithDetails(final Long distid) { return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid)); @@ -168,32 +173,39 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteDistributionSet(final Long... distributionSetIDs) { - final List toHardDelete = new ArrayList<>(); + public void deleteDistributionSet(final Long... distributionSetIDs) { + final List toHardDelete = new ArrayList<>(); - final List assigned = distributionSetRepository - .findAssignedToTargetDistributionSetsById(distributionSetIDs); - assigned.addAll(distributionSetRepository.findAssignedToRolloutDistributionSetsById(distributionSetIDs)); + final List assigned = distributionSetRepository + .findAssignedToTargetDistributionSetsById(distributionSetIDs); + assigned.addAll(distributionSetRepository + .findAssignedToRolloutDistributionSetsById(distributionSetIDs)); - // soft delete assigned - if (!assigned.isEmpty()) { - distributionSetRepository.deleteDistributionSet(assigned.toArray(new Long[assigned.size()])); - } + // soft delete assigned + if (!assigned.isEmpty()) { + distributionSetRepository.deleteDistributionSet(assigned + .toArray(new Long[assigned.size()])); + } - // mark the rest as hard delete - for (final Long setId : distributionSetIDs) { - if (!assigned.contains(setId)) { - toHardDelete.add(setId); - } - } + // mark the rest as hard delete + for (final Long setId : distributionSetIDs) { + if (!assigned.contains(setId)) { + toHardDelete.add(setId); + } + } - // hard delete the rest if exixts - if (!toHardDelete.isEmpty()) { - // don't give the delete statement an empty list, JPA/Oracle cannot - // handle the empty list - distributionSetRepository.deleteByIdIn(toHardDelete); - } - } + // hard delete the rest if exixts + if (!toHardDelete.isEmpty()) { + // don't give the delete statement an empty list, JPA/Oracle cannot + // handle the empty list + distributionSetRepository.deleteByIdIn(toHardDelete); + } + + afterCommit.afterCommit(() -> eventBus + .post(new DistributionDeletedEvent(tenantAware + .getCurrentTenant(), distributionSetIDs))); + + } @Override @Modifying diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 1cd2ffc3c..30a5dd5d9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -29,6 +29,7 @@ import javax.persistence.criteria.Root; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.jpa.configuration.Constants; @@ -48,6 +49,7 @@ import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.domain.Page; @@ -96,6 +98,10 @@ public class JpaTargetManagement implements TargetManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; + + + @Autowired + private TenantAware tenantAware; @Override public Target findTargetByControllerID(final String controllerId) { @@ -202,12 +208,14 @@ public class JpaTargetManagement implements TargetManagement { // hibernate session. final List targetsForCurrentTenant = targetRepository.findAll(Lists.newArrayList(targetIDs)).stream() .map(Target::getId).collect(Collectors.toList()); - if (!targetsForCurrentTenant.isEmpty()) { - targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant); - targetRepository.deleteByIdIn(targetsForCurrentTenant); - } + if (!targetsForCurrentTenant.isEmpty()) { + targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant); + targetRepository.deleteByIdIn(targetsForCurrentTenant); + targetsForCurrentTenant.forEach(targetId -> notifyTargetDeleted( + tenantAware.getCurrentTenant(), targetId)); + } } - + @Override public Page findTargetByAssignedDistributionSet(final Long distributionSetID, final Pageable pageReq) { return targetRepository.findByAssignedDistributionSetId(pageReq, distributionSetID); @@ -651,5 +659,9 @@ public class JpaTargetManagement implements TargetManagement { } return resultList; } + + private void notifyTargetDeleted(final String tenant, final Long targetId) { + afterCommit.afterCommit(() -> eventBus.post(new TargetDeletedEvent(tenant, targetId))); + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/eventbus/EntityChangeEventListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/eventbus/EntityChangeEventListener.java deleted file mode 100644 index 5f41063d2..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/eventbus/EntityChangeEventListener.java +++ /dev/null @@ -1,154 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.eventbus; - -import java.util.Collection; - -import javax.persistence.EntityManager; - -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; -import org.eclipse.hawkbit.repository.jpa.TargetRepository; -import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; -import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; -import org.eclipse.hawkbit.tenancy.TenantAware; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.google.common.eventbus.EventBus; - -/** - * An aspect implementation which wraps the necessary repository services for - * saving {@link TenantAwareBaseEntity}s to publish create or update events. - * - * - * - * - */ -@Service -@Aspect -public class EntityChangeEventListener { - - @Autowired - private EventBus eventBus; - - @Autowired - private TenantAware tenantAware; - - @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} - * information in the target created event. So we are listening to the - * {@link TargetInfo} creation to indicate if an Target has been created. - * - * @param joinpoint - * the aspect join point - * @return the object of the {@link ProceedingJoinPoint#proceed()} - * @throws Throwable - * in case exception happens in the - * {@link ProceedingJoinPoint#proceed()} - */ - @Around("execution(* org.eclipse.hawkbit.repository.jpa.TargetInfoRepository.save(..))") - // Exception squid:S00112 - Is aspectJ proxy - @SuppressWarnings({ "squid:S00112" }) - public Object targetCreated(final ProceedingJoinPoint joinpoint) throws Throwable { - final boolean isNew = isTargetInfoNew(joinpoint.getArgs()[0]); - final Object result = joinpoint.proceed(); - if (result instanceof TargetInfo) { - if (isNew) { - notifyTargetCreated(entityManager.merge(entityManager.merge(((TargetInfo) result).getTarget()))); - } else { - notifyTargetInfoChanged((TargetInfo) result); - } - } - return result; - } - - /** - * Proxy method around the delete method of the {@link TargetRepository} to - * notify the {@link TargetDeletedEvent} in case targets has been deleted. - * - * @param joinpoint - * the aspect join point - * @return the object of the {@link ProceedingJoinPoint#proceed()} - * @throws Throwable - * in case exception happens in the - * {@link ProceedingJoinPoint#proceed()} - */ - @Around("execution(* org.eclipse.hawkbit.repository.jpa.TargetRepository.deleteByIdIn(..))") - // Exception squid:S00112 - Is aspectJ proxy - @SuppressWarnings({ "squid:S00112" }) - public Object targetDeletedById(final ProceedingJoinPoint joinpoint) throws Throwable { - final String currentTenant = tenantAware.getCurrentTenant(); - final Object result = joinpoint.proceed(); - final Collection targetIds = (Collection) joinpoint.getArgs()[0]; - targetIds.forEach(targetId -> notifyTargetDeleted(currentTenant, targetId)); - return result; - } - - /** - * Proxy method around the delete method of the {@link TargetRepository} to - * notify the {@link TargetDeletedEvent} in case targets has been deleted. - * - * @param joinpoint - * the aspect join point - * @return the object of the {@link ProceedingJoinPoint#proceed()} - * @throws Throwable - * in case exception happens in the - * {@link ProceedingJoinPoint#proceed()} - */ - @Around("execution(* org.eclipse.hawkbit.repository.jpa.TargetRepository.delete(..))") - // Exception squid:S00112 - Is aspectJ proxy - @SuppressWarnings({ "squid:S00112", "unchecked" }) - public Object targetDeleted(final ProceedingJoinPoint joinpoint) throws Throwable { - final String currentTenant = tenantAware.getCurrentTenant(); - final Object result = joinpoint.proceed(); - final Object param = joinpoint.getArgs()[0]; - // delete by id - if (param instanceof Long) { - notifyTargetDeleted(currentTenant, (Long) param); - } else if (param instanceof Target) { - notifyTargetDeleted(currentTenant, ((Target) param).getId()); - } else if (param instanceof Iterable) { - ((Iterable) param).forEach(target -> notifyTargetDeleted(currentTenant, target.getId())); - } - return result; - } - - private void notifyTargetCreated(final Target t) { - afterCommit.afterCommit(() -> eventBus.post(new TargetCreatedEvent(t))); - - } - - private void notifyTargetInfoChanged(final TargetInfo targetInfo) { - afterCommit.afterCommit(() -> eventBus.post(new TargetInfoUpdateEvent(targetInfo))); - } - - private void notifyTargetDeleted(final String tenant, final Long targetId) { - afterCommit.afterCommit(() -> eventBus.post(new TargetDeletedEvent(tenant, targetId))); - } - - private static boolean isTargetInfoNew(final Object targetInfo) { - return ((JpaTargetInfo) targetInfo).isNew(); - } - -} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java new file mode 100644 index 000000000..ce32b025f --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +/** + * + * Interface defining the action to be performed after entity is + * created/updated. + * + */ +public interface AbstractDescriptorEventVisitor { + void publishEventPostAction(DescriptorEventDetails eventDetails); +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java new file mode 100644 index 000000000..8755f8051 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java @@ -0,0 +1,189 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.stream.Collectors; + +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; +import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; +import org.eclipse.hawkbit.repository.jpa.model.DescriptorEventDetails.ActionType; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.eclipse.persistence.internal.sessions.ObjectChangeSet; +import org.eclipse.persistence.queries.UpdateObjectQuery; +import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.eventbus.EventBus; + +/** + * Implementation of @link{AbstractDescriptorEventVisitor} .Publishes the + * appropriate event after any action on entity like create/update. + * + */ +public class AbstractDescriptorEventVisitorImpl implements + AbstractDescriptorEventVisitor { + + private static final String COMPLETE = "complete"; + private static final Logger LOG = LoggerFactory + .getLogger(AbstractDescriptorEventVisitorImpl.class); + + @Override + public void publishEventPostAction(final DescriptorEventDetails event) { + Method method = null; + DescriptorEvent descriptorEvent = event.getDescriptorEvent(); + ActionType actiontype = event.getActiontype(); + try { + method = getMethod(descriptorEvent, actiontype); + if (method != null) { + method.invoke(this, descriptorEvent.getObject(), + descriptorEvent); + } + } catch (NoSuchMethodException | SecurityException + | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + LOG.info( + "Exception when invoking approriate method to publis event {}", + e); + } + } + + private Method getMethod(DescriptorEvent descriptorEvent, + ActionType actiontype) throws NoSuchMethodException { + if (actiontype == ActionType.UPDATE) { + return this.getClass().getMethod("publishEventAfterUpdate", + descriptorEvent.getObject().getClass(), + DescriptorEvent.class); + } else if (actiontype == ActionType.CREATE) { + return this.getClass().getMethod("publishEventAfterCreate", + descriptorEvent.getObject().getClass(), + DescriptorEvent.class); + } + return null; + } + + public void publishEventAfterCreate(JpaAction action, DescriptorEvent event) { + if (action.getRollout() != null) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post(new ActionCreatedEvent(action))); + } + } + + public void publishEventAfterCreate(JpaTarget target, DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post(new TargetCreatedEvent(target))); + } + + public void publishEventAfterCreate(JpaDistributionSet ds, + DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post(new DistributionCreatedEvent(ds))); + + } + + public void publishEventAfterUpdate(JpaAction action, DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post( + new ActionPropertyChangeEvent(action, getChangeSet( + Action.class, event)))); + } + + public void publishEventAfterUpdate(JpaTarget target, DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post(new TargetUpdatedEvent(target))); + } + + public void publishEventAfterUpdate(JpaTargetInfo targetInfo, + DescriptorEvent event) { + getAfterTransactionCommmitExecutor() + .afterCommit( + () -> getEventBus().post( + new TargetInfoUpdateEvent(targetInfo))); + } + + public void publishEventAfterUpdate(JpaRollout entity, DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post( + new RolloutPropertyChangeEvent(entity, getChangeSet( + Rollout.class, event)))); + } + + public void publishEventAfterUpdate(JpaRolloutGroup entity, + DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post( + new RolloutGroupPropertyChangeEvent(entity, + getChangeSet(RolloutGroup.class, event)))); + + } + + public void publishEventAfterUpdate(JpaDistributionSet entity, + DescriptorEvent event) { + Map.Values> changeSet = getChangeSet( + JpaDistributionSet.class, event); + if (changeSet.containsKey(COMPLETE) + && changeSet.get(COMPLETE).getOldValue().equals(false) + && changeSet.get(COMPLETE).getNewValue().equals(true)) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post( + new DistributionCreatedEvent(entity))); + } + + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus() + .post(new DistributionSetUpdateEvent(entity))); + + } + + private Map.Values> getChangeSet( + final Class clazz, final DescriptorEvent event) { + final T rolloutGroup = clazz.cast(event.getObject()); + final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()) + .getObjectChangeSet(); + return changeSet + .getChanges() + .stream() + .filter(record -> record instanceof DirectToFieldChangeRecord) + .map(record -> (DirectToFieldChangeRecord) record) + .collect( + Collectors.toMap( + record -> record.getAttribute(), + record -> new AbstractPropertyChangeEvent( + rolloutGroup, null).new Values(record + .getOldValue(), record.getNewValue()))); + } + + private AfterTransactionCommitExecutor getAfterTransactionCommmitExecutor() { + return AfterTransactionCommitExecutorHolder.getInstance() + .getAfterCommit(); + } + + private EventBus getEventBus() { + return EventBusHolder.getInstance().getEventBus(); + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index 257828c6f..2785676fb 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -32,7 +32,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @MappedSuperclass @Access(AccessType.FIELD) @EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class }) -public abstract class AbstractJpaBaseEntity implements BaseEntity { +public abstract class AbstractJpaBaseEntity implements BaseEntity,AcceptVisitor { private static final long serialVersionUID = 1L; @Id @@ -178,4 +178,9 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { return true; } + + @Override + public void postActionOnEntity(AbstractDescriptorEventVisitor visitor, DescriptorEventDetails eventDetails){ + visitor.publishEventPostAction(eventDetails); + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java new file mode 100644 index 000000000..78d89219b --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +/** + * Interface to accept visitor @link{AbstractDescriptorEventVisitor}. + * + */ +public interface AcceptVisitor { + public void postActionOnEntity(AbstractDescriptorEventVisitor visitor, + DescriptorEventDetails eventDetails); +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java new file mode 100644 index 000000000..a13d0700c --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * + * Holds details of action(Create/Update) and @link{DescriptorEvent}. + * + */ +public class DescriptorEventDetails { + + enum ActionType { + CREATE, UPDATE; + } + + private DescriptorEvent descriptorEvent; + + private ActionType actiontype; + + public DescriptorEventDetails(ActionType actionType, + DescriptorEvent descriptorEvent) { + this.descriptorEvent = descriptorEvent; + this.actiontype = actionType; + } + + public DescriptorEvent getDescriptorEvent() { + return descriptorEvent; + } + + public ActionType getActiontype() { + return actiontype; + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java index 2dd0fdb40..bdb366edb 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java @@ -8,28 +8,9 @@ */ package org.eclipse.hawkbit.repository.jpa.model; -import java.util.Map; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; +import org.eclipse.hawkbit.repository.jpa.model.DescriptorEventDetails.ActionType; import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEventAdapter; -import org.eclipse.persistence.internal.sessions.ObjectChangeSet; -import org.eclipse.persistence.queries.UpdateObjectQuery; -import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; - -import com.google.common.eventbus.EventBus; /** * Listens to change in property values of an entity. @@ -37,50 +18,19 @@ import com.google.common.eventbus.EventBus; */ public class EntityPropertyChangeListener extends DescriptorEventAdapter { - @Override - public void postInsert(final DescriptorEvent event) { - if (event.getObject().getClass().equals(Action.class)) { - final Action action = (Action) event.getObject(); - if (action.getRollout() != null) { - final EventBus eventBus = getEventBus(); - final AfterTransactionCommitExecutor afterCommit = getAfterTransactionCommmitExecutor(); - afterCommit.afterCommit(() -> eventBus.post(new ActionCreatedEvent(action))); - } - } + @Override + public void postInsert(final DescriptorEvent event) { + AbstractDescriptorEventVisitor visitor = new AbstractDescriptorEventVisitorImpl(); + ((AbstractJpaBaseEntity) event.getObject()).postActionOnEntity(visitor, + new DescriptorEventDetails(ActionType.CREATE, event)); - } + } - @Override - public void postUpdate(final DescriptorEvent event) { - if (event.getObject().getClass().equals(JpaAction.class)) { - getAfterTransactionCommmitExecutor().afterCommit(() -> getEventBus().post( - new ActionPropertyChangeEvent((Action) event.getObject(), getChangeSet(Action.class, event)))); - } else if (event.getObject().getClass().equals(JpaRollout.class)) { - getAfterTransactionCommmitExecutor().afterCommit(() -> getEventBus().post( - new RolloutPropertyChangeEvent((Rollout) event.getObject(), getChangeSet(Rollout.class, event)))); - } else if (event.getObject().getClass().equals(JpaRolloutGroup.class)) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new RolloutGroupPropertyChangeEvent((RolloutGroup) event.getObject(), - getChangeSet(RolloutGroup.class, event)))); - } - } - - private Map.Values> getChangeSet( - final Class clazz, final DescriptorEvent event) { - final T rolloutGroup = clazz.cast(event.getObject()); - final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet(); - return changeSet.getChanges().stream().filter(record -> record instanceof DirectToFieldChangeRecord) - .map(record -> (DirectToFieldChangeRecord) record) - .collect(Collectors.toMap(record -> record.getAttribute(), - record -> new AbstractPropertyChangeEvent(rolloutGroup, null).new Values( - record.getOldValue(), record.getNewValue()))); - } - - private AfterTransactionCommitExecutor getAfterTransactionCommmitExecutor() { - return AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit(); - } - - private EventBus getEventBus() { - return EventBusHolder.getInstance().getEventBus(); - } + @Override + public void postUpdate(final DescriptorEvent event) { + AbstractDescriptorEventVisitor visitor = new AbstractDescriptorEventVisitorImpl(); + ((AbstractJpaBaseEntity) event.getObject()).postActionOnEntity(visitor, + new DescriptorEventDetails(ActionType.UPDATE, event)); + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEventProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEventProvider.java index cca4bdd4c..f064a76a1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEventProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEventProvider.java @@ -12,25 +12,29 @@ import java.util.HashSet; import java.util.Set; import org.eclipse.hawkbit.eventbus.event.Event; -import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedBulkEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.eventbus.event.RolloutChangeEvent; import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupChangeEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedBulkEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; /** * The default hawkbit event provider. */ public class HawkbitEventProvider implements UIEventProvider { - private static final Set> SINGLE_EVENTS = new HashSet<>(6); - private static final Set> BULK_EVENTS = new HashSet<>(3); + private static final Set> SINGLE_EVENTS = new HashSet<>(9); + private static final Set> BULK_EVENTS = new HashSet<>(5); static { SINGLE_EVENTS.add(TargetTagCreatedBulkEvent.class); @@ -41,10 +45,14 @@ public class HawkbitEventProvider implements UIEventProvider { SINGLE_EVENTS.add(RolloutGroupChangeEvent.class); SINGLE_EVENTS.add(RolloutChangeEvent.class); SINGLE_EVENTS.add(TargetTagUpdateEvent.class); + SINGLE_EVENTS.add(DistributionSetUpdateEvent.class); BULK_EVENTS.add(TargetCreatedEvent.class); BULK_EVENTS.add(TargetInfoUpdateEvent.class); BULK_EVENTS.add(TargetDeletedEvent.class); + BULK_EVENTS.add(DistributionDeletedEvent.class); + BULK_EVENTS.add(DistributionCreatedEvent.class); + BULK_EVENTS.add(TargetUpdatedEvent.class); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index a52c0b683..9430dc135 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -21,6 +21,9 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleIdName; @@ -116,6 +119,33 @@ public class DistributionSetTable extends AbstractNamedVersionTable visibleItemIds = (List) getVisibleItemIds(); + + // refresh the details tabs only if selected ds is updated + if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) { + // update table row+details layout + eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, ds)); + } else if (visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent()) { + // update the name/version details visible in table + UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); + } + } + + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvents(final List events) { + final Object firstEvent = events.get(0); + if (DistributionCreatedEvent.class.isInstance(firstEvent)) { + refreshDistributions(); + } else if (DistributionDeletedEvent.class.isInstance(firstEvent)) { + onDistributionDeleteEvent((List) events); + } + } + @Override protected String getTableId() { return SPUIComponentIdProvider.DIST_TABLE_ID; @@ -422,11 +452,15 @@ public class DistributionSetTable extends AbstractNamedVersionTable updateDistributionInTable(event.getEntity())); } @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final SaveActionWindowEvent event) { - if (event == SaveActionWindowEvent.DELETED_DISTRIBUTIONS || event == SaveActionWindowEvent.SAVED_ASSIGNMENTS) { + if (event == SaveActionWindowEvent.SAVED_ASSIGNMENTS) { UI.getCurrent().access(() -> refreshFilter()); } } @@ -467,6 +501,78 @@ public class DistributionSetTable extends AbstractNamedVersionTable events) { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + final List visibleItemIds = (List) getVisibleItemIds(); + boolean shouldRefreshDs = false; + for (final DistributionDeletedEvent deletedEvent : events) { + Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); + for (Long dsId : distributionSetIDs) { + final DistributionSetIdName targetIdName = new DistributionSetIdName(dsId, null, null); + if (visibleItemIds.contains(targetIdName)) { + dsContainer.removeItem(targetIdName); + } else { + shouldRefreshDs = true; + } + } + } + + if (shouldRefreshDs) { + refreshOnDelete(); + } else { + dsContainer.commit(); + } + reSelectItemsAfterDeletionEvent(); + } + + private void refreshOnDelete() { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + final int size = dsContainer.size(); + refreshTablecontainer(); + if (size != 0) { + setData(SPUIDefinitions.DATA_AVAILABLE); + } + } + + private void reSelectItemsAfterDeletionEvent() { + Set values = new HashSet<>(); + if (isMultiSelect()) { + values = new HashSet<>((Set) getValue()); + } else { + values.add(getValue()); + } + setValue(null); + + for (final Object value : values) { + if (getVisibleItemIds().contains(value)) { + select(value); + } + } + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java index a262f0d20..efe28beb5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java @@ -42,7 +42,7 @@ import com.google.common.base.Strings; public class ManageDistBeanQuery extends AbstractBeanQuery { private static final long serialVersionUID = 5176481314404662215L; - private Sort sort = new Sort(Direction.ASC, "name", "version"); + private Sort sort = new Sort(Direction.ASC, "createdAt"); private String searchText = null; private transient DistributionSetManagement distributionSetManagement; private transient Page firstPageDistributionSets = null; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java index 35f88f5a1..80c9b0497 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java @@ -155,9 +155,9 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery { size = getTargetManagement().countTargetByTargetFilterQuery(filterQuery); } getFilterManagementUIState().setTargetsCountAll(size); - if (size > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { - getFilterManagementUIState().setTargetsTruncated(size - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); - size = SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES; + if (size > SPUIDefinitions.MAX_TABLE_ENTRIES) { + getFilterManagementUIState().setTargetsTruncated(size - SPUIDefinitions.MAX_TABLE_ENTRIES); + size = SPUIDefinitions.MAX_TABLE_ENTRIES; } else { getFilterManagementUIState().setTargetsTruncated(null); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java index 4700b48eb..c82467425 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java @@ -93,7 +93,7 @@ public class TargetFilterCountMessageLabel extends Label { // set the icon setIcon(FontAwesome.INFO_CIRCLE); setDescription(i18n.get("label.target.filter.truncated", filterManagementUIState.getTargetsTruncated(), - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES)); + SPUIDefinitions.MAX_TABLE_ENTRIES)); } else { setIcon(null); @@ -102,8 +102,8 @@ public class TargetFilterCountMessageLabel extends Label { targetMessage.append(totalTargets); targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE); targetMessage.append(i18n.get("label.filter.shown")); - if (totalTargets > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { - targetMessage.append(SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); + if (totalTargets > SPUIDefinitions.MAX_TABLE_ENTRIES) { + targetMessage.append(SPUIDefinitions.MAX_TABLE_ENTRIES); } else { targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE); targetMessage.append(totalTargets); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 5b5d53524..6c79f3b3d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -10,8 +10,10 @@ package org.eclipse.hawkbit.ui.management.dstable; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import javax.annotation.PostConstruct; @@ -23,10 +25,10 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; +import org.eclipse.hawkbit.ui.common.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; +import org.eclipse.hawkbit.ui.distributions.dstable.DistributionSetTable; import org.eclipse.hawkbit.ui.management.event.DragEvent; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; @@ -89,6 +91,9 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { @Autowired private transient EntityFactory entityFactory; + + @Autowired + private transient DistributionSetTable distributionSetTable; private TextField distNameTextField; private TextField distVersionTextField; @@ -243,8 +248,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { distributionSetManagement.updateDistributionSet(currentDS); notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success", new Object[] { currentDS.getName(), currentDS.getVersion() })); - // update table row+details layout - eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, currentDS)); } catch (final EntityAlreadyExistsException entityAlreadyExistsException) { LOG.error("Update distribution failed {}", entityAlreadyExistsException); notificationMessage.displayValidationError( @@ -289,8 +292,10 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { new Object[] { newDist.getName(), newDist.getVersion() })); /* close the window */ closeThisWindow(); - - eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.NEW_ENTITY, newDist)); + + final Set s = new HashSet<>(); + s.add(new DistributionSetIdName(newDist.getId(),newDist.getName(),newDist.getVersion())); + distributionSetTable.setValue(s); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java index 63ed91250..672cc0a1c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java @@ -41,7 +41,7 @@ import com.google.common.base.Strings; public class DistributionBeanQuery extends AbstractBeanQuery { private static final long serialVersionUID = 5862679853949173536L; - private Sort sort = new Sort(Direction.ASC, "name", "version"); + private Sort sort = new Sort(Direction.ASC, "createdAt"); private Collection distributionTags; private String searchText; private String pinnedControllerId; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index 5b265fc14..056abf12e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -20,6 +20,9 @@ import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.Target; @@ -105,6 +108,35 @@ public class DistributionTable extends AbstractNamedVersionTable events) { + final Object firstEvent = events.get(0); + if (DistributionDeletedEvent.class.isInstance(firstEvent)) { + onDistributionDeleteEvent((List) events); + } else if (DistributionCreatedEvent.class.isInstance(firstEvent) + && ((DistributionCreatedEvent) firstEvent).getEntity().isComplete()) { + refreshDistributions(); + } + + } + + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvents(final DistributionSetUpdateEvent event) { + final DistributionSet ds = event.getEntity(); + final DistributionSetIdName lastSelectedDsIdName = managementUIState.getLastSelectedDsIdName(); + final List visibleItemIds = (List) getVisibleItemIds(); + + // refresh the details tabs only if selected ds is updated + // refresh the details tabs only if selected ds is updated + if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) { + // update table row+details layout + eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, ds)); + } else if (visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent()) { + //update the name/version details visible in table + UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); + } + } + /** * DistributionTableFilterEvent. * @@ -658,4 +690,69 @@ public class DistributionTable extends AbstractNamedVersionTable events) { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + final List visibleItemIds = (List) getVisibleItemIds(); + boolean shouldRefreshDs = false; + for (final DistributionDeletedEvent deletedEvent : events) { + Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); + for (Long dsId : distributionSetIDs) { + final DistributionSetIdName targetIdName = new DistributionSetIdName(dsId, null, null); + if (visibleItemIds.contains(targetIdName)) { + dsContainer.removeItem(targetIdName); + } else { + shouldRefreshDs = true; + } + } + } + + if (shouldRefreshDs) { + refreshOnDelete(); + } else { + dsContainer.commit(); + } + reSelectItemsAfterDeletionEvent(); + } + + private void reSelectItemsAfterDeletionEvent() { + Set values = new HashSet<>(); + if (isMultiSelect()) { + values = new HashSet<>((Set) getValue()); + } else { + values.add(getValue()); + } + setValue(null); + + for (final Object value : values) { + if (getVisibleItemIds().contains(value)) { + select(value); + } + } + } + + private void refreshDistributions() { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + final int size = dsContainer.size(); + if (size < SPUIDefinitions.MAX_TABLE_ENTRIES) { + refreshTablecontainer(); + } + if (size != 0) { + setData(SPUIDefinitions.DATA_AVAILABLE); + } + } + + private void refreshOnDelete() { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + final int size = dsContainer.size(); + refreshTablecontainer(); + if (size != 0) { + setData(SPUIDefinitions.DATA_AVAILABLE); + } + } + + private void refreshTablecontainer() { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + dsContainer.refresh(); + selectRow(); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java index fccee7cb5..6cf01410d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java @@ -174,7 +174,7 @@ public class CountMessageLabel extends Label { // set the icon setIcon(FontAwesome.INFO_CIRCLE); setDescription(i18n.get("label.target.filter.truncated", managementUIState.getTargetsTruncated(), - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES)); + SPUIDefinitions.MAX_TABLE_ENTRIES)); totalTargetTableEnteries += managementUIState.getTargetsTruncated(); } else { setIcon(null); @@ -184,9 +184,9 @@ public class CountMessageLabel extends Label { final StringBuilder message = new StringBuilder(i18n.get("label.target.filter.count")); message.append(managementUIState.getTargetsCountAll()); message.append(HawkbitCommonUtil.SP_STRING_SPACE); - if (totalTargetTableEnteries > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { + if (totalTargetTableEnteries > SPUIDefinitions.MAX_TABLE_ENTRIES) { message.append(i18n.get("label.filter.shown")); - message.append(SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); + message.append(SPUIDefinitions.MAX_TABLE_ENTRIES); } else { if (!targFilParams.hasFilter()) { message.append(i18n.get("label.filter.shown")); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java index 1a9d3572f..e4c56b165 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java @@ -387,7 +387,6 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin managementUIState.getTargetTableFilters().getPinnedDistId() .ifPresent(distId -> unPinDeletedDS(deletedIds, distId)); - eventBus.publish(this, SaveActionWindowEvent.DELETED_DISTRIBUTIONS); managementUIState.getDeletedDistributionList().clear(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java index e96a9af8e..6ce3c5cb6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java @@ -190,9 +190,9 @@ public class TargetBeanQuery extends AbstractBeanQuery { final ManagementUIState tmpManagementUIState = getManagementUIState(); tmpManagementUIState.setTargetsCountAll(totSize); - if (size > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { - tmpManagementUIState.setTargetsTruncated(size - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); - size = SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES; + if (size > SPUIDefinitions.MAX_TABLE_ENTRIES) { + tmpManagementUIState.setTargetsTruncated(size - SPUIDefinitions.MAX_TABLE_ENTRIES); + size = SPUIDefinitions.MAX_TABLE_ENTRIES; } else { tmpManagementUIState.setTargetsTruncated(null); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java index 0a70f60d5..0a0eaaa7e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java @@ -17,11 +17,12 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.repository.model.TargetInfo; @@ -142,6 +143,8 @@ public class TargetTable extends AbstractTable { onTargetInfoUpdateEvents((List) events); } else if (TargetDeletedEvent.class.isInstance(firstEvent)) { onTargetDeletedEvent((List) events); + } else if(TargetUpdatedEvent.class.isInstance(firstEvent)){ + onTargetUpdateEvents((List) events); } } @@ -809,7 +812,7 @@ public class TargetTable extends AbstractTable { private void refreshTargets() { final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource(); final int size = targetContainer.size(); - if (size < SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { + if (size < SPUIDefinitions.MAX_TABLE_ENTRIES) { refreshTablecontainer(); } else { // If table is not refreshed , explicitly target total count and @@ -829,10 +832,12 @@ public class TargetTable extends AbstractTable { final TargetIdName targetIdName) { final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource(); final Item item = targetContainer.getItem(targetIdName); - item.getItemProperty(SPUILabelDefinitions.VAR_TARGET_STATUS).setValue(targetInfo.getUpdateStatus()); item.getItemProperty(SPUILabelDefinitions.VAR_NAME).setValue(target.getName()); - item.getItemProperty(SPUILabelDefinitions.VAR_POLL_STATUS_TOOL_TIP) - .setValue(HawkbitCommonUtil.getPollStatusToolTip(targetInfo.getPollStatus(), i18n)); + if (targetInfo != null) { + item.getItemProperty(SPUILabelDefinitions.VAR_POLL_STATUS_TOOL_TIP).setValue( + HawkbitCommonUtil.getPollStatusToolTip(targetInfo.getPollStatus(), i18n)); + item.getItemProperty(SPUILabelDefinitions.VAR_TARGET_STATUS).setValue(targetInfo.getUpdateStatus()); + } } private boolean isLastSelectedTarget(final TargetIdName targetIdName) { @@ -879,6 +884,35 @@ public class TargetTable extends AbstractTable { } } + + private void onTargetUpdateEvents(List events) { + final List visibleItemIds = (List) getVisibleItemIds(); + boolean shoulTargetsUpdated = false; + Target lastSelectedTarget = null; + for (final TargetUpdatedEvent targetUpdatedEvent : events) { + Target target = targetUpdatedEvent.getEntity(); + final TargetIdName targetIdName = target.getTargetIdName(); + if (Filters.or(getTargetTableFilters(target)).doFilter()) { + shoulTargetsUpdated = true; + } else { + if (visibleItemIds.contains(targetIdName)) { + updateVisibleItemOnEvent(null, target, targetIdName); + } + } + if (isLastSelectedTarget(targetIdName)) { + lastSelectedTarget = target; + } + } + if (shoulTargetsUpdated) { + refreshTargets(); + } + if (lastSelectedTarget != null) { + eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, lastSelectedTarget)); + } + } + + + private void onTargetCreatedEvents() { refreshTargets(); } @@ -953,8 +987,8 @@ public class TargetTable extends AbstractTable { size = getTargetsCountWithFilter(totalTargetsCount, status, targetTags, distributionId, searchText, noTagClicked, pinnedDistId); - if (size > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { - managementUIState.setTargetsTruncated(size - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); + if (size > SPUIDefinitions.MAX_TABLE_ENTRIES) { + managementUIState.setTargetsTruncated(size - SPUIDefinitions.MAX_TABLE_ENTRIES); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsBeanQuery.java index 685be685e..487f05ae5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsBeanQuery.java @@ -140,9 +140,9 @@ public class RolloutGroupTargetsBeanQuery extends AbstractBeanQuery size = firstPageTargetSets.getTotalElements(); } getRolloutUIState().setRolloutGroupTargetsTotalCount(size); - if (size > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { - getRolloutUIState().setRolloutGroupTargetsTruncated(size - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); - return SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES; + if (size > SPUIDefinitions.MAX_TABLE_ENTRIES) { + getRolloutUIState().setRolloutGroupTargetsTruncated(size - SPUIDefinitions.MAX_TABLE_ENTRIES); + return SPUIDefinitions.MAX_TABLE_ENTRIES; } return (int) size; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java index c791a0eb2..e5c716e83 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java @@ -94,7 +94,7 @@ public class RolloutGroupTargetsCountLabelMessage extends Label { // set the icon setIcon(FontAwesome.INFO_CIRCLE); setDescription(i18n.get("rollout.group.label.target.truncated", - rolloutUIState.getRolloutGroupTargetsTruncated(), SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES)); + rolloutUIState.getRolloutGroupTargetsTruncated(), SPUIDefinitions.MAX_TABLE_ENTRIES)); totalTargetTableEnteries += rolloutUIState.getRolloutGroupTargetsTruncated(); } else { setIcon(null); @@ -104,9 +104,9 @@ public class RolloutGroupTargetsCountLabelMessage extends Label { final StringBuilder message = new StringBuilder(i18n.get("label.target.filter.count")); message.append(rolloutUIState.getRolloutGroupTargetsTotalCount()); message.append(HawkbitCommonUtil.SP_STRING_SPACE); - if (totalTargetTableEnteries > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { + if (totalTargetTableEnteries > SPUIDefinitions.MAX_TABLE_ENTRIES) { message.append(i18n.get("label.filter.shown")); - message.append(SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); + message.append(SPUIDefinitions.MAX_TABLE_ENTRIES); } else { message.append(i18n.get("label.filter.shown")); message.append(rolloutGroupTargetsListGrid.getContainerDataSource().size()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java index 1a6e8c163..1766485f6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java @@ -268,10 +268,6 @@ public final class SPUIDefinitions { * New Target save icon id. */ public static final String NEW_TARGET_SAVE = "target.add.save"; - /** - * New Target discard icon id. - */ - // public static final String NEW_TARGET_DISCARD = "target.add.discard"; /** * New Target add icon id. */ @@ -344,15 +340,6 @@ public final class SPUIDefinitions { * New Target tag color lable id. */ public static final String NEW_TARGET_TAG_COLOR = "target.tag.add.color"; - /** - * New Target tag save icon id. - */ - // public static final String NEW_TARGET_TAG_SAVE = "target.tag.add.save"; - /** - * New Target tag discard icon id. - */ - // public static final String NEW_TARGET_TAG_DISRACD = - // "target.tag.add.discard"; /** * New Target tag add icon id. */ @@ -860,7 +847,7 @@ public final class SPUIDefinitions { * truncates it. This protects to endless scroll to very high page numbers * which is very in performant. */ - public static final int MAX_TARGET_TABLE_ENTRIES = 5000; + public static final int MAX_TABLE_ENTRIES = 5000; /** * New software module set type add icon id. From 5f1db53defb244763315731257b1a9d85cfec6c1 Mon Sep 17 00:00:00 2001 From: GAH6KOR Date: Thu, 21 Jul 2016 12:39:54 +0200 Subject: [PATCH 02/42] Removed the extra level of abstraction and modified the code accordingly. --- .../AbstractDescriptorEventVisitorImpl.java | 189 ----- .../jpa/model/AbstractJpaBaseEntity.java | 6 +- .../repository/jpa/model/AcceptVisitor.java | 18 - .../model/EntityPropertyChangeListener.java | 31 +- ...ventVisitor.java => EventAwareEntity.java} | 17 +- .../repository/jpa/model/JpaAction.java | 373 +++++----- .../jpa/model/JpaDistributionSet.java | 602 ++++++++-------- .../repository/jpa/model/JpaRollout.java | 423 +++++------ .../repository/jpa/model/JpaRolloutGroup.java | 500 ++++++------- .../repository/jpa/model/JpaTarget.java | 491 +++++++------ .../repository/jpa/model/JpaTargetInfo.java | 668 +++++++++--------- .../helper/EntityPropertyChangeHelper.java | 42 ++ 12 files changed, 1673 insertions(+), 1687 deletions(-) delete mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java delete mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java rename hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/{AbstractDescriptorEventVisitor.java => EventAwareEntity.java} (53%) create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java deleted file mode 100644 index 8755f8051..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Map; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; -import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; -import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; -import org.eclipse.hawkbit.repository.jpa.model.DescriptorEventDetails.ActionType; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; -import org.eclipse.persistence.descriptors.DescriptorEvent; -import org.eclipse.persistence.internal.sessions.ObjectChangeSet; -import org.eclipse.persistence.queries.UpdateObjectQuery; -import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.eventbus.EventBus; - -/** - * Implementation of @link{AbstractDescriptorEventVisitor} .Publishes the - * appropriate event after any action on entity like create/update. - * - */ -public class AbstractDescriptorEventVisitorImpl implements - AbstractDescriptorEventVisitor { - - private static final String COMPLETE = "complete"; - private static final Logger LOG = LoggerFactory - .getLogger(AbstractDescriptorEventVisitorImpl.class); - - @Override - public void publishEventPostAction(final DescriptorEventDetails event) { - Method method = null; - DescriptorEvent descriptorEvent = event.getDescriptorEvent(); - ActionType actiontype = event.getActiontype(); - try { - method = getMethod(descriptorEvent, actiontype); - if (method != null) { - method.invoke(this, descriptorEvent.getObject(), - descriptorEvent); - } - } catch (NoSuchMethodException | SecurityException - | IllegalAccessException | IllegalArgumentException - | InvocationTargetException e) { - LOG.info( - "Exception when invoking approriate method to publis event {}", - e); - } - } - - private Method getMethod(DescriptorEvent descriptorEvent, - ActionType actiontype) throws NoSuchMethodException { - if (actiontype == ActionType.UPDATE) { - return this.getClass().getMethod("publishEventAfterUpdate", - descriptorEvent.getObject().getClass(), - DescriptorEvent.class); - } else if (actiontype == ActionType.CREATE) { - return this.getClass().getMethod("publishEventAfterCreate", - descriptorEvent.getObject().getClass(), - DescriptorEvent.class); - } - return null; - } - - public void publishEventAfterCreate(JpaAction action, DescriptorEvent event) { - if (action.getRollout() != null) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new ActionCreatedEvent(action))); - } - } - - public void publishEventAfterCreate(JpaTarget target, DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new TargetCreatedEvent(target))); - } - - public void publishEventAfterCreate(JpaDistributionSet ds, - DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new DistributionCreatedEvent(ds))); - - } - - public void publishEventAfterUpdate(JpaAction action, DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post( - new ActionPropertyChangeEvent(action, getChangeSet( - Action.class, event)))); - } - - public void publishEventAfterUpdate(JpaTarget target, DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new TargetUpdatedEvent(target))); - } - - public void publishEventAfterUpdate(JpaTargetInfo targetInfo, - DescriptorEvent event) { - getAfterTransactionCommmitExecutor() - .afterCommit( - () -> getEventBus().post( - new TargetInfoUpdateEvent(targetInfo))); - } - - public void publishEventAfterUpdate(JpaRollout entity, DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post( - new RolloutPropertyChangeEvent(entity, getChangeSet( - Rollout.class, event)))); - } - - public void publishEventAfterUpdate(JpaRolloutGroup entity, - DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post( - new RolloutGroupPropertyChangeEvent(entity, - getChangeSet(RolloutGroup.class, event)))); - - } - - public void publishEventAfterUpdate(JpaDistributionSet entity, - DescriptorEvent event) { - Map.Values> changeSet = getChangeSet( - JpaDistributionSet.class, event); - if (changeSet.containsKey(COMPLETE) - && changeSet.get(COMPLETE).getOldValue().equals(false) - && changeSet.get(COMPLETE).getNewValue().equals(true)) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post( - new DistributionCreatedEvent(entity))); - } - - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus() - .post(new DistributionSetUpdateEvent(entity))); - - } - - private Map.Values> getChangeSet( - final Class clazz, final DescriptorEvent event) { - final T rolloutGroup = clazz.cast(event.getObject()); - final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()) - .getObjectChangeSet(); - return changeSet - .getChanges() - .stream() - .filter(record -> record instanceof DirectToFieldChangeRecord) - .map(record -> (DirectToFieldChangeRecord) record) - .collect( - Collectors.toMap( - record -> record.getAttribute(), - record -> new AbstractPropertyChangeEvent( - rolloutGroup, null).new Values(record - .getOldValue(), record.getNewValue()))); - } - - private AfterTransactionCommitExecutor getAfterTransactionCommmitExecutor() { - return AfterTransactionCommitExecutorHolder.getInstance() - .getAfterCommit(); - } - - private EventBus getEventBus() { - return EventBusHolder.getInstance().getEventBus(); - } - -} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index 2785676fb..c2e91afea 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -32,7 +32,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @MappedSuperclass @Access(AccessType.FIELD) @EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class }) -public abstract class AbstractJpaBaseEntity implements BaseEntity,AcceptVisitor { +public abstract class AbstractJpaBaseEntity implements BaseEntity { private static final long serialVersionUID = 1L; @Id @@ -179,8 +179,4 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity,AcceptVisitor } - @Override - public void postActionOnEntity(AbstractDescriptorEventVisitor visitor, DescriptorEventDetails eventDetails){ - visitor.publishEventPostAction(eventDetails); - } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java deleted file mode 100644 index 78d89219b..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -/** - * Interface to accept visitor @link{AbstractDescriptorEventVisitor}. - * - */ -public interface AcceptVisitor { - public void postActionOnEntity(AbstractDescriptorEventVisitor visitor, - DescriptorEventDetails eventDetails); -} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java index bdb366edb..df36309df 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.repository.jpa.model; -import org.eclipse.hawkbit.repository.jpa.model.DescriptorEventDetails.ActionType; import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEventAdapter; @@ -18,19 +17,23 @@ import org.eclipse.persistence.descriptors.DescriptorEventAdapter; */ public class EntityPropertyChangeListener extends DescriptorEventAdapter { - @Override - public void postInsert(final DescriptorEvent event) { - AbstractDescriptorEventVisitor visitor = new AbstractDescriptorEventVisitorImpl(); - ((AbstractJpaBaseEntity) event.getObject()).postActionOnEntity(visitor, - new DescriptorEventDetails(ActionType.CREATE, event)); + @Override + public void postInsert(final DescriptorEvent event) { + + final Object object = event.getObject(); + if (object instanceof EventAwareEntity) { + ((EventAwareEntity) object).fireCreateEvent(object,event); + } + } + + @Override + public void postUpdate(final DescriptorEvent event) { + + final Object object = event.getObject(); + if (object instanceof EventAwareEntity) { + ((EventAwareEntity) object).fireUpdateEvent(object,event); + } + } - } - @Override - public void postUpdate(final DescriptorEvent event) { - AbstractDescriptorEventVisitor visitor = new AbstractDescriptorEventVisitorImpl(); - ((AbstractJpaBaseEntity) event.getObject()).postActionOnEntity(visitor, - new DescriptorEventDetails(ActionType.UPDATE, event)); - } - } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java similarity index 53% rename from hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java rename to hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java index ce32b025f..2c1fe51d2 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java @@ -8,12 +8,13 @@ */ package org.eclipse.hawkbit.repository.jpa.model; -/** - * - * Interface defining the action to be performed after entity is - * created/updated. - * - */ -public interface AbstractDescriptorEventVisitor { - void publishEventPostAction(DescriptorEventDetails eventDetails); +import org.eclipse.persistence.descriptors.DescriptorEvent; + +public interface EventAwareEntity { + + public void fireCreateEvent(T t,DescriptorEvent descriptorEvent); + + public void fireUpdateEvent(T t,DescriptorEvent descriptorEvent); + + public void fireDeleteEvent(T t,DescriptorEvent descriptorEvent); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java index 5fa2c3bed..fc879aa87 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -1,174 +1,199 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.NamedEntityGraphs; -import javax.persistence.NamedSubgraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.ActionStatus; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.persistence.annotations.CascadeOnDelete; - -/** - * JPA implementation of {@link Action}. - */ -@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"), - @Index(name = "sp_idx_action_02", columnList = "tenant,target,active"), - @Index(name = "sp_idx_action_prim", columnList = "tenant,id") }) -@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }), - @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), - @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) }) -@Entity -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action { - private static final long serialVersionUID = 1L; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds")) - private JpaDistributionSet distributionSet; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target")) - private JpaTarget target; - - @Column(name = "active") - private boolean active; - - @Column(name = "action_type", nullable = false) - @Enumerated(EnumType.STRING) - private ActionType actionType; - - @Column(name = "forced_time") - private long forcedTime; - - @Column(name = "status") - private Status status; - - @CascadeOnDelete - @OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { - CascadeType.REMOVE }) - private List actionStatus; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) - private JpaRolloutGroup rolloutGroup; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) - private JpaRollout rollout; - - @Override - public DistributionSet getDistributionSet() { - return distributionSet; - } - - @Override - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = (JpaDistributionSet) distributionSet; - } - - public void setActive(final boolean active) { - this.active = active; - } - - @Override - public Status getStatus() { - return status; - } - - @Override - public void setStatus(final Status status) { - this.status = status; - } - - @Override - public boolean isActive() { - return active; - } - - public void setActionType(final ActionType actionType) { - this.actionType = actionType; - } - - @Override - public ActionType getActionType() { - return actionType; - } - - @Override - public List getActionStatus() { - return actionStatus; - } - - @Override - public void setTarget(final Target target) { - this.target = (JpaTarget) target; - } - - @Override - public Target getTarget() { - return target; - } - - @Override - public long getForcedTime() { - return forcedTime; - } - - public void setForcedTime(final long forcedTime) { - this.forcedTime = forcedTime; - } - - @Override - public RolloutGroup getRolloutGroup() { - return rolloutGroup; - } - - public void setRolloutGroup(final RolloutGroup rolloutGroup) { - this.rolloutGroup = (JpaRolloutGroup) rolloutGroup; - } - - @Override - public Rollout getRollout() { - return rollout; - } - - public void setRollout(final Rollout rollout) { - this.rollout = (JpaRollout) rollout; - } - - @Override - public String toString() { - return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]"; - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.NamedEntityGraphs; +import javax.persistence.NamedSubgraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.ActionStatus; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA implementation of {@link Action}. + */ +@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"), + @Index(name = "sp_idx_action_02", columnList = "tenant,target,active"), + @Index(name = "sp_idx_action_prim", columnList = "tenant,id") }) +@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }), + @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), + @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) }) +@Entity +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action,EventAwareEntity { + private static final long serialVersionUID = 1L; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds")) + private JpaDistributionSet distributionSet; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target")) + private JpaTarget target; + + @Column(name = "active") + private boolean active; + + @Column(name = "action_type", nullable = false) + @Enumerated(EnumType.STRING) + private ActionType actionType; + + @Column(name = "forced_time") + private long forcedTime; + + @Column(name = "status") + private Status status; + + @CascadeOnDelete + @OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { + CascadeType.REMOVE }) + private List actionStatus; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) + private JpaRolloutGroup rolloutGroup; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) + private JpaRollout rollout; + + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + public void setActive(final boolean active) { + this.active = active; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public void setStatus(final Status status) { + this.status = status; + } + + @Override + public boolean isActive() { + return active; + } + + public void setActionType(final ActionType actionType) { + this.actionType = actionType; + } + + @Override + public ActionType getActionType() { + return actionType; + } + + @Override + public List getActionStatus() { + return actionStatus; + } + + @Override + public void setTarget(final Target target) { + this.target = (JpaTarget) target; + } + + @Override + public Target getTarget() { + return target; + } + + @Override + public long getForcedTime() { + return forcedTime; + } + + public void setForcedTime(final long forcedTime) { + this.forcedTime = forcedTime; + } + + @Override + public RolloutGroup getRolloutGroup() { + return rolloutGroup; + } + + public void setRolloutGroup(final RolloutGroup rolloutGroup) { + this.rolloutGroup = (JpaRolloutGroup) rolloutGroup; + } + + @Override + public Rollout getRollout() { + return rollout; + } + + public void setRollout(final Rollout rollout) { + this.rollout = (JpaRollout) rollout; + } + + @Override + public String toString() { + return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); + + } + + @Override + public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus(). + post(new ActionPropertyChangeEvent(jpaAction, EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); + + } + + + @Override + public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index 676215424..af8984286 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -1,282 +1,320 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; -import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.persistence.annotations.CascadeOnDelete; - -/** - * Jpa implementation of {@link DistributionSet}. - * - */ -@Entity -@Table(name = "sp_distribution_set", uniqueConstraints = { - @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { - @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"), - @Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"), - @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) -@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), - @NamedAttributeNode("tags"), @NamedAttributeNode("type") }) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet { - private static final long serialVersionUID = 1L; - - @Column(name = "required_migration_step") - private boolean requiredMigrationStep; - - @ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY) - @JoinTable(name = "sp_ds_module", joinColumns = { - @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = { - @JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) }) - private final Set modules = new HashSet<>(); - - @ManyToMany(targetEntity = JpaDistributionSetTag.class) - @JoinTable(name = "sp_ds_dstag", joinColumns = { - @JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = { - @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) - private Set tags = new HashSet<>(); - - @Column(name = "deleted") - private boolean deleted; - - @OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY) - private List assignedToTargets; - - @OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY) - private List installedAtTargets; - - @OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY) - private List actions; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = { - CascadeType.REMOVE }) - @JoinColumn(name = "ds_id", insertable = false, updatable = false) - private final List metadata = new ArrayList<>(); - - @ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class) - @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) - private DistributionSetType type; - - @Column(name = "complete") - private boolean complete; - - /** - * Default constructor. - */ - public JpaDistributionSet() { - super(); - } - - /** - * Parameterized constructor. - * - * @param name - * of the {@link DistributionSet} - * @param version - * of the {@link DistributionSet} - * @param description - * of the {@link DistributionSet} - * @param type - * of the {@link DistributionSet} - * @param moduleList - * {@link SoftwareModule}s of the {@link DistributionSet} - */ - public JpaDistributionSet(final String name, final String version, final String description, - final DistributionSetType type, final Collection moduleList) { - super(name, version, description); - - this.type = type; - if (moduleList != null) { - moduleList.forEach(this::addModule); - } - if (this.type != null) { - complete = this.type.checkComplete(this); - } - } - - @Override - public Set getTags() { - return tags; - } - - @Override - public boolean isDeleted() { - return deleted; - } - - @Override - public List getMetadata() { - return Collections.unmodifiableList(metadata); - } - - public List getActions() { - return actions; - } - - @Override - public boolean isRequiredMigrationStep() { - return requiredMigrationStep; - } - - @Override - public DistributionSet setDeleted(final boolean deleted) { - this.deleted = deleted; - return this; - } - - @Override - public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) { - requiredMigrationStep = isRequiredMigrationStep; - return this; - } - - public DistributionSet setTags(final Set tags) { - this.tags = tags; - return this; - } - - @Override - public List getAssignedTargets() { - return assignedToTargets; - } - - @Override - public List getInstalledTargets() { - return installedAtTargets; - } - - @Override - public String toString() { - return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision() - + ", getId()=" + getId() + "]"; - } - - @Override - public Set getModules() { - return Collections.unmodifiableSet(modules); - } - - @Override - public boolean addModule(final SoftwareModule softwareModule) { - - // we cannot allow that modules are added without a type defined - if (type == null) { - throw new DistributionSetTypeUndefinedException(); - } - - // check if it is allowed to such a module to this DS type - if (!type.containsModuleType(softwareModule.getType())) { - throw new UnsupportedSoftwareModuleForThisDistributionSetException(); - } - - final Optional found = modules.stream() - .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); - - if (found.isPresent()) { - return false; - } - - final long allready = modules.stream() - .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count(); - - if (allready >= softwareModule.getType().getMaxAssignments()) { - final Optional sameKey = modules.stream() - .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst(); - modules.remove(sameKey.get()); - } - - if (modules.add(softwareModule)) { - complete = type.checkComplete(this); - return true; - } - - return false; - } - - @Override - public boolean removeModule(final SoftwareModule softwareModule) { - final Optional found = modules.stream() - .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); - - if (found.isPresent()) { - modules.remove(found.get()); - complete = type.checkComplete(this); - return true; - } - - return false; - - } - - @Override - public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { - final Optional result = modules.stream().filter(module -> module.getType().equals(type)) - .findFirst(); - - if (result.isPresent()) { - return result.get(); - } - - return null; - } - - @Override - public DistributionSetType getType() { - return type; - } - - @Override - public void setType(final DistributionSetType type) { - this.type = type; - } - - @Override - public boolean isComplete() { - return complete; - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; +import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; +import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * Jpa implementation of {@link DistributionSet}. + * + */ +@Entity +@Table(name = "sp_distribution_set", uniqueConstraints = { + @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { + @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"), + @Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"), + @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) +@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), + @NamedAttributeNode("tags"), @NamedAttributeNode("type") }) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet,EventAwareEntity { + private static final long serialVersionUID = 1L; + + private static final String COMPLETE = "complete"; + + @Column(name = "required_migration_step") + private boolean requiredMigrationStep; + + @ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY) + @JoinTable(name = "sp_ds_module", joinColumns = { + @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = { + @JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) }) + private final Set modules = new HashSet<>(); + + @ManyToMany(targetEntity = JpaDistributionSetTag.class) + @JoinTable(name = "sp_ds_dstag", joinColumns = { + @JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = { + @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) + private Set tags = new HashSet<>(); + + @Column(name = "deleted") + private boolean deleted; + + @OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY) + private List assignedToTargets; + + @OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY) + private List installedAtTargets; + + @OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY) + private List actions; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = { + CascadeType.REMOVE }) + @JoinColumn(name = "ds_id", insertable = false, updatable = false) + private final List metadata = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class) + @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) + private DistributionSetType type; + + @Column(name = "complete") + private boolean complete; + + /** + * Default constructor. + */ + public JpaDistributionSet() { + super(); + } + + /** + * Parameterized constructor. + * + * @param name + * of the {@link DistributionSet} + * @param version + * of the {@link DistributionSet} + * @param description + * of the {@link DistributionSet} + * @param type + * of the {@link DistributionSet} + * @param moduleList + * {@link SoftwareModule}s of the {@link DistributionSet} + */ + public JpaDistributionSet(final String name, final String version, final String description, + final DistributionSetType type, final Collection moduleList) { + super(name, version, description); + + this.type = type; + if (moduleList != null) { + moduleList.forEach(this::addModule); + } + if (this.type != null) { + complete = this.type.checkComplete(this); + } + } + + @Override + public Set getTags() { + return tags; + } + + @Override + public boolean isDeleted() { + return deleted; + } + + @Override + public List getMetadata() { + return Collections.unmodifiableList(metadata); + } + + public List getActions() { + return actions; + } + + @Override + public boolean isRequiredMigrationStep() { + return requiredMigrationStep; + } + + @Override + public DistributionSet setDeleted(final boolean deleted) { + this.deleted = deleted; + return this; + } + + @Override + public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) { + requiredMigrationStep = isRequiredMigrationStep; + return this; + } + + public DistributionSet setTags(final Set tags) { + this.tags = tags; + return this; + } + + @Override + public List getAssignedTargets() { + return assignedToTargets; + } + + @Override + public List getInstalledTargets() { + return installedAtTargets; + } + + @Override + public String toString() { + return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision() + + ", getId()=" + getId() + "]"; + } + + @Override + public Set getModules() { + return Collections.unmodifiableSet(modules); + } + + @Override + public boolean addModule(final SoftwareModule softwareModule) { + + // we cannot allow that modules are added without a type defined + if (type == null) { + throw new DistributionSetTypeUndefinedException(); + } + + // check if it is allowed to such a module to this DS type + if (!type.containsModuleType(softwareModule.getType())) { + throw new UnsupportedSoftwareModuleForThisDistributionSetException(); + } + + final Optional found = modules.stream() + .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); + + if (found.isPresent()) { + return false; + } + + final long allready = modules.stream() + .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count(); + + if (allready >= softwareModule.getType().getMaxAssignments()) { + final Optional sameKey = modules.stream() + .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst(); + modules.remove(sameKey.get()); + } + + if (modules.add(softwareModule)) { + complete = type.checkComplete(this); + return true; + } + + return false; + } + + @Override + public boolean removeModule(final SoftwareModule softwareModule) { + final Optional found = modules.stream() + .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); + + if (found.isPresent()) { + modules.remove(found.get()); + complete = type.checkComplete(this); + return true; + } + + return false; + + } + + @Override + public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { + final Optional result = modules.stream().filter(module -> module.getType().equals(type)) + .findFirst(); + + if (result.isPresent()) { + return result.get(); + } + + return null; + } + + @Override + public DistributionSetType getType() { + return type; + } + + @Override + public void setType(final DistributionSetType type) { + this.type = type; + } + + @Override + public boolean isComplete() { + return complete; + } + + @Override + public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); + + } + + @Override + public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + final Map.Values> changeSet = EntityPropertyChangeHelper.getChangeSet( + JpaDistributionSet.class, descriptorEvent); + if (changeSet.containsKey(COMPLETE) + && changeSet.get(COMPLETE).getOldValue().equals(false) + && changeSet.get(COMPLETE).getNewValue().equals(true)) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post( + new DistributionCreatedEvent(jpaDistributionSet))); + } + + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); + + } + + @Override + public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java index 3cbe65717..73d19086d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java @@ -1,200 +1,223 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.util.List; - -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.jpa.cache.CacheField; -import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; -import org.eclipse.hawkbit.repository.model.Action.ActionType; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; - -/** - * JPA implementation of a {@link Rollout}. - * - */ -@Entity -@Table(name = "sp_rollout", indexes = { - @Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "tenant" }, name = "uk_rollout")) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaRollout extends AbstractJpaNamedEntity implements Rollout { - - private static final long serialVersionUID = 1L; - - @OneToMany(targetEntity = JpaRolloutGroup.class) - @JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup")) - private List rolloutGroups; - - @Column(name = "target_filter", length = 1024, nullable = false) - private String targetFilterQuery; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) - private JpaDistributionSet distributionSet; - - @Column(name = "status") - private RolloutStatus status = RolloutStatus.CREATING; - - @Column(name = "last_check") - private long lastCheck; - - @Column(name = "action_type", nullable = false) - @Enumerated(EnumType.STRING) - private ActionType actionType = ActionType.FORCED; - - @Column(name = "forced_time") - private long forcedTime; - - @Column(name = "total_targets") - private long totalTargets; - - @Transient - @CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL) - private int rolloutGroupsTotal; - - @Transient - @CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED) - private int rolloutGroupsCreated; - - @Transient - private transient TotalTargetCountStatus totalTargetCountStatus; - - @Override - public DistributionSet getDistributionSet() { - return distributionSet; - } - - @Override - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = (JpaDistributionSet) distributionSet; - } - - @Override - public List getRolloutGroups() { - return rolloutGroups; - } - - public void setRolloutGroups(final List rolloutGroups) { - this.rolloutGroups = rolloutGroups; - } - - @Override - public String getTargetFilterQuery() { - return targetFilterQuery; - } - - @Override - public void setTargetFilterQuery(final String targetFilterQuery) { - this.targetFilterQuery = targetFilterQuery; - } - - @Override - public RolloutStatus getStatus() { - return status; - } - - public void setStatus(final RolloutStatus status) { - this.status = status; - } - - public long getLastCheck() { - return lastCheck; - } - - public void setLastCheck(final long lastCheck) { - this.lastCheck = lastCheck; - } - - @Override - public ActionType getActionType() { - return actionType; - } - - @Override - public void setActionType(final ActionType actionType) { - this.actionType = actionType; - } - - @Override - public long getForcedTime() { - return forcedTime; - } - - @Override - public void setForcedTime(final long forcedTime) { - this.forcedTime = forcedTime; - } - - @Override - public long getTotalTargets() { - return totalTargets; - } - - public void setTotalTargets(final long totalTargets) { - this.totalTargets = totalTargets; - } - - public int getRolloutGroupsTotal() { - return rolloutGroupsTotal; - } - - public void setRolloutGroupsTotal(final int rolloutGroupsTotal) { - this.rolloutGroupsTotal = rolloutGroupsTotal; - } - - @Override - public int getRolloutGroupsCreated() { - return rolloutGroupsCreated; - } - - public void setRolloutGroupsCreated(final int rolloutGroupsCreated) { - this.rolloutGroupsCreated = rolloutGroupsCreated; - } - - @Override - public TotalTargetCountStatus getTotalTargetCountStatus() { - if (totalTargetCountStatus == null) { - totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); - } - return totalTargetCountStatus; - } - - public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { - this.totalTargetCountStatus = totalTargetCountStatus; - } - - @Override - public String toString() { - return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery - + ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck - + ", getName()=" + getName() + ", getId()=" + getId() + "]"; - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.cache.CacheField; +import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action.ActionType; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA implementation of a {@link Rollout}. + * + */ +@Entity +@Table(name = "sp_rollout", indexes = { + @Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "tenant" }, name = "uk_rollout")) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventAwareEntity { + + private static final long serialVersionUID = 1L; + + @OneToMany(targetEntity = JpaRolloutGroup.class) + @JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup")) + private List rolloutGroups; + + @Column(name = "target_filter", length = 1024, nullable = false) + private String targetFilterQuery; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) + private JpaDistributionSet distributionSet; + + @Column(name = "status") + private RolloutStatus status = RolloutStatus.CREATING; + + @Column(name = "last_check") + private long lastCheck; + + @Column(name = "action_type", nullable = false) + @Enumerated(EnumType.STRING) + private ActionType actionType = ActionType.FORCED; + + @Column(name = "forced_time") + private long forcedTime; + + @Column(name = "total_targets") + private long totalTargets; + + @Transient + @CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL) + private int rolloutGroupsTotal; + + @Transient + @CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED) + private int rolloutGroupsCreated; + + @Transient + private transient TotalTargetCountStatus totalTargetCountStatus; + + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + @Override + public List getRolloutGroups() { + return rolloutGroups; + } + + public void setRolloutGroups(final List rolloutGroups) { + this.rolloutGroups = rolloutGroups; + } + + @Override + public String getTargetFilterQuery() { + return targetFilterQuery; + } + + @Override + public void setTargetFilterQuery(final String targetFilterQuery) { + this.targetFilterQuery = targetFilterQuery; + } + + @Override + public RolloutStatus getStatus() { + return status; + } + + public void setStatus(final RolloutStatus status) { + this.status = status; + } + + public long getLastCheck() { + return lastCheck; + } + + public void setLastCheck(final long lastCheck) { + this.lastCheck = lastCheck; + } + + @Override + public ActionType getActionType() { + return actionType; + } + + @Override + public void setActionType(final ActionType actionType) { + this.actionType = actionType; + } + + @Override + public long getForcedTime() { + return forcedTime; + } + + @Override + public void setForcedTime(final long forcedTime) { + this.forcedTime = forcedTime; + } + + @Override + public long getTotalTargets() { + return totalTargets; + } + + public void setTotalTargets(final long totalTargets) { + this.totalTargets = totalTargets; + } + + public int getRolloutGroupsTotal() { + return rolloutGroupsTotal; + } + + public void setRolloutGroupsTotal(final int rolloutGroupsTotal) { + this.rolloutGroupsTotal = rolloutGroupsTotal; + } + + @Override + public int getRolloutGroupsCreated() { + return rolloutGroupsCreated; + } + + public void setRolloutGroupsCreated(final int rolloutGroupsCreated) { + this.rolloutGroupsCreated = rolloutGroupsCreated; + } + + @Override + public TotalTargetCountStatus getTotalTargetCountStatus() { + if (totalTargetCountStatus == null) { + totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); + } + return totalTargetCountStatus; + } + + public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { + this.totalTargetCountStatus = totalTargetCountStatus; + } + + @Override + public String toString() { + return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery + + ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck + + ", getName()=" + getName() + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + + } + + @Override + public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). + post(new RolloutPropertyChangeEvent(jpaRollout, EntityPropertyChangeHelper.getChangeSet( + Rollout.class, descriptorEvent)))); + + } + + @Override + public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java index 79da6630a..6456a3e93 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java @@ -1,239 +1,261 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.util.ArrayList; -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; - -/** - * JPA entity definition of persisting a group of an rollout. - * - */ -@Entity -@Table(name = "sp_rolloutgroup", indexes = { - @Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup { - - private static final long serialVersionUID = 1L; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) - private JpaRollout rollout; - - @Column(name = "status") - private RolloutGroupStatus status = RolloutGroupStatus.READY; - - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) - @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) - private final List rolloutTargetGroup = new ArrayList<>(); - - @ManyToOne(fetch = FetchType.LAZY) - private JpaRolloutGroup parent; - - @Column(name = "success_condition", nullable = false) - private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; - - @Column(name = "success_condition_exp", length = 512, nullable = false) - private String successConditionExp; - - @Column(name = "success_action", nullable = false) - private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; - - @Column(name = "success_action_exp", length = 512, nullable = false) - private String successActionExp; - - @Column(name = "error_condition") - private RolloutGroupErrorCondition errorCondition; - - @Column(name = "error_condition_exp", length = 512) - private String errorConditionExp; - - @Column(name = "error_action") - private RolloutGroupErrorAction errorAction; - - @Column(name = "error_action_exp", length = 512) - private String errorActionExp; - - @Column(name = "total_targets") - private long totalTargets; - - @Transient - private transient TotalTargetCountStatus totalTargetCountStatus; - - @Override - public Rollout getRollout() { - return rollout; - } - - @Override - public void setRollout(final Rollout rollout) { - this.rollout = (JpaRollout) rollout; - } - - @Override - public RolloutGroupStatus getStatus() { - return status; - } - - @Override - public void setStatus(final RolloutGroupStatus status) { - this.status = status; - } - - public List getRolloutTargetGroup() { - return rolloutTargetGroup; - } - - @Override - public RolloutGroup getParent() { - return parent; - } - - public void setParent(final RolloutGroup parent) { - this.parent = (JpaRolloutGroup) parent; - } - - @Override - public RolloutGroupSuccessCondition getSuccessCondition() { - return successCondition; - } - - @Override - public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { - successCondition = finishCondition; - } - - @Override - public String getSuccessConditionExp() { - return successConditionExp; - } - - @Override - public void setSuccessConditionExp(final String finishExp) { - successConditionExp = finishExp; - } - - @Override - public RolloutGroupErrorCondition getErrorCondition() { - return errorCondition; - } - - @Override - public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { - this.errorCondition = errorCondition; - } - - @Override - public String getErrorConditionExp() { - return errorConditionExp; - } - - @Override - public void setErrorConditionExp(final String errorExp) { - errorConditionExp = errorExp; - } - - @Override - public RolloutGroupErrorAction getErrorAction() { - return errorAction; - } - - @Override - public void setErrorAction(final RolloutGroupErrorAction errorAction) { - this.errorAction = errorAction; - } - - @Override - public String getErrorActionExp() { - return errorActionExp; - } - - @Override - public void setErrorActionExp(final String errorActionExp) { - this.errorActionExp = errorActionExp; - } - - @Override - public RolloutGroupSuccessAction getSuccessAction() { - return successAction; - } - - @Override - public String getSuccessActionExp() { - return successActionExp; - } - - @Override - public long getTotalTargets() { - return totalTargets; - } - - public void setTotalTargets(final long totalTargets) { - this.totalTargets = totalTargets; - } - - public void setSuccessAction(final RolloutGroupSuccessAction successAction) { - this.successAction = successAction; - } - - public void setSuccessActionExp(final String successActionExp) { - this.successActionExp = successActionExp; - } - - /** - * @return the totalTargetCountStatus - */ - @Override - public TotalTargetCountStatus getTotalTargetCountStatus() { - if (totalTargetCountStatus == null) { - totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); - } - return totalTargetCountStatus; - } - - /** - * @param totalTargetCountStatus - * the totalTargetCountStatus to set - */ - @Override - public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { - this.totalTargetCountStatus = totalTargetCountStatus; - } - - @Override - public String toString() { - return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup - + ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp - + ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName() - + ", getId()=" + getId() + "]"; - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA entity definition of persisting a group of an rollout. + * + */ +@Entity +@Table(name = "sp_rolloutgroup", indexes = { + @Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup,EventAwareEntity { + + private static final long serialVersionUID = 1L; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) + private JpaRollout rollout; + + @Column(name = "status") + private RolloutGroupStatus status = RolloutGroupStatus.READY; + + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) + @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) + private final List rolloutTargetGroup = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.LAZY) + private JpaRolloutGroup parent; + + @Column(name = "success_condition", nullable = false) + private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; + + @Column(name = "success_condition_exp", length = 512, nullable = false) + private String successConditionExp; + + @Column(name = "success_action", nullable = false) + private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; + + @Column(name = "success_action_exp", length = 512, nullable = false) + private String successActionExp; + + @Column(name = "error_condition") + private RolloutGroupErrorCondition errorCondition; + + @Column(name = "error_condition_exp", length = 512) + private String errorConditionExp; + + @Column(name = "error_action") + private RolloutGroupErrorAction errorAction; + + @Column(name = "error_action_exp", length = 512) + private String errorActionExp; + + @Column(name = "total_targets") + private long totalTargets; + + @Transient + private transient TotalTargetCountStatus totalTargetCountStatus; + + @Override + public Rollout getRollout() { + return rollout; + } + + @Override + public void setRollout(final Rollout rollout) { + this.rollout = (JpaRollout) rollout; + } + + @Override + public RolloutGroupStatus getStatus() { + return status; + } + + @Override + public void setStatus(final RolloutGroupStatus status) { + this.status = status; + } + + public List getRolloutTargetGroup() { + return rolloutTargetGroup; + } + + @Override + public RolloutGroup getParent() { + return parent; + } + + public void setParent(final RolloutGroup parent) { + this.parent = (JpaRolloutGroup) parent; + } + + @Override + public RolloutGroupSuccessCondition getSuccessCondition() { + return successCondition; + } + + @Override + public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { + successCondition = finishCondition; + } + + @Override + public String getSuccessConditionExp() { + return successConditionExp; + } + + @Override + public void setSuccessConditionExp(final String finishExp) { + successConditionExp = finishExp; + } + + @Override + public RolloutGroupErrorCondition getErrorCondition() { + return errorCondition; + } + + @Override + public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { + this.errorCondition = errorCondition; + } + + @Override + public String getErrorConditionExp() { + return errorConditionExp; + } + + @Override + public void setErrorConditionExp(final String errorExp) { + errorConditionExp = errorExp; + } + + @Override + public RolloutGroupErrorAction getErrorAction() { + return errorAction; + } + + @Override + public void setErrorAction(final RolloutGroupErrorAction errorAction) { + this.errorAction = errorAction; + } + + @Override + public String getErrorActionExp() { + return errorActionExp; + } + + @Override + public void setErrorActionExp(final String errorActionExp) { + this.errorActionExp = errorActionExp; + } + + @Override + public RolloutGroupSuccessAction getSuccessAction() { + return successAction; + } + + @Override + public String getSuccessActionExp() { + return successActionExp; + } + + @Override + public long getTotalTargets() { + return totalTargets; + } + + public void setTotalTargets(final long totalTargets) { + this.totalTargets = totalTargets; + } + + public void setSuccessAction(final RolloutGroupSuccessAction successAction) { + this.successAction = successAction; + } + + public void setSuccessActionExp(final String successActionExp) { + this.successActionExp = successActionExp; + } + + /** + * @return the totalTargetCountStatus + */ + @Override + public TotalTargetCountStatus getTotalTargetCountStatus() { + if (totalTargetCountStatus == null) { + totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); + } + return totalTargetCountStatus; + } + + /** + * @param totalTargetCountStatus + * the totalTargetCountStatus to set + */ + @Override + public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { + this.totalTargetCountStatus = totalTargetCountStatus; + } + + @Override + public String toString() { + return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup + + ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp + + ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName() + + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + + } + + @Override + public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). + post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, + EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); + } + + @Override + public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index 183405470..f6a2b8346 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -1,234 +1,257 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker; -import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetTag; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.springframework.data.domain.Persistable; - -/** - * JPA implementation of {@link Target}. - * - */ -@Entity -@Table(name = "sp_target", indexes = { - @Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"), - @Index(name = "sp_idx_target_02", columnList = "tenant,name"), - @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), - @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), - @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "controller_id", "tenant" }, name = "uk_tenant_controller_id")) -@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), - @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target { - private static final long serialVersionUID = 1L; - - @Column(name = "controller_id", length = 64) - @Size(min = 1) - @NotNull - private String controllerId; - - @Transient - private boolean entityNew; - - @ManyToMany(targetEntity = JpaTargetTag.class) - @JoinTable(name = "sp_target_target_tag", joinColumns = { - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { - @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) - private Set tags = new HashSet<>(); - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { - CascadeType.REMOVE }, targetEntity = JpaAction.class) - @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) - private final List actions = new ArrayList<>(); - - @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class) - @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) - private JpaDistributionSet assignedDistributionSet; - - @CascadeOnDelete - @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class) - @PrimaryKeyJoinColumn - private JpaTargetInfo targetInfo; - - /** - * the security token of the target which allows if enabled to authenticate - * with this security token. - */ - @Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128) - private String securityToken; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) - @JoinColumn(name = "target_Id", insertable = false, updatable = false) - private final List rolloutTargetGroup = new ArrayList<>(); - - /** - * Constructor. - * - * @param controllerId - * controller ID of the {@link Target} - */ - public JpaTarget(final String controllerId) { - this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken()); - } - - /** - * Constructor. - * - * @param controllerId - * controller ID of the {@link Target} - * @param securityToken - * for target authentication if enabled - */ - public JpaTarget(final String controllerId, final String securityToken) { - this.controllerId = controllerId; - setName(controllerId); - this.securityToken = securityToken; - targetInfo = new JpaTargetInfo(this); - } - - /** - * empty constructor for JPA. - */ - JpaTarget() { - controllerId = null; - securityToken = null; - } - - @Override - public DistributionSet getAssignedDistributionSet() { - return assignedDistributionSet; - } - - @Override - public String getControllerId() { - return controllerId; - } - - @Override - public Set getTags() { - return tags; - } - - public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { - this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet; - } - - public void setControllerId(final String controllerId) { - this.controllerId = controllerId; - } - - public void setTags(final Set tags) { - this.tags = tags; - } - - @Override - public List getActions() { - return actions; - } - - @Override - @Transient - public boolean isNew() { - return entityNew; - } - - /** - * @param isNew - * the isNew to set - */ - public void setNew(final boolean entityNew) { - this.entityNew = entityNew; - } - - /** - * @return the targetInfo - */ - @Override - public TargetInfo getTargetInfo() { - return targetInfo; - } - - /** - * @param targetInfo - * the targetInfo to set - */ - public void setTargetInfo(final TargetInfo targetInfo) { - this.targetInfo = (JpaTargetInfo) targetInfo; - } - - /** - * @return the securityToken if the current security context contains the - * necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN} - * or the current context is executed as system code, otherwise - * {@code null}. - */ - @Override - public String getSecurityToken() { - if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode() - || SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { - return securityToken; - } - return null; - } - - /** - * @param securityToken - * the securityToken to set - */ - public void setSecurityToken(final String securityToken) { - this.securityToken = securityToken; - } - - @Override - public String toString() { - return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]"; - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.eclipse.hawkbit.im.authentication.SpPermission; +import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker; +import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.springframework.data.domain.Persistable; + +/** + * JPA implementation of {@link Target}. + * + */ +@Entity +@Table(name = "sp_target", indexes = { + @Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"), + @Index(name = "sp_idx_target_02", columnList = "tenant,name"), + @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), + @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), + @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "controller_id", "tenant" }, name = "uk_tenant_controller_id")) +@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), + @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target, EventAwareEntity { + private static final long serialVersionUID = 1L; + + @Column(name = "controller_id", length = 64) + @Size(min = 1) + @NotNull + private String controllerId; + + @Transient + private boolean entityNew; + + @ManyToMany(targetEntity = JpaTargetTag.class) + @JoinTable(name = "sp_target_target_tag", joinColumns = { + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { + @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) + private Set tags = new HashSet<>(); + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { + CascadeType.REMOVE }, targetEntity = JpaAction.class) + @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) + private final List actions = new ArrayList<>(); + + @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class) + @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) + private JpaDistributionSet assignedDistributionSet; + + @CascadeOnDelete + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class) + @PrimaryKeyJoinColumn + private JpaTargetInfo targetInfo; + + /** + * the security token of the target which allows if enabled to authenticate + * with this security token. + */ + @Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128) + private String securityToken; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) + @JoinColumn(name = "target_Id", insertable = false, updatable = false) + private final List rolloutTargetGroup = new ArrayList<>(); + + /** + * Constructor. + * + * @param controllerId + * controller ID of the {@link Target} + */ + public JpaTarget(final String controllerId) { + this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken()); + } + + /** + * Constructor. + * + * @param controllerId + * controller ID of the {@link Target} + * @param securityToken + * for target authentication if enabled + */ + public JpaTarget(final String controllerId, final String securityToken) { + this.controllerId = controllerId; + setName(controllerId); + this.securityToken = securityToken; + targetInfo = new JpaTargetInfo(this); + } + + /** + * empty constructor for JPA. + */ + JpaTarget() { + controllerId = null; + securityToken = null; + } + + @Override + public DistributionSet getAssignedDistributionSet() { + return assignedDistributionSet; + } + + @Override + public String getControllerId() { + return controllerId; + } + + @Override + public Set getTags() { + return tags; + } + + public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { + this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet; + } + + public void setControllerId(final String controllerId) { + this.controllerId = controllerId; + } + + public void setTags(final Set tags) { + this.tags = tags; + } + + @Override + public List getActions() { + return actions; + } + + @Override + @Transient + public boolean isNew() { + return entityNew; + } + + /** + * @param isNew + * the isNew to set + */ + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; + } + + /** + * @return the targetInfo + */ + @Override + public TargetInfo getTargetInfo() { + return targetInfo; + } + + /** + * @param targetInfo + * the targetInfo to set + */ + public void setTargetInfo(final TargetInfo targetInfo) { + this.targetInfo = (JpaTargetInfo) targetInfo; + } + + /** + * @return the securityToken if the current security context contains the + * necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN} + * or the current context is executed as system code, otherwise + * {@code null}. + */ + @Override + public String getSecurityToken() { + if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode() + || SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { + return securityToken; + } + return null; + } + + /** + * @param securityToken + * the securityToken to set + */ + @Override + public void setSecurityToken(final String securityToken) { + this.securityToken = securityToken; + } + + @Override + public String toString() { + return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); + } + + @Override + public void fireUpdateEvent(final JpaTarget jpaTarget,final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); + + } + + @Override + public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { + + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java index 0606def4f..a21c7547f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -1,324 +1,344 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.net.URI; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.persistence.CascadeType; -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.MapKeyColumn; -import javax.persistence.MapsId; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.Transient; - -import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; -import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.PollStatus; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Persistable; - -/** - * A table which contains all the information inserted, updated by the - * controller itself. So this entity does not provide audit information because - * changes on this entity are mostly only done by controller requests. That's - * the reason that we store these information in a separated table so we don't - * modifying the {@link Target} itself when a controller reports it's - * {@link #lastTargetQuery} for example. - * - */ -@Table(name = "sp_target_info", indexes = { - @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) -@Entity -public class JpaTargetInfo implements Persistable, TargetInfo { - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); - - @Id - private Long targetId; - - @Transient - private boolean entityNew; - - @CascadeOnDelete - @OneToOne(cascade = { CascadeType.MERGE, - CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class) - @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) - @MapsId - private JpaTarget target; - - @Column(name = "address", length = 512) - private String address; - - @Column(name = "last_target_query") - private Long lastTargetQuery; - - @Column(name = "install_date") - private Long installationDate; - - @Column(name = "update_status", nullable = false, length = 255) - @Enumerated(EnumType.STRING) - private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; - - @ManyToOne(optional = true, fetch = FetchType.LAZY) - @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) - private JpaDistributionSet installedDistributionSet; - - /** - * Read only on management API. Are commited by controller. - */ - @ElementCollection - @Column(name = "attribute_value", length = 128) - @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) - @CollectionTable(name = "sp_target_attributes", joinColumns = { - @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) - - private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); - - // set default request controller attributes to true, because we want to - // request them the first - // time - @Column(name = "request_controller_attributes", nullable = false) - private boolean requestControllerAttributes = true; - - /** - * Constructor for {@link TargetStatus}. - * - * @param target - * related to this status. - */ - public JpaTargetInfo(final JpaTarget target) { - this.target = target; - targetId = target.getId(); - } - - JpaTargetInfo() { - target = null; - targetId = null; - } - - @Override - public Long getId() { - return targetId; - } - - @Override - @Transient - public boolean isNew() { - return entityNew; - } - - /** - * @param isNew - * the isNew to set - */ - public void setNew(final boolean entityNew) { - this.entityNew = entityNew; - } - - /** - * @return the ipAddress - */ - @Override - public URI getAddress() { - if (address == null) { - return null; - } - try { - return URI.create(address); - } catch (final IllegalArgumentException e) { - LOG.warn("Invalid address provided. Cloud not be configured to URI", e); - return null; - } - } - - /** - * @param address - * the target address to set - * - * @throws IllegalArgumentException - * If the given string violates RFC 2396 - */ - @Override - public void setAddress(final String address) { - // check if this is a real URI - if (address != null) { - try { - URI.create(address); - } catch (final IllegalArgumentException e) { - throw new InvalidTargetAddressException( - "The given address " + address + " violates the RFC-2396 specification", e); - } - } - - this.address = address; - } - - public Long getTargetId() { - return targetId; - } - - public void setTargetId(final Long targetId) { - this.targetId = targetId; - } - - @Override - public Target getTarget() { - return target; - } - - public void setTarget(final JpaTarget target) { - this.target = target; - } - - @Override - public Long getLastTargetQuery() { - return lastTargetQuery; - } - - public void setLastTargetQuery(final Long lastTargetQuery) { - this.lastTargetQuery = lastTargetQuery; - } - - public void setRequestControllerAttributes(final boolean requestControllerAttributes) { - this.requestControllerAttributes = requestControllerAttributes; - } - - @Override - public Map getControllerAttributes() { - return controllerAttributes; - } - - @Override - public boolean isRequestControllerAttributes() { - return requestControllerAttributes; - } - - @Override - public Long getInstallationDate() { - return installationDate; - } - - public void setInstallationDate(final Long installationDate) { - this.installationDate = installationDate; - } - - @Override - public TargetUpdateStatus getUpdateStatus() { - return updateStatus; - } - - public void setUpdateStatus(final TargetUpdateStatus updateStatus) { - this.updateStatus = updateStatus; - } - - @Override - public DistributionSet getInstalledDistributionSet() { - return installedDistributionSet; - } - - public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) { - this.installedDistributionSet = installedDistributionSet; - } - - /** - * @return the poll time which holds the last poll time of the target, the - * next poll time and the overdue time. In case the - * {@link #lastTargetQuery} is not set e.g. the target never polled - * before this method returns {@code null} - */ - @Override - public PollStatus getPollStatus() { - if (lastTargetQuery == null) { - return null; - } - return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> { - final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder - .getInstance().getTenantConfigurationManagement() - .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); - final Duration overdueTime = DurationHelper.formattedStringToDuration( - TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement() - .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) - .getValue()); - final LocalDateTime currentDate = LocalDateTime.now(); - final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), - ZoneId.systemDefault()); - final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); - final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); - return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); - }); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - result = prime * result + ((targetId == null) ? 0 : targetId.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TargetInfo)) { - return false; - } - final JpaTargetInfo other = (JpaTargetInfo) obj; - if (target == null) { - if (other.target != null) { - return false; - } - } else if (!target.equals(other.target)) { - return false; - } - if (targetId == null) { - if (other.targetId != null) { - return false; - } - } else if (!targetId.equals(other.targetId)) { - return false; - } - return true; - } -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.net.URI; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.MapKeyColumn; +import javax.persistence.MapsId; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Transient; + +import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.PollStatus; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Persistable; + +/** + * A table which contains all the information inserted, updated by the + * controller itself. So this entity does not provide audit information because + * changes on this entity are mostly only done by controller requests. That's + * the reason that we store these information in a separated table so we don't + * modifying the {@link Target} itself when a controller reports it's + * {@link #lastTargetQuery} for example. + * + */ +@Table(name = "sp_target_info", indexes = { + @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) +@Entity +@EntityListeners(EntityPropertyChangeListener.class) +public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareEntity { + private static final long serialVersionUID = 1L; + + private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); + + @Id + private Long targetId; + + @Transient + private boolean entityNew; + + @CascadeOnDelete + @OneToOne(cascade = { CascadeType.MERGE, + CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class) + @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) + @MapsId + private JpaTarget target; + + @Column(name = "address", length = 512) + private String address; + + @Column(name = "last_target_query") + private Long lastTargetQuery; + + @Column(name = "install_date") + private Long installationDate; + + @Column(name = "update_status", nullable = false, length = 255) + @Enumerated(EnumType.STRING) + private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; + + @ManyToOne(optional = true, fetch = FetchType.LAZY) + @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) + private JpaDistributionSet installedDistributionSet; + + /** + * Read only on management API. Are commited by controller. + */ + @ElementCollection + @Column(name = "attribute_value", length = 128) + @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) + @CollectionTable(name = "sp_target_attributes", joinColumns = { + @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) + + private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); + + // set default request controller attributes to true, because we want to + // request them the first + // time + @Column(name = "request_controller_attributes", nullable = false) + private boolean requestControllerAttributes = true; + + /** + * Constructor for {@link TargetStatus}. + * + * @param target + * related to this status. + */ + public JpaTargetInfo(final JpaTarget target) { + this.target = target; + targetId = target.getId(); + } + + JpaTargetInfo() { + target = null; + targetId = null; + } + + @Override + public Long getId() { + return targetId; + } + + @Override + @Transient + public boolean isNew() { + return entityNew; + } + + /** + * @param isNew + * the isNew to set + */ + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; + } + + /** + * @return the ipAddress + */ + @Override + public URI getAddress() { + if (address == null) { + return null; + } + try { + return URI.create(address); + } catch (final IllegalArgumentException e) { + LOG.warn("Invalid address provided. Cloud not be configured to URI", e); + return null; + } + } + + /** + * @param address + * the target address to set + * + * @throws IllegalArgumentException + * If the given string violates RFC 2396 + */ + @Override + public void setAddress(final String address) { + // check if this is a real URI + if (address != null) { + try { + URI.create(address); + } catch (final IllegalArgumentException e) { + throw new InvalidTargetAddressException( + "The given address " + address + " violates the RFC-2396 specification", e); + } + } + + this.address = address; + } + + public Long getTargetId() { + return targetId; + } + + public void setTargetId(final Long targetId) { + this.targetId = targetId; + } + + @Override + public Target getTarget() { + return target; + } + + public void setTarget(final JpaTarget target) { + this.target = target; + } + + @Override + public Long getLastTargetQuery() { + return lastTargetQuery; + } + + public void setLastTargetQuery(final Long lastTargetQuery) { + this.lastTargetQuery = lastTargetQuery; + } + + public void setRequestControllerAttributes(final boolean requestControllerAttributes) { + this.requestControllerAttributes = requestControllerAttributes; + } + + @Override + public Map getControllerAttributes() { + return controllerAttributes; + } + + @Override + public boolean isRequestControllerAttributes() { + return requestControllerAttributes; + } + + @Override + public Long getInstallationDate() { + return installationDate; + } + + public void setInstallationDate(final Long installationDate) { + this.installationDate = installationDate; + } + + @Override + public TargetUpdateStatus getUpdateStatus() { + return updateStatus; + } + + public void setUpdateStatus(final TargetUpdateStatus updateStatus) { + this.updateStatus = updateStatus; + } + + @Override + public DistributionSet getInstalledDistributionSet() { + return installedDistributionSet; + } + + public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) { + this.installedDistributionSet = installedDistributionSet; + } + + /** + * @return the poll time which holds the last poll time of the target, the + * next poll time and the overdue time. In case the + * {@link #lastTargetQuery} is not set e.g. the target never polled + * before this method returns {@code null} + */ + @Override + public PollStatus getPollStatus() { + if (lastTargetQuery == null) { + return null; + } + return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> { + final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder + .getInstance().getTenantConfigurationManagement() + .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); + final Duration overdueTime = DurationHelper.formattedStringToDuration( + TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement() + .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) + .getValue()); + final LocalDateTime currentDate = LocalDateTime.now(); + final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), + ZoneId.systemDefault()); + final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); + final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); + return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); + }); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + result = prime * result + ((targetId == null) ? 0 : targetId.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TargetInfo)) { + return false; + } + final JpaTargetInfo other = (JpaTargetInfo) obj; + if (target == null) { + if (other.target != null) { + return false; + } + } else if (!target.equals(other.target)) { + return false; + } + if (targetId == null) { + if (other.targetId != null) { + return false; + } + } else if (!targetId.equals(other.targetId)) { + return false; + } + return true; + } + + @Override + public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo,final DescriptorEvent descriptorEvent) { + // there is no target info created event + } + + @Override + public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); + } + + @Override + public void fireDeleteEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + } +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java new file mode 100644 index 000000000..71c374c5f --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model.helper; + +import java.util.Map; +import java.util.stream.Collectors; + +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.eclipse.persistence.internal.sessions.ObjectChangeSet; +import org.eclipse.persistence.queries.UpdateObjectQuery; +import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; + +public class EntityPropertyChangeHelper { + + + public static Map.Values> getChangeSet( + final Class clazz, final DescriptorEvent event) { + final T rolloutGroup = clazz.cast(event.getObject()); + final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()) + .getObjectChangeSet(); + return changeSet + .getChanges() + .stream() + .filter(record -> record instanceof DirectToFieldChangeRecord) + .map(record -> (DirectToFieldChangeRecord) record) + .collect( + Collectors.toMap( + record -> record.getAttribute(), + record -> new AbstractPropertyChangeEvent( + rolloutGroup, null).new Values(record + .getOldValue(), record.getNewValue()))); + } + +} From bf28a8dde8764522c00085614b79b85da84216a0 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 28 Jul 2016 14:07:19 +0200 Subject: [PATCH 03/42] Fixed the issue for metadata not getting updated and also the refresh of page not displaying the distribution details in deployment and distribution view. Signed-off-by: Gaurav --- .../repository/DistributionSetManagement.java | 1206 +++++++-------- .../repository/SoftwareManagement.java | 990 ++++++------ .../jpa/JpaDistributionSetManagement.java | 61 +- .../repository/jpa/JpaSoftwareManagement.java | 1335 +++++++++-------- .../AbstractTableDetailsLayout.java | 1 - .../DistributionSetMetadatadetailslayout.java | 112 +- .../SoftwareModuleMetadatadetailslayout.java | 4 +- .../dstable/DistributionSetDetails.java | 65 +- .../dstable/DsMetadataPopupLayout.java | 32 +- .../ui/distributions/event/MetadataEvent.java | 9 +- .../DistributionAddUpdateWindowLayout.java | 10 +- .../dstable/DistributionDetails.java | 69 +- 12 files changed, 1936 insertions(+), 1958 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index a2e7e5213..f7566b86b 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -1,598 +1,608 @@ -/** - * 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.Collection; -import java.util.List; -import java.util.Set; - -import javax.validation.constraints.NotNull; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMissingMandatoryModuleException; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; -import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.Tag; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder; -import org.hibernate.validator.constraints.NotEmpty; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.security.access.prepost.PreAuthorize; - -/** - * Management service for {@link DistributionSet}s. - * - */ -public interface DistributionSetManagement { - - // TODO rename/document the whole with details thing (document what the - // details are and maybe find a better name, e.g. with dependencies?) - - /** - * Assigns {@link SoftwareModule} to existing {@link DistributionSet}. - * - * @param ds - * to assign and update - * @param softwareModules - * to get assigned - * @return the updated {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet assignSoftwareModules(@NotNull DistributionSet ds, Set softwareModules); - - /** - * Assign a {@link DistributionSetTag} assignment to given - * {@link DistributionSet}s. - * - * @param dsIds - * to assign for - * @param tag - * to assign - * @return list of assigned ds - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List assignTag(@NotEmpty Collection dsIds, @NotNull DistributionSetTag tag); - - /** - * Count all {@link DistributionSet}s in the repository that are not marked - * as deleted. - * - * @return number of {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetsAll(); - - /** - * Count all {@link DistributionSet}s in the repository that are not marked - * as deleted. - * - * @param type - * to look for - * - * @return number of {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetsByType(@NotNull DistributionSetType type); - - /** - * @return number of {@link DistributionSetType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetTypesAll(); - - /** - * Creates a new {@link DistributionSet}. - * - * @param dSet - * {@link DistributionSet} to be created - * @return the new persisted {@link DistributionSet} - * - * @throws EntityAlreadyExistsException - * if a given entity already exists - * @throws DistributionSetCreationFailedMissingMandatoryModuleException - * is {@link DistributionSet} does not contain mandatory - * {@link SoftwareModule}s. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - DistributionSet createDistributionSet(@NotNull DistributionSet dSet); - - /** - * creates a list of distribution set meta data entries. - * - * @param metadata - * the meta data entries to create or update - * @return the updated or created distribution set meta data entries - * @throws EntityAlreadyExistsException - * in case one of the meta data entry already exists for the - * specific key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List createDistributionSetMetadata(@NotEmpty Collection metadata); - - /** - * creates or updates a single distribution set meta data entry. - * - * @param metadata - * the meta data entry to create or update - * @return the updated or created distribution set meta data entry - * @throws EntityAlreadyExistsException - * in case the meta data entry already exists for the specific - * key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetMetadata createDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); - - /** - * Creates multiple {@link DistributionSet}s. - * - * @param distributionSets - * to be created - * @return the new {@link DistributionSet}s - * @throws EntityAlreadyExistsException - * if a given entity already exists - * @throws DistributionSetCreationFailedMissingMandatoryModuleException - * is {@link DistributionSet} does not contain mandatory - * {@link SoftwareModule}s. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createDistributionSets(@NotNull Collection distributionSets); - - /** - * Creates new {@link DistributionSetType}. - * - * @param type - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - DistributionSetType createDistributionSetType(@NotNull DistributionSetType type); - - /** - * Creates multiple {@link DistributionSetType}s. - * - * @param types - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createDistributionSetTypes(@NotNull Collection types); - - /** - *

- * {@link DistributionSet} can be deleted/erased from the repository if they - * have never been assigned to any {@link UpdateAction} or {@link Target}. - *

- * - *

- * If they have been assigned that need to be marked as deleted which as a - * result means that they cannot be assigned anymore to any targets. (define - * e.g. findByDeletedFalse()) - *

- * - * @param set - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSet(@NotNull DistributionSet set); - - /** - * Deleted {@link DistributionSet}s by their IDs. That is either a soft - * delete of the entities have been linked to an {@link UpdateAction} before - * or a hard delete if not. - * - * @param distributionSetIDs - * to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSet(@NotEmpty Long... distributionSetIDs); - - /** - * deletes a distribution set meta data entry. - * - * @param id - * the ID of the distribution set meta data to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - void deleteDistributionSetMetadata(@NotNull final DistributionSet distributionSet, @NotNull final String key); - - /** - * Deletes or mark as delete in case the type is in use. - * - * @param type - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSetType(@NotNull DistributionSetType type); - - /** - * retrieves the distribution set for a given action. - * - * @param action - * the action associated with the distribution set - * @return the distribution set which is associated with the action - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByAction(@NotNull Action action); - - /** - * Find {@link DistributionSet} based on given ID without details, e.g. - * {@link DistributionSet#getAgentHub()}. - * - * @param distid - * to look for. - * @return {@link DistributionSet} or null if it does not exist - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetById(@NotNull Long distid); - - /** - * Find {@link DistributionSet} based on given ID including (lazy loaded) - * details, e.g. {@link DistributionSet#getAgentHub()}. - * - * Note: for performance reasons it is recommended to use - * {@link #findDistributionSetById(Long)} if details are not necessary. - * - * @param distid - * to look for. - * @return {@link DistributionSet} or null if it does not exist - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByIdWithDetails(@NotNull Long distid); - - /** - * Find distribution set by name and version. - * - * @param distributionName - * name of {@link DistributionSet}; case insensitive - * @param version - * version of {@link DistributionSet} - * @return the page with the found {@link DistributionSet} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version); - - /** - * finds all meta data by the given distribution set id. - * - * @param distributionSetId - * the distribution set id to retrieve the meta data from - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given distribution - * set id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, - @NotNull Pageable pageable); - - /** - * finds all meta data by the given distribution set id. - * - * @param distributionSetId - * the distribution set id to retrieve the meta data from - * @param rsqlParam - * rsql query string - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given distribution - * set id - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, - @NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Retrieves {@link DistributionSet} List for overview purposes (no - * {@link SoftwareModule}s and {@link DistributionSetTag}s). - * - * Please use {@link #findDistributionSetListWithDetails(Iterable)} if - * details are required. - * - * @param dist - * List of {@link DistributionSet} IDs to be found - * @return the found {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - List findDistributionSetsAll(Collection dist); - - // TODO discuss: use enum instead of the true,false,null switch ? - /** - * finds all {@link DistributionSet}s. - * - * @param pageReq - * the pagination parameter - * @param deleted - * if TRUE, {@link DistributionSet}s marked as deleted are - * returned. If FALSE, on {@link DistributionSet}s with - * {@link DistributionSet#isDeleted()} == FALSE are returned. - * null if both are to be returned - * @param complete - * to true for returning only completed distribution - * sets or false for only incomplete ones nor - * null to return both. - * @param complete - * set to if false incomplete DS should also be - * shown. - * - * - * @return all found {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsByDeletedAndOrCompleted(@NotNull Pageable pageReq, Boolean deleted, - Boolean complete); - - /** - * finds all {@link DistributionSet}s. - * - * @param rsqlParam - * rsql query string - * @param pageReq - * the pagination parameter - * @param deleted - * if TRUE, {@link DistributionSet}s marked as deleted are - * returned. If FALSE, on {@link DistributionSet}s with - * {@link DistributionSet#isDeleted()} == FALSE are returned. - * null if both are to be returned - * @return all found {@link DistributionSet}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsAll(@NotNull String rsqlParam, @NotNull Pageable pageReq, - Boolean deleted); - - /** - * method retrieves all {@link DistributionSet}s from the repository in the - * following order: - *

- * 1) {@link DistributionSet}s which have the given {@link Target} as - * {@link TargetStatus#getInstalledDistributionSet()} - *

- * 2) {@link DistributionSet}s which have the given {@link Target} as - * {@link Target#getAssignedDistributionSet()} - *

- * 3) {@link DistributionSet}s which have no connection to the given - * {@link Target} ordered by ID of the DistributionSet. - * - * @param pageable - * the page request to page the result set * - * @param distributionSetFilterBuilder - * has details of filters to be applied - * @param assignedOrInstalled - * the controllerID of the Target to be ordered by - * @return - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsAllOrderedByLinkTarget(@NotNull Pageable pageable, - @NotNull DistributionSetFilterBuilder distributionSetFilterBuilder, @NotEmpty String assignedOrInstalled); - - /** - * retrieves {@link DistributionSet}s by filtering on the given parameters. - * - * @param pageable - * page parameter - * @param distributionSetFilter - * has details of filters to be applied. - * @return the page of found {@link DistributionSet} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsByFilters(@NotNull Pageable pageable, - @NotNull DistributionSetFilter distributionSetFilter); - - /** - * @param id - * as {@link DistributionSetType#getId()} - * @return {@link DistributionSetType} if found or null if not - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeById(@NotNull Long id); - - /** - * @param key - * as {@link DistributionSetType#getKey()} - * @return {@link DistributionSetType} if found or null if not - */ - - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeByKey(@NotNull String key); - - /** - * @param name - * as {@link DistributionSetType#getName()} - * @return {@link DistributionSetType} if found or null if not - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeByName(@NotEmpty String name); - - /** - * @param pageable - * parameter - * @return all {@link DistributionSetType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetTypesAll(@NotNull Pageable pageable); - - /** - * Generic predicate based query for {@link DistributionSetType}. - * - * @param rsqlParam - * rsql query string - * @param pageable - * parameter for paging - * - * @return the found {@link SoftwareModuleType}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * finds a single distribution set meta data by its id. - * - * @param id - * the id of the distribution set meta data containing the meta - * data key and the ID of the distribution set - * @return the found DistributionSetMetadata or {@code null} if not exits - * @throws EntityNotFoundException - * in case the meta data does not exists for the given key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetMetadata findOne(@NotNull DistributionSet distributionSet, @NotNull String key); - - /** - * Checks if a {@link DistributionSet} is currently in use by a target in - * the repository. - * - * @param distributionSet - * to check - * - * @return true if in use - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - boolean isDistributionSetInUse(@NotNull DistributionSet distributionSet); - - /** - * {@link Entity} based method call for - * {@link #toggleTagAssignment(Collection, String)}. - * - * @param sets - * to toggle for - * @param tag - * to toggle - * @return {@link DistributionSetTagAssignmentResult} with all meta data of - * the assignment outcome. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection sets, - @NotNull DistributionSetTag tag); - - /** - * Toggles {@link DistributionSetTag} assignment to given - * {@link DistributionSet}s by means that if some (or all) of the targets in - * the list have the {@link Tag} not yet assigned, they will be. If all of - * theme have the tag already assigned they will be removed instead. - * - * @param dsIds - * to toggle for - * @param tagName - * to toggle - * @return {@link DistributionSetTagAssignmentResult} with all meta data of - * the assignment outcome. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection dsIds, @NotNull String tagName); - - /** - * Unassign all {@link DistributionSet} from a given - * {@link DistributionSetTag} . - * - * @param tag - * to unassign all ds - * @return list of unassigned ds - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List unAssignAllDistributionSetsByTag(@NotNull DistributionSetTag tag); - - /** - * Unassigns a {@link SoftwareModule} form an existing - * {@link DistributionSet}. - * - * @param ds - * to get unassigned form - * @param softwareModule - * to get unassigned - * @return the updated {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet unassignSoftwareModule(@NotNull DistributionSet ds, @NotNull SoftwareModule softwareModule); - - /** - * Unassign a {@link DistributionSetTag} assignment to given - * {@link DistributionSet}. - * - * @param dsId - * to unassign for - * @param distributionSetTag - * to unassign - * @return the unassigned ds or if no ds is unassigned - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet unAssignTag(@NotNull Long dsId, @NotNull DistributionSetTag distributionSetTag); - - /** - * Updates existing {@link DistributionSet}. - * - * @param ds - * to update - * @return the saved {@link Entity}. - * @throws NullPointerException - * of {@link DistributionSet#getId()} is null - * @throw DataDependencyViolationException in case of illegal update - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet updateDistributionSet(@NotNull DistributionSet ds); - - /** - * updates a distribution set meta data value if corresponding entry exists. - * - * @param metadata - * the meta data entry to be updated - * @return the updated meta data entry - * @throws EntityNotFoundException - * in case the meta data entry does not exists and cannot be - * updated - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetMetadata updateDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); - - /** - * Updates existing {@link DistributionSetType}. However, keep in mind that - * is not possible to change the {@link DistributionSetTypeElement}s while - * the DS type is already in use. - * - * @param dsType - * to update - * @return updated {@link Entity} - * - * @throws EntityReadOnlyException - * if use tries to change the {@link DistributionSetTypeElement} - * s while the DS type is already in use. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetType updateDistributionSetType(@NotNull DistributionSetType dsType); - -} +/** + * 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.Collection; +import java.util.List; +import java.util.Set; + +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMissingMandatoryModuleException; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetFilter; +import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder; +import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.model.Tag; +import org.eclipse.hawkbit.repository.model.Target; +import org.hibernate.validator.constraints.NotEmpty; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.access.prepost.PreAuthorize; + +/** + * Management service for {@link DistributionSet}s. + * + */ +public interface DistributionSetManagement { + + // TODO rename/document the whole with details thing (document what the + // details are and maybe find a better name, e.g. with dependencies?) + + /** + * Assigns {@link SoftwareModule} to existing {@link DistributionSet}. + * + * @param ds + * to assign and update + * @param softwareModules + * to get assigned + * @return the updated {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet assignSoftwareModules(@NotNull DistributionSet ds, Set softwareModules); + + /** + * Assign a {@link DistributionSetTag} assignment to given + * {@link DistributionSet}s. + * + * @param dsIds + * to assign for + * @param tag + * to assign + * @return list of assigned ds + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List assignTag(@NotEmpty Collection dsIds, @NotNull DistributionSetTag tag); + + /** + * Count all {@link DistributionSet}s in the repository that are not marked + * as deleted. + * + * @return number of {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetsAll(); + + /** + * Count all {@link DistributionSet}s in the repository that are not marked + * as deleted. + * + * @param type + * to look for + * + * @return number of {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetsByType(@NotNull DistributionSetType type); + + /** + * @return number of {@link DistributionSetType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetTypesAll(); + + /** + * Creates a new {@link DistributionSet}. + * + * @param dSet + * {@link DistributionSet} to be created + * @return the new persisted {@link DistributionSet} + * + * @throws EntityAlreadyExistsException + * if a given entity already exists + * @throws DistributionSetCreationFailedMissingMandatoryModuleException + * is {@link DistributionSet} does not contain mandatory + * {@link SoftwareModule}s. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + DistributionSet createDistributionSet(@NotNull DistributionSet dSet); + + /** + * creates a list of distribution set meta data entries. + * + * @param metadata + * the meta data entries to create or update + * @return the updated or created distribution set meta data entries + * @throws EntityAlreadyExistsException + * in case one of the meta data entry already exists for the + * specific key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List createDistributionSetMetadata(@NotEmpty Collection metadata); + + /** + * creates or updates a single distribution set meta data entry. + * + * @param metadata + * the meta data entry to create or update + * @return the updated or created distribution set meta data entry + * @throws EntityAlreadyExistsException + * in case the meta data entry already exists for the specific + * key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetMetadata createDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); + + /** + * Creates multiple {@link DistributionSet}s. + * + * @param distributionSets + * to be created + * @return the new {@link DistributionSet}s + * @throws EntityAlreadyExistsException + * if a given entity already exists + * @throws DistributionSetCreationFailedMissingMandatoryModuleException + * is {@link DistributionSet} does not contain mandatory + * {@link SoftwareModule}s. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createDistributionSets(@NotNull Collection distributionSets); + + /** + * Creates new {@link DistributionSetType}. + * + * @param type + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + DistributionSetType createDistributionSetType(@NotNull DistributionSetType type); + + /** + * Creates multiple {@link DistributionSetType}s. + * + * @param types + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createDistributionSetTypes(@NotNull Collection types); + + /** + *

+ * {@link DistributionSet} can be deleted/erased from the repository if they + * have never been assigned to any {@link UpdateAction} or {@link Target}. + *

+ * + *

+ * If they have been assigned that need to be marked as deleted which as a + * result means that they cannot be assigned anymore to any targets. (define + * e.g. findByDeletedFalse()) + *

+ * + * @param set + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSet(@NotNull DistributionSet set); + + /** + * Deleted {@link DistributionSet}s by their IDs. That is either a soft + * delete of the entities have been linked to an {@link UpdateAction} before + * or a hard delete if not. + * + * @param distributionSetIDs + * to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSet(@NotEmpty Long... distributionSetIDs); + + /** + * deletes a distribution set meta data entry. + * + * @param id + * the ID of the distribution set meta data to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void deleteDistributionSetMetadata(@NotNull final DistributionSet distributionSet, @NotNull final String key); + + /** + * Deletes or mark as delete in case the type is in use. + * + * @param type + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSetType(@NotNull DistributionSetType type); + + /** + * retrieves the distribution set for a given action. + * + * @param action + * the action associated with the distribution set + * @return the distribution set which is associated with the action + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByAction(@NotNull Action action); + + /** + * Find {@link DistributionSet} based on given ID without details, e.g. + * {@link DistributionSet#getAgentHub()}. + * + * @param distid + * to look for. + * @return {@link DistributionSet} or null if it does not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetById(@NotNull Long distid); + + /** + * Find {@link DistributionSet} based on given ID including (lazy loaded) + * details, e.g. {@link DistributionSet#getAgentHub()}. + * + * Note: for performance reasons it is recommended to use + * {@link #findDistributionSetById(Long)} if details are not necessary. + * + * @param distid + * to look for. + * @return {@link DistributionSet} or null if it does not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByIdWithDetails(@NotNull Long distid); + + /** + * Find distribution set by name and version. + * + * @param distributionName + * name of {@link DistributionSet}; case insensitive + * @param version + * version of {@link DistributionSet} + * @return the page with the found {@link DistributionSet} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given distribution + * set id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, + @NotNull Pageable pageable); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @return list of distributionSetMetadata for a given distribution set Id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @param rsqlParam + * rsql query string + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given distribution + * set id + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, + @NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Retrieves {@link DistributionSet} List for overview purposes (no + * {@link SoftwareModule}s and {@link DistributionSetTag}s). + * + * Please use {@link #findDistributionSetListWithDetails(Iterable)} if + * details are required. + * + * @param dist + * List of {@link DistributionSet} IDs to be found + * @return the found {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findDistributionSetsAll(Collection dist); + + // TODO discuss: use enum instead of the true,false,null switch ? + /** + * finds all {@link DistributionSet}s. + * + * @param pageReq + * the pagination parameter + * @param deleted + * if TRUE, {@link DistributionSet}s marked as deleted are + * returned. If FALSE, on {@link DistributionSet}s with + * {@link DistributionSet#isDeleted()} == FALSE are returned. + * null if both are to be returned + * @param complete + * to true for returning only completed distribution + * sets or false for only incomplete ones nor + * null to return both. + * @param complete + * set to if false incomplete DS should also be + * shown. + * + * + * @return all found {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsByDeletedAndOrCompleted(@NotNull Pageable pageReq, Boolean deleted, + Boolean complete); + + /** + * finds all {@link DistributionSet}s. + * + * @param rsqlParam + * rsql query string + * @param pageReq + * the pagination parameter + * @param deleted + * if TRUE, {@link DistributionSet}s marked as deleted are + * returned. If FALSE, on {@link DistributionSet}s with + * {@link DistributionSet#isDeleted()} == FALSE are returned. + * null if both are to be returned + * @return all found {@link DistributionSet}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsAll(@NotNull String rsqlParam, @NotNull Pageable pageReq, + Boolean deleted); + + /** + * method retrieves all {@link DistributionSet}s from the repository in the + * following order: + *

+ * 1) {@link DistributionSet}s which have the given {@link Target} as + * {@link TargetStatus#getInstalledDistributionSet()} + *

+ * 2) {@link DistributionSet}s which have the given {@link Target} as + * {@link Target#getAssignedDistributionSet()} + *

+ * 3) {@link DistributionSet}s which have no connection to the given + * {@link Target} ordered by ID of the DistributionSet. + * + * @param pageable + * the page request to page the result set * + * @param distributionSetFilterBuilder + * has details of filters to be applied + * @param assignedOrInstalled + * the controllerID of the Target to be ordered by + * @return + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsAllOrderedByLinkTarget(@NotNull Pageable pageable, + @NotNull DistributionSetFilterBuilder distributionSetFilterBuilder, @NotEmpty String assignedOrInstalled); + + /** + * retrieves {@link DistributionSet}s by filtering on the given parameters. + * + * @param pageable + * page parameter + * @param distributionSetFilter + * has details of filters to be applied. + * @return the page of found {@link DistributionSet} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsByFilters(@NotNull Pageable pageable, + @NotNull DistributionSetFilter distributionSetFilter); + + /** + * @param id + * as {@link DistributionSetType#getId()} + * @return {@link DistributionSetType} if found or null if not + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeById(@NotNull Long id); + + /** + * @param key + * as {@link DistributionSetType#getKey()} + * @return {@link DistributionSetType} if found or null if not + */ + + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeByKey(@NotNull String key); + + /** + * @param name + * as {@link DistributionSetType#getName()} + * @return {@link DistributionSetType} if found or null if not + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeByName(@NotEmpty String name); + + /** + * @param pageable + * parameter + * @return all {@link DistributionSetType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetTypesAll(@NotNull Pageable pageable); + + /** + * Generic predicate based query for {@link DistributionSetType}. + * + * @param rsqlParam + * rsql query string + * @param pageable + * parameter for paging + * + * @return the found {@link SoftwareModuleType}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * finds a single distribution set meta data by its id. + * + * @param id + * the id of the distribution set meta data containing the meta + * data key and the ID of the distribution set + * @return the found DistributionSetMetadata or {@code null} if not exits + * @throws EntityNotFoundException + * in case the meta data does not exists for the given key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetMetadata findOne(@NotNull DistributionSet distributionSet, @NotNull String key); + + /** + * Checks if a {@link DistributionSet} is currently in use by a target in + * the repository. + * + * @param distributionSet + * to check + * + * @return true if in use + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + boolean isDistributionSetInUse(@NotNull DistributionSet distributionSet); + + /** + * {@link Entity} based method call for + * {@link #toggleTagAssignment(Collection, String)}. + * + * @param sets + * to toggle for + * @param tag + * to toggle + * @return {@link DistributionSetTagAssignmentResult} with all meta data of + * the assignment outcome. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection sets, + @NotNull DistributionSetTag tag); + + /** + * Toggles {@link DistributionSetTag} assignment to given + * {@link DistributionSet}s by means that if some (or all) of the targets in + * the list have the {@link Tag} not yet assigned, they will be. If all of + * theme have the tag already assigned they will be removed instead. + * + * @param dsIds + * to toggle for + * @param tagName + * to toggle + * @return {@link DistributionSetTagAssignmentResult} with all meta data of + * the assignment outcome. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection dsIds, @NotNull String tagName); + + /** + * Unassign all {@link DistributionSet} from a given + * {@link DistributionSetTag} . + * + * @param tag + * to unassign all ds + * @return list of unassigned ds + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List unAssignAllDistributionSetsByTag(@NotNull DistributionSetTag tag); + + /** + * Unassigns a {@link SoftwareModule} form an existing + * {@link DistributionSet}. + * + * @param ds + * to get unassigned form + * @param softwareModule + * to get unassigned + * @return the updated {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet unassignSoftwareModule(@NotNull DistributionSet ds, @NotNull SoftwareModule softwareModule); + + /** + * Unassign a {@link DistributionSetTag} assignment to given + * {@link DistributionSet}. + * + * @param dsId + * to unassign for + * @param distributionSetTag + * to unassign + * @return the unassigned ds or if no ds is unassigned + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet unAssignTag(@NotNull Long dsId, @NotNull DistributionSetTag distributionSetTag); + + /** + * Updates existing {@link DistributionSet}. + * + * @param ds + * to update + * @return the saved {@link Entity}. + * @throws NullPointerException + * of {@link DistributionSet#getId()} is null + * @throw DataDependencyViolationException in case of illegal update + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet updateDistributionSet(@NotNull DistributionSet ds); + + /** + * updates a distribution set meta data value if corresponding entry exists. + * + * @param metadata + * the meta data entry to be updated + * @return the updated meta data entry + * @throws EntityNotFoundException + * in case the meta data entry does not exists and cannot be + * updated + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetMetadata updateDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); + + /** + * Updates existing {@link DistributionSetType}. However, keep in mind that + * is not possible to change the {@link DistributionSetTypeElement}s while + * the DS type is already in use. + * + * @param dsType + * to update + * @return updated {@link Entity} + * + * @throws EntityReadOnlyException + * if use tries to change the {@link DistributionSetTypeElement} + * s while the DS type is already in use. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetType updateDistributionSetType(@NotNull DistributionSetType dsType); + +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java index 0934e871e..e48aaa3ab 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java @@ -1,486 +1,504 @@ -/** - * 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.Collection; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.hibernate.validator.constraints.NotEmpty; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.security.access.prepost.PreAuthorize; - -/** - * Service for managing {@link SoftwareModule}s. - * - */ -public interface SoftwareManagement { - - /** - * Counts {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * and {@link SoftwareModule#getType()} that are not marked as deleted. - * - * @param searchText - * to search for in name and version - * @param type - * to filter the result - * @return number of found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModuleByFilters(String searchText, SoftwareModuleType type); - - /** - * Count all {@link SoftwareModule}s in the repository that are not marked - * as deleted. - * - * @return number of {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModulesAll(); - - /** - * Counts {@link SoftwareModule}s with given {@link SoftwareModuleType}. - * - * @param type - * to count - * @return number of found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModulesByType(@NotNull SoftwareModuleType type); - - /** - * @return number of {@link SoftwareModuleType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModuleTypesAll(); - - /** - * Create {@link SoftwareModule}s in the repository. - * - * @param swModules - * {@link SoftwareModule}s to create - * @return SoftwareModule - * @throws EntityAlreadyExistsException - * if a given entity already exists - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createSoftwareModule(@NotNull Collection swModules); - - /** - * - * @param swModule - * SoftwareModule to create - * @return SoftwareModule - * @throws EntityAlreadyExistsException - * if a given entity already exists - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - SoftwareModule createSoftwareModule(@NotNull SoftwareModule swModule); - - /** - * creates a list of software module meta data entries. - * - * @param metadata - * the meta data entries to create or update - * @return the updated or created software module meta data entries - * @throws EntityAlreadyExistsException - * in case one of the meta data entry already exists for the - * specific key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List createSoftwareModuleMetadata(@NotNull Collection metadata); - - /** - * creates or updates a single software module meta data entry. - * - * @param metadata - * the meta data entry to create or update - * @return the updated or created software module meta data entry - * @throws EntityAlreadyExistsException - * in case the meta data entry already exists for the specific - * key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleMetadata createSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); - - /** - * Creates multiple {@link SoftwareModuleType}s. - * - * @param types - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createSoftwareModuleType(@NotNull final Collection types); - - /** - * Creates new {@link SoftwareModuleType}. - * - * @param type - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - SoftwareModuleType createSoftwareModuleType(@NotNull SoftwareModuleType type); - - /** - * Deletes the given {@link SoftwareModule} {@link Entity}. - * - * @param bsm - * is the {@link SoftwareModule} to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModule(@NotNull SoftwareModule bsm); - - /** - * deletes a software module meta data entry. - * - * @param id - * the ID of the software module meta data to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - void deleteSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotNull String key); - - /** - * Deletes {@link SoftwareModule}s which is any if the given ids. - * - * @param ids - * of the Software Modules to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModules(@NotNull Collection ids); - - /** - * Deletes or marks as delete in case the type is in use. - * - * @param type - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModuleType(@NotNull SoftwareModuleType type); - - /** - * @param pageable - * the page request to page the result set - * @param set - * to search for - * @return all {@link SoftwareModule}s that are assigned to given - * {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleByAssignedTo(@NotNull Pageable pageable, @NotNull DistributionSet set); - - /** - * @param pageable - * the page request to page the result set - * @param set - * to search for - * @param type - * to filter - * @return all {@link SoftwareModule}s that are assigned to given - * {@link DistributionSet} filtered by {@link SoftwareModuleType}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleByAssignedToAndType(@NotNull Pageable pageable, @NotNull DistributionSet set, - @NotNull SoftwareModuleType type); - - /** - * Filter {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * and {@link SoftwareModule#getType()} that are not marked as deleted. - * - * @param pageable - * page parameter - * @param searchText - * to be filtered as "like" on {@link SoftwareModule#getName()} - * @param type - * to be filtered as "like" on {@link SoftwareModule#getType()} - * @return the page of found {@link SoftwareModule} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModuleByFilters(@NotNull Pageable pageable, String searchText, - SoftwareModuleType type); - - /** - * Finds {@link SoftwareModule} by given id. - * - * @param id - * to search for - * @return the found {@link SoftwareModule}s or null if not - * found. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_CONTROLLER) - SoftwareModule findSoftwareModuleById(@NotNull Long id); - - /** - * retrieves {@link SoftwareModule} by their name AND version AND type.. - * - * @param name - * of the {@link SoftwareModule} - * @param version - * of the {@link SoftwareModule} - * @param type - * of the {@link SoftwareModule} - * @return the found {@link SoftwareModule} or null - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModule findSoftwareModuleByNameAndVersion(@NotEmpty String name, @NotEmpty String version, - @NotNull SoftwareModuleType type); - - /** - * finds a single software module meta data by its id. - * - * @param id - * the id of the software module meta data containing the meta - * data key and the ID of the software module - * @return the found SoftwareModuleMetadata or {@code null} if not exits - * @throws EntityNotFoundException - * in case the meta data does not exists for the given key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleMetadata findSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotEmpty String key); - - /** - * finds all meta data by the given software module id. - * - * @param swId - * the software module id to retrieve the meta data from - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given software - * module id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long swId, - @NotNull Pageable pageable); - - /** - * finds all meta data by the given software module id. - * - * @param softwareModuleId - * the software module id to retrieve the meta data from - * @param spec - * the specification to filter the result - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given software - * module id - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long softwareModuleId, - @NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Filter {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * search text and {@link SoftwareModule#getType()} that are not marked as - * deleted and sort them by means of given distribution set related modules - * on top of the list. - * - * After that the modules are sorted by {@link SoftwareModule#getName()} and - * {@link SoftwareModule#getVersion()} in ascending order. - * - * @param pageable - * page parameter - * @param orderByDistributionId - * the ID of distribution set to be ordered on top - * @param searchText - * filtered as "like" on {@link SoftwareModule#getName()} - * @param type - * filtered as "equal" on {@link SoftwareModule#getType()} - * @return the page of found {@link SoftwareModule} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( - @NotNull Pageable pageable, @NotNull Long orderByDistributionId, String searchText, - SoftwareModuleType type); - - /** - * Retrieves all software modules. Deleted ones are filtered. - * - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModulesAll(@NotNull Pageable pageable); - - /** - * Retrieves all software modules with a given list of ids - * {@link SoftwareModule#getId()}. - * - * @param ids - * to search for - * @return {@link List} of found {@link SoftwareModule}s - */ - List findSoftwareModulesById(@NotEmpty Collection ids); - - /** - * Retrieves all {@link SoftwareModule}s with a given specification. - * - * @param spec - * the specification to filter the software modules - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModule}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModulesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType} - * . - * - * @param pageable - * page parameters - * @param type - * to be filtered on - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModulesByType(@NotNull Pageable pageable, @NotNull SoftwareModuleType type); - - /** - * - * @param id - * to search for - * @return {@link SoftwareModuleType} in the repository with given - * {@link SoftwareModuleType#getId()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeById(@NotNull Long id); - - /** - * - * @param key - * to search for - * @return {@link SoftwareModuleType} in the repository with given - * {@link SoftwareModuleType#getKey()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeByKey(@NotNull String key); - - /** - * - * @param name - * to search for - * @return all {@link SoftwareModuleType}s in the repository with given - * {@link SoftwareModuleType#getName()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeByName(@NotNull String name); - - /** - * @param pageable - * parameter - * @return all {@link SoftwareModuleType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleTypesAll(@NotNull Pageable pageable); - - /** - * Retrieves all {@link SoftwareModuleType}s with a given specification. - * - * @param spec - * the specification to filter the software modules types - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModuleType}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Retrieves software module including details ( - * {@link SoftwareModule#getArtifacts()}). - * - * @param id - * parameter - * @param isDeleted - * parameter - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModule findSoftwareModuleWithDetails(@NotNull Long id); - - /** - * Updates existing {@link SoftwareModule}. Update-able values are - * {@link SoftwareModule#getDescription()} - * {@link SoftwareModule#getVendor()}. - * - * @param sm - * to update - * - * @return the saved {@link Entity}. - * - * @throws NullPointerException - * of {@link SoftwareModule#getId()} is null - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModule updateSoftwareModule(@NotNull SoftwareModule sm); - - /** - * updates a distribution set meta data value if corresponding entry exists. - * - * @param metadata - * the meta data entry to be updated - * @return the updated meta data entry - * @throws EntityNotFoundException - * in case the meta data entry does not exists and cannot be - * updated - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleMetadata updateSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); - - /** - * Updates existing {@link SoftwareModuleType}. Update-able value is - * {@link SoftwareModuleType#getDescription()} and - * {@link SoftwareModuleType#getColour()}. - * - * @param sm - * to update - * @return updated {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm); - -} +/** + * 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.Collection; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; +import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.hibernate.validator.constraints.NotEmpty; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.security.access.prepost.PreAuthorize; + +/** + * Service for managing {@link SoftwareModule}s. + * + */ +public interface SoftwareManagement { + + /** + * Counts {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * and {@link SoftwareModule#getType()} that are not marked as deleted. + * + * @param searchText + * to search for in name and version + * @param type + * to filter the result + * @return number of found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModuleByFilters(String searchText, SoftwareModuleType type); + + /** + * Count all {@link SoftwareModule}s in the repository that are not marked + * as deleted. + * + * @return number of {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModulesAll(); + + /** + * Counts {@link SoftwareModule}s with given {@link SoftwareModuleType}. + * + * @param type + * to count + * @return number of found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModulesByType(@NotNull SoftwareModuleType type); + + /** + * @return number of {@link SoftwareModuleType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModuleTypesAll(); + + /** + * Create {@link SoftwareModule}s in the repository. + * + * @param swModules + * {@link SoftwareModule}s to create + * @return SoftwareModule + * @throws EntityAlreadyExistsException + * if a given entity already exists + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createSoftwareModule(@NotNull Collection swModules); + + /** + * + * @param swModule + * SoftwareModule to create + * @return SoftwareModule + * @throws EntityAlreadyExistsException + * if a given entity already exists + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + SoftwareModule createSoftwareModule(@NotNull SoftwareModule swModule); + + /** + * creates a list of software module meta data entries. + * + * @param metadata + * the meta data entries to create or update + * @return the updated or created software module meta data entries + * @throws EntityAlreadyExistsException + * in case one of the meta data entry already exists for the + * specific key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List createSoftwareModuleMetadata(@NotNull Collection metadata); + + /** + * creates or updates a single software module meta data entry. + * + * @param metadata + * the meta data entry to create or update + * @return the updated or created software module meta data entry + * @throws EntityAlreadyExistsException + * in case the meta data entry already exists for the specific + * key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleMetadata createSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); + + /** + * Creates multiple {@link SoftwareModuleType}s. + * + * @param types + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createSoftwareModuleType(@NotNull final Collection types); + + /** + * Creates new {@link SoftwareModuleType}. + * + * @param type + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + SoftwareModuleType createSoftwareModuleType(@NotNull SoftwareModuleType type); + + /** + * Deletes the given {@link SoftwareModule} {@link Entity}. + * + * @param bsm + * is the {@link SoftwareModule} to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModule(@NotNull SoftwareModule bsm); + + /** + * deletes a software module meta data entry. + * + * @param id + * the ID of the software module meta data to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void deleteSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotNull String key); + + /** + * Deletes {@link SoftwareModule}s which is any if the given ids. + * + * @param ids + * of the Software Modules to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModules(@NotNull Collection ids); + + /** + * Deletes or marks as delete in case the type is in use. + * + * @param type + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModuleType(@NotNull SoftwareModuleType type); + + /** + * @param pageable + * the page request to page the result set + * @param set + * to search for + * @return all {@link SoftwareModule}s that are assigned to given + * {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleByAssignedTo(@NotNull Pageable pageable, @NotNull DistributionSet set); + + /** + * @param pageable + * the page request to page the result set + * @param set + * to search for + * @param type + * to filter + * @return all {@link SoftwareModule}s that are assigned to given + * {@link DistributionSet} filtered by {@link SoftwareModuleType}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleByAssignedToAndType(@NotNull Pageable pageable, @NotNull DistributionSet set, + @NotNull SoftwareModuleType type); + + /** + * Filter {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * and {@link SoftwareModule#getType()} that are not marked as deleted. + * + * @param pageable + * page parameter + * @param searchText + * to be filtered as "like" on {@link SoftwareModule#getName()} + * @param type + * to be filtered as "like" on {@link SoftwareModule#getType()} + * @return the page of found {@link SoftwareModule} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModuleByFilters(@NotNull Pageable pageable, String searchText, + SoftwareModuleType type); + + /** + * Finds {@link SoftwareModule} by given id. + * + * @param id + * to search for + * @return the found {@link SoftwareModule}s or null if not + * found. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.IS_CONTROLLER) + SoftwareModule findSoftwareModuleById(@NotNull Long id); + + /** + * retrieves {@link SoftwareModule} by their name AND version AND type.. + * + * @param name + * of the {@link SoftwareModule} + * @param version + * of the {@link SoftwareModule} + * @param type + * of the {@link SoftwareModule} + * @return the found {@link SoftwareModule} or null + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModule findSoftwareModuleByNameAndVersion(@NotEmpty String name, @NotEmpty String version, + @NotNull SoftwareModuleType type); + + /** + * finds a single software module meta data by its id. + * + * @param id + * the id of the software module meta data containing the meta + * data key and the ID of the software module + * @return the found SoftwareModuleMetadata or {@code null} if not exits + * @throws EntityNotFoundException + * in case the meta data does not exists for the given key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleMetadata findSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotEmpty String key); + + /** + * finds all meta data by the given software module id. + * + * @param swId + * the software module id to retrieve the meta data from + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given software + * module id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long swId, + @NotNull Pageable pageable); + + /** + * finds all meta data by the given software module id. + * + * @param softwareModuleId + * the software module id to retrieve the meta data from + * @param spec + * the specification to filter the result + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given software + * module id + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long softwareModuleId, + @NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Filter {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * search text and {@link SoftwareModule#getType()} that are not marked as + * deleted and sort them by means of given distribution set related modules + * on top of the list. + * + * After that the modules are sorted by {@link SoftwareModule#getName()} and + * {@link SoftwareModule#getVersion()} in ascending order. + * + * @param pageable + * page parameter + * @param orderByDistributionId + * the ID of distribution set to be ordered on top + * @param searchText + * filtered as "like" on {@link SoftwareModule#getName()} + * @param type + * filtered as "equal" on {@link SoftwareModule#getType()} + * @return the page of found {@link SoftwareModule} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( + @NotNull Pageable pageable, @NotNull Long orderByDistributionId, String searchText, + SoftwareModuleType type); + + /** + * Retrieves all software modules. Deleted ones are filtered. + * + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModulesAll(@NotNull Pageable pageable); + + /** + * Retrieves all software modules with a given list of ids + * {@link SoftwareModule#getId()}. + * + * @param ids + * to search for + * @return {@link List} of found {@link SoftwareModule}s + */ + List findSoftwareModulesById(@NotEmpty Collection ids); + + /** + * Retrieves all {@link SoftwareModule}s with a given specification. + * + * @param spec + * the specification to filter the software modules + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModule}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModulesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType} + * . + * + * @param pageable + * page parameters + * @param type + * to be filtered on + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModulesByType(@NotNull Pageable pageable, @NotNull SoftwareModuleType type); + + /** + * + * @param id + * to search for + * @return {@link SoftwareModuleType} in the repository with given + * {@link SoftwareModuleType#getId()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeById(@NotNull Long id); + + /** + * + * @param key + * to search for + * @return {@link SoftwareModuleType} in the repository with given + * {@link SoftwareModuleType#getKey()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeByKey(@NotNull String key); + + /** + * + * @param name + * to search for + * @return all {@link SoftwareModuleType}s in the repository with given + * {@link SoftwareModuleType#getName()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeByName(@NotNull String name); + + /** + * @param pageable + * parameter + * @return all {@link SoftwareModuleType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleTypesAll(@NotNull Pageable pageable); + + /** + * Retrieves all {@link SoftwareModuleType}s with a given specification. + * + * @param spec + * the specification to filter the software modules types + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModuleType}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Retrieves software module including details ( + * {@link SoftwareModule#getArtifacts()}). + * + * @param id + * parameter + * @param isDeleted + * parameter + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModule findSoftwareModuleWithDetails(@NotNull Long id); + + /** + * Updates existing {@link SoftwareModule}. Update-able values are + * {@link SoftwareModule#getDescription()} + * {@link SoftwareModule#getVendor()}. + * + * @param sm + * to update + * + * @return the saved {@link Entity}. + * + * @throws NullPointerException + * of {@link SoftwareModule#getId()} is null + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModule updateSoftwareModule(@NotNull SoftwareModule sm); + + /** + * updates a distribution set meta data value if corresponding entry exists. + * + * @param metadata + * the meta data entry to be updated + * @return the updated meta data entry + * @throws EntityNotFoundException + * in case the meta data entry does not exists and cannot be + * updated + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleMetadata updateSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); + + /** + * Updates existing {@link SoftwareModuleType}. Update-able value is + * {@link SoftwareModuleType#getDescription()} and + * {@link SoftwareModuleType#getColour()}. + * + * @param sm + * to update + * @return updated {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm); + + /** + * finds all meta data by the given software module id. + * + * @param softwareModuleId + * the software module id to retrieve the meta data from + + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + * @return result of all meta data entries for a given software + * module id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findSoftwareModuleMetadataBySoftwareModuleId(Long softwareModuleId); + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index b94677fb9..306b9bd80 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -173,39 +173,36 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteDistributionSet(final Long... distributionSetIDs) { - final List toHardDelete = new ArrayList<>(); + public void deleteDistributionSet(final Long... distributionSetIDs) { + final List toHardDelete = new ArrayList<>(); - final List assigned = distributionSetRepository - .findAssignedToTargetDistributionSetsById(distributionSetIDs); - assigned.addAll(distributionSetRepository - .findAssignedToRolloutDistributionSetsById(distributionSetIDs)); + final List assigned = distributionSetRepository + .findAssignedToTargetDistributionSetsById(distributionSetIDs); + assigned.addAll(distributionSetRepository.findAssignedToRolloutDistributionSetsById(distributionSetIDs)); - // soft delete assigned - if (!assigned.isEmpty()) { - distributionSetRepository.deleteDistributionSet(assigned - .toArray(new Long[assigned.size()])); - } + // soft delete assigned + if (!assigned.isEmpty()) { + distributionSetRepository.deleteDistributionSet(assigned.toArray(new Long[assigned.size()])); + } - // mark the rest as hard delete - for (final Long setId : distributionSetIDs) { - if (!assigned.contains(setId)) { - toHardDelete.add(setId); - } - } + // mark the rest as hard delete + for (final Long setId : distributionSetIDs) { + if (!assigned.contains(setId)) { + toHardDelete.add(setId); + } + } - // hard delete the rest if exixts - if (!toHardDelete.isEmpty()) { - // don't give the delete statement an empty list, JPA/Oracle cannot - // handle the empty list - distributionSetRepository.deleteByIdIn(toHardDelete); - } + // hard delete the rest if exixts + if (!toHardDelete.isEmpty()) { + // don't give the delete statement an empty list, JPA/Oracle cannot + // handle the empty list + distributionSetRepository.deleteByIdIn(toHardDelete); + } - afterCommit.afterCommit(() -> eventBus - .post(new DistributionDeletedEvent(tenantAware - .getCurrentTenant(), distributionSetIDs))); + afterCommit.afterCommit( + () -> eventBus.post(new DistributionDeletedEvent(tenantAware.getCurrentTenant(), distributionSetIDs))); - } + } @Override @Modifying @@ -530,6 +527,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying public void deleteDistributionSetMetadata(final DistributionSet distributionSet, final String key) { + entityManager.merge((JpaDistributionSet) distributionSet).setLastModifiedAt(0L); distributionSetMetadataRepository.delete(new DsMetadataCompositeKey(distributionSet, key)); } @@ -544,6 +542,15 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { pageable); } + @Override + public List findDistributionSetMetadataByDistributionSetId(final Long distributionSetId) { + + return new ArrayList(distributionSetMetadataRepository + .findAll((Specification) (root, query, cb) -> cb.equal( + root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id), + distributionSetId))); + } + @Override public Page findDistributionSetMetadataByDistributionSetId(final Long distributionSetId, final String rsqlParam, final Pageable pageable) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index b561667a9..afe1a1e02 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -1,663 +1,672 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.persistence.EntityManager; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.ListJoin; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.SoftwareManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleFields; -import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata_; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; -import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; -import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; -import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; -import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; -import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.LocalArtifact; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.AuditorAware; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.SliceImpl; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import com.google.common.base.Strings; -import com.google.common.collect.Sets; - -/** - * JPA implementation of {@link SoftwareManagement}. - * - */ -@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -@Validated -public class JpaSoftwareManagement implements SoftwareManagement { - - @Autowired - private EntityManager entityManager; - - @Autowired - private DistributionSetRepository distributionSetRepository; - - @Autowired - private DistributionSetTypeRepository distributionSetTypeRepository; - - @Autowired - private SoftwareModuleRepository softwareModuleRepository; - - @Autowired - private SoftwareModuleMetadataRepository softwareModuleMetadataRepository; - - @Autowired - private SoftwareModuleTypeRepository softwareModuleTypeRepository; - - @Autowired - private NoCountPagingRepository criteriaNoCountDao; - - @Autowired - private AuditorAware auditorProvider; - - @Autowired - private ArtifactManagement artifactManagement; - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModule updateSoftwareModule(final SoftwareModule sm) { - checkNotNull(sm.getId()); - - final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId()); - - boolean updated = false; - if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) { - module.setDescription(sm.getDescription()); - updated = true; - } - if (null == sm.getVendor() || !sm.getVendor().equals(module.getVendor())) { - module.setVendor(sm.getVendor()); - updated = true; - } - - return updated ? softwareModuleRepository.save(module) : module; - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) { - checkNotNull(sm.getId()); - - final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); - - boolean updated = false; - if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) { - type.setDescription(sm.getDescription()); - updated = true; - } - if (sm.getColour() != null && !sm.getColour().equals(type.getColour())) { - type.setColour(sm.getColour()); - updated = true; - } - return updated ? softwareModuleTypeRepository.save(type) : type; - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModule createSoftwareModule(final SoftwareModule swModule) { - if (null != swModule.getId()) { - throw new EntityAlreadyExistsException(); - } - return softwareModuleRepository.save((JpaSoftwareModule) swModule); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createSoftwareModule(final Collection swModules) { - swModules.forEach(swModule -> { - if (null != swModule.getId()) { - throw new EntityAlreadyExistsException(); - } - }); - - @SuppressWarnings({ "unchecked", "rawtypes" }) - final Collection jpaCast = (Collection) swModules; - - return new ArrayList<>(softwareModuleRepository.save(jpaCast)); - } - - @Override - public Slice findSoftwareModulesByType(final Pageable pageable, final SoftwareModuleType type) { - - final List> specList = new LinkedList<>(); - - Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - - spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - private static Slice convertSmPage(final Slice findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); - } - - private static Page convertSmPage(final Page findAll, final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - private static Page convertSmMdPage(final Page findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - @Override - public Long countSoftwareModulesByType(final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - - spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public SoftwareModule findSoftwareModuleById(final Long id) { - return artifactManagement.findSoftwareModuleById(id); - } - - @Override - public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version, - final SoftwareModuleType type) { - - return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type); - } - - private boolean isUnassigned(final JpaSoftwareModule bsmMerged) { - return distributionSetRepository.findByModules(bsmMerged).isEmpty(); - } - - private Slice findSwModuleByCriteriaAPI(final Pageable pageable, - final List> specList) { - return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, - JpaSoftwareModule.class); - } - - private Long countSwModuleByCriteriaAPI(final List> specList) { - return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList)); - } - - private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) { - for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) { - artifactManagement.deleteLocalArtifact(localArtifact); - } - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModules(final Collection ids) { - final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); - final Set assignedModuleIds = new HashSet<>(); - swModulesToDelete.forEach(swModule -> { - - // delete binary data of artifacts - deleteGridFsArtifacts(swModule); - - if (isUnassigned(swModule)) { - - softwareModuleRepository.delete(swModule); - - } else { - - assignedModuleIds.add(swModule.getId()); - } - }); - - if (!assignedModuleIds.isEmpty()) { - String currentUser = null; - if (auditorProvider != null) { - currentUser = auditorProvider.getCurrentAuditor(); - } - softwareModuleRepository.deleteSoftwareModule(System.currentTimeMillis(), currentUser, - assignedModuleIds.toArray(new Long[0])); - } - } - - @Override - public Slice findSoftwareModulesAll(final Pageable pageable) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - spec = (root, query, cb) -> { - if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(JpaSoftwareModule_.type); - } - return cb.conjunction(); - }; - - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - @Override - public Long countSoftwareModulesAll() { - - final List> specList = new ArrayList<>(); - - final Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public SoftwareModule findSoftwareModuleWithDetails(final Long id) { - return artifactManagement.findSoftwareModuleWithDetails(id); - } - - @Override - public Page findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) { - final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class); - - return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable); - } - - @Override - public Page findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) { - - final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class); - - return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable); - } - - private static Page convertSmTPage(final Page findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - @Override - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - public List findSoftwareModulesById(final Collection ids) { - return new ArrayList<>(softwareModuleRepository.findByIdIn(ids)); - } - - @Override - public Slice findSoftwareModuleByFilters(final Pageable pageable, final String searchText, - final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - if (!Strings.isNullOrEmpty(searchText)) { - spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); - specList.add(spec); - } - - if (null != type) { - spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - } - - spec = (root, query, cb) -> { - if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(JpaSoftwareModule_.type); - } - return cb.conjunction(); - }; - - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - @Override - public Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( - final Pageable pageable, final Long orderByDistributionId, final String searchText, - final SoftwareModuleType ty) { - final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; - - final List resultList = new ArrayList<>(); - final int pageSize = pageable.getPageSize(); - final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); - - // get the assigned software modules - final CriteriaQuery assignedQuery = cb.createQuery(JpaSoftwareModule.class); - final Root assignedRoot = assignedQuery.from(JpaSoftwareModule.class); - assignedQuery.distinct(true); - final ListJoin assignedDsJoin = assignedRoot - .join(JpaSoftwareModule_.assignedTo); - // build the specifications and then to predicates necessary by the - // given filters - final Predicate[] specPredicate = specificationsToPredicate(buildSpecificationList(searchText, type), - assignedRoot, assignedQuery, cb, - cb.equal(assignedDsJoin.get(JpaDistributionSet_.id), orderByDistributionId)); - // if we have some predicates then add it to the where clause of the - // multi select - assignedQuery.where(specPredicate); - assignedQuery.orderBy(cb.asc(assignedRoot.get(JpaSoftwareModule_.name)), - cb.asc(assignedRoot.get(JpaSoftwareModule_.version))); - // don't page the assigned query on database, we need all assigned - // software modules to filter - // them out in the unassigned query - final List assignedSoftwareModules = entityManager.createQuery(assignedQuery) - .getResultList(); - // map result - if (pageable.getOffset() < assignedSoftwareModules.size()) { - assignedSoftwareModules - .subList(pageable.getOffset(), Math.min(assignedSoftwareModules.size(), pageable.getPageSize())) - .forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, true))); - } - - if (assignedSoftwareModules.size() >= pageSize) { - return new SliceImpl<>(resultList); - } - - // get the unassigned software modules - final CriteriaQuery unassignedQuery = cb.createQuery(JpaSoftwareModule.class); - unassignedQuery.distinct(true); - final Root unassignedRoot = unassignedQuery.from(JpaSoftwareModule.class); - - Predicate[] unassignedSpec; - if (!assignedSoftwareModules.isEmpty()) { - unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, - unassignedQuery, cb, cb.not(unassignedRoot.get(JpaSoftwareModule_.id) - .in(assignedSoftwareModules.stream().map(sw -> sw.getId()).collect(Collectors.toList())))); - } else { - unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, - unassignedQuery, cb); - } - - unassignedQuery.where(unassignedSpec); - unassignedQuery.orderBy(cb.asc(unassignedRoot.get(JpaSoftwareModule_.name)), - cb.asc(unassignedRoot.get(JpaSoftwareModule_.version))); - final List unassignedSoftwareModules = entityManager.createQuery(unassignedQuery) - .setFirstResult(Math.max(0, pageable.getOffset() - assignedSoftwareModules.size())) - .setMaxResults(pageSize).getResultList(); - // map result - unassignedSoftwareModules.forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, false))); - - return new SliceImpl<>(resultList); - } - - private static List> buildSpecificationList(final String searchText, - final JpaSoftwareModuleType type) { - final List> specList = new ArrayList<>(); - if (!Strings.isNullOrEmpty(searchText)) { - specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText)); - } - if (type != null) { - specList.add(SoftwareModuleSpecification.equalType(type)); - } - specList.add(SoftwareModuleSpecification.isDeletedFalse()); - return specList; - } - - private Predicate[] specificationsToPredicate(final List> specifications, - final Root root, final CriteriaQuery query, final CriteriaBuilder cb, - final Predicate... additionalPredicates) { - final List predicates = new ArrayList<>(); - specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb))); - for (final Predicate predicate : additionalPredicates) { - predicates.add(predicate); - } - return predicates.toArray(new Predicate[predicates.size()]); - } - - @Override - public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - if (!Strings.isNullOrEmpty(searchText)) { - spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); - specList.add(spec); - } - - if (null != type) { - spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - } - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public Page findSoftwareModuleTypesAll(final Pageable pageable) { - return softwareModuleTypeRepository.findByDeleted(pageable, false); - } - - @Override - public Long countSoftwareModuleTypesAll() { - return softwareModuleTypeRepository.countByDeleted(false); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeByKey(final String key) { - return softwareModuleTypeRepository.findByKey(key); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeById(final Long id) { - return softwareModuleTypeRepository.findOne(id); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeByName(final String name) { - return softwareModuleTypeRepository.findByName(name); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleType type) { - if (type.getId() != null) { - throw new EntityAlreadyExistsException("Given type contains an Id!"); - } - - return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModuleType(final SoftwareModuleType ty) { - final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; - - if (softwareModuleRepository.countByType(type) > 0 - || distributionSetTypeRepository.countByElementsSmType(type) > 0) { - final JpaSoftwareModuleType toDelete = entityManager.merge(type); - toDelete.setDeleted(true); - softwareModuleTypeRepository.save(toDelete); - } else { - softwareModuleTypeRepository.delete(type.getId()); - } - } - - @Override - public Page findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) { - return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set); - } - - @Override - public Page findSoftwareModuleByAssignedToAndType(final Pageable pageable, - final DistributionSet set, final SoftwareModuleType type) { - return softwareModuleRepository.findByAssignedToAndType(pageable, (JpaDistributionSet) set, - (JpaSoftwareModuleType) type); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) { - final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; - - if (softwareModuleMetadataRepository.exists(metadata.getId())) { - throwMetadataKeyAlreadyExists(metadata.getId().getKey()); - } - // merge base software module so optLockRevision gets updated and audit - // log written because - // modifying metadata is modifying the base software module itself for - // auditing purposes. - entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); - return softwareModuleMetadataRepository.save(metadata); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public List createSoftwareModuleMetadata(final Collection md) { - @SuppressWarnings({ "unchecked", "rawtypes" }) - final Collection metadata = (Collection) md; - - for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) { - checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId()); - } - metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L)); - return new ArrayList<>(softwareModuleMetadataRepository.save(metadata)); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) { - final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; - - // check if exists otherwise throw entity not found exception - findSoftwareModuleMetadata(metadata.getId()); - // touch it to update the lock revision because we are modifying the - // software module - // indirectly - entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); - return softwareModuleMetadataRepository.save(metadata); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public void deleteSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { - softwareModuleMetadataRepository.delete(new SwMetadataCompositeKey(softwareModule, key)); - } - - @Override - public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long swId, - final Pageable pageable) { - return softwareModuleMetadataRepository.findBySoftwareModuleId(swId, pageable); - } - - @Override - public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId, - final String rsqlParam, final Pageable pageable) { - - final Specification spec = RSQLUtility.parse(rsqlParam, - SoftwareModuleMetadataFields.class); - return convertSmMdPage( - softwareModuleMetadataRepository - .findAll( - (Specification) (root, query, cb) -> cb.and( - cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) - .get(JpaSoftwareModule_.id), softwareModuleId), - spec.toPredicate(root, query, cb)), - pageable), - pageable); - } - - @Override - public SoftwareModuleMetadata findSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { - return findSoftwareModuleMetadata(new SwMetadataCompositeKey(softwareModule, key)); - } - - private SoftwareModuleMetadata findSoftwareModuleMetadata(final SwMetadataCompositeKey id) { - final SoftwareModuleMetadata findOne = softwareModuleMetadataRepository.findOne(id); - if (findOne == null) { - throw new EntityNotFoundException("Metadata with key '" + id.getKey() + "' does not exist"); - } - return findOne; - } - - private void checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(final SwMetadataCompositeKey metadataId) { - if (softwareModuleMetadataRepository.exists(metadataId)) { - throw new EntityAlreadyExistsException( - "Metadata entry with key '" + metadataId.getKey() + "' already exists"); - } - } - - private static void throwMetadataKeyAlreadyExists(final String metadataKey) { - throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists"); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModule(final SoftwareModule bsm) { - deleteSoftwareModules(Sets.newHashSet(bsm.getId())); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createSoftwareModuleType(final Collection types) { - - return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.ListJoin; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.SoftwareManagement; +import org.eclipse.hawkbit.repository.SoftwareModuleFields; +import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; +import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; +import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; +import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; +import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.LocalArtifact; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.AuditorAware; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import com.google.common.base.Strings; +import com.google.common.collect.Sets; + +/** + * JPA implementation of {@link SoftwareManagement}. + * + */ +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) +@Validated +public class JpaSoftwareManagement implements SoftwareManagement { + + @Autowired + private EntityManager entityManager; + + @Autowired + private DistributionSetRepository distributionSetRepository; + + @Autowired + private DistributionSetTypeRepository distributionSetTypeRepository; + + @Autowired + private SoftwareModuleRepository softwareModuleRepository; + + @Autowired + private SoftwareModuleMetadataRepository softwareModuleMetadataRepository; + + @Autowired + private SoftwareModuleTypeRepository softwareModuleTypeRepository; + + @Autowired + private NoCountPagingRepository criteriaNoCountDao; + + @Autowired + private AuditorAware auditorProvider; + + @Autowired + private ArtifactManagement artifactManagement; + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModule updateSoftwareModule(final SoftwareModule sm) { + checkNotNull(sm.getId()); + + final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId()); + + boolean updated = false; + if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) { + module.setDescription(sm.getDescription()); + updated = true; + } + if (null == sm.getVendor() || !sm.getVendor().equals(module.getVendor())) { + module.setVendor(sm.getVendor()); + updated = true; + } + + return updated ? softwareModuleRepository.save(module) : module; + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) { + checkNotNull(sm.getId()); + + final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); + + boolean updated = false; + if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) { + type.setDescription(sm.getDescription()); + updated = true; + } + if (sm.getColour() != null && !sm.getColour().equals(type.getColour())) { + type.setColour(sm.getColour()); + updated = true; + } + return updated ? softwareModuleTypeRepository.save(type) : type; + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModule createSoftwareModule(final SoftwareModule swModule) { + if (null != swModule.getId()) { + throw new EntityAlreadyExistsException(); + } + return softwareModuleRepository.save((JpaSoftwareModule) swModule); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public List createSoftwareModule(final Collection swModules) { + swModules.forEach(swModule -> { + if (null != swModule.getId()) { + throw new EntityAlreadyExistsException(); + } + }); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection jpaCast = (Collection) swModules; + + return new ArrayList<>(softwareModuleRepository.save(jpaCast)); + } + + @Override + public Slice findSoftwareModulesByType(final Pageable pageable, final SoftwareModuleType type) { + + final List> specList = new LinkedList<>(); + + Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + + spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + private static Slice convertSmPage(final Slice findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); + } + + private static Page convertSmPage(final Page findAll, final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + private static Page convertSmMdPage(final Page findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + @Override + public Long countSoftwareModulesByType(final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + + spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public SoftwareModule findSoftwareModuleById(final Long id) { + return artifactManagement.findSoftwareModuleById(id); + } + + @Override + public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version, + final SoftwareModuleType type) { + + return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type); + } + + private boolean isUnassigned(final JpaSoftwareModule bsmMerged) { + return distributionSetRepository.findByModules(bsmMerged).isEmpty(); + } + + private Slice findSwModuleByCriteriaAPI(final Pageable pageable, + final List> specList) { + return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, + JpaSoftwareModule.class); + } + + private Long countSwModuleByCriteriaAPI(final List> specList) { + return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList)); + } + + private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) { + for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) { + artifactManagement.deleteLocalArtifact(localArtifact); + } + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModules(final Collection ids) { + final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); + final Set assignedModuleIds = new HashSet<>(); + swModulesToDelete.forEach(swModule -> { + + // delete binary data of artifacts + deleteGridFsArtifacts(swModule); + + if (isUnassigned(swModule)) { + + softwareModuleRepository.delete(swModule); + + } else { + + assignedModuleIds.add(swModule.getId()); + } + }); + + if (!assignedModuleIds.isEmpty()) { + String currentUser = null; + if (auditorProvider != null) { + currentUser = auditorProvider.getCurrentAuditor(); + } + softwareModuleRepository.deleteSoftwareModule(System.currentTimeMillis(), currentUser, + assignedModuleIds.toArray(new Long[0])); + } + } + + @Override + public Slice findSoftwareModulesAll(final Pageable pageable) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + spec = (root, query, cb) -> { + if (!query.getResultType().isAssignableFrom(Long.class)) { + root.fetch(JpaSoftwareModule_.type); + } + return cb.conjunction(); + }; + + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + @Override + public Long countSoftwareModulesAll() { + + final List> specList = new ArrayList<>(); + + final Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public SoftwareModule findSoftwareModuleWithDetails(final Long id) { + return artifactManagement.findSoftwareModuleWithDetails(id); + } + + @Override + public Page findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) { + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class); + + return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable); + } + + @Override + public Page findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class); + + return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable); + } + + private static Page convertSmTPage(final Page findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + @Override + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + public List findSoftwareModulesById(final Collection ids) { + return new ArrayList<>(softwareModuleRepository.findByIdIn(ids)); + } + + @Override + public Slice findSoftwareModuleByFilters(final Pageable pageable, final String searchText, + final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + if (!Strings.isNullOrEmpty(searchText)) { + spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); + specList.add(spec); + } + + if (null != type) { + spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + } + + spec = (root, query, cb) -> { + if (!query.getResultType().isAssignableFrom(Long.class)) { + root.fetch(JpaSoftwareModule_.type); + } + return cb.conjunction(); + }; + + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + @Override + public Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( + final Pageable pageable, final Long orderByDistributionId, final String searchText, + final SoftwareModuleType ty) { + final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; + + final List resultList = new ArrayList<>(); + final int pageSize = pageable.getPageSize(); + final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + + // get the assigned software modules + final CriteriaQuery assignedQuery = cb.createQuery(JpaSoftwareModule.class); + final Root assignedRoot = assignedQuery.from(JpaSoftwareModule.class); + assignedQuery.distinct(true); + final ListJoin assignedDsJoin = assignedRoot + .join(JpaSoftwareModule_.assignedTo); + // build the specifications and then to predicates necessary by the + // given filters + final Predicate[] specPredicate = specificationsToPredicate(buildSpecificationList(searchText, type), + assignedRoot, assignedQuery, cb, + cb.equal(assignedDsJoin.get(JpaDistributionSet_.id), orderByDistributionId)); + // if we have some predicates then add it to the where clause of the + // multi select + assignedQuery.where(specPredicate); + assignedQuery.orderBy(cb.asc(assignedRoot.get(JpaSoftwareModule_.name)), + cb.asc(assignedRoot.get(JpaSoftwareModule_.version))); + // don't page the assigned query on database, we need all assigned + // software modules to filter + // them out in the unassigned query + final List assignedSoftwareModules = entityManager.createQuery(assignedQuery) + .getResultList(); + // map result + if (pageable.getOffset() < assignedSoftwareModules.size()) { + assignedSoftwareModules + .subList(pageable.getOffset(), Math.min(assignedSoftwareModules.size(), pageable.getPageSize())) + .forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, true))); + } + + if (assignedSoftwareModules.size() >= pageSize) { + return new SliceImpl<>(resultList); + } + + // get the unassigned software modules + final CriteriaQuery unassignedQuery = cb.createQuery(JpaSoftwareModule.class); + unassignedQuery.distinct(true); + final Root unassignedRoot = unassignedQuery.from(JpaSoftwareModule.class); + + Predicate[] unassignedSpec; + if (!assignedSoftwareModules.isEmpty()) { + unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, + unassignedQuery, cb, cb.not(unassignedRoot.get(JpaSoftwareModule_.id) + .in(assignedSoftwareModules.stream().map(sw -> sw.getId()).collect(Collectors.toList())))); + } else { + unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, + unassignedQuery, cb); + } + + unassignedQuery.where(unassignedSpec); + unassignedQuery.orderBy(cb.asc(unassignedRoot.get(JpaSoftwareModule_.name)), + cb.asc(unassignedRoot.get(JpaSoftwareModule_.version))); + final List unassignedSoftwareModules = entityManager.createQuery(unassignedQuery) + .setFirstResult(Math.max(0, pageable.getOffset() - assignedSoftwareModules.size())) + .setMaxResults(pageSize).getResultList(); + // map result + unassignedSoftwareModules.forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, false))); + + return new SliceImpl<>(resultList); + } + + private static List> buildSpecificationList(final String searchText, + final JpaSoftwareModuleType type) { + final List> specList = new ArrayList<>(); + if (!Strings.isNullOrEmpty(searchText)) { + specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText)); + } + if (type != null) { + specList.add(SoftwareModuleSpecification.equalType(type)); + } + specList.add(SoftwareModuleSpecification.isDeletedFalse()); + return specList; + } + + private Predicate[] specificationsToPredicate(final List> specifications, + final Root root, final CriteriaQuery query, final CriteriaBuilder cb, + final Predicate... additionalPredicates) { + final List predicates = new ArrayList<>(); + specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb))); + for (final Predicate predicate : additionalPredicates) { + predicates.add(predicate); + } + return predicates.toArray(new Predicate[predicates.size()]); + } + + @Override + public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + if (!Strings.isNullOrEmpty(searchText)) { + spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); + specList.add(spec); + } + + if (null != type) { + spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + } + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public Page findSoftwareModuleTypesAll(final Pageable pageable) { + return softwareModuleTypeRepository.findByDeleted(pageable, false); + } + + @Override + public Long countSoftwareModuleTypesAll() { + return softwareModuleTypeRepository.countByDeleted(false); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeByKey(final String key) { + return softwareModuleTypeRepository.findByKey(key); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeById(final Long id) { + return softwareModuleTypeRepository.findOne(id); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeByName(final String name) { + return softwareModuleTypeRepository.findByName(name); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleType type) { + if (type.getId() != null) { + throw new EntityAlreadyExistsException("Given type contains an Id!"); + } + + return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModuleType(final SoftwareModuleType ty) { + final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; + + if (softwareModuleRepository.countByType(type) > 0 + || distributionSetTypeRepository.countByElementsSmType(type) > 0) { + final JpaSoftwareModuleType toDelete = entityManager.merge(type); + toDelete.setDeleted(true); + softwareModuleTypeRepository.save(toDelete); + } else { + softwareModuleTypeRepository.delete(type.getId()); + } + } + + @Override + public Page findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) { + return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set); + } + + @Override + public Page findSoftwareModuleByAssignedToAndType(final Pageable pageable, + final DistributionSet set, final SoftwareModuleType type) { + return softwareModuleRepository.findByAssignedToAndType(pageable, (JpaDistributionSet) set, + (JpaSoftwareModuleType) type); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) { + final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; + + if (softwareModuleMetadataRepository.exists(metadata.getId())) { + throwMetadataKeyAlreadyExists(metadata.getId().getKey()); + } + // merge base software module so optLockRevision gets updated and audit + // log written because + // modifying metadata is modifying the base software module itself for + // auditing purposes. + entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); + return softwareModuleMetadataRepository.save(metadata); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public List createSoftwareModuleMetadata(final Collection md) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection metadata = (Collection) md; + + for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) { + checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId()); + } + metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L)); + return new ArrayList<>(softwareModuleMetadataRepository.save(metadata)); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) { + final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; + + // check if exists otherwise throw entity not found exception + findSoftwareModuleMetadata(metadata.getId()); + // touch it to update the lock revision because we are modifying the + // software module + // indirectly + entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); + return softwareModuleMetadataRepository.save(metadata); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public void deleteSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { + softwareModuleMetadataRepository.delete(new SwMetadataCompositeKey(softwareModule, key)); + } + + @Override + public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long swId, + final Pageable pageable) { + return softwareModuleMetadataRepository.findBySoftwareModuleId(swId, pageable); + } + + @Override + public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId, + final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, + SoftwareModuleMetadataFields.class); + return convertSmMdPage( + softwareModuleMetadataRepository + .findAll( + (Specification) (root, query, cb) -> cb.and( + cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) + .get(JpaSoftwareModule_.id), softwareModuleId), + spec.toPredicate(root, query, cb)), + pageable), + pageable); + } + + @Override + public List findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) { + return new ArrayList<> ( softwareModuleMetadataRepository + .findAll( + (Specification) (root, query, cb) -> cb.and( + cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) + .get(JpaSoftwareModule_.id), softwareModuleId)))); + } + + @Override + public SoftwareModuleMetadata findSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { + return findSoftwareModuleMetadata(new SwMetadataCompositeKey(softwareModule, key)); + } + + private SoftwareModuleMetadata findSoftwareModuleMetadata(final SwMetadataCompositeKey id) { + final SoftwareModuleMetadata findOne = softwareModuleMetadataRepository.findOne(id); + if (findOne == null) { + throw new EntityNotFoundException("Metadata with key '" + id.getKey() + "' does not exist"); + } + return findOne; + } + + private void checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(final SwMetadataCompositeKey metadataId) { + if (softwareModuleMetadataRepository.exists(metadataId)) { + throw new EntityAlreadyExistsException( + "Metadata entry with key '" + metadataId.getKey() + "' already exists"); + } + } + + private static void throwMetadataKeyAlreadyExists(final String metadataKey) { + throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists"); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModule(final SoftwareModule bsm) { + deleteSoftwareModules(Sets.newHashSet(bsm.getId())); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public List createSoftwareModuleType(final Collection types) { + + return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java index b6475f647..b96b59f6a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java @@ -222,7 +222,6 @@ public abstract class AbstractTableDetailsLayout extends populateLog(); populateDescription(); populateDetailsWidget(); - populateMetadataDetails(); } protected void populateLog() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java index d3892a9dc..cf41bdd4f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java @@ -40,38 +40,36 @@ import com.vaadin.ui.themes.ValoTheme; @SpringComponent @VaadinSessionScope -public class DistributionSetMetadatadetailslayout extends Table{ - +public class DistributionSetMetadatadetailslayout extends Table { + private static final long serialVersionUID = 2913758299611837718L; - - - private DistributionSetManagement distributionSetManagement; - + + private DistributionSetManagement distributionSetManagement; + private DsMetadataPopupLayout dsMetadataPopupLayout; private static final String METADATA_KEY = "Key"; - - private static final String VIEW ="view"; + + private static final String VIEW = "view"; private SpPermissionChecker permissionChecker; - + private transient EntityFactory entityFactory; private I18N i18n; - - private Long selectedDistSetId; - - /** - * - * @param i18n - * @param permissionChecker - * @param distributionSetManagement - * @param dsMetadataPopupLayout - */ + + private Long selectedDistSetId; + + /** + * + * @param i18n + * @param permissionChecker + * @param distributionSetManagement + * @param dsMetadataPopupLayout + */ public void init(final I18N i18n, final SpPermissionChecker permissionChecker, - final DistributionSetManagement distributionSetManagement, - final DsMetadataPopupLayout dsMetadataPopupLayout, - final EntityFactory entityFactory) { + final DistributionSetManagement distributionSetManagement, + final DsMetadataPopupLayout dsMetadataPopupLayout, final EntityFactory entityFactory) { this.i18n = i18n; this.permissionChecker = permissionChecker; this.distributionSetManagement = distributionSetManagement; @@ -80,7 +78,6 @@ public class DistributionSetMetadatadetailslayout extends Table{ createDSMetadataTable(); addCustomGeneratedColumns(); } - /** * Populate software module metadata. @@ -90,35 +87,15 @@ public class DistributionSetMetadatadetailslayout extends Table{ public void populateDSMetadata(final DistributionSet distributionSet) { removeAllItems(); if (null == distributionSet) { - return; + return; } selectedDistSetId = distributionSet.getId(); - final List dsMetadataList = distributionSet.getMetadata(); + final List dsMetadataList = distributionSetManagement + .findDistributionSetMetadataByDistributionSetId(selectedDistSetId); if (null != dsMetadataList && !dsMetadataList.isEmpty()) { dsMetadataList.forEach(dsMetadata -> setDSMetadataProperties(dsMetadata)); } - - } - - /** - * Create metadata . - * - * @param metadataKeyName - */ - public void createMetadata(final String metadataKeyName){ - final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource(); - final Item item = metadataContainer.addItem(metadataKeyName); - item.getItemProperty(METADATA_KEY).setValue(metadataKeyName); - } - - /** - * Delete metadata. - * - * @param metadataKeyName - */ - public void deleteMetadata(final String metadataKeyName){ - final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource(); - metadataContainer.removeItem(metadataKeyName); + } private void createDSMetadataTable() { @@ -131,9 +108,9 @@ public class DistributionSetMetadatadetailslayout extends Table{ setContainerDataSource(getDistSetContainer()); setColumnHeaderMode(ColumnHeaderMode.EXPLICIT); addDSMetadataTableHeader(); - setSizeFull(); - //same as height of other tabs in details tabsheet - setHeight(116,Unit.PIXELS); + setSizeFull(); + // same as height of other tabs in details tabsheet + setHeight(116, Unit.PIXELS); } private IndexedContainer getDistSetContainer() { @@ -141,7 +118,7 @@ public class DistributionSetMetadatadetailslayout extends Table{ container.addContainerProperty(METADATA_KEY, String.class, ""); setColumnExpandRatio(METADATA_KEY, 0.7f); setColumnAlignment(METADATA_KEY, Align.LEFT); - + if (permissionChecker.hasUpdateDistributionPermission()) { container.addContainerProperty(VIEW, Label.class, ""); setColumnExpandRatio(VIEW, 0.2F); @@ -154,39 +131,36 @@ public class DistributionSetMetadatadetailslayout extends Table{ setColumnHeader(METADATA_KEY, i18n.get("header.key")); } - - private void setDSMetadataProperties(final DistributionSetMetadata dsMetadata){ + private void setDSMetadataProperties(final DistributionSetMetadata dsMetadata) { final Item item = getContainerDataSource().addItem(dsMetadata.getKey()); item.getItemProperty(METADATA_KEY).setValue(dsMetadata.getKey()); - + } - - private void addCustomGeneratedColumns() { - addGeneratedColumn(METADATA_KEY, - (source, itemId, columnId) -> customMetadataDetailButton((String) itemId)); + + private void addCustomGeneratedColumns() { + addGeneratedColumn(METADATA_KEY, (source, itemId, columnId) -> customMetadataDetailButton((String) itemId)); } private Button customMetadataDetailButton(final String metadataKey) { - final Button viewIcon = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, "View " - + metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class); + final Button viewIcon = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, + "View " + metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class); viewIcon.setData(metadataKey); viewIcon.addStyleName(ValoTheme.BUTTON_TINY + " " + ValoTheme.BUTTON_LINK + " " + "on-focus-no-border link" + " " + "text-style"); viewIcon.addClickListener(event -> showMetadataDetails(selectedDistSetId, metadataKey)); return viewIcon; } - + private static String getDetailLinkId(final String name) { - return new StringBuilder(SPUIComponentIdProvider.DS_METADATA_DETAIL_LINK).append('.').append(name) - .toString(); + return new StringBuilder(SPUIComponentIdProvider.DS_METADATA_DETAIL_LINK).append('.').append(name).toString(); } - - private void showMetadataDetails(final Long selectedDistSetId , final String metadataKey) { - DistributionSet distSet = distributionSetManagement.findDistributionSetById(selectedDistSetId); - + + private void showMetadataDetails(final Long selectedDistSetId, final String metadataKey) { + final DistributionSet distSet = distributionSetManagement.findDistributionSetById(selectedDistSetId); + /* display the window */ UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(distSet, - entityFactory.generateDistributionSetMetadata(distSet, metadataKey, "") )); + entityFactory.generateDistributionSetMetadata(distSet, metadataKey, ""))); } - + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java index 854347c11..355080636 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java @@ -80,7 +80,7 @@ public class SoftwareModuleMetadatadetailslayout extends Table { return; } selectedSWModuleId = swModule.getId(); - final List swMetadataList = swModule.getMetadata(); + final List swMetadataList = softwareManagement.findSoftwareModuleMetadataBySoftwareModuleId(selectedSWModuleId); if (null != swMetadataList && !swMetadataList.isEmpty()) { swMetadataList.forEach(swMetadata -> setSWMetadataProperties(swMetadata)); } @@ -160,7 +160,7 @@ public class SoftwareModuleMetadatadetailslayout extends Table { } private void showMetadataDetails(final Long selectedSWModuleId, final String metadataKey) { - SoftwareModule swmodule = softwareManagement.findSoftwareModuleById(selectedSWModuleId); + final SoftwareModule swmodule = softwareManagement.findSoftwareModuleById(selectedSWModuleId); /* display the window */ UI.getCurrent().addWindow( swMetadataPopupLayout.getWindow(swmodule, diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java index 03a86c44d..32deef7a8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java @@ -17,7 +17,6 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleIdName; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; @@ -29,7 +28,6 @@ import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsTable; import org.eclipse.hawkbit.ui.common.tagdetails.DistributionTagToken; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent; import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleAssignmentDiscardEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; @@ -68,7 +66,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet private static final String SOFT_MODULE = "softwareModule"; private static final String UNASSIGN_SOFT_MODULE = "unassignSoftModule"; - + @Autowired private ManageDistUIState manageDistUIState; @@ -83,37 +81,20 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet @Autowired private transient DistributionSetManagement distributionSetManagement; - + @Autowired private DsMetadataPopupLayout dsMetadataPopupLayout; - + @Autowired private EntityFactory entityFactory; private SoftwareModuleDetailsTable softwareModuleTable; - + private DistributionSetMetadatadetailslayout dsMetadataTable; private VerticalLayout tagsLayout; - + private final Map assignedSWModule = new HashMap<>(); - - - @EventBusListenerMethod(scope = EventScope.SESSION) - void onEvent(final MetadataEvent event) { - UI.getCurrent() - .access(() -> { - DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); - if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { - if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); - } else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey()); - } - } - }); - } - /** * softwareLayout Initialize the component. @@ -124,8 +105,8 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet softwareModuleTable.init(getI18n(), true, getPermissionChecker(), distributionSetManagement, getEventBus(), manageDistUIState); dsMetadataTable = new DistributionSetMetadatadetailslayout(); - dsMetadataTable.init(getI18n(), getPermissionChecker(),distributionSetManagement, - dsMetadataPopupLayout,entityFactory); + dsMetadataTable.init(getI18n(), getPermissionChecker(), distributionSetManagement, dsMetadataPopupLayout, + entityFactory); super.init(); } @@ -141,7 +122,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet populateTags(); populateMetadataDetails(); } - + private void populateModule() { softwareModuleTable.populateModule(getSelectedBaseEntity()); showUnsavedAssignment(); @@ -271,12 +252,12 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet updateDistributionSetDetailsLayout(null, null); } } - + @Override - protected void populateMetadataDetails(){ + protected void populateMetadataDetails() { dsMetadataTable.populateDSMetadata(getSelectedBaseEntity()); - } - + } + private void updateDistributionSetDetailsLayout(final String type, final Boolean isMigrationRequired) { final VerticalLayout detailsTabLayout = getDetailsLayout(); detailsTabLayout.removeAllComponents(); @@ -403,26 +384,26 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet protected Boolean isMetadataIconToBeDisplayed() { return true; } - + @Override protected String getShowMetadataButtonId() { - DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() ? manageDistUIState - .getLastSelectedDistribution().get() : null; + final DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() + ? manageDistUIState.getLastSelectedDistribution().get() : null; return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "." + lastselectedDistDS.getVersion(); } - - private boolean isDistributionSetSelected(DistributionSet ds) { - DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() ? manageDistUIState - .getLastSelectedDistribution().get() : null; + + private boolean isDistributionSetSelected(final DistributionSet ds) { + final DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() + ? manageDistUIState.getLastSelectedDistribution().get() : null; return ds != null && lastselectedDistDS != null && lastselectedDistDS.getName().equals(ds.getName()) && lastselectedDistDS.getVersion().endsWith(ds.getVersion()); } - @Override - protected void showMetadata(ClickEvent event) { - DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); - UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null)); + protected void showMetadata(final ClickEvent event) { + final DistributionSet ds = distributionSetManagement + .findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); + UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java index 2041944d4..0d433d910 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java @@ -16,8 +16,6 @@ import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.ui.common.AbstractMetadataPopupLayout; -import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent; -import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent.MetadataUIEvent; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.spring.annotation.SpringComponent; @@ -42,19 +40,19 @@ public class DsMetadataPopupLayout extends AbstractMetadataPopupLayout getMetadataList() { return getSelectedEntity().getMetadata(); } - + /** * Update metadata for DistributionSet. */ @Override - protected void deleteMetadata(DistributionSet entity, String key, String value) { - DistributionSetMetadata dsMetaData = entityFactory.generateDistributionSetMetadata(entity, key, value); + protected void deleteMetadata(final DistributionSet entity, final String key, final String value) { + final DistributionSetMetadata dsMetaData = entityFactory.generateDistributionSetMetadata(entity, key, value); distributionSetManagement.deleteDistributionSetMetadata(entity, key); - eventBus.publish(this, new MetadataEvent(MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA, dsMetaData)); } - + @Override protected boolean hasCreatePermission() { return permChecker.hasCreateDistributionPermission(); } - + @Override protected boolean hasUpdatePermission() { return permChecker.hasUpdateDistributionPermission(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/MetadataEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/MetadataEvent.java index f82bc5c01..2436de9e5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/MetadataEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/MetadataEvent.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.distributions.event; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; + /** * * Metadata Events. @@ -18,21 +19,21 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; public class MetadataEvent { public enum MetadataUIEvent { - CREATE_DISTRIBUTION_SET_METADATA, DELETE_DISTRIBUTION_SET_METADATA, DELETE_SOFTWARE_MODULE_METADATA, CREATE_SOFTWARE_MODULE_METADATA; + DELETE_SOFTWARE_MODULE_METADATA, CREATE_SOFTWARE_MODULE_METADATA; } - private MetadataUIEvent metadataUIEvent; + private final MetadataUIEvent metadataUIEvent; private DistributionSetMetadata distributionSetMetadata; private SoftwareModuleMetadata softwareModuleMetadata; - public MetadataEvent(MetadataUIEvent metadataUIEvent, final DistributionSetMetadata distributionSetMetadata) { + public MetadataEvent(final MetadataUIEvent metadataUIEvent, final DistributionSetMetadata distributionSetMetadata) { this.metadataUIEvent = metadataUIEvent; this.distributionSetMetadata = distributionSetMetadata; } - public MetadataEvent(MetadataUIEvent metadataUIEvent, final SoftwareModuleMetadata softwareModuleMetadata) { + public MetadataEvent(final MetadataUIEvent metadataUIEvent, final SoftwareModuleMetadata softwareModuleMetadata) { this.metadataUIEvent = metadataUIEvent; this.softwareModuleMetadata = softwareModuleMetadata; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index d83f7b4c8..a4b8c6a86 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -37,6 +37,7 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.eclipse.hawkbit.ui.utils.UINotification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -84,10 +85,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { @Autowired private transient EntityFactory entityFactory; - - @Autowired - private transient DistributionSetTable distributionSetTable; - private TextField distNameTextField; private TextField distVersionTextField; private TextArea descTextArea; @@ -239,9 +236,10 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success", new Object[] { newDist.getName(), newDist.getVersion() })); - + final Set s = new HashSet<>(); - s.add(new DistributionSetIdName(newDist.getId(),newDist.getName(),newDist.getVersion())); + s.add(new DistributionSetIdName(newDist.getId(), newDist.getName(), newDist.getVersion())); + final DistributionSetTable distributionSetTable = SpringContextHelper.getBean(DistributionSetTable.class); distributionSetTable.setValue(s); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java index e59820e9c..b61cc103c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java @@ -11,7 +11,6 @@ package org.eclipse.hawkbit.ui.management.dstable; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.ui.common.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout; import org.eclipse.hawkbit.ui.common.detailslayout.DistributionSetMetadatadetailslayout; @@ -19,7 +18,6 @@ import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsTable; import org.eclipse.hawkbit.ui.common.tagdetails.DistributionTagToken; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.distributions.dstable.DsMetadataPopupLayout; -import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -53,48 +51,32 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail @Autowired private DistributionTagToken distributionTagToken; - + @Autowired - private transient DistributionSetManagement distributionSetManagement; - + private transient DistributionSetManagement distributionSetManagement; + @Autowired private DsMetadataPopupLayout dsMetadataPopupLayout; - + @Autowired private EntityFactory entityFactory; private SoftwareModuleDetailsTable softwareModuleTable; private DistributionSetMetadatadetailslayout dsMetadataTable; - + @Override protected void init() { softwareModuleTable = new SoftwareModuleDetailsTable(); softwareModuleTable.init(getI18n(), false, getPermissionChecker(), null, null, null); - + dsMetadataTable = new DistributionSetMetadatadetailslayout(); - dsMetadataTable.init(getI18n(), getPermissionChecker(),distributionSetManagement, - dsMetadataPopupLayout,entityFactory); - + dsMetadataTable.init(getI18n(), getPermissionChecker(), distributionSetManagement, dsMetadataPopupLayout, + entityFactory); + super.init(); } - @EventBusListenerMethod(scope = EventScope.SESSION) - void onEvent(final MetadataEvent event) { - UI.getCurrent() - .access(() -> { - DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); - if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { - if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); - } else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey()); - } - } - }); - } - - @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final DistributionTableEvent distributionTableEvent) { onBaseEntityEvent(distributionTableEvent); @@ -156,12 +138,11 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail populateMetadataDetails(); } - - + @Override - protected void populateMetadataDetails(){ + protected void populateMetadataDetails() { dsMetadataTable.populateDSMetadata(getSelectedBaseEntity()); - } + } private void populateDetails(final DistributionSet ds) { if (ds != null) { @@ -206,30 +187,32 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail protected String getDetailsHeaderCaptionId() { return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_HEADER_LABEL_ID; } - + @Override protected Boolean isMetadataIconToBeDisplayed() { return true; } - + @Override protected String getShowMetadataButtonId() { - DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState - .getLastSelectedDistribution().get() : null; + final DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() + ? managementUIState.getLastSelectedDistribution().get() : null; return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "." + lastselectedDistDS.getVersion(); } - private boolean isDistributionSetSelected(DistributionSet ds) { - DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState - .getLastSelectedDistribution().get() : null; - return ds!=null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) + + private boolean isDistributionSetSelected(final DistributionSet ds) { + final DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() + ? managementUIState.getLastSelectedDistribution().get() : null; + return ds != null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) && lastselectedManageDS.getVersion().endsWith(ds.getVersion()); } @Override - protected void showMetadata(ClickEvent event) { - DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); - UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null)); + protected void showMetadata(final ClickEvent event) { + final DistributionSet ds = distributionSetManagement + .findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); + UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null)); } - + } From f2853e6d9fb16be0700c7d3c33ab006c7cf4231d Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 28 Jul 2016 14:24:49 +0200 Subject: [PATCH 04/42] Resolved the conflicts --- .../dstable/DistributionDetails.java | 37 +------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java index 68a65ab45..6dc1d7a69 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java @@ -76,25 +76,6 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail super.init(); } -<<<<<<< HEAD -======= - - @EventBusListenerMethod(scope = EventScope.SESSION) - void onEvent(final MetadataEvent event) { - UI.getCurrent() - .access(() -> { - final DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); - if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { - if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); - } else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey()); - } - } - }); - } - ->>>>>>> refs/heads/master @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final DistributionTableEvent distributionTableEvent) { @@ -214,41 +195,25 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail @Override protected String getShowMetadataButtonId() { -<<<<<<< HEAD final DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState.getLastSelectedDistribution().get() : null; -======= - final DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState - .getLastSelectedDistribution().get() : null; ->>>>>>> refs/heads/master + return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "." + lastselectedDistDS.getVersion(); } -<<<<<<< HEAD private boolean isDistributionSetSelected(final DistributionSet ds) { final DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState.getLastSelectedDistribution().get() : null; return ds != null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) -======= - private boolean isDistributionSetSelected(final DistributionSet ds) { - final DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState - .getLastSelectedDistribution().get() : null; - return ds!=null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) ->>>>>>> refs/heads/master && lastselectedManageDS.getVersion().endsWith(ds.getVersion()); } @Override protected void showMetadata(final ClickEvent event) { -<<<<<<< HEAD final DistributionSet ds = distributionSetManagement .findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null)); -======= - final DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); - UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null)); ->>>>>>> refs/heads/master } } From e32d6b1b3eb866f81f0ec430c4317a1670535af6 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 29 Jul 2016 12:33:10 +0200 Subject: [PATCH 05/42] Modified EOL from windows to unix. --- .../repository/DistributionSetManagement.java | 1216 +++++++-------- .../repository/SoftwareManagement.java | 1008 ++++++------- .../repository/jpa/JpaSoftwareManagement.java | 1344 ++++++++--------- .../repository/jpa/model/JpaAction.java | 398 ++--- .../jpa/model/JpaDistributionSet.java | 640 ++++---- .../repository/jpa/model/JpaRollout.java | 446 +++--- .../repository/jpa/model/JpaRolloutGroup.java | 522 +++---- .../repository/jpa/model/JpaTarget.java | 514 +++---- .../repository/jpa/model/JpaTargetInfo.java | 688 ++++----- 9 files changed, 3388 insertions(+), 3388 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index f7566b86b..b3b4fd86f 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -1,608 +1,608 @@ -/** - * 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.Collection; -import java.util.List; -import java.util.Set; - -import javax.validation.constraints.NotNull; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMissingMandatoryModuleException; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; -import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.Tag; -import org.eclipse.hawkbit.repository.model.Target; -import org.hibernate.validator.constraints.NotEmpty; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.security.access.prepost.PreAuthorize; - -/** - * Management service for {@link DistributionSet}s. - * - */ -public interface DistributionSetManagement { - - // TODO rename/document the whole with details thing (document what the - // details are and maybe find a better name, e.g. with dependencies?) - - /** - * Assigns {@link SoftwareModule} to existing {@link DistributionSet}. - * - * @param ds - * to assign and update - * @param softwareModules - * to get assigned - * @return the updated {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet assignSoftwareModules(@NotNull DistributionSet ds, Set softwareModules); - - /** - * Assign a {@link DistributionSetTag} assignment to given - * {@link DistributionSet}s. - * - * @param dsIds - * to assign for - * @param tag - * to assign - * @return list of assigned ds - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List assignTag(@NotEmpty Collection dsIds, @NotNull DistributionSetTag tag); - - /** - * Count all {@link DistributionSet}s in the repository that are not marked - * as deleted. - * - * @return number of {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetsAll(); - - /** - * Count all {@link DistributionSet}s in the repository that are not marked - * as deleted. - * - * @param type - * to look for - * - * @return number of {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetsByType(@NotNull DistributionSetType type); - - /** - * @return number of {@link DistributionSetType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetTypesAll(); - - /** - * Creates a new {@link DistributionSet}. - * - * @param dSet - * {@link DistributionSet} to be created - * @return the new persisted {@link DistributionSet} - * - * @throws EntityAlreadyExistsException - * if a given entity already exists - * @throws DistributionSetCreationFailedMissingMandatoryModuleException - * is {@link DistributionSet} does not contain mandatory - * {@link SoftwareModule}s. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - DistributionSet createDistributionSet(@NotNull DistributionSet dSet); - - /** - * creates a list of distribution set meta data entries. - * - * @param metadata - * the meta data entries to create or update - * @return the updated or created distribution set meta data entries - * @throws EntityAlreadyExistsException - * in case one of the meta data entry already exists for the - * specific key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List createDistributionSetMetadata(@NotEmpty Collection metadata); - - /** - * creates or updates a single distribution set meta data entry. - * - * @param metadata - * the meta data entry to create or update - * @return the updated or created distribution set meta data entry - * @throws EntityAlreadyExistsException - * in case the meta data entry already exists for the specific - * key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetMetadata createDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); - - /** - * Creates multiple {@link DistributionSet}s. - * - * @param distributionSets - * to be created - * @return the new {@link DistributionSet}s - * @throws EntityAlreadyExistsException - * if a given entity already exists - * @throws DistributionSetCreationFailedMissingMandatoryModuleException - * is {@link DistributionSet} does not contain mandatory - * {@link SoftwareModule}s. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createDistributionSets(@NotNull Collection distributionSets); - - /** - * Creates new {@link DistributionSetType}. - * - * @param type - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - DistributionSetType createDistributionSetType(@NotNull DistributionSetType type); - - /** - * Creates multiple {@link DistributionSetType}s. - * - * @param types - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createDistributionSetTypes(@NotNull Collection types); - - /** - *

- * {@link DistributionSet} can be deleted/erased from the repository if they - * have never been assigned to any {@link UpdateAction} or {@link Target}. - *

- * - *

- * If they have been assigned that need to be marked as deleted which as a - * result means that they cannot be assigned anymore to any targets. (define - * e.g. findByDeletedFalse()) - *

- * - * @param set - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSet(@NotNull DistributionSet set); - - /** - * Deleted {@link DistributionSet}s by their IDs. That is either a soft - * delete of the entities have been linked to an {@link UpdateAction} before - * or a hard delete if not. - * - * @param distributionSetIDs - * to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSet(@NotEmpty Long... distributionSetIDs); - - /** - * deletes a distribution set meta data entry. - * - * @param id - * the ID of the distribution set meta data to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - void deleteDistributionSetMetadata(@NotNull final DistributionSet distributionSet, @NotNull final String key); - - /** - * Deletes or mark as delete in case the type is in use. - * - * @param type - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSetType(@NotNull DistributionSetType type); - - /** - * retrieves the distribution set for a given action. - * - * @param action - * the action associated with the distribution set - * @return the distribution set which is associated with the action - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByAction(@NotNull Action action); - - /** - * Find {@link DistributionSet} based on given ID without details, e.g. - * {@link DistributionSet#getAgentHub()}. - * - * @param distid - * to look for. - * @return {@link DistributionSet} or null if it does not exist - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetById(@NotNull Long distid); - - /** - * Find {@link DistributionSet} based on given ID including (lazy loaded) - * details, e.g. {@link DistributionSet#getAgentHub()}. - * - * Note: for performance reasons it is recommended to use - * {@link #findDistributionSetById(Long)} if details are not necessary. - * - * @param distid - * to look for. - * @return {@link DistributionSet} or null if it does not exist - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByIdWithDetails(@NotNull Long distid); - - /** - * Find distribution set by name and version. - * - * @param distributionName - * name of {@link DistributionSet}; case insensitive - * @param version - * version of {@link DistributionSet} - * @return the page with the found {@link DistributionSet} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version); - - /** - * finds all meta data by the given distribution set id. - * - * @param distributionSetId - * the distribution set id to retrieve the meta data from - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given distribution - * set id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, - @NotNull Pageable pageable); - - /** - * finds all meta data by the given distribution set id. - * - * @param distributionSetId - * the distribution set id to retrieve the meta data from - * @return list of distributionSetMetadata for a given distribution set Id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - List findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId); - - /** - * finds all meta data by the given distribution set id. - * - * @param distributionSetId - * the distribution set id to retrieve the meta data from - * @param rsqlParam - * rsql query string - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given distribution - * set id - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, - @NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Retrieves {@link DistributionSet} List for overview purposes (no - * {@link SoftwareModule}s and {@link DistributionSetTag}s). - * - * Please use {@link #findDistributionSetListWithDetails(Iterable)} if - * details are required. - * - * @param dist - * List of {@link DistributionSet} IDs to be found - * @return the found {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - List findDistributionSetsAll(Collection dist); - - // TODO discuss: use enum instead of the true,false,null switch ? - /** - * finds all {@link DistributionSet}s. - * - * @param pageReq - * the pagination parameter - * @param deleted - * if TRUE, {@link DistributionSet}s marked as deleted are - * returned. If FALSE, on {@link DistributionSet}s with - * {@link DistributionSet#isDeleted()} == FALSE are returned. - * null if both are to be returned - * @param complete - * to true for returning only completed distribution - * sets or false for only incomplete ones nor - * null to return both. - * @param complete - * set to if false incomplete DS should also be - * shown. - * - * - * @return all found {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsByDeletedAndOrCompleted(@NotNull Pageable pageReq, Boolean deleted, - Boolean complete); - - /** - * finds all {@link DistributionSet}s. - * - * @param rsqlParam - * rsql query string - * @param pageReq - * the pagination parameter - * @param deleted - * if TRUE, {@link DistributionSet}s marked as deleted are - * returned. If FALSE, on {@link DistributionSet}s with - * {@link DistributionSet#isDeleted()} == FALSE are returned. - * null if both are to be returned - * @return all found {@link DistributionSet}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsAll(@NotNull String rsqlParam, @NotNull Pageable pageReq, - Boolean deleted); - - /** - * method retrieves all {@link DistributionSet}s from the repository in the - * following order: - *

- * 1) {@link DistributionSet}s which have the given {@link Target} as - * {@link TargetStatus#getInstalledDistributionSet()} - *

- * 2) {@link DistributionSet}s which have the given {@link Target} as - * {@link Target#getAssignedDistributionSet()} - *

- * 3) {@link DistributionSet}s which have no connection to the given - * {@link Target} ordered by ID of the DistributionSet. - * - * @param pageable - * the page request to page the result set * - * @param distributionSetFilterBuilder - * has details of filters to be applied - * @param assignedOrInstalled - * the controllerID of the Target to be ordered by - * @return - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsAllOrderedByLinkTarget(@NotNull Pageable pageable, - @NotNull DistributionSetFilterBuilder distributionSetFilterBuilder, @NotEmpty String assignedOrInstalled); - - /** - * retrieves {@link DistributionSet}s by filtering on the given parameters. - * - * @param pageable - * page parameter - * @param distributionSetFilter - * has details of filters to be applied. - * @return the page of found {@link DistributionSet} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsByFilters(@NotNull Pageable pageable, - @NotNull DistributionSetFilter distributionSetFilter); - - /** - * @param id - * as {@link DistributionSetType#getId()} - * @return {@link DistributionSetType} if found or null if not - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeById(@NotNull Long id); - - /** - * @param key - * as {@link DistributionSetType#getKey()} - * @return {@link DistributionSetType} if found or null if not - */ - - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeByKey(@NotNull String key); - - /** - * @param name - * as {@link DistributionSetType#getName()} - * @return {@link DistributionSetType} if found or null if not - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeByName(@NotEmpty String name); - - /** - * @param pageable - * parameter - * @return all {@link DistributionSetType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetTypesAll(@NotNull Pageable pageable); - - /** - * Generic predicate based query for {@link DistributionSetType}. - * - * @param rsqlParam - * rsql query string - * @param pageable - * parameter for paging - * - * @return the found {@link SoftwareModuleType}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * finds a single distribution set meta data by its id. - * - * @param id - * the id of the distribution set meta data containing the meta - * data key and the ID of the distribution set - * @return the found DistributionSetMetadata or {@code null} if not exits - * @throws EntityNotFoundException - * in case the meta data does not exists for the given key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetMetadata findOne(@NotNull DistributionSet distributionSet, @NotNull String key); - - /** - * Checks if a {@link DistributionSet} is currently in use by a target in - * the repository. - * - * @param distributionSet - * to check - * - * @return true if in use - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - boolean isDistributionSetInUse(@NotNull DistributionSet distributionSet); - - /** - * {@link Entity} based method call for - * {@link #toggleTagAssignment(Collection, String)}. - * - * @param sets - * to toggle for - * @param tag - * to toggle - * @return {@link DistributionSetTagAssignmentResult} with all meta data of - * the assignment outcome. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection sets, - @NotNull DistributionSetTag tag); - - /** - * Toggles {@link DistributionSetTag} assignment to given - * {@link DistributionSet}s by means that if some (or all) of the targets in - * the list have the {@link Tag} not yet assigned, they will be. If all of - * theme have the tag already assigned they will be removed instead. - * - * @param dsIds - * to toggle for - * @param tagName - * to toggle - * @return {@link DistributionSetTagAssignmentResult} with all meta data of - * the assignment outcome. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection dsIds, @NotNull String tagName); - - /** - * Unassign all {@link DistributionSet} from a given - * {@link DistributionSetTag} . - * - * @param tag - * to unassign all ds - * @return list of unassigned ds - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List unAssignAllDistributionSetsByTag(@NotNull DistributionSetTag tag); - - /** - * Unassigns a {@link SoftwareModule} form an existing - * {@link DistributionSet}. - * - * @param ds - * to get unassigned form - * @param softwareModule - * to get unassigned - * @return the updated {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet unassignSoftwareModule(@NotNull DistributionSet ds, @NotNull SoftwareModule softwareModule); - - /** - * Unassign a {@link DistributionSetTag} assignment to given - * {@link DistributionSet}. - * - * @param dsId - * to unassign for - * @param distributionSetTag - * to unassign - * @return the unassigned ds or if no ds is unassigned - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet unAssignTag(@NotNull Long dsId, @NotNull DistributionSetTag distributionSetTag); - - /** - * Updates existing {@link DistributionSet}. - * - * @param ds - * to update - * @return the saved {@link Entity}. - * @throws NullPointerException - * of {@link DistributionSet#getId()} is null - * @throw DataDependencyViolationException in case of illegal update - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet updateDistributionSet(@NotNull DistributionSet ds); - - /** - * updates a distribution set meta data value if corresponding entry exists. - * - * @param metadata - * the meta data entry to be updated - * @return the updated meta data entry - * @throws EntityNotFoundException - * in case the meta data entry does not exists and cannot be - * updated - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetMetadata updateDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); - - /** - * Updates existing {@link DistributionSetType}. However, keep in mind that - * is not possible to change the {@link DistributionSetTypeElement}s while - * the DS type is already in use. - * - * @param dsType - * to update - * @return updated {@link Entity} - * - * @throws EntityReadOnlyException - * if use tries to change the {@link DistributionSetTypeElement} - * s while the DS type is already in use. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetType updateDistributionSetType(@NotNull DistributionSetType dsType); - -} +/** + * 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.Collection; +import java.util.List; +import java.util.Set; + +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMissingMandatoryModuleException; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetFilter; +import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder; +import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.model.Tag; +import org.eclipse.hawkbit.repository.model.Target; +import org.hibernate.validator.constraints.NotEmpty; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.access.prepost.PreAuthorize; + +/** + * Management service for {@link DistributionSet}s. + * + */ +public interface DistributionSetManagement { + + // TODO rename/document the whole with details thing (document what the + // details are and maybe find a better name, e.g. with dependencies?) + + /** + * Assigns {@link SoftwareModule} to existing {@link DistributionSet}. + * + * @param ds + * to assign and update + * @param softwareModules + * to get assigned + * @return the updated {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet assignSoftwareModules(@NotNull DistributionSet ds, Set softwareModules); + + /** + * Assign a {@link DistributionSetTag} assignment to given + * {@link DistributionSet}s. + * + * @param dsIds + * to assign for + * @param tag + * to assign + * @return list of assigned ds + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List assignTag(@NotEmpty Collection dsIds, @NotNull DistributionSetTag tag); + + /** + * Count all {@link DistributionSet}s in the repository that are not marked + * as deleted. + * + * @return number of {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetsAll(); + + /** + * Count all {@link DistributionSet}s in the repository that are not marked + * as deleted. + * + * @param type + * to look for + * + * @return number of {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetsByType(@NotNull DistributionSetType type); + + /** + * @return number of {@link DistributionSetType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetTypesAll(); + + /** + * Creates a new {@link DistributionSet}. + * + * @param dSet + * {@link DistributionSet} to be created + * @return the new persisted {@link DistributionSet} + * + * @throws EntityAlreadyExistsException + * if a given entity already exists + * @throws DistributionSetCreationFailedMissingMandatoryModuleException + * is {@link DistributionSet} does not contain mandatory + * {@link SoftwareModule}s. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + DistributionSet createDistributionSet(@NotNull DistributionSet dSet); + + /** + * creates a list of distribution set meta data entries. + * + * @param metadata + * the meta data entries to create or update + * @return the updated or created distribution set meta data entries + * @throws EntityAlreadyExistsException + * in case one of the meta data entry already exists for the + * specific key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List createDistributionSetMetadata(@NotEmpty Collection metadata); + + /** + * creates or updates a single distribution set meta data entry. + * + * @param metadata + * the meta data entry to create or update + * @return the updated or created distribution set meta data entry + * @throws EntityAlreadyExistsException + * in case the meta data entry already exists for the specific + * key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetMetadata createDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); + + /** + * Creates multiple {@link DistributionSet}s. + * + * @param distributionSets + * to be created + * @return the new {@link DistributionSet}s + * @throws EntityAlreadyExistsException + * if a given entity already exists + * @throws DistributionSetCreationFailedMissingMandatoryModuleException + * is {@link DistributionSet} does not contain mandatory + * {@link SoftwareModule}s. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createDistributionSets(@NotNull Collection distributionSets); + + /** + * Creates new {@link DistributionSetType}. + * + * @param type + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + DistributionSetType createDistributionSetType(@NotNull DistributionSetType type); + + /** + * Creates multiple {@link DistributionSetType}s. + * + * @param types + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createDistributionSetTypes(@NotNull Collection types); + + /** + *

+ * {@link DistributionSet} can be deleted/erased from the repository if they + * have never been assigned to any {@link UpdateAction} or {@link Target}. + *

+ * + *

+ * If they have been assigned that need to be marked as deleted which as a + * result means that they cannot be assigned anymore to any targets. (define + * e.g. findByDeletedFalse()) + *

+ * + * @param set + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSet(@NotNull DistributionSet set); + + /** + * Deleted {@link DistributionSet}s by their IDs. That is either a soft + * delete of the entities have been linked to an {@link UpdateAction} before + * or a hard delete if not. + * + * @param distributionSetIDs + * to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSet(@NotEmpty Long... distributionSetIDs); + + /** + * deletes a distribution set meta data entry. + * + * @param id + * the ID of the distribution set meta data to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void deleteDistributionSetMetadata(@NotNull final DistributionSet distributionSet, @NotNull final String key); + + /** + * Deletes or mark as delete in case the type is in use. + * + * @param type + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSetType(@NotNull DistributionSetType type); + + /** + * retrieves the distribution set for a given action. + * + * @param action + * the action associated with the distribution set + * @return the distribution set which is associated with the action + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByAction(@NotNull Action action); + + /** + * Find {@link DistributionSet} based on given ID without details, e.g. + * {@link DistributionSet#getAgentHub()}. + * + * @param distid + * to look for. + * @return {@link DistributionSet} or null if it does not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetById(@NotNull Long distid); + + /** + * Find {@link DistributionSet} based on given ID including (lazy loaded) + * details, e.g. {@link DistributionSet#getAgentHub()}. + * + * Note: for performance reasons it is recommended to use + * {@link #findDistributionSetById(Long)} if details are not necessary. + * + * @param distid + * to look for. + * @return {@link DistributionSet} or null if it does not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByIdWithDetails(@NotNull Long distid); + + /** + * Find distribution set by name and version. + * + * @param distributionName + * name of {@link DistributionSet}; case insensitive + * @param version + * version of {@link DistributionSet} + * @return the page with the found {@link DistributionSet} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given distribution + * set id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, + @NotNull Pageable pageable); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @return list of distributionSetMetadata for a given distribution set Id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @param rsqlParam + * rsql query string + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given distribution + * set id + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, + @NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Retrieves {@link DistributionSet} List for overview purposes (no + * {@link SoftwareModule}s and {@link DistributionSetTag}s). + * + * Please use {@link #findDistributionSetListWithDetails(Iterable)} if + * details are required. + * + * @param dist + * List of {@link DistributionSet} IDs to be found + * @return the found {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findDistributionSetsAll(Collection dist); + + // TODO discuss: use enum instead of the true,false,null switch ? + /** + * finds all {@link DistributionSet}s. + * + * @param pageReq + * the pagination parameter + * @param deleted + * if TRUE, {@link DistributionSet}s marked as deleted are + * returned. If FALSE, on {@link DistributionSet}s with + * {@link DistributionSet#isDeleted()} == FALSE are returned. + * null if both are to be returned + * @param complete + * to true for returning only completed distribution + * sets or false for only incomplete ones nor + * null to return both. + * @param complete + * set to if false incomplete DS should also be + * shown. + * + * + * @return all found {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsByDeletedAndOrCompleted(@NotNull Pageable pageReq, Boolean deleted, + Boolean complete); + + /** + * finds all {@link DistributionSet}s. + * + * @param rsqlParam + * rsql query string + * @param pageReq + * the pagination parameter + * @param deleted + * if TRUE, {@link DistributionSet}s marked as deleted are + * returned. If FALSE, on {@link DistributionSet}s with + * {@link DistributionSet#isDeleted()} == FALSE are returned. + * null if both are to be returned + * @return all found {@link DistributionSet}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsAll(@NotNull String rsqlParam, @NotNull Pageable pageReq, + Boolean deleted); + + /** + * method retrieves all {@link DistributionSet}s from the repository in the + * following order: + *

+ * 1) {@link DistributionSet}s which have the given {@link Target} as + * {@link TargetStatus#getInstalledDistributionSet()} + *

+ * 2) {@link DistributionSet}s which have the given {@link Target} as + * {@link Target#getAssignedDistributionSet()} + *

+ * 3) {@link DistributionSet}s which have no connection to the given + * {@link Target} ordered by ID of the DistributionSet. + * + * @param pageable + * the page request to page the result set * + * @param distributionSetFilterBuilder + * has details of filters to be applied + * @param assignedOrInstalled + * the controllerID of the Target to be ordered by + * @return + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsAllOrderedByLinkTarget(@NotNull Pageable pageable, + @NotNull DistributionSetFilterBuilder distributionSetFilterBuilder, @NotEmpty String assignedOrInstalled); + + /** + * retrieves {@link DistributionSet}s by filtering on the given parameters. + * + * @param pageable + * page parameter + * @param distributionSetFilter + * has details of filters to be applied. + * @return the page of found {@link DistributionSet} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsByFilters(@NotNull Pageable pageable, + @NotNull DistributionSetFilter distributionSetFilter); + + /** + * @param id + * as {@link DistributionSetType#getId()} + * @return {@link DistributionSetType} if found or null if not + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeById(@NotNull Long id); + + /** + * @param key + * as {@link DistributionSetType#getKey()} + * @return {@link DistributionSetType} if found or null if not + */ + + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeByKey(@NotNull String key); + + /** + * @param name + * as {@link DistributionSetType#getName()} + * @return {@link DistributionSetType} if found or null if not + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeByName(@NotEmpty String name); + + /** + * @param pageable + * parameter + * @return all {@link DistributionSetType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetTypesAll(@NotNull Pageable pageable); + + /** + * Generic predicate based query for {@link DistributionSetType}. + * + * @param rsqlParam + * rsql query string + * @param pageable + * parameter for paging + * + * @return the found {@link SoftwareModuleType}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * finds a single distribution set meta data by its id. + * + * @param id + * the id of the distribution set meta data containing the meta + * data key and the ID of the distribution set + * @return the found DistributionSetMetadata or {@code null} if not exits + * @throws EntityNotFoundException + * in case the meta data does not exists for the given key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetMetadata findOne(@NotNull DistributionSet distributionSet, @NotNull String key); + + /** + * Checks if a {@link DistributionSet} is currently in use by a target in + * the repository. + * + * @param distributionSet + * to check + * + * @return true if in use + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + boolean isDistributionSetInUse(@NotNull DistributionSet distributionSet); + + /** + * {@link Entity} based method call for + * {@link #toggleTagAssignment(Collection, String)}. + * + * @param sets + * to toggle for + * @param tag + * to toggle + * @return {@link DistributionSetTagAssignmentResult} with all meta data of + * the assignment outcome. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection sets, + @NotNull DistributionSetTag tag); + + /** + * Toggles {@link DistributionSetTag} assignment to given + * {@link DistributionSet}s by means that if some (or all) of the targets in + * the list have the {@link Tag} not yet assigned, they will be. If all of + * theme have the tag already assigned they will be removed instead. + * + * @param dsIds + * to toggle for + * @param tagName + * to toggle + * @return {@link DistributionSetTagAssignmentResult} with all meta data of + * the assignment outcome. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection dsIds, @NotNull String tagName); + + /** + * Unassign all {@link DistributionSet} from a given + * {@link DistributionSetTag} . + * + * @param tag + * to unassign all ds + * @return list of unassigned ds + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List unAssignAllDistributionSetsByTag(@NotNull DistributionSetTag tag); + + /** + * Unassigns a {@link SoftwareModule} form an existing + * {@link DistributionSet}. + * + * @param ds + * to get unassigned form + * @param softwareModule + * to get unassigned + * @return the updated {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet unassignSoftwareModule(@NotNull DistributionSet ds, @NotNull SoftwareModule softwareModule); + + /** + * Unassign a {@link DistributionSetTag} assignment to given + * {@link DistributionSet}. + * + * @param dsId + * to unassign for + * @param distributionSetTag + * to unassign + * @return the unassigned ds or if no ds is unassigned + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet unAssignTag(@NotNull Long dsId, @NotNull DistributionSetTag distributionSetTag); + + /** + * Updates existing {@link DistributionSet}. + * + * @param ds + * to update + * @return the saved {@link Entity}. + * @throws NullPointerException + * of {@link DistributionSet#getId()} is null + * @throw DataDependencyViolationException in case of illegal update + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet updateDistributionSet(@NotNull DistributionSet ds); + + /** + * updates a distribution set meta data value if corresponding entry exists. + * + * @param metadata + * the meta data entry to be updated + * @return the updated meta data entry + * @throws EntityNotFoundException + * in case the meta data entry does not exists and cannot be + * updated + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetMetadata updateDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); + + /** + * Updates existing {@link DistributionSetType}. However, keep in mind that + * is not possible to change the {@link DistributionSetTypeElement}s while + * the DS type is already in use. + * + * @param dsType + * to update + * @return updated {@link Entity} + * + * @throws EntityReadOnlyException + * if use tries to change the {@link DistributionSetTypeElement} + * s while the DS type is already in use. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetType updateDistributionSetType(@NotNull DistributionSetType dsType); + +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java index e48aaa3ab..bb73dbb30 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java @@ -1,504 +1,504 @@ -/** - * 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.Collection; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.hibernate.validator.constraints.NotEmpty; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.security.access.prepost.PreAuthorize; - -/** - * Service for managing {@link SoftwareModule}s. - * - */ -public interface SoftwareManagement { - - /** - * Counts {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * and {@link SoftwareModule#getType()} that are not marked as deleted. - * - * @param searchText - * to search for in name and version - * @param type - * to filter the result - * @return number of found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModuleByFilters(String searchText, SoftwareModuleType type); - - /** - * Count all {@link SoftwareModule}s in the repository that are not marked - * as deleted. - * - * @return number of {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModulesAll(); - - /** - * Counts {@link SoftwareModule}s with given {@link SoftwareModuleType}. - * - * @param type - * to count - * @return number of found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModulesByType(@NotNull SoftwareModuleType type); - - /** - * @return number of {@link SoftwareModuleType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModuleTypesAll(); - - /** - * Create {@link SoftwareModule}s in the repository. - * - * @param swModules - * {@link SoftwareModule}s to create - * @return SoftwareModule - * @throws EntityAlreadyExistsException - * if a given entity already exists - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createSoftwareModule(@NotNull Collection swModules); - - /** - * - * @param swModule - * SoftwareModule to create - * @return SoftwareModule - * @throws EntityAlreadyExistsException - * if a given entity already exists - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - SoftwareModule createSoftwareModule(@NotNull SoftwareModule swModule); - - /** - * creates a list of software module meta data entries. - * - * @param metadata - * the meta data entries to create or update - * @return the updated or created software module meta data entries - * @throws EntityAlreadyExistsException - * in case one of the meta data entry already exists for the - * specific key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List createSoftwareModuleMetadata(@NotNull Collection metadata); - - /** - * creates or updates a single software module meta data entry. - * - * @param metadata - * the meta data entry to create or update - * @return the updated or created software module meta data entry - * @throws EntityAlreadyExistsException - * in case the meta data entry already exists for the specific - * key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleMetadata createSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); - - /** - * Creates multiple {@link SoftwareModuleType}s. - * - * @param types - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createSoftwareModuleType(@NotNull final Collection types); - - /** - * Creates new {@link SoftwareModuleType}. - * - * @param type - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - SoftwareModuleType createSoftwareModuleType(@NotNull SoftwareModuleType type); - - /** - * Deletes the given {@link SoftwareModule} {@link Entity}. - * - * @param bsm - * is the {@link SoftwareModule} to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModule(@NotNull SoftwareModule bsm); - - /** - * deletes a software module meta data entry. - * - * @param id - * the ID of the software module meta data to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - void deleteSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotNull String key); - - /** - * Deletes {@link SoftwareModule}s which is any if the given ids. - * - * @param ids - * of the Software Modules to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModules(@NotNull Collection ids); - - /** - * Deletes or marks as delete in case the type is in use. - * - * @param type - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModuleType(@NotNull SoftwareModuleType type); - - /** - * @param pageable - * the page request to page the result set - * @param set - * to search for - * @return all {@link SoftwareModule}s that are assigned to given - * {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleByAssignedTo(@NotNull Pageable pageable, @NotNull DistributionSet set); - - /** - * @param pageable - * the page request to page the result set - * @param set - * to search for - * @param type - * to filter - * @return all {@link SoftwareModule}s that are assigned to given - * {@link DistributionSet} filtered by {@link SoftwareModuleType}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleByAssignedToAndType(@NotNull Pageable pageable, @NotNull DistributionSet set, - @NotNull SoftwareModuleType type); - - /** - * Filter {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * and {@link SoftwareModule#getType()} that are not marked as deleted. - * - * @param pageable - * page parameter - * @param searchText - * to be filtered as "like" on {@link SoftwareModule#getName()} - * @param type - * to be filtered as "like" on {@link SoftwareModule#getType()} - * @return the page of found {@link SoftwareModule} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModuleByFilters(@NotNull Pageable pageable, String searchText, - SoftwareModuleType type); - - /** - * Finds {@link SoftwareModule} by given id. - * - * @param id - * to search for - * @return the found {@link SoftwareModule}s or null if not - * found. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_CONTROLLER) - SoftwareModule findSoftwareModuleById(@NotNull Long id); - - /** - * retrieves {@link SoftwareModule} by their name AND version AND type.. - * - * @param name - * of the {@link SoftwareModule} - * @param version - * of the {@link SoftwareModule} - * @param type - * of the {@link SoftwareModule} - * @return the found {@link SoftwareModule} or null - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModule findSoftwareModuleByNameAndVersion(@NotEmpty String name, @NotEmpty String version, - @NotNull SoftwareModuleType type); - - /** - * finds a single software module meta data by its id. - * - * @param id - * the id of the software module meta data containing the meta - * data key and the ID of the software module - * @return the found SoftwareModuleMetadata or {@code null} if not exits - * @throws EntityNotFoundException - * in case the meta data does not exists for the given key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleMetadata findSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotEmpty String key); - - /** - * finds all meta data by the given software module id. - * - * @param swId - * the software module id to retrieve the meta data from - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given software - * module id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long swId, - @NotNull Pageable pageable); - - /** - * finds all meta data by the given software module id. - * - * @param softwareModuleId - * the software module id to retrieve the meta data from - * @param spec - * the specification to filter the result - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given software - * module id - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long softwareModuleId, - @NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Filter {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * search text and {@link SoftwareModule#getType()} that are not marked as - * deleted and sort them by means of given distribution set related modules - * on top of the list. - * - * After that the modules are sorted by {@link SoftwareModule#getName()} and - * {@link SoftwareModule#getVersion()} in ascending order. - * - * @param pageable - * page parameter - * @param orderByDistributionId - * the ID of distribution set to be ordered on top - * @param searchText - * filtered as "like" on {@link SoftwareModule#getName()} - * @param type - * filtered as "equal" on {@link SoftwareModule#getType()} - * @return the page of found {@link SoftwareModule} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( - @NotNull Pageable pageable, @NotNull Long orderByDistributionId, String searchText, - SoftwareModuleType type); - - /** - * Retrieves all software modules. Deleted ones are filtered. - * - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModulesAll(@NotNull Pageable pageable); - - /** - * Retrieves all software modules with a given list of ids - * {@link SoftwareModule#getId()}. - * - * @param ids - * to search for - * @return {@link List} of found {@link SoftwareModule}s - */ - List findSoftwareModulesById(@NotEmpty Collection ids); - - /** - * Retrieves all {@link SoftwareModule}s with a given specification. - * - * @param spec - * the specification to filter the software modules - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModule}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModulesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType} - * . - * - * @param pageable - * page parameters - * @param type - * to be filtered on - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModulesByType(@NotNull Pageable pageable, @NotNull SoftwareModuleType type); - - /** - * - * @param id - * to search for - * @return {@link SoftwareModuleType} in the repository with given - * {@link SoftwareModuleType#getId()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeById(@NotNull Long id); - - /** - * - * @param key - * to search for - * @return {@link SoftwareModuleType} in the repository with given - * {@link SoftwareModuleType#getKey()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeByKey(@NotNull String key); - - /** - * - * @param name - * to search for - * @return all {@link SoftwareModuleType}s in the repository with given - * {@link SoftwareModuleType#getName()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeByName(@NotNull String name); - - /** - * @param pageable - * parameter - * @return all {@link SoftwareModuleType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleTypesAll(@NotNull Pageable pageable); - - /** - * Retrieves all {@link SoftwareModuleType}s with a given specification. - * - * @param spec - * the specification to filter the software modules types - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModuleType}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Retrieves software module including details ( - * {@link SoftwareModule#getArtifacts()}). - * - * @param id - * parameter - * @param isDeleted - * parameter - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModule findSoftwareModuleWithDetails(@NotNull Long id); - - /** - * Updates existing {@link SoftwareModule}. Update-able values are - * {@link SoftwareModule#getDescription()} - * {@link SoftwareModule#getVendor()}. - * - * @param sm - * to update - * - * @return the saved {@link Entity}. - * - * @throws NullPointerException - * of {@link SoftwareModule#getId()} is null - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModule updateSoftwareModule(@NotNull SoftwareModule sm); - - /** - * updates a distribution set meta data value if corresponding entry exists. - * - * @param metadata - * the meta data entry to be updated - * @return the updated meta data entry - * @throws EntityNotFoundException - * in case the meta data entry does not exists and cannot be - * updated - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleMetadata updateSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); - - /** - * Updates existing {@link SoftwareModuleType}. Update-able value is - * {@link SoftwareModuleType#getDescription()} and - * {@link SoftwareModuleType#getColour()}. - * - * @param sm - * to update - * @return updated {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm); - - /** - * finds all meta data by the given software module id. - * - * @param softwareModuleId - * the software module id to retrieve the meta data from - - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - * @return result of all meta data entries for a given software - * module id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - List findSoftwareModuleMetadataBySoftwareModuleId(Long softwareModuleId); - -} +/** + * 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.Collection; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; +import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.hibernate.validator.constraints.NotEmpty; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.security.access.prepost.PreAuthorize; + +/** + * Service for managing {@link SoftwareModule}s. + * + */ +public interface SoftwareManagement { + + /** + * Counts {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * and {@link SoftwareModule#getType()} that are not marked as deleted. + * + * @param searchText + * to search for in name and version + * @param type + * to filter the result + * @return number of found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModuleByFilters(String searchText, SoftwareModuleType type); + + /** + * Count all {@link SoftwareModule}s in the repository that are not marked + * as deleted. + * + * @return number of {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModulesAll(); + + /** + * Counts {@link SoftwareModule}s with given {@link SoftwareModuleType}. + * + * @param type + * to count + * @return number of found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModulesByType(@NotNull SoftwareModuleType type); + + /** + * @return number of {@link SoftwareModuleType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModuleTypesAll(); + + /** + * Create {@link SoftwareModule}s in the repository. + * + * @param swModules + * {@link SoftwareModule}s to create + * @return SoftwareModule + * @throws EntityAlreadyExistsException + * if a given entity already exists + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createSoftwareModule(@NotNull Collection swModules); + + /** + * + * @param swModule + * SoftwareModule to create + * @return SoftwareModule + * @throws EntityAlreadyExistsException + * if a given entity already exists + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + SoftwareModule createSoftwareModule(@NotNull SoftwareModule swModule); + + /** + * creates a list of software module meta data entries. + * + * @param metadata + * the meta data entries to create or update + * @return the updated or created software module meta data entries + * @throws EntityAlreadyExistsException + * in case one of the meta data entry already exists for the + * specific key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List createSoftwareModuleMetadata(@NotNull Collection metadata); + + /** + * creates or updates a single software module meta data entry. + * + * @param metadata + * the meta data entry to create or update + * @return the updated or created software module meta data entry + * @throws EntityAlreadyExistsException + * in case the meta data entry already exists for the specific + * key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleMetadata createSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); + + /** + * Creates multiple {@link SoftwareModuleType}s. + * + * @param types + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createSoftwareModuleType(@NotNull final Collection types); + + /** + * Creates new {@link SoftwareModuleType}. + * + * @param type + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + SoftwareModuleType createSoftwareModuleType(@NotNull SoftwareModuleType type); + + /** + * Deletes the given {@link SoftwareModule} {@link Entity}. + * + * @param bsm + * is the {@link SoftwareModule} to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModule(@NotNull SoftwareModule bsm); + + /** + * deletes a software module meta data entry. + * + * @param id + * the ID of the software module meta data to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void deleteSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotNull String key); + + /** + * Deletes {@link SoftwareModule}s which is any if the given ids. + * + * @param ids + * of the Software Modules to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModules(@NotNull Collection ids); + + /** + * Deletes or marks as delete in case the type is in use. + * + * @param type + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModuleType(@NotNull SoftwareModuleType type); + + /** + * @param pageable + * the page request to page the result set + * @param set + * to search for + * @return all {@link SoftwareModule}s that are assigned to given + * {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleByAssignedTo(@NotNull Pageable pageable, @NotNull DistributionSet set); + + /** + * @param pageable + * the page request to page the result set + * @param set + * to search for + * @param type + * to filter + * @return all {@link SoftwareModule}s that are assigned to given + * {@link DistributionSet} filtered by {@link SoftwareModuleType}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleByAssignedToAndType(@NotNull Pageable pageable, @NotNull DistributionSet set, + @NotNull SoftwareModuleType type); + + /** + * Filter {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * and {@link SoftwareModule#getType()} that are not marked as deleted. + * + * @param pageable + * page parameter + * @param searchText + * to be filtered as "like" on {@link SoftwareModule#getName()} + * @param type + * to be filtered as "like" on {@link SoftwareModule#getType()} + * @return the page of found {@link SoftwareModule} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModuleByFilters(@NotNull Pageable pageable, String searchText, + SoftwareModuleType type); + + /** + * Finds {@link SoftwareModule} by given id. + * + * @param id + * to search for + * @return the found {@link SoftwareModule}s or null if not + * found. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.IS_CONTROLLER) + SoftwareModule findSoftwareModuleById(@NotNull Long id); + + /** + * retrieves {@link SoftwareModule} by their name AND version AND type.. + * + * @param name + * of the {@link SoftwareModule} + * @param version + * of the {@link SoftwareModule} + * @param type + * of the {@link SoftwareModule} + * @return the found {@link SoftwareModule} or null + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModule findSoftwareModuleByNameAndVersion(@NotEmpty String name, @NotEmpty String version, + @NotNull SoftwareModuleType type); + + /** + * finds a single software module meta data by its id. + * + * @param id + * the id of the software module meta data containing the meta + * data key and the ID of the software module + * @return the found SoftwareModuleMetadata or {@code null} if not exits + * @throws EntityNotFoundException + * in case the meta data does not exists for the given key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleMetadata findSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotEmpty String key); + + /** + * finds all meta data by the given software module id. + * + * @param swId + * the software module id to retrieve the meta data from + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given software + * module id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long swId, + @NotNull Pageable pageable); + + /** + * finds all meta data by the given software module id. + * + * @param softwareModuleId + * the software module id to retrieve the meta data from + * @param spec + * the specification to filter the result + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given software + * module id + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long softwareModuleId, + @NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Filter {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * search text and {@link SoftwareModule#getType()} that are not marked as + * deleted and sort them by means of given distribution set related modules + * on top of the list. + * + * After that the modules are sorted by {@link SoftwareModule#getName()} and + * {@link SoftwareModule#getVersion()} in ascending order. + * + * @param pageable + * page parameter + * @param orderByDistributionId + * the ID of distribution set to be ordered on top + * @param searchText + * filtered as "like" on {@link SoftwareModule#getName()} + * @param type + * filtered as "equal" on {@link SoftwareModule#getType()} + * @return the page of found {@link SoftwareModule} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( + @NotNull Pageable pageable, @NotNull Long orderByDistributionId, String searchText, + SoftwareModuleType type); + + /** + * Retrieves all software modules. Deleted ones are filtered. + * + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModulesAll(@NotNull Pageable pageable); + + /** + * Retrieves all software modules with a given list of ids + * {@link SoftwareModule#getId()}. + * + * @param ids + * to search for + * @return {@link List} of found {@link SoftwareModule}s + */ + List findSoftwareModulesById(@NotEmpty Collection ids); + + /** + * Retrieves all {@link SoftwareModule}s with a given specification. + * + * @param spec + * the specification to filter the software modules + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModule}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModulesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType} + * . + * + * @param pageable + * page parameters + * @param type + * to be filtered on + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModulesByType(@NotNull Pageable pageable, @NotNull SoftwareModuleType type); + + /** + * + * @param id + * to search for + * @return {@link SoftwareModuleType} in the repository with given + * {@link SoftwareModuleType#getId()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeById(@NotNull Long id); + + /** + * + * @param key + * to search for + * @return {@link SoftwareModuleType} in the repository with given + * {@link SoftwareModuleType#getKey()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeByKey(@NotNull String key); + + /** + * + * @param name + * to search for + * @return all {@link SoftwareModuleType}s in the repository with given + * {@link SoftwareModuleType#getName()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeByName(@NotNull String name); + + /** + * @param pageable + * parameter + * @return all {@link SoftwareModuleType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleTypesAll(@NotNull Pageable pageable); + + /** + * Retrieves all {@link SoftwareModuleType}s with a given specification. + * + * @param spec + * the specification to filter the software modules types + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModuleType}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Retrieves software module including details ( + * {@link SoftwareModule#getArtifacts()}). + * + * @param id + * parameter + * @param isDeleted + * parameter + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModule findSoftwareModuleWithDetails(@NotNull Long id); + + /** + * Updates existing {@link SoftwareModule}. Update-able values are + * {@link SoftwareModule#getDescription()} + * {@link SoftwareModule#getVendor()}. + * + * @param sm + * to update + * + * @return the saved {@link Entity}. + * + * @throws NullPointerException + * of {@link SoftwareModule#getId()} is null + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModule updateSoftwareModule(@NotNull SoftwareModule sm); + + /** + * updates a distribution set meta data value if corresponding entry exists. + * + * @param metadata + * the meta data entry to be updated + * @return the updated meta data entry + * @throws EntityNotFoundException + * in case the meta data entry does not exists and cannot be + * updated + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleMetadata updateSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); + + /** + * Updates existing {@link SoftwareModuleType}. Update-able value is + * {@link SoftwareModuleType#getDescription()} and + * {@link SoftwareModuleType#getColour()}. + * + * @param sm + * to update + * @return updated {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm); + + /** + * finds all meta data by the given software module id. + * + * @param softwareModuleId + * the software module id to retrieve the meta data from + + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + * @return result of all meta data entries for a given software + * module id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findSoftwareModuleMetadataBySoftwareModuleId(Long softwareModuleId); + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index afe1a1e02..31b222051 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -1,672 +1,672 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.persistence.EntityManager; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.ListJoin; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.SoftwareManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleFields; -import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata_; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; -import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; -import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; -import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; -import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; -import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.LocalArtifact; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.AuditorAware; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.SliceImpl; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import com.google.common.base.Strings; -import com.google.common.collect.Sets; - -/** - * JPA implementation of {@link SoftwareManagement}. - * - */ -@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -@Validated -public class JpaSoftwareManagement implements SoftwareManagement { - - @Autowired - private EntityManager entityManager; - - @Autowired - private DistributionSetRepository distributionSetRepository; - - @Autowired - private DistributionSetTypeRepository distributionSetTypeRepository; - - @Autowired - private SoftwareModuleRepository softwareModuleRepository; - - @Autowired - private SoftwareModuleMetadataRepository softwareModuleMetadataRepository; - - @Autowired - private SoftwareModuleTypeRepository softwareModuleTypeRepository; - - @Autowired - private NoCountPagingRepository criteriaNoCountDao; - - @Autowired - private AuditorAware auditorProvider; - - @Autowired - private ArtifactManagement artifactManagement; - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModule updateSoftwareModule(final SoftwareModule sm) { - checkNotNull(sm.getId()); - - final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId()); - - boolean updated = false; - if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) { - module.setDescription(sm.getDescription()); - updated = true; - } - if (null == sm.getVendor() || !sm.getVendor().equals(module.getVendor())) { - module.setVendor(sm.getVendor()); - updated = true; - } - - return updated ? softwareModuleRepository.save(module) : module; - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) { - checkNotNull(sm.getId()); - - final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); - - boolean updated = false; - if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) { - type.setDescription(sm.getDescription()); - updated = true; - } - if (sm.getColour() != null && !sm.getColour().equals(type.getColour())) { - type.setColour(sm.getColour()); - updated = true; - } - return updated ? softwareModuleTypeRepository.save(type) : type; - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModule createSoftwareModule(final SoftwareModule swModule) { - if (null != swModule.getId()) { - throw new EntityAlreadyExistsException(); - } - return softwareModuleRepository.save((JpaSoftwareModule) swModule); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createSoftwareModule(final Collection swModules) { - swModules.forEach(swModule -> { - if (null != swModule.getId()) { - throw new EntityAlreadyExistsException(); - } - }); - - @SuppressWarnings({ "unchecked", "rawtypes" }) - final Collection jpaCast = (Collection) swModules; - - return new ArrayList<>(softwareModuleRepository.save(jpaCast)); - } - - @Override - public Slice findSoftwareModulesByType(final Pageable pageable, final SoftwareModuleType type) { - - final List> specList = new LinkedList<>(); - - Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - - spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - private static Slice convertSmPage(final Slice findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); - } - - private static Page convertSmPage(final Page findAll, final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - private static Page convertSmMdPage(final Page findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - @Override - public Long countSoftwareModulesByType(final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - - spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public SoftwareModule findSoftwareModuleById(final Long id) { - return artifactManagement.findSoftwareModuleById(id); - } - - @Override - public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version, - final SoftwareModuleType type) { - - return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type); - } - - private boolean isUnassigned(final JpaSoftwareModule bsmMerged) { - return distributionSetRepository.findByModules(bsmMerged).isEmpty(); - } - - private Slice findSwModuleByCriteriaAPI(final Pageable pageable, - final List> specList) { - return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, - JpaSoftwareModule.class); - } - - private Long countSwModuleByCriteriaAPI(final List> specList) { - return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList)); - } - - private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) { - for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) { - artifactManagement.deleteLocalArtifact(localArtifact); - } - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModules(final Collection ids) { - final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); - final Set assignedModuleIds = new HashSet<>(); - swModulesToDelete.forEach(swModule -> { - - // delete binary data of artifacts - deleteGridFsArtifacts(swModule); - - if (isUnassigned(swModule)) { - - softwareModuleRepository.delete(swModule); - - } else { - - assignedModuleIds.add(swModule.getId()); - } - }); - - if (!assignedModuleIds.isEmpty()) { - String currentUser = null; - if (auditorProvider != null) { - currentUser = auditorProvider.getCurrentAuditor(); - } - softwareModuleRepository.deleteSoftwareModule(System.currentTimeMillis(), currentUser, - assignedModuleIds.toArray(new Long[0])); - } - } - - @Override - public Slice findSoftwareModulesAll(final Pageable pageable) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - spec = (root, query, cb) -> { - if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(JpaSoftwareModule_.type); - } - return cb.conjunction(); - }; - - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - @Override - public Long countSoftwareModulesAll() { - - final List> specList = new ArrayList<>(); - - final Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public SoftwareModule findSoftwareModuleWithDetails(final Long id) { - return artifactManagement.findSoftwareModuleWithDetails(id); - } - - @Override - public Page findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) { - final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class); - - return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable); - } - - @Override - public Page findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) { - - final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class); - - return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable); - } - - private static Page convertSmTPage(final Page findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - @Override - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - public List findSoftwareModulesById(final Collection ids) { - return new ArrayList<>(softwareModuleRepository.findByIdIn(ids)); - } - - @Override - public Slice findSoftwareModuleByFilters(final Pageable pageable, final String searchText, - final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - if (!Strings.isNullOrEmpty(searchText)) { - spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); - specList.add(spec); - } - - if (null != type) { - spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - } - - spec = (root, query, cb) -> { - if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(JpaSoftwareModule_.type); - } - return cb.conjunction(); - }; - - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - @Override - public Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( - final Pageable pageable, final Long orderByDistributionId, final String searchText, - final SoftwareModuleType ty) { - final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; - - final List resultList = new ArrayList<>(); - final int pageSize = pageable.getPageSize(); - final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); - - // get the assigned software modules - final CriteriaQuery assignedQuery = cb.createQuery(JpaSoftwareModule.class); - final Root assignedRoot = assignedQuery.from(JpaSoftwareModule.class); - assignedQuery.distinct(true); - final ListJoin assignedDsJoin = assignedRoot - .join(JpaSoftwareModule_.assignedTo); - // build the specifications and then to predicates necessary by the - // given filters - final Predicate[] specPredicate = specificationsToPredicate(buildSpecificationList(searchText, type), - assignedRoot, assignedQuery, cb, - cb.equal(assignedDsJoin.get(JpaDistributionSet_.id), orderByDistributionId)); - // if we have some predicates then add it to the where clause of the - // multi select - assignedQuery.where(specPredicate); - assignedQuery.orderBy(cb.asc(assignedRoot.get(JpaSoftwareModule_.name)), - cb.asc(assignedRoot.get(JpaSoftwareModule_.version))); - // don't page the assigned query on database, we need all assigned - // software modules to filter - // them out in the unassigned query - final List assignedSoftwareModules = entityManager.createQuery(assignedQuery) - .getResultList(); - // map result - if (pageable.getOffset() < assignedSoftwareModules.size()) { - assignedSoftwareModules - .subList(pageable.getOffset(), Math.min(assignedSoftwareModules.size(), pageable.getPageSize())) - .forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, true))); - } - - if (assignedSoftwareModules.size() >= pageSize) { - return new SliceImpl<>(resultList); - } - - // get the unassigned software modules - final CriteriaQuery unassignedQuery = cb.createQuery(JpaSoftwareModule.class); - unassignedQuery.distinct(true); - final Root unassignedRoot = unassignedQuery.from(JpaSoftwareModule.class); - - Predicate[] unassignedSpec; - if (!assignedSoftwareModules.isEmpty()) { - unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, - unassignedQuery, cb, cb.not(unassignedRoot.get(JpaSoftwareModule_.id) - .in(assignedSoftwareModules.stream().map(sw -> sw.getId()).collect(Collectors.toList())))); - } else { - unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, - unassignedQuery, cb); - } - - unassignedQuery.where(unassignedSpec); - unassignedQuery.orderBy(cb.asc(unassignedRoot.get(JpaSoftwareModule_.name)), - cb.asc(unassignedRoot.get(JpaSoftwareModule_.version))); - final List unassignedSoftwareModules = entityManager.createQuery(unassignedQuery) - .setFirstResult(Math.max(0, pageable.getOffset() - assignedSoftwareModules.size())) - .setMaxResults(pageSize).getResultList(); - // map result - unassignedSoftwareModules.forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, false))); - - return new SliceImpl<>(resultList); - } - - private static List> buildSpecificationList(final String searchText, - final JpaSoftwareModuleType type) { - final List> specList = new ArrayList<>(); - if (!Strings.isNullOrEmpty(searchText)) { - specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText)); - } - if (type != null) { - specList.add(SoftwareModuleSpecification.equalType(type)); - } - specList.add(SoftwareModuleSpecification.isDeletedFalse()); - return specList; - } - - private Predicate[] specificationsToPredicate(final List> specifications, - final Root root, final CriteriaQuery query, final CriteriaBuilder cb, - final Predicate... additionalPredicates) { - final List predicates = new ArrayList<>(); - specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb))); - for (final Predicate predicate : additionalPredicates) { - predicates.add(predicate); - } - return predicates.toArray(new Predicate[predicates.size()]); - } - - @Override - public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - if (!Strings.isNullOrEmpty(searchText)) { - spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); - specList.add(spec); - } - - if (null != type) { - spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - } - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public Page findSoftwareModuleTypesAll(final Pageable pageable) { - return softwareModuleTypeRepository.findByDeleted(pageable, false); - } - - @Override - public Long countSoftwareModuleTypesAll() { - return softwareModuleTypeRepository.countByDeleted(false); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeByKey(final String key) { - return softwareModuleTypeRepository.findByKey(key); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeById(final Long id) { - return softwareModuleTypeRepository.findOne(id); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeByName(final String name) { - return softwareModuleTypeRepository.findByName(name); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleType type) { - if (type.getId() != null) { - throw new EntityAlreadyExistsException("Given type contains an Id!"); - } - - return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModuleType(final SoftwareModuleType ty) { - final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; - - if (softwareModuleRepository.countByType(type) > 0 - || distributionSetTypeRepository.countByElementsSmType(type) > 0) { - final JpaSoftwareModuleType toDelete = entityManager.merge(type); - toDelete.setDeleted(true); - softwareModuleTypeRepository.save(toDelete); - } else { - softwareModuleTypeRepository.delete(type.getId()); - } - } - - @Override - public Page findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) { - return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set); - } - - @Override - public Page findSoftwareModuleByAssignedToAndType(final Pageable pageable, - final DistributionSet set, final SoftwareModuleType type) { - return softwareModuleRepository.findByAssignedToAndType(pageable, (JpaDistributionSet) set, - (JpaSoftwareModuleType) type); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) { - final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; - - if (softwareModuleMetadataRepository.exists(metadata.getId())) { - throwMetadataKeyAlreadyExists(metadata.getId().getKey()); - } - // merge base software module so optLockRevision gets updated and audit - // log written because - // modifying metadata is modifying the base software module itself for - // auditing purposes. - entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); - return softwareModuleMetadataRepository.save(metadata); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public List createSoftwareModuleMetadata(final Collection md) { - @SuppressWarnings({ "unchecked", "rawtypes" }) - final Collection metadata = (Collection) md; - - for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) { - checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId()); - } - metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L)); - return new ArrayList<>(softwareModuleMetadataRepository.save(metadata)); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) { - final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; - - // check if exists otherwise throw entity not found exception - findSoftwareModuleMetadata(metadata.getId()); - // touch it to update the lock revision because we are modifying the - // software module - // indirectly - entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); - return softwareModuleMetadataRepository.save(metadata); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public void deleteSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { - softwareModuleMetadataRepository.delete(new SwMetadataCompositeKey(softwareModule, key)); - } - - @Override - public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long swId, - final Pageable pageable) { - return softwareModuleMetadataRepository.findBySoftwareModuleId(swId, pageable); - } - - @Override - public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId, - final String rsqlParam, final Pageable pageable) { - - final Specification spec = RSQLUtility.parse(rsqlParam, - SoftwareModuleMetadataFields.class); - return convertSmMdPage( - softwareModuleMetadataRepository - .findAll( - (Specification) (root, query, cb) -> cb.and( - cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) - .get(JpaSoftwareModule_.id), softwareModuleId), - spec.toPredicate(root, query, cb)), - pageable), - pageable); - } - - @Override - public List findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) { - return new ArrayList<> ( softwareModuleMetadataRepository - .findAll( - (Specification) (root, query, cb) -> cb.and( - cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) - .get(JpaSoftwareModule_.id), softwareModuleId)))); - } - - @Override - public SoftwareModuleMetadata findSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { - return findSoftwareModuleMetadata(new SwMetadataCompositeKey(softwareModule, key)); - } - - private SoftwareModuleMetadata findSoftwareModuleMetadata(final SwMetadataCompositeKey id) { - final SoftwareModuleMetadata findOne = softwareModuleMetadataRepository.findOne(id); - if (findOne == null) { - throw new EntityNotFoundException("Metadata with key '" + id.getKey() + "' does not exist"); - } - return findOne; - } - - private void checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(final SwMetadataCompositeKey metadataId) { - if (softwareModuleMetadataRepository.exists(metadataId)) { - throw new EntityAlreadyExistsException( - "Metadata entry with key '" + metadataId.getKey() + "' already exists"); - } - } - - private static void throwMetadataKeyAlreadyExists(final String metadataKey) { - throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists"); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModule(final SoftwareModule bsm) { - deleteSoftwareModules(Sets.newHashSet(bsm.getId())); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createSoftwareModuleType(final Collection types) { - - return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.ListJoin; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.SoftwareManagement; +import org.eclipse.hawkbit.repository.SoftwareModuleFields; +import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; +import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; +import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; +import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; +import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.LocalArtifact; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.AuditorAware; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import com.google.common.base.Strings; +import com.google.common.collect.Sets; + +/** + * JPA implementation of {@link SoftwareManagement}. + * + */ +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) +@Validated +public class JpaSoftwareManagement implements SoftwareManagement { + + @Autowired + private EntityManager entityManager; + + @Autowired + private DistributionSetRepository distributionSetRepository; + + @Autowired + private DistributionSetTypeRepository distributionSetTypeRepository; + + @Autowired + private SoftwareModuleRepository softwareModuleRepository; + + @Autowired + private SoftwareModuleMetadataRepository softwareModuleMetadataRepository; + + @Autowired + private SoftwareModuleTypeRepository softwareModuleTypeRepository; + + @Autowired + private NoCountPagingRepository criteriaNoCountDao; + + @Autowired + private AuditorAware auditorProvider; + + @Autowired + private ArtifactManagement artifactManagement; + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModule updateSoftwareModule(final SoftwareModule sm) { + checkNotNull(sm.getId()); + + final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId()); + + boolean updated = false; + if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) { + module.setDescription(sm.getDescription()); + updated = true; + } + if (null == sm.getVendor() || !sm.getVendor().equals(module.getVendor())) { + module.setVendor(sm.getVendor()); + updated = true; + } + + return updated ? softwareModuleRepository.save(module) : module; + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) { + checkNotNull(sm.getId()); + + final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); + + boolean updated = false; + if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) { + type.setDescription(sm.getDescription()); + updated = true; + } + if (sm.getColour() != null && !sm.getColour().equals(type.getColour())) { + type.setColour(sm.getColour()); + updated = true; + } + return updated ? softwareModuleTypeRepository.save(type) : type; + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModule createSoftwareModule(final SoftwareModule swModule) { + if (null != swModule.getId()) { + throw new EntityAlreadyExistsException(); + } + return softwareModuleRepository.save((JpaSoftwareModule) swModule); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public List createSoftwareModule(final Collection swModules) { + swModules.forEach(swModule -> { + if (null != swModule.getId()) { + throw new EntityAlreadyExistsException(); + } + }); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection jpaCast = (Collection) swModules; + + return new ArrayList<>(softwareModuleRepository.save(jpaCast)); + } + + @Override + public Slice findSoftwareModulesByType(final Pageable pageable, final SoftwareModuleType type) { + + final List> specList = new LinkedList<>(); + + Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + + spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + private static Slice convertSmPage(final Slice findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); + } + + private static Page convertSmPage(final Page findAll, final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + private static Page convertSmMdPage(final Page findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + @Override + public Long countSoftwareModulesByType(final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + + spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public SoftwareModule findSoftwareModuleById(final Long id) { + return artifactManagement.findSoftwareModuleById(id); + } + + @Override + public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version, + final SoftwareModuleType type) { + + return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type); + } + + private boolean isUnassigned(final JpaSoftwareModule bsmMerged) { + return distributionSetRepository.findByModules(bsmMerged).isEmpty(); + } + + private Slice findSwModuleByCriteriaAPI(final Pageable pageable, + final List> specList) { + return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, + JpaSoftwareModule.class); + } + + private Long countSwModuleByCriteriaAPI(final List> specList) { + return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList)); + } + + private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) { + for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) { + artifactManagement.deleteLocalArtifact(localArtifact); + } + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModules(final Collection ids) { + final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); + final Set assignedModuleIds = new HashSet<>(); + swModulesToDelete.forEach(swModule -> { + + // delete binary data of artifacts + deleteGridFsArtifacts(swModule); + + if (isUnassigned(swModule)) { + + softwareModuleRepository.delete(swModule); + + } else { + + assignedModuleIds.add(swModule.getId()); + } + }); + + if (!assignedModuleIds.isEmpty()) { + String currentUser = null; + if (auditorProvider != null) { + currentUser = auditorProvider.getCurrentAuditor(); + } + softwareModuleRepository.deleteSoftwareModule(System.currentTimeMillis(), currentUser, + assignedModuleIds.toArray(new Long[0])); + } + } + + @Override + public Slice findSoftwareModulesAll(final Pageable pageable) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + spec = (root, query, cb) -> { + if (!query.getResultType().isAssignableFrom(Long.class)) { + root.fetch(JpaSoftwareModule_.type); + } + return cb.conjunction(); + }; + + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + @Override + public Long countSoftwareModulesAll() { + + final List> specList = new ArrayList<>(); + + final Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public SoftwareModule findSoftwareModuleWithDetails(final Long id) { + return artifactManagement.findSoftwareModuleWithDetails(id); + } + + @Override + public Page findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) { + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class); + + return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable); + } + + @Override + public Page findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class); + + return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable); + } + + private static Page convertSmTPage(final Page findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + @Override + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + public List findSoftwareModulesById(final Collection ids) { + return new ArrayList<>(softwareModuleRepository.findByIdIn(ids)); + } + + @Override + public Slice findSoftwareModuleByFilters(final Pageable pageable, final String searchText, + final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + if (!Strings.isNullOrEmpty(searchText)) { + spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); + specList.add(spec); + } + + if (null != type) { + spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + } + + spec = (root, query, cb) -> { + if (!query.getResultType().isAssignableFrom(Long.class)) { + root.fetch(JpaSoftwareModule_.type); + } + return cb.conjunction(); + }; + + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + @Override + public Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( + final Pageable pageable, final Long orderByDistributionId, final String searchText, + final SoftwareModuleType ty) { + final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; + + final List resultList = new ArrayList<>(); + final int pageSize = pageable.getPageSize(); + final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + + // get the assigned software modules + final CriteriaQuery assignedQuery = cb.createQuery(JpaSoftwareModule.class); + final Root assignedRoot = assignedQuery.from(JpaSoftwareModule.class); + assignedQuery.distinct(true); + final ListJoin assignedDsJoin = assignedRoot + .join(JpaSoftwareModule_.assignedTo); + // build the specifications and then to predicates necessary by the + // given filters + final Predicate[] specPredicate = specificationsToPredicate(buildSpecificationList(searchText, type), + assignedRoot, assignedQuery, cb, + cb.equal(assignedDsJoin.get(JpaDistributionSet_.id), orderByDistributionId)); + // if we have some predicates then add it to the where clause of the + // multi select + assignedQuery.where(specPredicate); + assignedQuery.orderBy(cb.asc(assignedRoot.get(JpaSoftwareModule_.name)), + cb.asc(assignedRoot.get(JpaSoftwareModule_.version))); + // don't page the assigned query on database, we need all assigned + // software modules to filter + // them out in the unassigned query + final List assignedSoftwareModules = entityManager.createQuery(assignedQuery) + .getResultList(); + // map result + if (pageable.getOffset() < assignedSoftwareModules.size()) { + assignedSoftwareModules + .subList(pageable.getOffset(), Math.min(assignedSoftwareModules.size(), pageable.getPageSize())) + .forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, true))); + } + + if (assignedSoftwareModules.size() >= pageSize) { + return new SliceImpl<>(resultList); + } + + // get the unassigned software modules + final CriteriaQuery unassignedQuery = cb.createQuery(JpaSoftwareModule.class); + unassignedQuery.distinct(true); + final Root unassignedRoot = unassignedQuery.from(JpaSoftwareModule.class); + + Predicate[] unassignedSpec; + if (!assignedSoftwareModules.isEmpty()) { + unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, + unassignedQuery, cb, cb.not(unassignedRoot.get(JpaSoftwareModule_.id) + .in(assignedSoftwareModules.stream().map(sw -> sw.getId()).collect(Collectors.toList())))); + } else { + unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, + unassignedQuery, cb); + } + + unassignedQuery.where(unassignedSpec); + unassignedQuery.orderBy(cb.asc(unassignedRoot.get(JpaSoftwareModule_.name)), + cb.asc(unassignedRoot.get(JpaSoftwareModule_.version))); + final List unassignedSoftwareModules = entityManager.createQuery(unassignedQuery) + .setFirstResult(Math.max(0, pageable.getOffset() - assignedSoftwareModules.size())) + .setMaxResults(pageSize).getResultList(); + // map result + unassignedSoftwareModules.forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, false))); + + return new SliceImpl<>(resultList); + } + + private static List> buildSpecificationList(final String searchText, + final JpaSoftwareModuleType type) { + final List> specList = new ArrayList<>(); + if (!Strings.isNullOrEmpty(searchText)) { + specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText)); + } + if (type != null) { + specList.add(SoftwareModuleSpecification.equalType(type)); + } + specList.add(SoftwareModuleSpecification.isDeletedFalse()); + return specList; + } + + private Predicate[] specificationsToPredicate(final List> specifications, + final Root root, final CriteriaQuery query, final CriteriaBuilder cb, + final Predicate... additionalPredicates) { + final List predicates = new ArrayList<>(); + specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb))); + for (final Predicate predicate : additionalPredicates) { + predicates.add(predicate); + } + return predicates.toArray(new Predicate[predicates.size()]); + } + + @Override + public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + if (!Strings.isNullOrEmpty(searchText)) { + spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); + specList.add(spec); + } + + if (null != type) { + spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + } + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public Page findSoftwareModuleTypesAll(final Pageable pageable) { + return softwareModuleTypeRepository.findByDeleted(pageable, false); + } + + @Override + public Long countSoftwareModuleTypesAll() { + return softwareModuleTypeRepository.countByDeleted(false); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeByKey(final String key) { + return softwareModuleTypeRepository.findByKey(key); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeById(final Long id) { + return softwareModuleTypeRepository.findOne(id); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeByName(final String name) { + return softwareModuleTypeRepository.findByName(name); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleType type) { + if (type.getId() != null) { + throw new EntityAlreadyExistsException("Given type contains an Id!"); + } + + return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModuleType(final SoftwareModuleType ty) { + final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; + + if (softwareModuleRepository.countByType(type) > 0 + || distributionSetTypeRepository.countByElementsSmType(type) > 0) { + final JpaSoftwareModuleType toDelete = entityManager.merge(type); + toDelete.setDeleted(true); + softwareModuleTypeRepository.save(toDelete); + } else { + softwareModuleTypeRepository.delete(type.getId()); + } + } + + @Override + public Page findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) { + return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set); + } + + @Override + public Page findSoftwareModuleByAssignedToAndType(final Pageable pageable, + final DistributionSet set, final SoftwareModuleType type) { + return softwareModuleRepository.findByAssignedToAndType(pageable, (JpaDistributionSet) set, + (JpaSoftwareModuleType) type); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) { + final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; + + if (softwareModuleMetadataRepository.exists(metadata.getId())) { + throwMetadataKeyAlreadyExists(metadata.getId().getKey()); + } + // merge base software module so optLockRevision gets updated and audit + // log written because + // modifying metadata is modifying the base software module itself for + // auditing purposes. + entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); + return softwareModuleMetadataRepository.save(metadata); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public List createSoftwareModuleMetadata(final Collection md) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection metadata = (Collection) md; + + for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) { + checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId()); + } + metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L)); + return new ArrayList<>(softwareModuleMetadataRepository.save(metadata)); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) { + final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; + + // check if exists otherwise throw entity not found exception + findSoftwareModuleMetadata(metadata.getId()); + // touch it to update the lock revision because we are modifying the + // software module + // indirectly + entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); + return softwareModuleMetadataRepository.save(metadata); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public void deleteSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { + softwareModuleMetadataRepository.delete(new SwMetadataCompositeKey(softwareModule, key)); + } + + @Override + public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long swId, + final Pageable pageable) { + return softwareModuleMetadataRepository.findBySoftwareModuleId(swId, pageable); + } + + @Override + public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId, + final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, + SoftwareModuleMetadataFields.class); + return convertSmMdPage( + softwareModuleMetadataRepository + .findAll( + (Specification) (root, query, cb) -> cb.and( + cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) + .get(JpaSoftwareModule_.id), softwareModuleId), + spec.toPredicate(root, query, cb)), + pageable), + pageable); + } + + @Override + public List findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) { + return new ArrayList<> ( softwareModuleMetadataRepository + .findAll( + (Specification) (root, query, cb) -> cb.and( + cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) + .get(JpaSoftwareModule_.id), softwareModuleId)))); + } + + @Override + public SoftwareModuleMetadata findSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { + return findSoftwareModuleMetadata(new SwMetadataCompositeKey(softwareModule, key)); + } + + private SoftwareModuleMetadata findSoftwareModuleMetadata(final SwMetadataCompositeKey id) { + final SoftwareModuleMetadata findOne = softwareModuleMetadataRepository.findOne(id); + if (findOne == null) { + throw new EntityNotFoundException("Metadata with key '" + id.getKey() + "' does not exist"); + } + return findOne; + } + + private void checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(final SwMetadataCompositeKey metadataId) { + if (softwareModuleMetadataRepository.exists(metadataId)) { + throw new EntityAlreadyExistsException( + "Metadata entry with key '" + metadataId.getKey() + "' already exists"); + } + } + + private static void throwMetadataKeyAlreadyExists(final String metadataKey) { + throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists"); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModule(final SoftwareModule bsm) { + deleteSoftwareModules(Sets.newHashSet(bsm.getId())); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public List createSoftwareModuleType(final Collection types) { + + return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java index fc879aa87..5bda8f63b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -1,199 +1,199 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.NamedEntityGraphs; -import javax.persistence.NamedSubgraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.ActionStatus; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.eclipse.persistence.descriptors.DescriptorEvent; - -/** - * JPA implementation of {@link Action}. - */ -@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"), - @Index(name = "sp_idx_action_02", columnList = "tenant,target,active"), - @Index(name = "sp_idx_action_prim", columnList = "tenant,id") }) -@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }), - @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), - @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) }) -@Entity -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action,EventAwareEntity { - private static final long serialVersionUID = 1L; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds")) - private JpaDistributionSet distributionSet; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target")) - private JpaTarget target; - - @Column(name = "active") - private boolean active; - - @Column(name = "action_type", nullable = false) - @Enumerated(EnumType.STRING) - private ActionType actionType; - - @Column(name = "forced_time") - private long forcedTime; - - @Column(name = "status") - private Status status; - - @CascadeOnDelete - @OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { - CascadeType.REMOVE }) - private List actionStatus; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) - private JpaRolloutGroup rolloutGroup; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) - private JpaRollout rollout; - - @Override - public DistributionSet getDistributionSet() { - return distributionSet; - } - - @Override - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = (JpaDistributionSet) distributionSet; - } - - public void setActive(final boolean active) { - this.active = active; - } - - @Override - public Status getStatus() { - return status; - } - - @Override - public void setStatus(final Status status) { - this.status = status; - } - - @Override - public boolean isActive() { - return active; - } - - public void setActionType(final ActionType actionType) { - this.actionType = actionType; - } - - @Override - public ActionType getActionType() { - return actionType; - } - - @Override - public List getActionStatus() { - return actionStatus; - } - - @Override - public void setTarget(final Target target) { - this.target = (JpaTarget) target; - } - - @Override - public Target getTarget() { - return target; - } - - @Override - public long getForcedTime() { - return forcedTime; - } - - public void setForcedTime(final long forcedTime) { - this.forcedTime = forcedTime; - } - - @Override - public RolloutGroup getRolloutGroup() { - return rolloutGroup; - } - - public void setRolloutGroup(final RolloutGroup rolloutGroup) { - this.rolloutGroup = (JpaRolloutGroup) rolloutGroup; - } - - @Override - public Rollout getRollout() { - return rollout; - } - - public void setRollout(final Rollout rollout) { - this.rollout = (JpaRollout) rollout; - } - - @Override - public String toString() { - return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]"; - } - - @Override - public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); - - } - - @Override - public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus(). - post(new ActionPropertyChangeEvent(jpaAction, EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); - - } - - - @Override - public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.NamedEntityGraphs; +import javax.persistence.NamedSubgraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.ActionStatus; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA implementation of {@link Action}. + */ +@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"), + @Index(name = "sp_idx_action_02", columnList = "tenant,target,active"), + @Index(name = "sp_idx_action_prim", columnList = "tenant,id") }) +@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }), + @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), + @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) }) +@Entity +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action,EventAwareEntity { + private static final long serialVersionUID = 1L; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds")) + private JpaDistributionSet distributionSet; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target")) + private JpaTarget target; + + @Column(name = "active") + private boolean active; + + @Column(name = "action_type", nullable = false) + @Enumerated(EnumType.STRING) + private ActionType actionType; + + @Column(name = "forced_time") + private long forcedTime; + + @Column(name = "status") + private Status status; + + @CascadeOnDelete + @OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { + CascadeType.REMOVE }) + private List actionStatus; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) + private JpaRolloutGroup rolloutGroup; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) + private JpaRollout rollout; + + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + public void setActive(final boolean active) { + this.active = active; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public void setStatus(final Status status) { + this.status = status; + } + + @Override + public boolean isActive() { + return active; + } + + public void setActionType(final ActionType actionType) { + this.actionType = actionType; + } + + @Override + public ActionType getActionType() { + return actionType; + } + + @Override + public List getActionStatus() { + return actionStatus; + } + + @Override + public void setTarget(final Target target) { + this.target = (JpaTarget) target; + } + + @Override + public Target getTarget() { + return target; + } + + @Override + public long getForcedTime() { + return forcedTime; + } + + public void setForcedTime(final long forcedTime) { + this.forcedTime = forcedTime; + } + + @Override + public RolloutGroup getRolloutGroup() { + return rolloutGroup; + } + + public void setRolloutGroup(final RolloutGroup rolloutGroup) { + this.rolloutGroup = (JpaRolloutGroup) rolloutGroup; + } + + @Override + public Rollout getRollout() { + return rollout; + } + + public void setRollout(final Rollout rollout) { + this.rollout = (JpaRollout) rollout; + } + + @Override + public String toString() { + return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); + + } + + @Override + public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus(). + post(new ActionPropertyChangeEvent(jpaAction, EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); + + } + + + @Override + public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index af8984286..77a5f88fd 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -1,320 +1,320 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; -import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; -import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.eclipse.persistence.descriptors.DescriptorEvent; - -/** - * Jpa implementation of {@link DistributionSet}. - * - */ -@Entity -@Table(name = "sp_distribution_set", uniqueConstraints = { - @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { - @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"), - @Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"), - @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) -@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), - @NamedAttributeNode("tags"), @NamedAttributeNode("type") }) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet,EventAwareEntity { - private static final long serialVersionUID = 1L; - - private static final String COMPLETE = "complete"; - - @Column(name = "required_migration_step") - private boolean requiredMigrationStep; - - @ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY) - @JoinTable(name = "sp_ds_module", joinColumns = { - @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = { - @JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) }) - private final Set modules = new HashSet<>(); - - @ManyToMany(targetEntity = JpaDistributionSetTag.class) - @JoinTable(name = "sp_ds_dstag", joinColumns = { - @JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = { - @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) - private Set tags = new HashSet<>(); - - @Column(name = "deleted") - private boolean deleted; - - @OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY) - private List assignedToTargets; - - @OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY) - private List installedAtTargets; - - @OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY) - private List actions; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = { - CascadeType.REMOVE }) - @JoinColumn(name = "ds_id", insertable = false, updatable = false) - private final List metadata = new ArrayList<>(); - - @ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class) - @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) - private DistributionSetType type; - - @Column(name = "complete") - private boolean complete; - - /** - * Default constructor. - */ - public JpaDistributionSet() { - super(); - } - - /** - * Parameterized constructor. - * - * @param name - * of the {@link DistributionSet} - * @param version - * of the {@link DistributionSet} - * @param description - * of the {@link DistributionSet} - * @param type - * of the {@link DistributionSet} - * @param moduleList - * {@link SoftwareModule}s of the {@link DistributionSet} - */ - public JpaDistributionSet(final String name, final String version, final String description, - final DistributionSetType type, final Collection moduleList) { - super(name, version, description); - - this.type = type; - if (moduleList != null) { - moduleList.forEach(this::addModule); - } - if (this.type != null) { - complete = this.type.checkComplete(this); - } - } - - @Override - public Set getTags() { - return tags; - } - - @Override - public boolean isDeleted() { - return deleted; - } - - @Override - public List getMetadata() { - return Collections.unmodifiableList(metadata); - } - - public List getActions() { - return actions; - } - - @Override - public boolean isRequiredMigrationStep() { - return requiredMigrationStep; - } - - @Override - public DistributionSet setDeleted(final boolean deleted) { - this.deleted = deleted; - return this; - } - - @Override - public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) { - requiredMigrationStep = isRequiredMigrationStep; - return this; - } - - public DistributionSet setTags(final Set tags) { - this.tags = tags; - return this; - } - - @Override - public List getAssignedTargets() { - return assignedToTargets; - } - - @Override - public List getInstalledTargets() { - return installedAtTargets; - } - - @Override - public String toString() { - return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision() - + ", getId()=" + getId() + "]"; - } - - @Override - public Set getModules() { - return Collections.unmodifiableSet(modules); - } - - @Override - public boolean addModule(final SoftwareModule softwareModule) { - - // we cannot allow that modules are added without a type defined - if (type == null) { - throw new DistributionSetTypeUndefinedException(); - } - - // check if it is allowed to such a module to this DS type - if (!type.containsModuleType(softwareModule.getType())) { - throw new UnsupportedSoftwareModuleForThisDistributionSetException(); - } - - final Optional found = modules.stream() - .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); - - if (found.isPresent()) { - return false; - } - - final long allready = modules.stream() - .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count(); - - if (allready >= softwareModule.getType().getMaxAssignments()) { - final Optional sameKey = modules.stream() - .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst(); - modules.remove(sameKey.get()); - } - - if (modules.add(softwareModule)) { - complete = type.checkComplete(this); - return true; - } - - return false; - } - - @Override - public boolean removeModule(final SoftwareModule softwareModule) { - final Optional found = modules.stream() - .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); - - if (found.isPresent()) { - modules.remove(found.get()); - complete = type.checkComplete(this); - return true; - } - - return false; - - } - - @Override - public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { - final Optional result = modules.stream().filter(module -> module.getType().equals(type)) - .findFirst(); - - if (result.isPresent()) { - return result.get(); - } - - return null; - } - - @Override - public DistributionSetType getType() { - return type; - } - - @Override - public void setType(final DistributionSetType type) { - this.type = type; - } - - @Override - public boolean isComplete() { - return complete; - } - - @Override - public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); - - } - - @Override - public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - final Map.Values> changeSet = EntityPropertyChangeHelper.getChangeSet( - JpaDistributionSet.class, descriptorEvent); - if (changeSet.containsKey(COMPLETE) - && changeSet.get(COMPLETE).getOldValue().equals(false) - && changeSet.get(COMPLETE).getNewValue().equals(true)) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post( - new DistributionCreatedEvent(jpaDistributionSet))); - } - - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); - - } - - @Override - public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; +import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; +import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * Jpa implementation of {@link DistributionSet}. + * + */ +@Entity +@Table(name = "sp_distribution_set", uniqueConstraints = { + @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { + @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"), + @Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"), + @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) +@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), + @NamedAttributeNode("tags"), @NamedAttributeNode("type") }) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet,EventAwareEntity { + private static final long serialVersionUID = 1L; + + private static final String COMPLETE = "complete"; + + @Column(name = "required_migration_step") + private boolean requiredMigrationStep; + + @ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY) + @JoinTable(name = "sp_ds_module", joinColumns = { + @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = { + @JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) }) + private final Set modules = new HashSet<>(); + + @ManyToMany(targetEntity = JpaDistributionSetTag.class) + @JoinTable(name = "sp_ds_dstag", joinColumns = { + @JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = { + @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) + private Set tags = new HashSet<>(); + + @Column(name = "deleted") + private boolean deleted; + + @OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY) + private List assignedToTargets; + + @OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY) + private List installedAtTargets; + + @OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY) + private List actions; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = { + CascadeType.REMOVE }) + @JoinColumn(name = "ds_id", insertable = false, updatable = false) + private final List metadata = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class) + @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) + private DistributionSetType type; + + @Column(name = "complete") + private boolean complete; + + /** + * Default constructor. + */ + public JpaDistributionSet() { + super(); + } + + /** + * Parameterized constructor. + * + * @param name + * of the {@link DistributionSet} + * @param version + * of the {@link DistributionSet} + * @param description + * of the {@link DistributionSet} + * @param type + * of the {@link DistributionSet} + * @param moduleList + * {@link SoftwareModule}s of the {@link DistributionSet} + */ + public JpaDistributionSet(final String name, final String version, final String description, + final DistributionSetType type, final Collection moduleList) { + super(name, version, description); + + this.type = type; + if (moduleList != null) { + moduleList.forEach(this::addModule); + } + if (this.type != null) { + complete = this.type.checkComplete(this); + } + } + + @Override + public Set getTags() { + return tags; + } + + @Override + public boolean isDeleted() { + return deleted; + } + + @Override + public List getMetadata() { + return Collections.unmodifiableList(metadata); + } + + public List getActions() { + return actions; + } + + @Override + public boolean isRequiredMigrationStep() { + return requiredMigrationStep; + } + + @Override + public DistributionSet setDeleted(final boolean deleted) { + this.deleted = deleted; + return this; + } + + @Override + public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) { + requiredMigrationStep = isRequiredMigrationStep; + return this; + } + + public DistributionSet setTags(final Set tags) { + this.tags = tags; + return this; + } + + @Override + public List getAssignedTargets() { + return assignedToTargets; + } + + @Override + public List getInstalledTargets() { + return installedAtTargets; + } + + @Override + public String toString() { + return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision() + + ", getId()=" + getId() + "]"; + } + + @Override + public Set getModules() { + return Collections.unmodifiableSet(modules); + } + + @Override + public boolean addModule(final SoftwareModule softwareModule) { + + // we cannot allow that modules are added without a type defined + if (type == null) { + throw new DistributionSetTypeUndefinedException(); + } + + // check if it is allowed to such a module to this DS type + if (!type.containsModuleType(softwareModule.getType())) { + throw new UnsupportedSoftwareModuleForThisDistributionSetException(); + } + + final Optional found = modules.stream() + .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); + + if (found.isPresent()) { + return false; + } + + final long allready = modules.stream() + .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count(); + + if (allready >= softwareModule.getType().getMaxAssignments()) { + final Optional sameKey = modules.stream() + .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst(); + modules.remove(sameKey.get()); + } + + if (modules.add(softwareModule)) { + complete = type.checkComplete(this); + return true; + } + + return false; + } + + @Override + public boolean removeModule(final SoftwareModule softwareModule) { + final Optional found = modules.stream() + .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); + + if (found.isPresent()) { + modules.remove(found.get()); + complete = type.checkComplete(this); + return true; + } + + return false; + + } + + @Override + public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { + final Optional result = modules.stream().filter(module -> module.getType().equals(type)) + .findFirst(); + + if (result.isPresent()) { + return result.get(); + } + + return null; + } + + @Override + public DistributionSetType getType() { + return type; + } + + @Override + public void setType(final DistributionSetType type) { + this.type = type; + } + + @Override + public boolean isComplete() { + return complete; + } + + @Override + public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); + + } + + @Override + public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + final Map.Values> changeSet = EntityPropertyChangeHelper.getChangeSet( + JpaDistributionSet.class, descriptorEvent); + if (changeSet.containsKey(COMPLETE) + && changeSet.get(COMPLETE).getOldValue().equals(false) + && changeSet.get(COMPLETE).getNewValue().equals(true)) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post( + new DistributionCreatedEvent(jpaDistributionSet))); + } + + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); + + } + + @Override + public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java index 73d19086d..1cf1ccb77 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java @@ -1,223 +1,223 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.util.List; - -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.cache.CacheField; -import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Action.ActionType; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; -import org.eclipse.persistence.descriptors.DescriptorEvent; - -/** - * JPA implementation of a {@link Rollout}. - * - */ -@Entity -@Table(name = "sp_rollout", indexes = { - @Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "tenant" }, name = "uk_rollout")) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventAwareEntity { - - private static final long serialVersionUID = 1L; - - @OneToMany(targetEntity = JpaRolloutGroup.class) - @JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup")) - private List rolloutGroups; - - @Column(name = "target_filter", length = 1024, nullable = false) - private String targetFilterQuery; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) - private JpaDistributionSet distributionSet; - - @Column(name = "status") - private RolloutStatus status = RolloutStatus.CREATING; - - @Column(name = "last_check") - private long lastCheck; - - @Column(name = "action_type", nullable = false) - @Enumerated(EnumType.STRING) - private ActionType actionType = ActionType.FORCED; - - @Column(name = "forced_time") - private long forcedTime; - - @Column(name = "total_targets") - private long totalTargets; - - @Transient - @CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL) - private int rolloutGroupsTotal; - - @Transient - @CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED) - private int rolloutGroupsCreated; - - @Transient - private transient TotalTargetCountStatus totalTargetCountStatus; - - @Override - public DistributionSet getDistributionSet() { - return distributionSet; - } - - @Override - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = (JpaDistributionSet) distributionSet; - } - - @Override - public List getRolloutGroups() { - return rolloutGroups; - } - - public void setRolloutGroups(final List rolloutGroups) { - this.rolloutGroups = rolloutGroups; - } - - @Override - public String getTargetFilterQuery() { - return targetFilterQuery; - } - - @Override - public void setTargetFilterQuery(final String targetFilterQuery) { - this.targetFilterQuery = targetFilterQuery; - } - - @Override - public RolloutStatus getStatus() { - return status; - } - - public void setStatus(final RolloutStatus status) { - this.status = status; - } - - public long getLastCheck() { - return lastCheck; - } - - public void setLastCheck(final long lastCheck) { - this.lastCheck = lastCheck; - } - - @Override - public ActionType getActionType() { - return actionType; - } - - @Override - public void setActionType(final ActionType actionType) { - this.actionType = actionType; - } - - @Override - public long getForcedTime() { - return forcedTime; - } - - @Override - public void setForcedTime(final long forcedTime) { - this.forcedTime = forcedTime; - } - - @Override - public long getTotalTargets() { - return totalTargets; - } - - public void setTotalTargets(final long totalTargets) { - this.totalTargets = totalTargets; - } - - public int getRolloutGroupsTotal() { - return rolloutGroupsTotal; - } - - public void setRolloutGroupsTotal(final int rolloutGroupsTotal) { - this.rolloutGroupsTotal = rolloutGroupsTotal; - } - - @Override - public int getRolloutGroupsCreated() { - return rolloutGroupsCreated; - } - - public void setRolloutGroupsCreated(final int rolloutGroupsCreated) { - this.rolloutGroupsCreated = rolloutGroupsCreated; - } - - @Override - public TotalTargetCountStatus getTotalTargetCountStatus() { - if (totalTargetCountStatus == null) { - totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); - } - return totalTargetCountStatus; - } - - public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { - this.totalTargetCountStatus = totalTargetCountStatus; - } - - @Override - public String toString() { - return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery - + ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck - + ", getName()=" + getName() + ", getId()=" + getId() + "]"; - } - - @Override - public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - - } - - @Override - public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). - post(new RolloutPropertyChangeEvent(jpaRollout, EntityPropertyChangeHelper.getChangeSet( - Rollout.class, descriptorEvent)))); - - } - - @Override - public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.cache.CacheField; +import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action.ActionType; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA implementation of a {@link Rollout}. + * + */ +@Entity +@Table(name = "sp_rollout", indexes = { + @Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "tenant" }, name = "uk_rollout")) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventAwareEntity { + + private static final long serialVersionUID = 1L; + + @OneToMany(targetEntity = JpaRolloutGroup.class) + @JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup")) + private List rolloutGroups; + + @Column(name = "target_filter", length = 1024, nullable = false) + private String targetFilterQuery; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) + private JpaDistributionSet distributionSet; + + @Column(name = "status") + private RolloutStatus status = RolloutStatus.CREATING; + + @Column(name = "last_check") + private long lastCheck; + + @Column(name = "action_type", nullable = false) + @Enumerated(EnumType.STRING) + private ActionType actionType = ActionType.FORCED; + + @Column(name = "forced_time") + private long forcedTime; + + @Column(name = "total_targets") + private long totalTargets; + + @Transient + @CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL) + private int rolloutGroupsTotal; + + @Transient + @CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED) + private int rolloutGroupsCreated; + + @Transient + private transient TotalTargetCountStatus totalTargetCountStatus; + + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + @Override + public List getRolloutGroups() { + return rolloutGroups; + } + + public void setRolloutGroups(final List rolloutGroups) { + this.rolloutGroups = rolloutGroups; + } + + @Override + public String getTargetFilterQuery() { + return targetFilterQuery; + } + + @Override + public void setTargetFilterQuery(final String targetFilterQuery) { + this.targetFilterQuery = targetFilterQuery; + } + + @Override + public RolloutStatus getStatus() { + return status; + } + + public void setStatus(final RolloutStatus status) { + this.status = status; + } + + public long getLastCheck() { + return lastCheck; + } + + public void setLastCheck(final long lastCheck) { + this.lastCheck = lastCheck; + } + + @Override + public ActionType getActionType() { + return actionType; + } + + @Override + public void setActionType(final ActionType actionType) { + this.actionType = actionType; + } + + @Override + public long getForcedTime() { + return forcedTime; + } + + @Override + public void setForcedTime(final long forcedTime) { + this.forcedTime = forcedTime; + } + + @Override + public long getTotalTargets() { + return totalTargets; + } + + public void setTotalTargets(final long totalTargets) { + this.totalTargets = totalTargets; + } + + public int getRolloutGroupsTotal() { + return rolloutGroupsTotal; + } + + public void setRolloutGroupsTotal(final int rolloutGroupsTotal) { + this.rolloutGroupsTotal = rolloutGroupsTotal; + } + + @Override + public int getRolloutGroupsCreated() { + return rolloutGroupsCreated; + } + + public void setRolloutGroupsCreated(final int rolloutGroupsCreated) { + this.rolloutGroupsCreated = rolloutGroupsCreated; + } + + @Override + public TotalTargetCountStatus getTotalTargetCountStatus() { + if (totalTargetCountStatus == null) { + totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); + } + return totalTargetCountStatus; + } + + public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { + this.totalTargetCountStatus = totalTargetCountStatus; + } + + @Override + public String toString() { + return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery + + ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck + + ", getName()=" + getName() + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + + } + + @Override + public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). + post(new RolloutPropertyChangeEvent(jpaRollout, EntityPropertyChangeHelper.getChangeSet( + Rollout.class, descriptorEvent)))); + + } + + @Override + public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java index 6456a3e93..225fd458e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java @@ -1,261 +1,261 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.util.ArrayList; -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; -import org.eclipse.persistence.descriptors.DescriptorEvent; - -/** - * JPA entity definition of persisting a group of an rollout. - * - */ -@Entity -@Table(name = "sp_rolloutgroup", indexes = { - @Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup,EventAwareEntity { - - private static final long serialVersionUID = 1L; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) - private JpaRollout rollout; - - @Column(name = "status") - private RolloutGroupStatus status = RolloutGroupStatus.READY; - - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) - @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) - private final List rolloutTargetGroup = new ArrayList<>(); - - @ManyToOne(fetch = FetchType.LAZY) - private JpaRolloutGroup parent; - - @Column(name = "success_condition", nullable = false) - private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; - - @Column(name = "success_condition_exp", length = 512, nullable = false) - private String successConditionExp; - - @Column(name = "success_action", nullable = false) - private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; - - @Column(name = "success_action_exp", length = 512, nullable = false) - private String successActionExp; - - @Column(name = "error_condition") - private RolloutGroupErrorCondition errorCondition; - - @Column(name = "error_condition_exp", length = 512) - private String errorConditionExp; - - @Column(name = "error_action") - private RolloutGroupErrorAction errorAction; - - @Column(name = "error_action_exp", length = 512) - private String errorActionExp; - - @Column(name = "total_targets") - private long totalTargets; - - @Transient - private transient TotalTargetCountStatus totalTargetCountStatus; - - @Override - public Rollout getRollout() { - return rollout; - } - - @Override - public void setRollout(final Rollout rollout) { - this.rollout = (JpaRollout) rollout; - } - - @Override - public RolloutGroupStatus getStatus() { - return status; - } - - @Override - public void setStatus(final RolloutGroupStatus status) { - this.status = status; - } - - public List getRolloutTargetGroup() { - return rolloutTargetGroup; - } - - @Override - public RolloutGroup getParent() { - return parent; - } - - public void setParent(final RolloutGroup parent) { - this.parent = (JpaRolloutGroup) parent; - } - - @Override - public RolloutGroupSuccessCondition getSuccessCondition() { - return successCondition; - } - - @Override - public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { - successCondition = finishCondition; - } - - @Override - public String getSuccessConditionExp() { - return successConditionExp; - } - - @Override - public void setSuccessConditionExp(final String finishExp) { - successConditionExp = finishExp; - } - - @Override - public RolloutGroupErrorCondition getErrorCondition() { - return errorCondition; - } - - @Override - public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { - this.errorCondition = errorCondition; - } - - @Override - public String getErrorConditionExp() { - return errorConditionExp; - } - - @Override - public void setErrorConditionExp(final String errorExp) { - errorConditionExp = errorExp; - } - - @Override - public RolloutGroupErrorAction getErrorAction() { - return errorAction; - } - - @Override - public void setErrorAction(final RolloutGroupErrorAction errorAction) { - this.errorAction = errorAction; - } - - @Override - public String getErrorActionExp() { - return errorActionExp; - } - - @Override - public void setErrorActionExp(final String errorActionExp) { - this.errorActionExp = errorActionExp; - } - - @Override - public RolloutGroupSuccessAction getSuccessAction() { - return successAction; - } - - @Override - public String getSuccessActionExp() { - return successActionExp; - } - - @Override - public long getTotalTargets() { - return totalTargets; - } - - public void setTotalTargets(final long totalTargets) { - this.totalTargets = totalTargets; - } - - public void setSuccessAction(final RolloutGroupSuccessAction successAction) { - this.successAction = successAction; - } - - public void setSuccessActionExp(final String successActionExp) { - this.successActionExp = successActionExp; - } - - /** - * @return the totalTargetCountStatus - */ - @Override - public TotalTargetCountStatus getTotalTargetCountStatus() { - if (totalTargetCountStatus == null) { - totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); - } - return totalTargetCountStatus; - } - - /** - * @param totalTargetCountStatus - * the totalTargetCountStatus to set - */ - @Override - public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { - this.totalTargetCountStatus = totalTargetCountStatus; - } - - @Override - public String toString() { - return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup - + ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp - + ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName() - + ", getId()=" + getId() + "]"; - } - - @Override - public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - - } - - @Override - public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). - post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, - EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); - } - - @Override - public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA entity definition of persisting a group of an rollout. + * + */ +@Entity +@Table(name = "sp_rolloutgroup", indexes = { + @Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup,EventAwareEntity { + + private static final long serialVersionUID = 1L; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) + private JpaRollout rollout; + + @Column(name = "status") + private RolloutGroupStatus status = RolloutGroupStatus.READY; + + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) + @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) + private final List rolloutTargetGroup = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.LAZY) + private JpaRolloutGroup parent; + + @Column(name = "success_condition", nullable = false) + private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; + + @Column(name = "success_condition_exp", length = 512, nullable = false) + private String successConditionExp; + + @Column(name = "success_action", nullable = false) + private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; + + @Column(name = "success_action_exp", length = 512, nullable = false) + private String successActionExp; + + @Column(name = "error_condition") + private RolloutGroupErrorCondition errorCondition; + + @Column(name = "error_condition_exp", length = 512) + private String errorConditionExp; + + @Column(name = "error_action") + private RolloutGroupErrorAction errorAction; + + @Column(name = "error_action_exp", length = 512) + private String errorActionExp; + + @Column(name = "total_targets") + private long totalTargets; + + @Transient + private transient TotalTargetCountStatus totalTargetCountStatus; + + @Override + public Rollout getRollout() { + return rollout; + } + + @Override + public void setRollout(final Rollout rollout) { + this.rollout = (JpaRollout) rollout; + } + + @Override + public RolloutGroupStatus getStatus() { + return status; + } + + @Override + public void setStatus(final RolloutGroupStatus status) { + this.status = status; + } + + public List getRolloutTargetGroup() { + return rolloutTargetGroup; + } + + @Override + public RolloutGroup getParent() { + return parent; + } + + public void setParent(final RolloutGroup parent) { + this.parent = (JpaRolloutGroup) parent; + } + + @Override + public RolloutGroupSuccessCondition getSuccessCondition() { + return successCondition; + } + + @Override + public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { + successCondition = finishCondition; + } + + @Override + public String getSuccessConditionExp() { + return successConditionExp; + } + + @Override + public void setSuccessConditionExp(final String finishExp) { + successConditionExp = finishExp; + } + + @Override + public RolloutGroupErrorCondition getErrorCondition() { + return errorCondition; + } + + @Override + public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { + this.errorCondition = errorCondition; + } + + @Override + public String getErrorConditionExp() { + return errorConditionExp; + } + + @Override + public void setErrorConditionExp(final String errorExp) { + errorConditionExp = errorExp; + } + + @Override + public RolloutGroupErrorAction getErrorAction() { + return errorAction; + } + + @Override + public void setErrorAction(final RolloutGroupErrorAction errorAction) { + this.errorAction = errorAction; + } + + @Override + public String getErrorActionExp() { + return errorActionExp; + } + + @Override + public void setErrorActionExp(final String errorActionExp) { + this.errorActionExp = errorActionExp; + } + + @Override + public RolloutGroupSuccessAction getSuccessAction() { + return successAction; + } + + @Override + public String getSuccessActionExp() { + return successActionExp; + } + + @Override + public long getTotalTargets() { + return totalTargets; + } + + public void setTotalTargets(final long totalTargets) { + this.totalTargets = totalTargets; + } + + public void setSuccessAction(final RolloutGroupSuccessAction successAction) { + this.successAction = successAction; + } + + public void setSuccessActionExp(final String successActionExp) { + this.successActionExp = successActionExp; + } + + /** + * @return the totalTargetCountStatus + */ + @Override + public TotalTargetCountStatus getTotalTargetCountStatus() { + if (totalTargetCountStatus == null) { + totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); + } + return totalTargetCountStatus; + } + + /** + * @param totalTargetCountStatus + * the totalTargetCountStatus to set + */ + @Override + public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { + this.totalTargetCountStatus = totalTargetCountStatus; + } + + @Override + public String toString() { + return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup + + ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp + + ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName() + + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + + } + + @Override + public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). + post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, + EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); + } + + @Override + public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index f6a2b8346..431ebb102 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -1,257 +1,257 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker; -import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetTag; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.eclipse.persistence.descriptors.DescriptorEvent; -import org.springframework.data.domain.Persistable; - -/** - * JPA implementation of {@link Target}. - * - */ -@Entity -@Table(name = "sp_target", indexes = { - @Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"), - @Index(name = "sp_idx_target_02", columnList = "tenant,name"), - @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), - @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), - @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "controller_id", "tenant" }, name = "uk_tenant_controller_id")) -@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), - @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target, EventAwareEntity { - private static final long serialVersionUID = 1L; - - @Column(name = "controller_id", length = 64) - @Size(min = 1) - @NotNull - private String controllerId; - - @Transient - private boolean entityNew; - - @ManyToMany(targetEntity = JpaTargetTag.class) - @JoinTable(name = "sp_target_target_tag", joinColumns = { - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { - @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) - private Set tags = new HashSet<>(); - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { - CascadeType.REMOVE }, targetEntity = JpaAction.class) - @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) - private final List actions = new ArrayList<>(); - - @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class) - @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) - private JpaDistributionSet assignedDistributionSet; - - @CascadeOnDelete - @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class) - @PrimaryKeyJoinColumn - private JpaTargetInfo targetInfo; - - /** - * the security token of the target which allows if enabled to authenticate - * with this security token. - */ - @Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128) - private String securityToken; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) - @JoinColumn(name = "target_Id", insertable = false, updatable = false) - private final List rolloutTargetGroup = new ArrayList<>(); - - /** - * Constructor. - * - * @param controllerId - * controller ID of the {@link Target} - */ - public JpaTarget(final String controllerId) { - this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken()); - } - - /** - * Constructor. - * - * @param controllerId - * controller ID of the {@link Target} - * @param securityToken - * for target authentication if enabled - */ - public JpaTarget(final String controllerId, final String securityToken) { - this.controllerId = controllerId; - setName(controllerId); - this.securityToken = securityToken; - targetInfo = new JpaTargetInfo(this); - } - - /** - * empty constructor for JPA. - */ - JpaTarget() { - controllerId = null; - securityToken = null; - } - - @Override - public DistributionSet getAssignedDistributionSet() { - return assignedDistributionSet; - } - - @Override - public String getControllerId() { - return controllerId; - } - - @Override - public Set getTags() { - return tags; - } - - public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { - this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet; - } - - public void setControllerId(final String controllerId) { - this.controllerId = controllerId; - } - - public void setTags(final Set tags) { - this.tags = tags; - } - - @Override - public List getActions() { - return actions; - } - - @Override - @Transient - public boolean isNew() { - return entityNew; - } - - /** - * @param isNew - * the isNew to set - */ - public void setNew(final boolean entityNew) { - this.entityNew = entityNew; - } - - /** - * @return the targetInfo - */ - @Override - public TargetInfo getTargetInfo() { - return targetInfo; - } - - /** - * @param targetInfo - * the targetInfo to set - */ - public void setTargetInfo(final TargetInfo targetInfo) { - this.targetInfo = (JpaTargetInfo) targetInfo; - } - - /** - * @return the securityToken if the current security context contains the - * necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN} - * or the current context is executed as system code, otherwise - * {@code null}. - */ - @Override - public String getSecurityToken() { - if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode() - || SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { - return securityToken; - } - return null; - } - - /** - * @param securityToken - * the securityToken to set - */ - @Override - public void setSecurityToken(final String securityToken) { - this.securityToken = securityToken; - } - - @Override - public String toString() { - return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]"; - } - - @Override - public void fireCreateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); - } - - @Override - public void fireUpdateEvent(final JpaTarget jpaTarget,final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); - - } - - @Override - public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - - - } - -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.eclipse.hawkbit.im.authentication.SpPermission; +import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker; +import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.springframework.data.domain.Persistable; + +/** + * JPA implementation of {@link Target}. + * + */ +@Entity +@Table(name = "sp_target", indexes = { + @Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"), + @Index(name = "sp_idx_target_02", columnList = "tenant,name"), + @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), + @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), + @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "controller_id", "tenant" }, name = "uk_tenant_controller_id")) +@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), + @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target, EventAwareEntity { + private static final long serialVersionUID = 1L; + + @Column(name = "controller_id", length = 64) + @Size(min = 1) + @NotNull + private String controllerId; + + @Transient + private boolean entityNew; + + @ManyToMany(targetEntity = JpaTargetTag.class) + @JoinTable(name = "sp_target_target_tag", joinColumns = { + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { + @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) + private Set tags = new HashSet<>(); + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { + CascadeType.REMOVE }, targetEntity = JpaAction.class) + @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) + private final List actions = new ArrayList<>(); + + @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class) + @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) + private JpaDistributionSet assignedDistributionSet; + + @CascadeOnDelete + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class) + @PrimaryKeyJoinColumn + private JpaTargetInfo targetInfo; + + /** + * the security token of the target which allows if enabled to authenticate + * with this security token. + */ + @Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128) + private String securityToken; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) + @JoinColumn(name = "target_Id", insertable = false, updatable = false) + private final List rolloutTargetGroup = new ArrayList<>(); + + /** + * Constructor. + * + * @param controllerId + * controller ID of the {@link Target} + */ + public JpaTarget(final String controllerId) { + this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken()); + } + + /** + * Constructor. + * + * @param controllerId + * controller ID of the {@link Target} + * @param securityToken + * for target authentication if enabled + */ + public JpaTarget(final String controllerId, final String securityToken) { + this.controllerId = controllerId; + setName(controllerId); + this.securityToken = securityToken; + targetInfo = new JpaTargetInfo(this); + } + + /** + * empty constructor for JPA. + */ + JpaTarget() { + controllerId = null; + securityToken = null; + } + + @Override + public DistributionSet getAssignedDistributionSet() { + return assignedDistributionSet; + } + + @Override + public String getControllerId() { + return controllerId; + } + + @Override + public Set getTags() { + return tags; + } + + public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { + this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet; + } + + public void setControllerId(final String controllerId) { + this.controllerId = controllerId; + } + + public void setTags(final Set tags) { + this.tags = tags; + } + + @Override + public List getActions() { + return actions; + } + + @Override + @Transient + public boolean isNew() { + return entityNew; + } + + /** + * @param isNew + * the isNew to set + */ + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; + } + + /** + * @return the targetInfo + */ + @Override + public TargetInfo getTargetInfo() { + return targetInfo; + } + + /** + * @param targetInfo + * the targetInfo to set + */ + public void setTargetInfo(final TargetInfo targetInfo) { + this.targetInfo = (JpaTargetInfo) targetInfo; + } + + /** + * @return the securityToken if the current security context contains the + * necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN} + * or the current context is executed as system code, otherwise + * {@code null}. + */ + @Override + public String getSecurityToken() { + if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode() + || SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { + return securityToken; + } + return null; + } + + /** + * @param securityToken + * the securityToken to set + */ + @Override + public void setSecurityToken(final String securityToken) { + this.securityToken = securityToken; + } + + @Override + public String toString() { + return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); + } + + @Override + public void fireUpdateEvent(final JpaTarget jpaTarget,final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); + + } + + @Override + public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { + + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java index a21c7547f..bfae18248 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -1,344 +1,344 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import java.net.URI; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.persistence.CascadeType; -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.EntityListeners; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.MapKeyColumn; -import javax.persistence.MapsId; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.Transient; - -import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; -import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.PollStatus; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.eclipse.persistence.descriptors.DescriptorEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Persistable; - -/** - * A table which contains all the information inserted, updated by the - * controller itself. So this entity does not provide audit information because - * changes on this entity are mostly only done by controller requests. That's - * the reason that we store these information in a separated table so we don't - * modifying the {@link Target} itself when a controller reports it's - * {@link #lastTargetQuery} for example. - * - */ -@Table(name = "sp_target_info", indexes = { - @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) -@Entity -@EntityListeners(EntityPropertyChangeListener.class) -public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareEntity { - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); - - @Id - private Long targetId; - - @Transient - private boolean entityNew; - - @CascadeOnDelete - @OneToOne(cascade = { CascadeType.MERGE, - CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class) - @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) - @MapsId - private JpaTarget target; - - @Column(name = "address", length = 512) - private String address; - - @Column(name = "last_target_query") - private Long lastTargetQuery; - - @Column(name = "install_date") - private Long installationDate; - - @Column(name = "update_status", nullable = false, length = 255) - @Enumerated(EnumType.STRING) - private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; - - @ManyToOne(optional = true, fetch = FetchType.LAZY) - @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) - private JpaDistributionSet installedDistributionSet; - - /** - * Read only on management API. Are commited by controller. - */ - @ElementCollection - @Column(name = "attribute_value", length = 128) - @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) - @CollectionTable(name = "sp_target_attributes", joinColumns = { - @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) - - private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); - - // set default request controller attributes to true, because we want to - // request them the first - // time - @Column(name = "request_controller_attributes", nullable = false) - private boolean requestControllerAttributes = true; - - /** - * Constructor for {@link TargetStatus}. - * - * @param target - * related to this status. - */ - public JpaTargetInfo(final JpaTarget target) { - this.target = target; - targetId = target.getId(); - } - - JpaTargetInfo() { - target = null; - targetId = null; - } - - @Override - public Long getId() { - return targetId; - } - - @Override - @Transient - public boolean isNew() { - return entityNew; - } - - /** - * @param isNew - * the isNew to set - */ - public void setNew(final boolean entityNew) { - this.entityNew = entityNew; - } - - /** - * @return the ipAddress - */ - @Override - public URI getAddress() { - if (address == null) { - return null; - } - try { - return URI.create(address); - } catch (final IllegalArgumentException e) { - LOG.warn("Invalid address provided. Cloud not be configured to URI", e); - return null; - } - } - - /** - * @param address - * the target address to set - * - * @throws IllegalArgumentException - * If the given string violates RFC 2396 - */ - @Override - public void setAddress(final String address) { - // check if this is a real URI - if (address != null) { - try { - URI.create(address); - } catch (final IllegalArgumentException e) { - throw new InvalidTargetAddressException( - "The given address " + address + " violates the RFC-2396 specification", e); - } - } - - this.address = address; - } - - public Long getTargetId() { - return targetId; - } - - public void setTargetId(final Long targetId) { - this.targetId = targetId; - } - - @Override - public Target getTarget() { - return target; - } - - public void setTarget(final JpaTarget target) { - this.target = target; - } - - @Override - public Long getLastTargetQuery() { - return lastTargetQuery; - } - - public void setLastTargetQuery(final Long lastTargetQuery) { - this.lastTargetQuery = lastTargetQuery; - } - - public void setRequestControllerAttributes(final boolean requestControllerAttributes) { - this.requestControllerAttributes = requestControllerAttributes; - } - - @Override - public Map getControllerAttributes() { - return controllerAttributes; - } - - @Override - public boolean isRequestControllerAttributes() { - return requestControllerAttributes; - } - - @Override - public Long getInstallationDate() { - return installationDate; - } - - public void setInstallationDate(final Long installationDate) { - this.installationDate = installationDate; - } - - @Override - public TargetUpdateStatus getUpdateStatus() { - return updateStatus; - } - - public void setUpdateStatus(final TargetUpdateStatus updateStatus) { - this.updateStatus = updateStatus; - } - - @Override - public DistributionSet getInstalledDistributionSet() { - return installedDistributionSet; - } - - public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) { - this.installedDistributionSet = installedDistributionSet; - } - - /** - * @return the poll time which holds the last poll time of the target, the - * next poll time and the overdue time. In case the - * {@link #lastTargetQuery} is not set e.g. the target never polled - * before this method returns {@code null} - */ - @Override - public PollStatus getPollStatus() { - if (lastTargetQuery == null) { - return null; - } - return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> { - final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder - .getInstance().getTenantConfigurationManagement() - .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); - final Duration overdueTime = DurationHelper.formattedStringToDuration( - TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement() - .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) - .getValue()); - final LocalDateTime currentDate = LocalDateTime.now(); - final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), - ZoneId.systemDefault()); - final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); - final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); - return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); - }); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - result = prime * result + ((targetId == null) ? 0 : targetId.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TargetInfo)) { - return false; - } - final JpaTargetInfo other = (JpaTargetInfo) obj; - if (target == null) { - if (other.target != null) { - return false; - } - } else if (!target.equals(other.target)) { - return false; - } - if (targetId == null) { - if (other.targetId != null) { - return false; - } - } else if (!targetId.equals(other.targetId)) { - return false; - } - return true; - } - - @Override - public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo,final DescriptorEvent descriptorEvent) { - // there is no target info created event - } - - @Override - public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); - } - - @Override - public void fireDeleteEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { - } -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import java.net.URI; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.MapKeyColumn; +import javax.persistence.MapsId; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Transient; + +import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.PollStatus; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Persistable; + +/** + * A table which contains all the information inserted, updated by the + * controller itself. So this entity does not provide audit information because + * changes on this entity are mostly only done by controller requests. That's + * the reason that we store these information in a separated table so we don't + * modifying the {@link Target} itself when a controller reports it's + * {@link #lastTargetQuery} for example. + * + */ +@Table(name = "sp_target_info", indexes = { + @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) +@Entity +@EntityListeners(EntityPropertyChangeListener.class) +public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareEntity { + private static final long serialVersionUID = 1L; + + private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); + + @Id + private Long targetId; + + @Transient + private boolean entityNew; + + @CascadeOnDelete + @OneToOne(cascade = { CascadeType.MERGE, + CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class) + @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) + @MapsId + private JpaTarget target; + + @Column(name = "address", length = 512) + private String address; + + @Column(name = "last_target_query") + private Long lastTargetQuery; + + @Column(name = "install_date") + private Long installationDate; + + @Column(name = "update_status", nullable = false, length = 255) + @Enumerated(EnumType.STRING) + private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; + + @ManyToOne(optional = true, fetch = FetchType.LAZY) + @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) + private JpaDistributionSet installedDistributionSet; + + /** + * Read only on management API. Are commited by controller. + */ + @ElementCollection + @Column(name = "attribute_value", length = 128) + @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) + @CollectionTable(name = "sp_target_attributes", joinColumns = { + @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) + + private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); + + // set default request controller attributes to true, because we want to + // request them the first + // time + @Column(name = "request_controller_attributes", nullable = false) + private boolean requestControllerAttributes = true; + + /** + * Constructor for {@link TargetStatus}. + * + * @param target + * related to this status. + */ + public JpaTargetInfo(final JpaTarget target) { + this.target = target; + targetId = target.getId(); + } + + JpaTargetInfo() { + target = null; + targetId = null; + } + + @Override + public Long getId() { + return targetId; + } + + @Override + @Transient + public boolean isNew() { + return entityNew; + } + + /** + * @param isNew + * the isNew to set + */ + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; + } + + /** + * @return the ipAddress + */ + @Override + public URI getAddress() { + if (address == null) { + return null; + } + try { + return URI.create(address); + } catch (final IllegalArgumentException e) { + LOG.warn("Invalid address provided. Cloud not be configured to URI", e); + return null; + } + } + + /** + * @param address + * the target address to set + * + * @throws IllegalArgumentException + * If the given string violates RFC 2396 + */ + @Override + public void setAddress(final String address) { + // check if this is a real URI + if (address != null) { + try { + URI.create(address); + } catch (final IllegalArgumentException e) { + throw new InvalidTargetAddressException( + "The given address " + address + " violates the RFC-2396 specification", e); + } + } + + this.address = address; + } + + public Long getTargetId() { + return targetId; + } + + public void setTargetId(final Long targetId) { + this.targetId = targetId; + } + + @Override + public Target getTarget() { + return target; + } + + public void setTarget(final JpaTarget target) { + this.target = target; + } + + @Override + public Long getLastTargetQuery() { + return lastTargetQuery; + } + + public void setLastTargetQuery(final Long lastTargetQuery) { + this.lastTargetQuery = lastTargetQuery; + } + + public void setRequestControllerAttributes(final boolean requestControllerAttributes) { + this.requestControllerAttributes = requestControllerAttributes; + } + + @Override + public Map getControllerAttributes() { + return controllerAttributes; + } + + @Override + public boolean isRequestControllerAttributes() { + return requestControllerAttributes; + } + + @Override + public Long getInstallationDate() { + return installationDate; + } + + public void setInstallationDate(final Long installationDate) { + this.installationDate = installationDate; + } + + @Override + public TargetUpdateStatus getUpdateStatus() { + return updateStatus; + } + + public void setUpdateStatus(final TargetUpdateStatus updateStatus) { + this.updateStatus = updateStatus; + } + + @Override + public DistributionSet getInstalledDistributionSet() { + return installedDistributionSet; + } + + public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) { + this.installedDistributionSet = installedDistributionSet; + } + + /** + * @return the poll time which holds the last poll time of the target, the + * next poll time and the overdue time. In case the + * {@link #lastTargetQuery} is not set e.g. the target never polled + * before this method returns {@code null} + */ + @Override + public PollStatus getPollStatus() { + if (lastTargetQuery == null) { + return null; + } + return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> { + final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder + .getInstance().getTenantConfigurationManagement() + .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); + final Duration overdueTime = DurationHelper.formattedStringToDuration( + TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement() + .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) + .getValue()); + final LocalDateTime currentDate = LocalDateTime.now(); + final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), + ZoneId.systemDefault()); + final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); + final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); + return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); + }); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + result = prime * result + ((targetId == null) ? 0 : targetId.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TargetInfo)) { + return false; + } + final JpaTargetInfo other = (JpaTargetInfo) obj; + if (target == null) { + if (other.target != null) { + return false; + } + } else if (!target.equals(other.target)) { + return false; + } + if (targetId == null) { + if (other.targetId != null) { + return false; + } + } else if (!targetId.equals(other.targetId)) { + return false; + } + return true; + } + + @Override + public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo,final DescriptorEvent descriptorEvent) { + // there is no target info created event + } + + @Override + public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); + } + + @Override + public void fireDeleteEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + } +} From 9c468c76f04b385ba9fbf28dd44cd80edc2d3b05 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 29 Jul 2016 13:12:51 +0200 Subject: [PATCH 06/42] Fix for EOL. --- .../eclipse/hawkbit/repository/DistributionSetManagement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index b3b4fd86f..c405dccf4 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -289,7 +289,7 @@ public interface DistributionSetManagement { * * @param distributionSetId * the distribution set id to retrieve the meta data from - * @return list of distributionSetMetadata for a given distribution set Id + * @return list of distributionSetMetadata for a given distribution set Id. */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) List findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId); From dfd449592cded96d177c1c04deb046c7dd7a3b80 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 29 Jul 2016 13:22:38 +0200 Subject: [PATCH 07/42] Fix for EOL from widows EOL to unix EOL --- .../repository/SoftwareManagement.java | 2 +- .../repository/jpa/JpaSoftwareManagement.java | 13 ++++---- .../repository/jpa/model/JpaAction.java | 17 ++++++----- .../jpa/model/JpaDistributionSet.java | 30 +++++++++---------- .../repository/jpa/model/JpaRollout.java | 14 ++++----- .../repository/jpa/model/JpaRolloutGroup.java | 13 ++++---- .../repository/jpa/model/JpaTarget.java | 16 +++++----- .../repository/jpa/model/JpaTargetInfo.java | 5 ++-- 8 files changed, 58 insertions(+), 52 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java index bb73dbb30..9b4426ff2 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java @@ -496,7 +496,7 @@ public interface SoftwareManagement { * @throws RSQLParameterSyntaxException * if the RSQL syntax is wrong * @return result of all meta data entries for a given software - * module id + * module id. */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) List findSoftwareModuleMetadataBySoftwareModuleId(Long softwareModuleId); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index 31b222051..3f8c1a54b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -620,14 +620,15 @@ public class JpaSoftwareManagement implements SoftwareManagement { pageable), pageable); } - + @Override public List findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) { - return new ArrayList<> ( softwareModuleMetadataRepository - .findAll( - (Specification) (root, query, cb) -> cb.and( - cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) - .get(JpaSoftwareModule_.id), softwareModuleId)))); + return new ArrayList<>( + softwareModuleMetadataRepository + .findAll((Specification) (root, query, + cb) -> cb.and(cb.equal( + root.get(JpaSoftwareModuleMetadata_.softwareModule).get(JpaSoftwareModule_.id), + softwareModuleId)))); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java index 5bda8f63b..e7bb04c04 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -55,7 +55,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action,EventAwareEntity { +public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action, EventAwareEntity { private static final long serialVersionUID = 1L; @ManyToOne(fetch = FetchType.LAZY) @@ -179,21 +179,22 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio @Override public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); - + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() + .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); + } @Override public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus(). - post(new ActionPropertyChangeEvent(jpaAction, EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post(new ActionPropertyChangeEvent(jpaAction, + EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); } - - + @Override public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index 77a5f88fd..afbddbade 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -69,9 +69,10 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet,EventAwareEntity { +public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity + implements DistributionSet, EventAwareEntity { private static final long serialVersionUID = 1L; - + private static final String COMPLETE = "complete"; @Column(name = "required_migration_step") @@ -291,30 +292,29 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen @Override public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); - + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder + .getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); + } @Override public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - final Map.Values> changeSet = EntityPropertyChangeHelper.getChangeSet( - JpaDistributionSet.class, descriptorEvent); - if (changeSet.containsKey(COMPLETE) - && changeSet.get(COMPLETE).getOldValue().equals(false) + final Map.Values> changeSet = EntityPropertyChangeHelper + .getChangeSet(JpaDistributionSet.class, descriptorEvent); + if (changeSet.containsKey(COMPLETE) && changeSet.get(COMPLETE).getOldValue().equals(false) && changeSet.get(COMPLETE).getNewValue().equals(true)) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post( - new DistributionCreatedEvent(jpaDistributionSet))); + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder + .getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); } - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); - + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder + .getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); + } @Override public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java index 1cf1ccb77..57c4d8a69 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java @@ -49,7 +49,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventAwareEntity { +public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, EventAwareEntity { private static final long serialVersionUID = 1L; @@ -204,20 +204,20 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventA @Override public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - + } @Override public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). - post(new RolloutPropertyChangeEvent(jpaRollout, EntityPropertyChangeHelper.getChangeSet( - Rollout.class, descriptorEvent)))); - + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post(new RolloutPropertyChangeEvent(jpaRollout, + EntityPropertyChangeHelper.getChangeSet(Rollout.class, descriptorEvent)))); + } @Override public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java index 225fd458e..0b7a23985 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java @@ -45,7 +45,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup,EventAwareEntity { +public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup, EventAwareEntity { private static final long serialVersionUID = 1L; @@ -243,19 +243,20 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr @Override public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - + } @Override public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). - post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, - EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() + .afterCommit(() -> EventBusHolder.getInstance().getEventBus() + .post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, + EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); } @Override public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index 431ebb102..d67d8e9d1 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -69,7 +69,8 @@ import org.springframework.data.domain.Persistable; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target, EventAwareEntity { +public class JpaTarget extends AbstractJpaNamedEntity + implements Persistable, Target, EventAwareEntity { private static final long serialVersionUID = 1L; @Column(name = "controller_id", length = 64) @@ -239,19 +240,20 @@ public class JpaTarget extends AbstractJpaNamedEntity implements PersistableEventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() + .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); } @Override - public void fireUpdateEvent(final JpaTarget jpaTarget,final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); - + public void fireUpdateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() + .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); + } @Override public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - - + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java index bfae18248..59cff35c8 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -329,13 +329,14 @@ public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareE } @Override - public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo,final DescriptorEvent descriptorEvent) { + public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { // there is no target info created event } @Override public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); } @Override From 5be513422de8c89fc52781976f023c677a45f869 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 1 Aug 2016 10:24:09 +0200 Subject: [PATCH 08/42] remove notification of target deletion from management layer Signed-off-by: Michael Hirsch --- .../repository/jpa/JpaTargetManagement.java | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 30a5dd5d9..1cd2ffc3c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -29,7 +29,6 @@ import javax.persistence.criteria.Root; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetManagement; -import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.jpa.configuration.Constants; @@ -49,7 +48,6 @@ import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.domain.Page; @@ -98,10 +96,6 @@ public class JpaTargetManagement implements TargetManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; - - - @Autowired - private TenantAware tenantAware; @Override public Target findTargetByControllerID(final String controllerId) { @@ -208,14 +202,12 @@ public class JpaTargetManagement implements TargetManagement { // hibernate session. final List targetsForCurrentTenant = targetRepository.findAll(Lists.newArrayList(targetIDs)).stream() .map(Target::getId).collect(Collectors.toList()); - if (!targetsForCurrentTenant.isEmpty()) { - targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant); - targetRepository.deleteByIdIn(targetsForCurrentTenant); - targetsForCurrentTenant.forEach(targetId -> notifyTargetDeleted( - tenantAware.getCurrentTenant(), targetId)); - } + if (!targetsForCurrentTenant.isEmpty()) { + targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant); + targetRepository.deleteByIdIn(targetsForCurrentTenant); + } } - + @Override public Page findTargetByAssignedDistributionSet(final Long distributionSetID, final Pageable pageReq) { return targetRepository.findByAssignedDistributionSetId(pageReq, distributionSetID); @@ -659,9 +651,5 @@ public class JpaTargetManagement implements TargetManagement { } return resultList; } - - private void notifyTargetDeleted(final String tenant, final Long targetId) { - afterCommit.afterCommit(() -> eventBus.post(new TargetDeletedEvent(tenant, targetId))); - } } From 72899df4a46cb6b5304857d96972a793bd7a7768 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 1 Aug 2016 10:30:45 +0200 Subject: [PATCH 09/42] remove notification of distribution set deletion from management layer Signed-off-by: Michael Hirsch --- .../repository/jpa/JpaDistributionSetManagement.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index 306b9bd80..84c81966f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -28,7 +28,6 @@ import org.eclipse.hawkbit.repository.DistributionSetMetadataFields; import org.eclipse.hawkbit.repository.DistributionSetTypeFields; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TagManagement; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityLockedException; @@ -55,7 +54,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -104,9 +102,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; - @Autowired - private TenantAware tenantAware; - @Override public DistributionSet findDistributionSetByIdWithDetails(final Long distid) { return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid)); @@ -198,10 +193,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { // handle the empty list distributionSetRepository.deleteByIdIn(toHardDelete); } - - afterCommit.afterCommit( - () -> eventBus.post(new DistributionDeletedEvent(tenantAware.getCurrentTenant(), distributionSetIDs))); - } @Override @@ -527,14 +518,12 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying public void deleteDistributionSetMetadata(final DistributionSet distributionSet, final String key) { - entityManager.merge((JpaDistributionSet) distributionSet).setLastModifiedAt(0L); distributionSetMetadataRepository.delete(new DsMetadataCompositeKey(distributionSet, key)); } @Override public Page findDistributionSetMetadataByDistributionSetId(final Long distributionSetId, final Pageable pageable) { - return convertMdPage(distributionSetMetadataRepository .findAll((Specification) (root, query, cb) -> cb.equal( root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id), @@ -544,7 +533,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override public List findDistributionSetMetadataByDistributionSetId(final Long distributionSetId) { - return new ArrayList(distributionSetMetadataRepository .findAll((Specification) (root, query, cb) -> cb.equal( root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id), From 4e237f748bad38dec815360226abf5cc012172e6 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 1 Aug 2016 13:01:25 +0200 Subject: [PATCH 10/42] refactor the EventAwareEntity interface Signed-off-by: Michael Hirsch --- .../model/EntityPropertyChangeListener.java | 26 +++++++++--- .../jpa/model/EventAwareEntity.java | 40 +++++++++---------- .../repository/jpa/model/JpaAction.java | 21 ++++------ .../jpa/model/JpaDistributionSet.java | 39 +++++++++--------- .../repository/jpa/model/JpaRollout.java | 24 +++++------ .../repository/jpa/model/JpaRolloutGroup.java | 20 ++++------ .../repository/jpa/model/JpaTarget.java | 21 ++++------ .../repository/jpa/model/JpaTargetInfo.java | 13 +++--- 8 files changed, 101 insertions(+), 103 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java index df36309df..13b1507db 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa.model; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEventAdapter; @@ -19,21 +20,34 @@ public class EntityPropertyChangeListener extends DescriptorEventAdapter { @Override public void postInsert(final DescriptorEvent event) { - final Object object = event.getObject(); - if (object instanceof EventAwareEntity) { - ((EventAwareEntity) object).fireCreateEvent(object,event); + if (isEventAwareEntity(object)) { + doNotifiy(() -> ((EventAwareEntity) object).fireCreateEvent(event)); } } @Override public void postUpdate(final DescriptorEvent event) { - final Object object = event.getObject(); - if (object instanceof EventAwareEntity) { - ((EventAwareEntity) object).fireUpdateEvent(object,event); + if (isEventAwareEntity(object)) { + doNotifiy(() -> ((EventAwareEntity) object).fireUpdateEvent(event)); } } + @Override + public void postDelete(final DescriptorEvent event) { + final Object object = event.getObject(); + if (isEventAwareEntity(object)) { + doNotifiy(() -> ((EventAwareEntity) object).fireDeleteEvent(event)); + } + } + + private boolean isEventAwareEntity(final Object object) { + return object instanceof EventAwareEntity; + } + + private void doNotifiy(final Runnable runnable) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(runnable); + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java index 2c1fe51d2..1c6f217c9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java @@ -1,20 +1,20 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import org.eclipse.persistence.descriptors.DescriptorEvent; - -public interface EventAwareEntity { - - public void fireCreateEvent(T t,DescriptorEvent descriptorEvent); - - public void fireUpdateEvent(T t,DescriptorEvent descriptorEvent); - - public void fireDeleteEvent(T t,DescriptorEvent descriptorEvent); -} +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.jpa.model; + +import org.eclipse.persistence.descriptors.DescriptorEvent; + +public interface EventAwareEntity { + + void fireCreateEvent(DescriptorEvent descriptorEvent); + + void fireUpdateEvent(DescriptorEvent descriptorEvent); + + void fireDeleteEvent(DescriptorEvent descriptorEvent); +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java index e7bb04c04..72ef46ba3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -30,7 +30,6 @@ import javax.persistence.Table; import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Action; @@ -55,7 +54,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action, EventAwareEntity { +public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action, EventAwareEntity { private static final long serialVersionUID = 1L; @ManyToOne(fetch = FetchType.LAZY) @@ -178,23 +177,19 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio } @Override - public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() - .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); - + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(this)); } @Override - public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post(new ActionPropertyChangeEvent(jpaAction, - EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); - + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new ActionPropertyChangeEvent(this, + EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent))); } @Override - public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + // there is no action deletion } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index afbddbade..cbaed2dbf 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -36,10 +36,10 @@ import javax.persistence.UniqueConstraint; import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Action; @@ -69,11 +69,12 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity - implements DistributionSet, EventAwareEntity { +public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet, EventAwareEntity { private static final long serialVersionUID = 1L; - private static final String COMPLETE = "complete"; + private static final String COMPLETE_PROPERTY = "complete"; + + private static final String DELETED_PROPERTY = "deleted"; @Column(name = "required_migration_step") private boolean requiredMigrationStep; @@ -291,30 +292,30 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity } @Override - public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder - .getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); - + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(this)); } @Override - public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { final Map.Values> changeSet = EntityPropertyChangeHelper .getChangeSet(JpaDistributionSet.class, descriptorEvent); - if (changeSet.containsKey(COMPLETE) && changeSet.get(COMPLETE).getOldValue().equals(false) - && changeSet.get(COMPLETE).getNewValue().equals(true)) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder - .getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); + if (changeSet.containsKey(COMPLETE_PROPERTY) && changeSet.get(COMPLETE_PROPERTY).getOldValue().equals(false) + && changeSet.get(COMPLETE_PROPERTY).getNewValue().equals(true)) { + EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(this)); } + EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(this)); - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder - .getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); - + if (changeSet.containsKey(DELETED_PROPERTY)) { + final Boolean newDeleted = (Boolean) changeSet.get(DELETED_PROPERTY).getNewValue(); + if (newDeleted) { + EventBusHolder.getInstance().getEventBus().post(new DistributionDeletedEvent(getTenant(), getId())); + } + } } @Override - public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new DistributionDeletedEvent(getTenant(), getId())); } - } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java index 57c4d8a69..85395e27b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java @@ -28,7 +28,6 @@ import javax.persistence.UniqueConstraint; import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; import org.eclipse.hawkbit.repository.jpa.cache.CacheField; import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Action.ActionType; @@ -49,7 +48,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, EventAwareEntity { +public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, EventAwareEntity { private static final long serialVersionUID = 1L; @@ -203,21 +202,20 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event } @Override - public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { + // there is no rollout creation event + } + + @Override + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new RolloutPropertyChangeEvent(this, + EntityPropertyChangeHelper.getChangeSet(Rollout.class, descriptorEvent))); } @Override - public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post(new RolloutPropertyChangeEvent(jpaRollout, - EntityPropertyChangeHelper.getChangeSet(Rollout.class, descriptorEvent)))); - - } - - @Override - public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + // there is no rollout deletion event } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java index 0b7a23985..9bb8644f4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java @@ -26,7 +26,6 @@ import javax.persistence.Transient; import javax.persistence.UniqueConstraint; import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Rollout; @@ -45,7 +44,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup, EventAwareEntity { +public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup, EventAwareEntity { private static final long serialVersionUID = 1L; @@ -242,21 +241,18 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr } @Override - public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { + // there is no RolloutGroup created event } @Override - public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() - .afterCommit(() -> EventBusHolder.getInstance().getEventBus() - .post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, - EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new RolloutGroupPropertyChangeEvent(this, + EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent))); } @Override - public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + // there is no RolloutGroup deleted event } - } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index d67d8e9d1..c91247321 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -37,8 +37,8 @@ import javax.validation.constraints.Size; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker; import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; @@ -69,8 +69,7 @@ import org.springframework.data.domain.Persistable; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaTarget extends AbstractJpaNamedEntity - implements Persistable, Target, EventAwareEntity { +public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target, EventAwareEntity { private static final long serialVersionUID = 1L; @Column(name = "controller_id", length = 64) @@ -239,21 +238,17 @@ public class JpaTarget extends AbstractJpaNamedEntity } @Override - public void fireCreateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() - .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(this)); } @Override - public void fireUpdateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() - .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); - + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(this)); } @Override - public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new TargetDeletedEvent(getTenant(), getId())); } - } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java index 59cff35c8..3923275df 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -40,7 +40,6 @@ import javax.persistence.Transient; import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; @@ -70,7 +69,7 @@ import org.springframework.data.domain.Persistable; @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) @Entity @EntityListeners(EntityPropertyChangeListener.class) -public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareEntity { +public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareEntity { private static final long serialVersionUID = 1L; private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); @@ -329,17 +328,17 @@ public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareE } @Override - public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { // there is no target info created event } @Override - public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(this)); } @Override - public void fireDeleteEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + // there is no target info deleted event } } From 60cc2c333c60ac5f6dfd44f67e4702dfc345ab95 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 1 Aug 2016 15:12:03 +0200 Subject: [PATCH 11/42] Refactored the code for displaying distributions in the deployment view. --- .../jpa/model/JpaDistributionSet.java | 11 ----- .../management/dstable/DistributionTable.java | 44 +++++++++++-------- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index afbddbade..1fddb8837 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -13,7 +13,6 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; @@ -34,13 +33,11 @@ import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -299,14 +296,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity @Override public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - final Map.Values> changeSet = EntityPropertyChangeHelper - .getChangeSet(JpaDistributionSet.class, descriptorEvent); - if (changeSet.containsKey(COMPLETE) && changeSet.get(COMPLETE).getOldValue().equals(false) - && changeSet.get(COMPLETE).getNewValue().equals(true)) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder - .getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); - } - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder .getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index ff1edafc8..633a5834b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -21,7 +21,6 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -123,9 +122,6 @@ public class DistributionTable extends AbstractNamedVersionTable) events); - } else if (DistributionCreatedEvent.class.isInstance(firstEvent) - && ((DistributionCreatedEvent) firstEvent).getEntity().isComplete()) { - refreshDistributions(); } } @@ -133,18 +129,28 @@ public class DistributionTable extends AbstractNamedVersionTable visibleItemIds = (List) getVisibleItemIds(); - - // refresh the details tabs only if selected ds is updated - // refresh the details tabs only if selected ds is updated + + + final Boolean dsVisible = visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent(); + + if((ds.isComplete() && !dsVisible) ){ + refreshDistributions(); + } + else if( (!ds.isComplete() && dsVisible)){ + refreshDistributions(); + managementUIState.setLastSelectedDistribution(null); + } + else if(dsVisible){ + UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); + } + final DistributionSetIdName lastSelectedDsIdName = managementUIState.getLastSelectedDsIdName(); + // refresh the details tabs only if selected ds is updated if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) { // update table row+details layout eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, ds)); - } else if (visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent()) { - //update the name/version details visible in table - UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); - } + } } /** @@ -261,7 +267,7 @@ public class DistributionTable extends AbstractNamedVersionTable showMetadataDetails(itemId)); @@ -281,7 +287,7 @@ public class DistributionTable extends AbstractNamedVersionTable events) { + private void onDistributionDeleteEvent(final List events) { final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); final List visibleItemIds = (List) getVisibleItemIds(); boolean shouldRefreshDs = false; for (final DistributionDeletedEvent deletedEvent : events) { - Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); - for (Long dsId : distributionSetIDs) { + final Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); + for (final Long dsId : distributionSetIDs) { final DistributionSetIdName targetIdName = new DistributionSetIdName(dsId, null, null); if (visibleItemIds.contains(targetIdName)) { dsContainer.removeItem(targetIdName); From 9c442967f8a66c31ed0d8f6ac1d35a77793a558f Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 1 Aug 2016 15:14:40 +0200 Subject: [PATCH 12/42] add tests for repository entity events Signed-off-by: Michael Hirsch --- .../event/DistributionDeletedEvent.java | 25 ++- .../jpa/JpaDistributionSetManagement.java | 8 + .../repository/jpa/JpaTargetManagement.java | 7 + .../eventbus/RepositoryEntityEventTest.java | 161 ++++++++++++++++++ .../dstable/DistributionSetTable.java | 48 +++--- .../management/dstable/DistributionTable.java | 55 +++--- 6 files changed, 237 insertions(+), 67 deletions(-) create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/eventbus/RepositoryEntityEventTest.java diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java index 1edfb47ac..7d04ba9c6 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java @@ -11,27 +11,26 @@ package org.eclipse.hawkbit.repository.eventbus.event; import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent; import org.eclipse.hawkbit.repository.model.DistributionSet; - /** - * * Defines the {@link AbstractDistributedEvent} for deletion of {@link DistributionSet}. - - * + * Defines the {@link AbstractDistributedEvent} for deletion of + * {@link DistributionSet}. */ -public class DistributionDeletedEvent extends AbstractDistributedEvent{ - private static final long serialVersionUID = -3308850381757843098L; - final Long[] distributionSetIDs; +public class DistributionDeletedEvent extends AbstractDistributedEvent { + private static final long serialVersionUID = -3308850381757843098L; + private final Long distributionId; + /** * @param tenant * the tenant for this event * @param distributionSetId - * the ID of the target which has been deleted + * the ID of the distribution set which has been deleted */ - public DistributionDeletedEvent(final String tenant, final Long...distributionIds) { + public DistributionDeletedEvent(final String tenant, final Long distributionId) { super(-1, tenant); - this.distributionSetIDs = distributionIds; + this.distributionId = distributionId; } - public Long[] getDistributionSetIDs() { - return distributionSetIDs; - } + public Long getDistributionSetId() { + return distributionId; + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index 84c81966f..8842a3507 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -28,6 +28,7 @@ import org.eclipse.hawkbit.repository.DistributionSetMetadataFields; import org.eclipse.hawkbit.repository.DistributionSetTypeFields; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TagManagement; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityLockedException; @@ -54,6 +55,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -102,6 +104,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; + @Autowired + private TenantAware tenantAware; + @Override public DistributionSet findDistributionSetByIdWithDetails(final Long distid) { return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid)); @@ -193,6 +198,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { // handle the empty list distributionSetRepository.deleteByIdIn(toHardDelete); } + + Arrays.stream(distributionSetIDs) + .forEach(dsId -> eventBus.post(new DistributionDeletedEvent(tenantAware.getCurrentTenant(), dsId))); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 1cd2ffc3c..225c0b4b2 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -29,6 +29,7 @@ import javax.persistence.criteria.Root; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.jpa.configuration.Constants; @@ -48,6 +49,7 @@ import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.domain.Page; @@ -94,6 +96,9 @@ public class JpaTargetManagement implements TargetManagement { @Autowired private EventBus eventBus; + @Autowired + private TenantAware tenantAware; + @Autowired private AfterTransactionCommitExecutor afterCommit; @@ -206,6 +211,8 @@ public class JpaTargetManagement implements TargetManagement { targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant); targetRepository.deleteByIdIn(targetsForCurrentTenant); } + targetsForCurrentTenant + .forEach(targetId -> eventBus.post(new TargetDeletedEvent(tenantAware.getCurrentTenant(), targetId))); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/eventbus/RepositoryEntityEventTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/eventbus/RepositoryEntityEventTest.java new file mode 100644 index 000000000..0aa305d52 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/eventbus/RepositoryEntityEventTest.java @@ -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.repository.jpa.eventbus; + +import static org.fest.assertions.Assertions.assertThat; + +import java.net.URI; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.eclipse.hawkbit.eventbus.event.Event; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; +import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.fest.assertions.api.Assertions; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +import ru.yandex.qatools.allure.annotations.Description; +import ru.yandex.qatools.allure.annotations.Features; +import ru.yandex.qatools.allure.annotations.Stories; + +@Features("Component Tests - Repository") +@Stories("Entity Events") +public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest { + + @Autowired + private EventBus eventBus; + + private final MyEventListener eventListener = new MyEventListener(); + + @Before + public void beforeTest() { + eventListener.queue.clear(); + eventBus.register(eventListener); + } + + @Test + @Description("Verifies that the target created event is published when a target has been created") + public void targetCreatedEventIsPublished() throws InterruptedException { + final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345")); + + final TargetCreatedEvent targetCreatedEvent = eventListener.waitForEvent(TargetCreatedEvent.class, 1, + TimeUnit.SECONDS); + assertThat(targetCreatedEvent).isNotNull(); + assertThat(targetCreatedEvent.getEntity().getId()).isEqualTo(createdTarget.getId()); + } + + @Test + @Description("Verifies that the target update event is published when a target has been updated") + public void targetUpdateEventIsPublished() throws InterruptedException { + final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345")); + createdTarget.setName("updateName"); + targetManagement.updateTarget(createdTarget); + + final TargetUpdatedEvent targetUpdatedEvent = eventListener.waitForEvent(TargetUpdatedEvent.class, 1, + TimeUnit.SECONDS); + assertThat(targetUpdatedEvent).isNotNull(); + assertThat(targetUpdatedEvent.getEntity().getId()).isEqualTo(createdTarget.getId()); + } + + @Test + @Description("Verifies that the target info update event is published when a target info has been updated") + public void targetInfoUpdateEventIsPublished() throws InterruptedException { + final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345")); + controllerManagament.updateTargetStatus(createdTarget.getTargetInfo(), TargetUpdateStatus.PENDING, + System.currentTimeMillis(), URI.create("http://127.0.0.1")); + + final TargetInfoUpdateEvent targetInfoUpdatedEvent = eventListener.waitForEvent(TargetInfoUpdateEvent.class, 1, + TimeUnit.SECONDS); + assertThat(targetInfoUpdatedEvent).isNotNull(); + assertThat(targetInfoUpdatedEvent.getEntity().getTarget().getId()).isEqualTo(createdTarget.getId()); + } + + @Test + @Description("Verifies that the target deleted event is published when a target has been deleted") + public void targetDeletedEventIsPublished() throws InterruptedException { + final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345")); + + targetManagement.deleteTargets(createdTarget.getId()); + + final TargetDeletedEvent targetDeletedEvent = eventListener.waitForEvent(TargetDeletedEvent.class, 1, + TimeUnit.SECONDS); + assertThat(targetDeletedEvent).isNotNull(); + assertThat(targetDeletedEvent.getTargetId()).isEqualTo(createdTarget.getId()); + } + + @Test + @Description("Verifies that the distribution set created event is published when a distribution set has been created") + public void distributionSetCreatedEventIsPublished() throws InterruptedException { + final DistributionSet generateDistributionSet = entityFactory.generateDistributionSet(); + generateDistributionSet.setName("dsEventTest"); + generateDistributionSet.setVersion("1"); + final DistributionSet createDistributionSet = distributionSetManagement + .createDistributionSet(generateDistributionSet); + + final DistributionCreatedEvent dsCreatedEvent = eventListener.waitForEvent(DistributionCreatedEvent.class, 1, + TimeUnit.SECONDS); + assertThat(dsCreatedEvent).isNotNull(); + assertThat(dsCreatedEvent.getEntity().getId()).isEqualTo(createDistributionSet.getId()); + } + + @Test + @Description("Verifies that the distribution set deleted event is published when a distribution set has been deleted") + public void distributionSetDeletedEventIsPublished() throws InterruptedException { + + final DistributionSet generateDistributionSet = entityFactory.generateDistributionSet(); + generateDistributionSet.setName("dsEventTest"); + generateDistributionSet.setVersion("1"); + final DistributionSet createDistributionSet = distributionSetManagement + .createDistributionSet(generateDistributionSet); + + distributionSetManagement.deleteDistributionSet(createDistributionSet); + + final DistributionDeletedEvent dsDeletedEvent = eventListener.waitForEvent(DistributionDeletedEvent.class, 1, + TimeUnit.SECONDS); + assertThat(dsDeletedEvent).isNotNull(); + assertThat(dsDeletedEvent.getDistributionSetId()).isEqualTo(createDistributionSet.getId()); + } + + private class MyEventListener { + + private final BlockingQueue queue = new LinkedBlockingQueue<>(); + + @Subscribe + public void onEvent(final Event event) { + queue.offer(event); + } + + public T waitForEvent(final Class eventType, final long timeout, final TimeUnit timeUnit) + throws InterruptedException { + Event event = null; + while ((event = queue.poll(timeout, timeUnit)) != null) { + if (event.getClass().isAssignableFrom(eventType)) { + return (T) event; + } + } + Assertions.fail("Missing event " + eventType + " within timeout " + timeout + " " + timeUnit); + return null; + } + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index 7946532a3..6bef7a794 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -108,7 +108,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable visibleItemIds = (List) getVisibleItemIds(); // refresh the details tabs only if selected ds is updated @@ -219,10 +219,10 @@ public class DistributionSetTable extends AbstractNamedVersionTable showMetadataDetails(((DistributionSetIdName) itemId).getId())); + manageMetaDataBtn + .addClickListener(event -> showMetadataDetails(((DistributionSetIdName) itemId).getId())); return manageMetaDataBtn; } }); } - @Override protected List getTableVisibleColumns() { @@ -541,7 +541,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable events) { + private void onDistributionDeleteEvent(final List events) { final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); final List visibleItemIds = (List) getVisibleItemIds(); boolean shouldRefreshDs = false; for (final DistributionDeletedEvent deletedEvent : events) { - Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); - for (Long dsId : distributionSetIDs) { - final DistributionSetIdName targetIdName = new DistributionSetIdName(dsId, null, null); - if (visibleItemIds.contains(targetIdName)) { - dsContainer.removeItem(targetIdName); - } else { - shouldRefreshDs = true; - } + final Long distributionSetId = deletedEvent.getDistributionSetId(); + final DistributionSetIdName targetIdName = new DistributionSetIdName(distributionSetId, null, null); + if (visibleItemIds.contains(targetIdName)) { + dsContainer.removeItem(targetIdName); + } else { + shouldRefreshDs = true; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index ff1edafc8..7609f71ef 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -93,16 +93,16 @@ public class DistributionTable extends AbstractNamedVersionTable) events); } else if (DistributionCreatedEvent.class.isInstance(firstEvent) && ((DistributionCreatedEvent) firstEvent).getEntity().isComplete()) { - refreshDistributions(); - } + refreshDistributions(); + } } @@ -137,12 +137,12 @@ public class DistributionTable extends AbstractNamedVersionTable visibleItemIds = (List) getVisibleItemIds(); // refresh the details tabs only if selected ds is updated - // refresh the details tabs only if selected ds is updated + // refresh the details tabs only if selected ds is updated if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) { // update table row+details layout eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, ds)); } else if (visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent()) { - //update the name/version details visible in table + // update the name/version details visible in table UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); } } @@ -261,27 +261,26 @@ public class DistributionTable extends AbstractNamedVersionTable showMetadataDetails(itemId)); - iconLayout.addComponent((Button)getPinButton(itemId)); + iconLayout.addComponent((Button) getPinButton(itemId)); iconLayout.addComponent(manageMetaDataBtn); return iconLayout; } - + }); } - - + private String getNameAndVerion(final Object itemId) { final Item item = getItem(itemId); final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue(); return name + "." + version; } - - private Button createManageMetadataButton(String nameVersionStr) { + + private Button createManageMetadataButton(final String nameVersionStr) { final Button manageMetadataBtn = SPUIComponentProvider.getButton( SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false, FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class); @@ -313,9 +312,9 @@ public class DistributionTable extends AbstractNamedVersionTable events) { + private void onDistributionDeleteEvent(final List events) { final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); final List visibleItemIds = (List) getVisibleItemIds(); boolean shouldRefreshDs = false; for (final DistributionDeletedEvent deletedEvent : events) { - Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); - for (Long dsId : distributionSetIDs) { - final DistributionSetIdName targetIdName = new DistributionSetIdName(dsId, null, null); - if (visibleItemIds.contains(targetIdName)) { - dsContainer.removeItem(targetIdName); - } else { - shouldRefreshDs = true; - } + final Long distributionSetId = deletedEvent.getDistributionSetId(); + final DistributionSetIdName targetIdName = new DistributionSetIdName(distributionSetId, null, null); + if (visibleItemIds.contains(targetIdName)) { + dsContainer.removeItem(targetIdName); + } else { + shouldRefreshDs = true; } } From 1bf91372ae63d98a5d5f176ad31c449a2bff1bba Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 1 Aug 2016 17:51:34 +0200 Subject: [PATCH 13/42] Added the javadoc. --- .../repository/jpa/model/EventAwareEntity.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java index 1c6f217c9..95a14a979 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java @@ -12,9 +12,21 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; public interface EventAwareEntity { + /** + * Fired for the Entity creation. + * @param descriptorEvent + */ void fireCreateEvent(DescriptorEvent descriptorEvent); + /** + * Fired for the Entity updation. + * @param descriptorEvent + */ void fireUpdateEvent(DescriptorEvent descriptorEvent); + /** + * Fired for the Entity deletion. + * @param descriptorEvent + */ void fireDeleteEvent(DescriptorEvent descriptorEvent); } From 0854d023fb1654f41146c555bcc9c8fb553fd529 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Tue, 2 Aug 2016 18:32:44 +0200 Subject: [PATCH 14/42] Fixed the code for the create ds for deployment view and fixed the issue for delete metadata(getting optimistic lock exception) --- .../jpa/JpaDistributionSetManagement.java | 11 +++- .../management/dstable/DistributionTable.java | 57 ++++++++++--------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index 8842a3507..e8e05a9e1 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -483,11 +483,13 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { if (distributionSetMetadataRepository.exists(metadata.getId())) { throwMetadataKeyAlreadyExists(metadata.getId().getKey()); } + + final DistributionSet latestDistributionSet = findDistributionSetById(metadata.getDistributionSet().getId()); // merge base distribution set so optLockRevision gets updated and audit // log written because // modifying metadata is modifying the base distribution set itself for // auditing purposes. - entityManager.merge((JpaDistributionSet) metadata.getDistributionSet()).setLastModifiedAt(0L); + entityManager.merge((JpaDistributionSet) latestDistributionSet).setLastModifiedAt(0L); return distributionSetMetadataRepository.save(metadata); } @@ -502,7 +504,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { for (final JpaDistributionSetMetadata distributionSetMetadata : metadata) { checkAndThrowAlreadyIfDistributionSetMetadataExists(distributionSetMetadata.getId()); } - metadata.forEach(m -> entityManager.merge((JpaDistributionSet) m.getDistributionSet()).setLastModifiedAt(0L)); + metadata.forEach(m -> entityManager.merge((JpaDistributionSet) findDistributionSetById(m.getDistributionSet().getId())).setLastModifiedAt(0L)); return new ArrayList<>( (Collection) distributionSetMetadataRepository.save(metadata)); @@ -518,7 +520,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { findOne(metadata.getDistributionSet(), metadata.getKey()); // touch it to update the lock revision because we are modifying the // DS indirectly - entityManager.merge((JpaDistributionSet) metadata.getDistributionSet()).setLastModifiedAt(0L); + final DistributionSet latestDistributionSet = findDistributionSetById(metadata.getDistributionSet().getId()); + entityManager.merge((JpaDistributionSet) latestDistributionSet).setLastModifiedAt(0L); return distributionSetMetadataRepository.save(metadata); } @@ -526,6 +529,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying public void deleteDistributionSetMetadata(final DistributionSet distributionSet, final String key) { + final DistributionSet latestDistributionSet = findDistributionSetById(distributionSet.getId()); + entityManager.merge((JpaDistributionSet) latestDistributionSet).setLastModifiedAt(0L); distributionSetMetadataRepository.delete(new DsMetadataCompositeKey(distributionSet, key)); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index 3ded0ed07..56fdd9114 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -21,6 +21,7 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -92,16 +93,16 @@ public class DistributionTable extends AbstractNamedVersionTable) events); - } + } else if (DistributionCreatedEvent.class.isInstance(firstEvent) + && ((DistributionCreatedEvent) firstEvent).getEntity().isComplete()) { + refreshDistributions(); + } } @EventBusListenerMethod(scope = EventScope.SESSION) void onEvents(final DistributionSetUpdateEvent event) { final DistributionSet ds = event.getEntity(); - + final List visibleItemIds = (List) getVisibleItemIds(); - - - final Boolean dsVisible = visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent(); - - if((ds.isComplete() && !dsVisible) ){ + + final Boolean dsVisible = visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst() + .isPresent(); + + if ((ds.isComplete() && !dsVisible)) { refreshDistributions(); - } - else if( (!ds.isComplete() && dsVisible)){ + } else if ((!ds.isComplete() && dsVisible)) { refreshDistributions(); - managementUIState.setLastSelectedDistribution(null); - } - else if(dsVisible){ + if (ds.getId().equals(managementUIState.getLastSelectedDsIdName().getId())) { + managementUIState.setLastSelectedDistribution(null); + managementUIState.setLastSelectedEntity(null); + } + + } else if (dsVisible) { UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); } final DistributionSetIdName lastSelectedDsIdName = managementUIState.getLastSelectedDsIdName(); - // refresh the details tabs only if selected ds is updated + // refresh the details tabs only if selected ds is updated if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) { // update table row+details layout eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, ds)); - } + } } /** @@ -271,22 +277,21 @@ public class DistributionTable extends AbstractNamedVersionTable showMetadataDetails(itemId)); - iconLayout.addComponent((Button)getPinButton(itemId)); + iconLayout.addComponent((Button) getPinButton(itemId)); iconLayout.addComponent(manageMetaDataBtn); return iconLayout; } - + }); } - - + private String getNameAndVerion(final Object itemId) { final Item item = getItem(itemId); final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue(); return name + "." + version; } - + private Button createManageMetadataButton(final String nameVersionStr) { final Button manageMetadataBtn = SPUIComponentProvider.getButton( SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false, @@ -319,9 +324,9 @@ public class DistributionTable extends AbstractNamedVersionTable Date: Mon, 8 Aug 2016 09:14:48 +0200 Subject: [PATCH 15/42] add javadoc Signed-off-by: Michael Hirsch --- .../repository/jpa/model/EntityPropertyChangeListener.java | 3 ++- .../hawkbit/repository/jpa/model/EventAwareEntity.java | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java index 13b1507db..27fbc687e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java @@ -13,7 +13,8 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEventAdapter; /** - * Listens to change in property values of an entity. + * Listens to change in property values of an entity and calls the corresponding + * {@link EventAwareEntity}. * */ public class EntityPropertyChangeListener extends DescriptorEventAdapter { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java index 95a14a979..889a61796 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java @@ -10,22 +10,29 @@ package org.eclipse.hawkbit.repository.jpa.model; import org.eclipse.persistence.descriptors.DescriptorEvent; +/** + * Interfaces which can be implemented by entities to be called when the entity + * should fire an event because the entity has been created, updated or deleted. + */ public interface EventAwareEntity { /** * Fired for the Entity creation. + * * @param descriptorEvent */ void fireCreateEvent(DescriptorEvent descriptorEvent); /** * Fired for the Entity updation. + * * @param descriptorEvent */ void fireUpdateEvent(DescriptorEvent descriptorEvent); /** * Fired for the Entity deletion. + * * @param descriptorEvent */ void fireDeleteEvent(DescriptorEvent descriptorEvent); From 8fa2a60a7177cc3801382b755b0af5faa0aec082 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 8 Aug 2016 13:30:16 +0200 Subject: [PATCH 16/42] Formatted the code. Signed-off-by: Gaurav --- .../eventbus/event/TargetUpdatedEvent.java | 18 ++++---- .../jpa/model/DescriptorEventDetails.java | 44 ++++++++++--------- .../helper/EntityPropertyChangeHelper.java | 25 ++++------- 3 files changed, 42 insertions(+), 45 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java index 4896f4ca8..8ae5718e9 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java @@ -16,14 +16,16 @@ import org.eclipse.hawkbit.repository.model.Target; */ public class TargetUpdatedEvent extends AbstractBaseEntityEvent { - private static final long serialVersionUID = 5665118668865832477L; + private static final long serialVersionUID = 5665118668865832477L; - /** - * Constructor - * @param baseEntity Target entity - */ - public TargetUpdatedEvent(final Target baseEntity) { - super(baseEntity); - } + /** + * Constructor + * + * @param baseEntity + * Target entity + */ + public TargetUpdatedEvent(final Target baseEntity) { + super(baseEntity); + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java index a80891604..091b2eb77 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java @@ -17,31 +17,33 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; */ public class DescriptorEventDetails { - enum ActionType { - CREATE, UPDATE; - } + enum ActionType { + CREATE, UPDATE; + } - private final DescriptorEvent descriptorEvent; + private final DescriptorEvent descriptorEvent; - private final ActionType actiontype; + private final ActionType actiontype; - /** - * Constructor - * @param actionType Action type - * @param descriptorEvent Descriptor Event - */ - public DescriptorEventDetails(final ActionType actionType, - final DescriptorEvent descriptorEvent) { - this.descriptorEvent = descriptorEvent; - this.actiontype = actionType; - } + /** + * Constructor + * + * @param actionType + * Action type + * @param descriptorEvent + * Descriptor Event + */ + public DescriptorEventDetails(final ActionType actionType, final DescriptorEvent descriptorEvent) { + this.descriptorEvent = descriptorEvent; + this.actiontype = actionType; + } - public DescriptorEvent getDescriptorEvent() { - return descriptorEvent; - } + public DescriptorEvent getDescriptorEvent() { + return descriptorEvent; + } - public ActionType getActiontype() { - return actiontype; - } + public ActionType getActiontype() { + return actiontype; + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java index 0697bcead..2be398e24 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java @@ -19,15 +19,15 @@ import org.eclipse.persistence.queries.UpdateObjectQuery; import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; /** - *Helper class to get the change set for the property changes in the Entity. + * Helper class to get the change set for the property changes in the Entity. * * @param */ -public class EntityPropertyChangeHelper { - - +public class EntityPropertyChangeHelper { + /** * To get the map of entity property change set + * * @param clazz * @param event * @return the map of the changeSet @@ -35,19 +35,12 @@ public class EntityPropertyChangeHelper { public static Map.Values> getChangeSet( final Class clazz, final DescriptorEvent event) { final T rolloutGroup = clazz.cast(event.getObject()); - final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()) - .getObjectChangeSet(); - return changeSet - .getChanges() - .stream() - .filter(record -> record instanceof DirectToFieldChangeRecord) + final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet(); + return changeSet.getChanges().stream().filter(record -> record instanceof DirectToFieldChangeRecord) .map(record -> (DirectToFieldChangeRecord) record) - .collect( - Collectors.toMap( - record -> record.getAttribute(), - record -> new AbstractPropertyChangeEvent( - rolloutGroup, null).new Values(record - .getOldValue(), record.getNewValue()))); + .collect(Collectors.toMap(record -> record.getAttribute(), + record -> new AbstractPropertyChangeEvent(rolloutGroup, null).new Values( + record.getOldValue(), record.getNewValue()))); } } From 25fb8e55143b0c7d7d9470bc04a1f0e0c5427923 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 11 Aug 2016 09:50:38 +0200 Subject: [PATCH 17/42] introduce property to disable amqp interface in simulator Signed-off-by: Michael Hirsch --- examples/hawkbit-device-simulator/README.md | 6 +++++ .../simulator/SimulationController.java | 23 +++++++++++++------ .../simulator/amqp/AmqpConfiguration.java | 4 ++++ .../simulator/amqp/AmqpProperties.java | 19 +++++++++++++++ .../simulator/amqp/SpReceiverService.java | 4 ++++ .../hawkbit/simulator/ui/GenerateDialog.java | 14 ++++++++--- .../hawkbit/simulator/ui/SimulatorView.java | 6 ++++- .../src/main/resources/application.properties | 1 + 8 files changed, 66 insertions(+), 11 deletions(-) diff --git a/examples/hawkbit-device-simulator/README.md b/examples/hawkbit-device-simulator/README.md index 1ba29bb7e..ba241601a 100644 --- a/examples/hawkbit-device-simulator/README.md +++ b/examples/hawkbit-device-simulator/README.md @@ -24,6 +24,12 @@ The simulator has user authentication enabled in **cloud profile**. Default cred This can be configured/disabled by spring boot properties +## hawkBit APIs + +The simulator supports `DDI` as well as the `DMF` integration APIs. +In case there is no AMQP message broker (like rabbitMQ) running, you can disable the AMQP support for the device simulator, so the simulator is not trying to connect to a amqp message broker. +Configuration property `hawkbit.device.simulator.amqp.enabled=true` + ## Usage ### Graphical User Interface diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java index 43f954c00..b100cb28f 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java @@ -8,11 +8,13 @@ */ package org.eclipse.hawkbit.simulator; +import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX; + import java.net.MalformedURLException; import java.net.URL; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; -import org.eclipse.hawkbit.simulator.amqp.SpSenderService; +import org.eclipse.hawkbit.simulator.amqp.AmqpProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; @@ -21,22 +23,19 @@ import org.springframework.web.bind.annotation.RestController; /** * REST endpoint for controlling the device simulator. - * - * - * */ @RestController public class SimulationController { - @Autowired - private SpSenderService spSenderService; - @Autowired private DeviceSimulatorRepository repository; @Autowired private SimulatedDeviceFactory deviceFactory; + @Autowired + private AmqpProperties amqpProperties; + /** * The start resource to start a device creation. * @@ -82,6 +81,12 @@ public class SimulationController { return ResponseEntity.badRequest().body("query param api only allows value of 'dmf' or 'ddi'"); } + if (protocol == Protocol.DMF_AMQP && isDmfDisabled()) { + return ResponseEntity.badRequest() + .body("The AMQP interface has been disabled, to use DMF protocol you need to enable the AMQP interface via '" + + CONFIGURATION_PREFIX + ".enabled=true'"); + } + for (int i = 0; i < amount; i++) { final String deviceId = name + i; repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant, protocol, pollDelay, new URL(endpoint), @@ -90,4 +95,8 @@ public class SimulationController { return ResponseEntity.ok("Updated " + amount + " DMF connected targets!"); } + + private boolean isDmfDisabled() { + return !amqpProperties.isEnabled(); + } } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java index edaf9d11a..5e9b3e049 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.simulator.amqp; +import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX; + import java.time.Duration; import java.util.HashMap; import java.util.Map; @@ -27,6 +29,7 @@ import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.amqp.RabbitProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -39,6 +42,7 @@ import org.springframework.retry.support.RetryTemplate; */ @Configuration @EnableConfigurationProperties(AmqpProperties.class) +@ConditionalOnProperty(prefix = CONFIGURATION_PREFIX, name = "enabled") public class AmqpConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(AmqpConfiguration.class); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java index 8fba3ac5b..3730a3350 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java @@ -19,6 +19,17 @@ import org.springframework.stereotype.Component; @Component @ConfigurationProperties("hawkbit.device.simulator.amqp") public class AmqpProperties { + + /** + * The prefix for this configuration. + */ + public static final String CONFIGURATION_PREFIX = "hawkbit.device.simulator.amqp"; + + /** + * Indicates if the AMQP interface is enabled for the device simulator. + */ + private boolean enabled; + /** * Queue for receiving DMF messages from update server. */ @@ -84,4 +95,12 @@ public class AmqpProperties { public void setDeadLetterTtl(final int deadLetterTtl) { this.deadLetterTtl = deadLetterTtl; } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java index 7d55fb375..8dac6d4bc 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.simulator.amqp; +import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX; + import java.util.Map; import org.eclipse.hawkbit.dmf.amqp.api.EventTopic; @@ -22,6 +24,7 @@ import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Component; @@ -32,6 +35,7 @@ import com.google.common.collect.Lists; * */ @Component +@ConditionalOnProperty(prefix = CONFIGURATION_PREFIX, name = "enabled") public class SpReceiverService extends ReceiverService { private static final Logger LOGGER = LoggerFactory.getLogger(ReceiverService.class); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java index b50098829..6d1806463 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java @@ -52,6 +52,7 @@ public class GenerateDialog extends Window { private final TextField gatewayTokenTextField; private OptionGroup protocolGroup; private Button buttonOk; + private final boolean dmfEnabled; /** * Creates a new pop window for setting the configuration of simulating @@ -60,9 +61,12 @@ public class GenerateDialog extends Window { * @param callback * the callback which is called when the dialog has been * successfully confirmed. + * @param dmfEnabled + * indicates if the AMQP/DMF interface is enabled by + * configuration and if the option DMF should be enabled or not */ - public GenerateDialog(final GenerateDialogCallback callback) { - + public GenerateDialog(final GenerateDialogCallback callback, final boolean dmfEnabled) { + this.dmfEnabled = dmfEnabled; formLayout.setSpacing(true); formLayout.setMargin(true); @@ -187,15 +191,19 @@ public class GenerateDialog extends Window { this.protocolGroup = new OptionGroup("Simulated Device Protocol"); protocolGroup.addItem(Protocol.DMF_AMQP); protocolGroup.addItem(Protocol.DDI_HTTP); + protocolGroup.select(Protocol.DMF_AMQP); protocolGroup.setItemCaption(Protocol.DMF_AMQP, "Device Management Federation API (AMQP push)"); protocolGroup.setItemCaption(Protocol.DDI_HTTP, "Direct Device Interface (HTTP poll)"); protocolGroup.setNullSelectionAllowed(false); - protocolGroup.select(Protocol.DMF_AMQP); protocolGroup.addValueChangeListener(event -> { final boolean directDeviceOptionSelected = event.getProperty().getValue().equals(Protocol.DDI_HTTP); pollUrlTextField.setVisible(directDeviceOptionSelected); gatewayTokenTextField.setVisible(directDeviceOptionSelected); }); + protocolGroup.setItemEnabled(Protocol.DMF_AMQP, dmfEnabled); + if (!dmfEnabled) { + protocolGroup.select(Protocol.DDI_HTTP); + } } private void createOkButton(final GenerateDialogCallback callback) { diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java index 686945407..25e575cf1 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java @@ -17,6 +17,7 @@ import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Status; import org.eclipse.hawkbit.simulator.DeviceSimulatorRepository; import org.eclipse.hawkbit.simulator.SimulatedDeviceFactory; import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus; +import org.eclipse.hawkbit.simulator.amqp.AmqpProperties; import org.eclipse.hawkbit.simulator.amqp.SpSenderService; import org.eclipse.hawkbit.simulator.event.InitUpdate; import org.eclipse.hawkbit.simulator.event.NextPollCounterUpdate; @@ -90,6 +91,9 @@ public class SimulatorView extends VerticalLayout implements View { @Autowired private transient EventBus eventbus; + @Autowired + private transient AmqpProperties amqpProperties; + private final Label caption = new Label("DMF/DDI Simulated Devices"); private final HorizontalLayout toolbar = new HorizontalLayout(); private final Grid grid = new Grid(); @@ -268,7 +272,7 @@ public class SimulatorView extends VerticalLayout implements View { tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken))); spSenderService.createOrUpdateThing(tenant, deviceId); } - })); + }, amqpProperties.isEnabled())); } private ProtocolConverter createProtocolConverter() { diff --git a/examples/hawkbit-device-simulator/src/main/resources/application.properties b/examples/hawkbit-device-simulator/src/main/resources/application.properties index 5d3f04be7..60fa817e2 100644 --- a/examples/hawkbit-device-simulator/src/main/resources/application.properties +++ b/examples/hawkbit-device-simulator/src/main/resources/application.properties @@ -8,6 +8,7 @@ # ## Configuration for DMF communication +hawkbit.device.simulator.amqp.enabled=true hawkbit.device.simulator.amqp.receiverConnectorQueueFromSp=simulator_receiver hawkbit.device.simulator.amqp.deadLetterQueue=simulator_deadletter hawkbit.device.simulator.amqp.deadLetterExchange=simulator.deadletter From 4534ece86047da37683781c6747be8f9082e7c0a Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 11 Aug 2016 14:03:40 +0200 Subject: [PATCH 18/42] Fixed the issue of refreshing the tag details section for the distributions. Signed-off-by: Gaurav --- .../hawkbit/ui/distributions/dstable/DistributionSetTable.java | 2 +- .../hawkbit/ui/management/dstable/DistributionTable.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index 3695ef488..6cda2cd16 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -137,7 +137,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable e.getId().equals(ds.getId())).findFirst().isPresent()) { // update the name/version details visible in table UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index 6e4714e14..e4313dd80 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -155,7 +155,7 @@ public class DistributionTable extends AbstractNamedVersionTable Date: Fri, 12 Aug 2016 09:54:18 +0200 Subject: [PATCH 19/42] adapt manifest Signed-off-by: Michael Hirsch --- examples/hawkbit-device-simulator/cf/manifest.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/hawkbit-device-simulator/cf/manifest.yml b/examples/hawkbit-device-simulator/cf/manifest.yml index 51a43ace6..188ef7780 100644 --- a/examples/hawkbit-device-simulator/cf/manifest.yml +++ b/examples/hawkbit-device-simulator/cf/manifest.yml @@ -17,6 +17,4 @@ applications: services: - dmf-rabbit env: - SPRING_PROFILES_ACTIVE: cloud,amqp - CF_STAGING_TIMEOUT: 15 - CF_STARTUP_TIMEOUT: 15 + SPRING_PROFILES_ACTIVE: cloud From 2cbe13c14f1bd47582dc433516428b89acc0fa8b Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 12 Aug 2016 16:31:40 +0200 Subject: [PATCH 20/42] don't reject too many status entries exception Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 8906bc96c..871a4973a 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -41,6 +41,7 @@ import org.eclipse.hawkbit.repository.RepositoryConstants; import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.TenantNotExistException; +import org.eclipse.hawkbit.repository.exception.ToManyStatusEntriesException; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; @@ -153,8 +154,8 @@ public class AmqpMessageHandlerService extends BaseAmqpService { return handleAuthentifiactionMessage(message); } catch (final IllegalArgumentException ex) { throw new AmqpRejectAndDontRequeueException("Invalid message!", ex); - } catch (final TenantNotExistException teex) { - throw new AmqpRejectAndDontRequeueException(teex); + } catch (final TenantNotExistException | ToManyStatusEntriesException e) { + throw new AmqpRejectAndDontRequeueException(e); } finally { SecurityContextHolder.setContext(oldContext); } From 3accac9aded02c55ebc75bbec9caf7bebe5ec342 Mon Sep 17 00:00:00 2001 From: Dominic Schabel Date: Mon, 15 Aug 2016 11:30:21 +0200 Subject: [PATCH 21/42] Minor code improvements Signed-off-by: Dominic Schabel dominic.schabel@bosch-si.com --- .../simulator/DeviceSimulatorUpdater.java | 24 ++-- .../hawkbit/repository/FieldNameProvider.java | 89 ++++++-------- .../model/target/MgmtTargetAttributes.java | 3 +- .../event/AbstractPropertyChangeEvent.java | 17 ++- .../event/ActionPropertyChangeEvent.java | 3 +- .../RolloutGroupPropertyChangeEvent.java | 4 +- .../event/RolloutPropertyChangeEvent.java | 5 +- .../report/model/AbstractReportSeries.java | 7 -- .../report/model/ListReportSeries.java | 10 +- .../jpa/JpaDeploymentManagement.java | 19 +-- .../repository/jpa/JpaRolloutManagement.java | 2 +- .../jpa/JpaTargetFilterQueryManagement.java | 1 - .../ExceptionMappingAspectHandler.java | 11 +- .../model/EntityPropertyChangeListener.java | 23 ++-- .../repository/jpa/model/JpaActionStatus.java | 4 +- .../repository/jpa/model/JpaTarget.java | 4 +- .../repository/jpa/model/JpaTargetInfo.java | 4 +- .../repository/jpa/rsql/RSQLUtility.java | 24 ++-- .../util/RestResourceConversionHelper.java | 88 +++++++------- .../eclipse/hawkbit/security/DosFilter.java | 4 +- .../java/org/eclipse/hawkbit/util/IpUtil.java | 26 +++-- .../org/eclipse/hawkbit/util/IpUtilTest.java | 56 +++++---- .../smtable/SoftwareModuleTable.java | 25 ++-- ...dow.java => UploadConfirmationWindow.java} | 59 ++++------ .../ui/artifacts/upload/UploadLayout.java | 6 +- .../upload/UploadStatusInfoWindow.java | 79 ++++++------- .../hawkbit/ui/common/CoordinatesToColor.java | 29 ++--- .../DistributionSetMetadatadetailslayout.java | 110 +++++++++--------- .../filterlayout/AbstractFilterButtons.java | 36 +++--- .../ui/components/SPUIComponentProvider.java | 41 +++---- .../client/RolloutRendererConnector.java | 17 +-- .../client/renderers/RolloutRendererData.java | 66 +++++------ .../renderers/RolloutRenderer.java | 68 ++++++----- .../ui/decorators/SPUIWindowDecorator.java | 59 +++++----- .../disttype/DSTypeFilterButtons.java | 1 - .../smtable/SwMetadataPopupLayout.java | 44 +++---- .../smtype/DistSMTypeFilterButtons.java | 28 +++-- .../state/ManageDistUIState.java | 26 +++-- .../AbstractCreateUpdateTagLayout.java | 6 +- ...eateUpdateDistributionTagLayoutWindow.java | 8 +- .../dstag/DistributionTagButtons.java | 2 +- .../targettable/BulkUploadHandler.java | 26 ++--- .../targettag/TargetTagFilterButtons.java | 2 +- .../hawkbit/ui/menu/DashboardMenu.java | 54 +++++---- .../ui/rollout/DistributionBarHelper.java | 47 ++++---- .../rollout/AddUpdateRolloutWindowLayout.java | 14 +-- .../rolloutgroup/RolloutGroupListGrid.java | 24 ++-- .../AuthenticationConfigurationView.java | 8 +- .../hawkbit/ui/utils/HawkbitCommonUtil.java | 12 +- .../hawkbit/ui/utils/SPUIDefinitions.java | 10 +- 50 files changed, 639 insertions(+), 696 deletions(-) rename hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/{UploadConfirmationwindow.java => UploadConfirmationWindow.java} (95%) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java index 9c4c43ad2..01a9231e3 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java @@ -8,9 +8,12 @@ */ package org.eclipse.hawkbit.simulator; +import static java.util.concurrent.Executors.newScheduledThreadPool; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.security.DigestOutputStream; import java.security.KeyManagementException; import java.security.KeyStoreException; @@ -20,7 +23,6 @@ import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; import java.util.Random; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -56,9 +58,10 @@ import com.google.common.io.ByteStreams; */ @Service public class DeviceSimulatorUpdater { + private static final Logger LOGGER = LoggerFactory.getLogger(DeviceSimulatorUpdater.class); - private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(8); + private static final ScheduledExecutorService threadPool = newScheduledThreadPool(8); @Autowired private SpSenderService spSenderService; @@ -118,14 +121,9 @@ public class DeviceSimulatorUpdater { } private static final class DeviceSimulatorUpdateThread implements Runnable { - /** - * - */ + private static final String BUT_GOT_LOG_MESSAGE = " but got: "; - /** - * - */ private static final String DOWNLOAD_LOG_MESSAGE = "Download "; private static final int MINIMUM_TOKENLENGTH_FOR_HINT = 6; @@ -279,13 +277,17 @@ public class DeviceSimulatorUpdater { private static long getOverallRead(final CloseableHttpResponse response, final MessageDigest md) throws IOException { + long overallread; - try (final BufferedOutputStream bdos = new BufferedOutputStream( - new DigestOutputStream(ByteStreams.nullOutputStream(), md))) { + + try (final OutputStream os = ByteStreams.nullOutputStream(); + final BufferedOutputStream bos = new BufferedOutputStream(new DigestOutputStream(os, md))) { + try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) { - overallread = ByteStreams.copy(bis, bdos); + overallread = ByteStreams.copy(bis, bos); } } + return overallread; } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java index 574ce61e2..841f6d7e6 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java @@ -16,7 +16,6 @@ import java.util.Map; * An interface for declaring the name of the field described in the database * which is used as string representation of the field, e.g. for sorting the * fields over REST. - * */ public interface FieldNameProvider { /** @@ -32,64 +31,18 @@ public interface FieldNameProvider { /** * Contains the sub entity the given field. - * + * * @param propertyField * the given field * @return contains contains not */ default boolean containsSubEntityAttribute(final String propertyField) { - return FieldNameProvider.containsSubEntityAttribute(propertyField, getSubEntityAttributes()); - } - /** - * - * @return all sub entities attributes. - */ - default List getSubEntityAttributes() { - return Collections.emptyList(); - } - - /** - * the database column for the key - * - * @return key fieldname - */ - default String getKeyFieldName() { - return null; - } - - /** - * the database column for the value - * - * @return key fieldname - */ - default String getValueFieldName() { - return null; - } - - /** - * Is the entity field a {@link Map}. - * - * @return is a map is not a map - */ - default boolean isMap() { - return getKeyFieldName() != null; - } - - /** - * Check if a sub attribute exists. - * - * @param propertyField - * the sub property field. - * @param subEntityAttribues - * the list of available properties - * @return property exists not exists - */ - static boolean containsSubEntityAttribute(final String propertyField, final List subEntityAttribues) { - if (subEntityAttribues.contains(propertyField)) { + final List subEntityAttributes = getSubEntityAttributes(); + if (subEntityAttributes.contains(propertyField)) { return true; } - for (final String attribute : subEntityAttribues) { + for (final String attribute : subEntityAttributes) { final String[] graph = attribute.split("\\" + SUB_ATTRIBUTE_SEPERATOR); for (final String subAttribute : graph) { @@ -102,4 +55,38 @@ public interface FieldNameProvider { return false; } + /** + * + * @return all sub entities attributes. + */ + default List getSubEntityAttributes() { + return Collections.emptyList(); + } + + /** + * the database column for the key + * + * @return key fieldname + */ + default String getKeyFieldName() { + return null; + } + + /** + * the database column for the value + * + * @return key fieldname + */ + default String getValueFieldName() { + return null; + } + + /** + * Is the entity field a {@link Map}. + * + * @return is a map is not a map + */ + default boolean isMap() { + return getKeyFieldName() != null; + } } diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetAttributes.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetAttributes.java index dad8e868f..ea01b87ca 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetAttributes.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetAttributes.java @@ -8,8 +8,9 @@ import java.util.Map; /** * {@link Map} with attributes of SP Target. - * */ public class MgmtTargetAttributes extends HashMap { + private static final long serialVersionUID = 1L; + } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/AbstractPropertyChangeEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/AbstractPropertyChangeEvent.java index 97cf13b66..2520ebc9c 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/AbstractPropertyChangeEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/AbstractPropertyChangeEvent.java @@ -20,18 +20,18 @@ import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; public class AbstractPropertyChangeEvent extends AbstractBaseEntityEvent { private static final long serialVersionUID = -3671601415138242311L; - private final transient Map changeSet; + private final transient Map changeSet; /** * Initialize base entity and property changed with old and new value. - * + * * @param baseEntity * entity changed * @param changeSetValues * details of properties changed and old value and new value of * the changed properties */ - public AbstractPropertyChangeEvent(final E baseEntity, final Map changeSetValues) { + public AbstractPropertyChangeEvent(final E baseEntity, final Map changeSetValues) { super(baseEntity); this.changeSet = changeSetValues; } @@ -39,27 +39,27 @@ public class AbstractPropertyChangeEvent extend /** * @return the changeSet */ - public Map getChangeSet() { + public Map getChangeSet() { return changeSet; } /** * Carries old value and new value of a property . - * */ - public class Values { + public static class PropertyChange { + private final Object oldValue; private final Object newValue; /** * Initialize old value and new changes value of property. - * + * * @param oldValue * old value before change * @param newValue * new value after change */ - public Values(final Object oldValue, final Object newValue) { + public PropertyChange(final Object oldValue, final Object newValue) { super(); this.oldValue = oldValue; this.newValue = newValue; @@ -78,6 +78,5 @@ public class AbstractPropertyChangeEvent extend public Object getNewValue() { return newValue; } - } } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/ActionPropertyChangeEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/ActionPropertyChangeEvent.java index 84487547e..5197bd9a0 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/ActionPropertyChangeEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/ActionPropertyChangeEvent.java @@ -22,8 +22,7 @@ public class ActionPropertyChangeEvent extends AbstractPropertyChangeEvent.Values> changeSetValues) { + public ActionPropertyChangeEvent(final Action action, final Map changeSetValues) { super(action, changeSetValues); } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutGroupPropertyChangeEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutGroupPropertyChangeEvent.java index 887a1c2ff..b0b31b79a 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutGroupPropertyChangeEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutGroupPropertyChangeEvent.java @@ -20,12 +20,12 @@ public class RolloutGroupPropertyChangeEvent extends AbstractPropertyChangeEvent private static final long serialVersionUID = 4026477044419472686L; /** - * + * * @param rolloutGroup * @param changeSetValues */ public RolloutGroupPropertyChangeEvent(final RolloutGroup rolloutGroup, - final Map.Values> changeSetValues) { + final Map changeSetValues) { super(rolloutGroup, changeSetValues); } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutPropertyChangeEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutPropertyChangeEvent.java index 9287a0fb3..9bb975c3a 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutPropertyChangeEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutPropertyChangeEvent.java @@ -19,12 +19,11 @@ public class RolloutPropertyChangeEvent extends AbstractPropertyChangeEvent.Values> changeSetValues) { + public RolloutPropertyChangeEvent(final Rollout rollout, final Map changeSetValues) { super(rollout, changeSetValues); } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/AbstractReportSeries.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/AbstractReportSeries.java index 747cd8279..9ba5ba2da 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/AbstractReportSeries.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/AbstractReportSeries.java @@ -12,16 +12,9 @@ import java.io.Serializable; /** * An abstract report series. - * - * - * - * */ public class AbstractReportSeries implements Serializable { - /** - * - */ private static final long serialVersionUID = 1L; private final String name; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/ListReportSeries.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/ListReportSeries.java index 18b011420..27f5fb3ec 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/ListReportSeries.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/report/model/ListReportSeries.java @@ -14,13 +14,11 @@ import java.util.List; /** * A simple list report series which just contains a list of values of a report. - * - * - * - * */ public class ListReportSeries extends AbstractReportSeries { + private static final long serialVersionUID = 1L; + private final List data = new ArrayList<>(); /** @@ -50,8 +48,8 @@ public class ListReportSeries extends AbstractReportSeries { * @param values */ private void setData(final Number... values) { - this.data.clear(); - Collections.addAll(this.data, values); + data.clear(); + Collections.addAll(data, values); } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java index 6236e8d6f..5a2c6fdda 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java @@ -82,7 +82,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -599,11 +598,16 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Override public Page findActionsByTarget(final String rsqlParam, final Target target, final Pageable pageable) { - final Specification specification = RSQLUtility.parse(rsqlParam, ActionFields.class); - return convertAcPage(actionRepository.findAll((Specification) (root, query, cb) -> cb - .and(specification.toPredicate(root, query, cb), cb.equal(root.get(JpaAction_.target), target)), - pageable), pageable); + final Specification byTargetSpec = createSpecificationFor(target, rsqlParam); + final Page actions = actionRepository.findAll(byTargetSpec, pageable); + return convertAcPage(actions, pageable); + } + + private Specification createSpecificationFor(final Target target, final String rsqlParam) { + final Specification spec = RSQLUtility.parse(rsqlParam, ActionFields.class); + return (root, query, cb) -> cb.and(spec.toPredicate(root, query, cb), + cb.equal(root.get(JpaAction_.target), target)); } private static Page convertAcPage(final Page findAll, final Pageable pageable) { @@ -642,10 +646,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Override public Long countActionsByTarget(final String rsqlParam, final Target target) { - final Specification spec = RSQLUtility.parse(rsqlParam, ActionFields.class); - - return actionRepository.count((root, query, cb) -> cb.and(spec.toPredicate(root, query, cb), - cb.equal(root.get(JpaAction_.target), target))); + return actionRepository.count(createSpecificationFor(target, rsqlParam)); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java index 239302a70..3a903ea89 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java @@ -599,7 +599,7 @@ public class JpaRolloutManagement implements RolloutManagement { /** * Get count of targets in different status in rollout. * - * @param page + * @param pageable * the page request to sort and limit the result * @return a list of rollouts with details of targets count for different * statuses diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java index 65ed6faa4..6438e19f6 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java @@ -26,7 +26,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specifications; import org.springframework.data.jpa.repository.Modifying; -import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/aspects/ExceptionMappingAspectHandler.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/aspects/ExceptionMappingAspectHandler.java index be21cdfe7..c18f614fd 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/aspects/ExceptionMappingAspectHandler.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/aspects/ExceptionMappingAspectHandler.java @@ -46,6 +46,7 @@ import org.springframework.transaction.TransactionSystemException; */ @Aspect public class ExceptionMappingAspectHandler implements Ordered { + private static final Logger LOG = LoggerFactory.getLogger(ExceptionMappingAspectHandler.class); private static final Map EXCEPTION_MAPPING = new HashMap<>(); @@ -63,6 +64,7 @@ public class ExceptionMappingAspectHandler implements Ordered { 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); @@ -90,9 +92,11 @@ public class ExceptionMappingAspectHandler implements Ordered { + " || execution( * org.eclipse.hawkbit.controller.*.*(..)) " + " || execution( * org.eclipse.hawkbit.rest.resource.*.*(..)) " + " || execution( * org.eclipse.hawkbit.service.*.*(..)) )", throwing = "ex") - // Exception squid:S00112 - Is aspectJ proxy - @SuppressWarnings({ "squid:S00112" }) + // Exception for squid:S00112, squid:S1162 + // It is a AspectJ proxy which deals with exceptions. + @SuppressWarnings({ "squid:S00112", "squid:S1162" }) public void catchAndWrapJpaExceptionsService(final Exception ex) throws Throwable { + LOG.trace("exception occured", ex); Exception translatedAccessException = translateEclipseLinkExceptionIfPossible(ex); @@ -122,6 +126,7 @@ public class ExceptionMappingAspectHandler implements Ordered { break; } } + LOG.trace("mapped exception {} to {}", translatedAccessException.getClass(), mappingException.getClass()); throw mappingException; } @@ -138,7 +143,7 @@ public class ExceptionMappingAspectHandler implements Ordered { * 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 diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java index 2dd0fdb40..6b1385440 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java @@ -11,7 +11,7 @@ package org.eclipse.hawkbit.repository.jpa.model; import java.util.Map; import java.util.stream.Collectors; -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent.PropertyChange; import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; @@ -33,7 +33,6 @@ import com.google.common.eventbus.EventBus; /** * Listens to change in property values of an entity. - * */ public class EntityPropertyChangeListener extends DescriptorEventAdapter { @@ -53,27 +52,23 @@ public class EntityPropertyChangeListener extends DescriptorEventAdapter { @Override public void postUpdate(final DescriptorEvent event) { if (event.getObject().getClass().equals(JpaAction.class)) { - getAfterTransactionCommmitExecutor().afterCommit(() -> getEventBus().post( - new ActionPropertyChangeEvent((Action) event.getObject(), getChangeSet(Action.class, event)))); + getAfterTransactionCommmitExecutor().afterCommit(() -> getEventBus() + .post(new ActionPropertyChangeEvent((Action) event.getObject(), getChangeSet(event)))); } else if (event.getObject().getClass().equals(JpaRollout.class)) { - getAfterTransactionCommmitExecutor().afterCommit(() -> getEventBus().post( - new RolloutPropertyChangeEvent((Rollout) event.getObject(), getChangeSet(Rollout.class, event)))); + getAfterTransactionCommmitExecutor().afterCommit(() -> getEventBus() + .post(new RolloutPropertyChangeEvent((Rollout) event.getObject(), getChangeSet(event)))); } else if (event.getObject().getClass().equals(JpaRolloutGroup.class)) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new RolloutGroupPropertyChangeEvent((RolloutGroup) event.getObject(), - getChangeSet(RolloutGroup.class, event)))); + getAfterTransactionCommmitExecutor().afterCommit(() -> getEventBus() + .post(new RolloutGroupPropertyChangeEvent((RolloutGroup) event.getObject(), getChangeSet(event)))); } } - private Map.Values> getChangeSet( - final Class clazz, final DescriptorEvent event) { - final T rolloutGroup = clazz.cast(event.getObject()); + private Map getChangeSet(final DescriptorEvent event) { final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet(); return changeSet.getChanges().stream().filter(record -> record instanceof DirectToFieldChangeRecord) .map(record -> (DirectToFieldChangeRecord) record) .collect(Collectors.toMap(record -> record.getAttribute(), - record -> new AbstractPropertyChangeEvent(rolloutGroup, null).new Values( - record.getOldValue(), record.getNewValue()))); + record -> new PropertyChange(record.getOldValue(), record.getNewValue()))); } private AfterTransactionCommitExecutor getAfterTransactionCommmitExecutor() { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java index 3a8cb8683..e1843eb33 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaActionStatus.java @@ -98,8 +98,8 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements * the status for this action status * @param occurredAt * the occurred timestamp - * @param messages - * the messages which should be added to this action status + * @param message + * the message which should be added to this action status */ public JpaActionStatus(final JpaAction action, final Status status, final Long occurredAt, final String message) { this.action = action; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index 183405470..233e89664 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -65,6 +65,7 @@ import org.springframework.data.domain.Persistable; // sub entities @SuppressWarnings("squid:S2160") public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target { + private static final long serialVersionUID = 1L; @Column(name = "controller_id", length = 64) @@ -180,7 +181,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, TargetInfo { private boolean requestControllerAttributes = true; /** - * Constructor for {@link TargetStatus}. + * Constructor for {@link JpaTargetInfo}. * * @param target * related to this status. @@ -144,7 +144,7 @@ public class JpaTargetInfo implements Persistable, TargetInfo { } /** - * @param isNew + * @param entityNew * the isNew to set */ public void setNew(final boolean entityNew) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java index 91e03342e..90dd039f5 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.repository.jpa.rsql; +import static org.eclipse.hawkbit.repository.FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -15,7 +17,6 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; @@ -49,7 +50,7 @@ import cz.jirutka.rsql.parser.ast.RSQLVisitor; * A utility class which is able to parse RSQL strings into an spring data * {@link Specification} which then can be enhanced sql queries to filter * entities. RSQL parser library: https://github.com/jirutka/rsql-parser - * + * *
    *
  • Equal to : ==
  • *
  • Not equal to : !=
  • @@ -83,14 +84,12 @@ public final class RSQLUtility { /** * parses an RSQL valid string into an JPA {@link Specification} which then * can be used to filter for JPA entities with the given RSQL query. - * + * * @param rsql * the rsql query * @param fieldNameProvider * the enum class type which implements the * {@link FieldNameProvider} - * @param entityManager - * {@link EntityManager} * @return an specification which can be used with JPA * @throws RSQLParameterUnsupportedFieldException * if a field in the RSQL string is used but not provided by the @@ -105,10 +104,10 @@ public final class RSQLUtility { /** * Validate the given rsql string regarding existence and correct syntax. - * + * * @param rsql * the rsql string to get validated - * + * */ public static void isValid(final String rsql) { parseRsql(rsql); @@ -156,7 +155,7 @@ public final class RSQLUtility { /** * An implementation of the {@link RSQLVisitor} to visit the parsed tokens * and build jpa where clauses. - * + * * * * @param @@ -205,7 +204,7 @@ public final class RSQLUtility { } private String getAndValidatePropertyFieldName(final A propertyEnum, final ComparisonNode node) { - String finalProperty = propertyEnum.getFieldName(); + final String[] graph = node.getSelector().split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR); validateMapParamter(propertyEnum, node, graph); @@ -215,9 +214,12 @@ public final class RSQLUtility { throw createRSQLParameterUnsupportedException(node); } + final StringBuilder fieldNameBuilder = new StringBuilder(propertyEnum.getFieldName()); + for (int i = 1; i < graph.length; i++) { + final String propertyField = graph[i]; - finalProperty += FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR + propertyField; + fieldNameBuilder.append(SUB_ATTRIBUTE_SEPERATOR).append(propertyField); // the key of map is not in the graph if (propertyEnum.isMap() && graph.length == (i + 1)) { @@ -229,7 +231,7 @@ public final class RSQLUtility { } } - return finalProperty; + return fieldNameBuilder.toString(); } private void validateMapParamter(final A propertyEnum, final ComparisonNode node, final String[] graph) { diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java index 0c9dd39c5..7e2fbed7c 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/RestResourceConversionHelper.java @@ -9,11 +9,24 @@ package org.eclipse.hawkbit.rest.util; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.net.HttpHeaders.ACCEPT_RANGES; +import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION; +import static com.google.common.net.HttpHeaders.CONTENT_LENGTH; +import static com.google.common.net.HttpHeaders.CONTENT_RANGE; +import static com.google.common.net.HttpHeaders.ETAG; +import static com.google.common.net.HttpHeaders.IF_RANGE; +import static com.google.common.net.HttpHeaders.LAST_MODIFIED; +import static java.math.RoundingMode.DOWN; +import static javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT; +import static org.eclipse.hawkbit.rest.util.ByteRange.MULTIPART_BOUNDARY; +import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.HttpStatus.PARTIAL_CONTENT; +import static org.springframework.http.HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.math.RoundingMode; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -27,23 +40,19 @@ import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import com.google.common.math.DoubleMath; -import com.google.common.net.HttpHeaders; /** * Utility class for the Rest Source API. - * */ public final class RestResourceConversionHelper { + private static final Logger LOG = LoggerFactory.getLogger(RestResourceConversionHelper.class); private static final int BUFFER_SIZE = 4096; - // utility class, private constructor. private RestResourceConversionHelper() { } @@ -92,7 +101,8 @@ public final class RestResourceConversionHelper { * * @return http code * - * @see https://tools.ietf.org/html/rfc7233 + * @see https://tools.ietf.org + * /html/rfc7233 */ public static ResponseEntity writeFileResponse(final LocalArtifact artifact, final HttpServletResponse response, final HttpServletRequest request, final DbArtifact file, @@ -107,11 +117,11 @@ public final class RestResourceConversionHelper { response.reset(); response.setBufferSize(BUFFER_SIZE); - response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + artifact.getFilename()); - response.setHeader(HttpHeaders.ETAG, etag); - response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes"); - response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModified); - response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + response.setHeader(CONTENT_DISPOSITION, "attachment;filename=" + artifact.getFilename()); + response.setHeader(ETAG, etag); + response.setHeader(ACCEPT_RANGES, "bytes"); + response.setDateHeader(LAST_MODIFIED, lastModified); + response.setContentType(APPLICATION_OCTET_STREAM_VALUE); final ByteRange full = new ByteRange(0, length - 1, length); final List ranges = new ArrayList<>(); @@ -123,9 +133,9 @@ public final class RestResourceConversionHelper { // Range header matches"bytes=n-n,n-n,n-n..." if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) { - response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + length); + response.setHeader(CONTENT_RANGE, "bytes */" + length); LOG.debug("range header for filename ({}) is not satisfiable: ", artifact.getFilename()); - return new ResponseEntity<>(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE); + return new ResponseEntity<>(REQUESTED_RANGE_NOT_SATISFIABLE); } // RFC: if the representation is unchanged, send me the part(s) that @@ -144,32 +154,31 @@ public final class RestResourceConversionHelper { // full request - no range if (ranges.isEmpty() || ranges.get(0).equals(full)) { LOG.debug("filename ({}) results into a full request: ", artifact.getFilename()); - fullfileRequest(artifact, response, file, controllerManagement, statusId, full); - result = new ResponseEntity<>(HttpStatus.OK); + handleFullFileRequest(artifact, response, file, controllerManagement, statusId, full); + result = new ResponseEntity<>(OK); } // standard range request else if (ranges.size() == 1) { LOG.debug("filename ({}) results into a standard range request: ", artifact.getFilename()); - standardRangeRequest(artifact, response, file, controllerManagement, statusId, ranges); - result = new ResponseEntity<>(HttpStatus.PARTIAL_CONTENT); + handleStandardRangeRequest(artifact, response, file, controllerManagement, statusId, ranges); + result = new ResponseEntity<>(PARTIAL_CONTENT); } // multipart range request else { LOG.debug("filename ({}) results into a multipart range request: ", artifact.getFilename()); - multipartRangeRequest(artifact, response, file, controllerManagement, statusId, ranges); - result = new ResponseEntity<>(HttpStatus.PARTIAL_CONTENT); + handleMultipartRangeRequest(artifact, response, file, controllerManagement, statusId, ranges); + result = new ResponseEntity<>(PARTIAL_CONTENT); } return result; - } - private static void fullfileRequest(final LocalArtifact artifact, final HttpServletResponse response, + private static void handleFullFileRequest(final LocalArtifact artifact, final HttpServletResponse response, final DbArtifact file, final ControllerManagement controllerManagement, final Long statusId, final ByteRange full) { final ByteRange r = full; - response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal()); - response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(r.getLength())); + response.setHeader(CONTENT_RANGE, "bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal()); + response.setHeader(CONTENT_LENGTH, String.valueOf(r.getLength())); try { copyStreams(file.getFileInputStream(), response.getOutputStream(), controllerManagement, statusId, @@ -182,7 +191,7 @@ public final class RestResourceConversionHelper { private static ResponseEntity extractRange(final HttpServletResponse response, final long length, final List ranges, final String range) { - ResponseEntity result = null; + if (ranges.isEmpty()) { for (final String part : range.substring(6).split(",")) { long start = sublong(part, 0, part.indexOf('-')); @@ -198,9 +207,8 @@ public final class RestResourceConversionHelper { // Check if Range is syntactically valid. If not, then return // 416. if (start > end) { - response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + length); - result = new ResponseEntity<>(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE); - return result; + response.setHeader(CONTENT_RANGE, "bytes */" + length); + return new ResponseEntity<>(REQUESTED_RANGE_NOT_SATISFIABLE); } // Add range. @@ -218,10 +226,10 @@ public final class RestResourceConversionHelper { private static void checkForShortcut(final HttpServletRequest request, final String etag, final long lastModified, final ByteRange full, final List ranges) { - final String ifRange = request.getHeader(HttpHeaders.IF_RANGE); + final String ifRange = request.getHeader(IF_RANGE); if (ifRange != null && !ifRange.equals(etag)) { try { - final long ifRangeTime = request.getDateHeader(HttpHeaders.IF_RANGE); + final long ifRangeTime = request.getDateHeader(IF_RANGE); if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) { ranges.add(full); } @@ -232,17 +240,17 @@ public final class RestResourceConversionHelper { } } - private static void multipartRangeRequest(final LocalArtifact artifact, final HttpServletResponse response, + private static void handleMultipartRangeRequest(final LocalArtifact artifact, final HttpServletResponse response, final DbArtifact file, final ControllerManagement controllerManagement, final Long statusId, final List ranges) { - response.setContentType("multipart/byteranges; boundary=" + ByteRange.MULTIPART_BOUNDARY); - response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); + response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY); + response.setStatus(SC_PARTIAL_CONTENT); try { for (final ByteRange r : ranges) { // Add multipart boundary and header fields for every range. response.getOutputStream().println(); - response.getOutputStream().println("--" + ByteRange.MULTIPART_BOUNDARY); + response.getOutputStream().println("--" + MULTIPART_BOUNDARY); response.getOutputStream() .println("Content-Range: bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal()); @@ -253,20 +261,20 @@ public final class RestResourceConversionHelper { // End with final multipart boundary. response.getOutputStream().println(); - response.getOutputStream().print("--" + ByteRange.MULTIPART_BOUNDARY + "--"); + response.getOutputStream().print("--" + MULTIPART_BOUNDARY + "--"); } catch (final IOException e) { LOG.error("multipartRangeRequest of file ({}) failed!", artifact.getFilename(), e); throw new FileSteamingFailedException(artifact.getFilename()); } } - private static void standardRangeRequest(final LocalArtifact artifact, final HttpServletResponse response, + private static void handleStandardRangeRequest(final LocalArtifact artifact, final HttpServletResponse response, final DbArtifact file, final ControllerManagement controllerManagement, final Long statusId, final List ranges) { final ByteRange r = ranges.get(0); - response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal()); - response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(r.getLength())); - response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); + response.setHeader(CONTENT_RANGE, "bytes " + r.getStart() + "-" + r.getEnd() + "/" + r.getTotal()); + response.setHeader(CONTENT_LENGTH, String.valueOf(r.getLength())); + response.setStatus(SC_PARTIAL_CONTENT); try { copyStreams(file.getFileInputStream(), response.getOutputStream(), controllerManagement, statusId, @@ -315,7 +323,7 @@ public final class RestResourceConversionHelper { } if (controllerManagement != null) { - final int newPercent = DoubleMath.roundToInt(total * 100.0 / length, RoundingMode.DOWN); + final int newPercent = DoubleMath.roundToInt(total * 100.0 / length, DOWN); // every 10 percent an event if (newPercent == 100 || newPercent > progressPercent + 10) { diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DosFilter.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DosFilter.java index 008aa3e95..89d0f4387 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DosFilter.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DosFilter.java @@ -100,7 +100,8 @@ public class DosFilter extends OncePerRequestFilter { boolean processChain; - final String ip = IpUtil.getClientIpFromRequest(request, forwardHeader, true).getHost(); + final String ip = IpUtil.getClientIpFromRequest(request, forwardHeader).getHost(); + if (checkIpFails(ip)) { processChain = handleMissingIpAddress(response); } else { @@ -121,7 +122,6 @@ public class DosFilter extends OncePerRequestFilter { if (processChain) { filterChain.doFilter(request, response); } - } /** diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/util/IpUtil.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/util/IpUtil.java index c7778f776..30306526a 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/util/IpUtil.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/util/IpUtil.java @@ -44,7 +44,7 @@ public final class IpUtil { * {@link HttpServletRequest} by either the * {@link HttpHeaders#X_FORWARDED_FOR} or by the * {@link HttpServletRequest#getRemoteAddr()} methods. - * + * * @param request * the {@link HttpServletRequest} to determine the IP address * where this request has been sent from @@ -65,21 +65,23 @@ public final class IpUtil { * {@link HttpServletRequest} by either the * {@link HttpHeaders#X_FORWARDED_FOR} or by the * {@link HttpServletRequest#getRemoteAddr()} methods. - * + * * @param request * the {@link HttpServletRequest} to determine the IP address * where this request has been sent from * @param forwardHeader * the header name containing the IP address e.g. forwarded by a * proxy {@code x-forwarded-for} - * - * @param trackRemoteIp - * to true if remote IP should be tracked. * @return the {@link URI} based IP address from the client which sent the * request */ - public static URI getClientIpFromRequest(final HttpServletRequest request, final String forwardHeader, + public static URI getClientIpFromRequest(final HttpServletRequest request, final String forwardHeader) { + return getClientIpFromRequest(request, forwardHeader, true); + } + + private static URI getClientIpFromRequest(final HttpServletRequest request, final String forwardHeader, final boolean trackRemoteIp) { + String ip; if (trackRemoteIp) { @@ -113,7 +115,7 @@ public final class IpUtil { /** * Create a {@link URI} with scheme and host. - * + * * @param scheme * the scheme * @param host @@ -132,7 +134,7 @@ public final class IpUtil { /** * Create a {@link URI} with amqp scheme and host. - * + * * @param host * the host * @param exchange @@ -147,7 +149,7 @@ public final class IpUtil { /** * Create a {@link URI} with http scheme and host. - * + * * @param host * the host * @return the {@link URI} @@ -160,7 +162,7 @@ public final class IpUtil { /** * Check if scheme contains http and uri ist not null. - * + * * @param uri * the uri * @return true = is http host false = not @@ -171,7 +173,7 @@ public final class IpUtil { /** * Check if host scheme amqp and uri ist not null. - * + * * @param uri * the uri * @return true = is http host false = not @@ -183,7 +185,7 @@ public final class IpUtil { /** * Check if the IP address of that {@link URI} is known, i.e. not an AQMP * exchange in DMF case and not HIDDEN_IP in DDI case. - * + * * @param uri * the uri * @return true if IP address is actually known by the server diff --git a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/util/IpUtilTest.java b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/util/IpUtilTest.java index 0f4a01d26..836a9f13e 100644 --- a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/util/IpUtilTest.java +++ b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/util/IpUtilTest.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.util; +import static com.google.common.net.HttpHeaders.X_FORWARDED_FOR; import static org.fest.assertions.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -21,13 +22,13 @@ import java.net.URI; import javax.servlet.http.HttpServletRequest; +import org.eclipse.hawkbit.security.HawkbitSecurityProperties; +import org.eclipse.hawkbit.security.HawkbitSecurityProperties.Clients; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import com.google.common.net.HttpHeaders; - import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Features; import ru.yandex.qatools.allure.annotations.Stories; @@ -37,69 +38,73 @@ import ru.yandex.qatools.allure.annotations.Stories; @Stories("IP Util Test") public class IpUtilTest { + private static final String KNOWN_REQUEST_HEADER = "bumlux"; + @Mock private HttpServletRequest requestMock; + @Mock + private Clients clientMock; + + @Mock + private HawkbitSecurityProperties securityPropertyMock; + @Test @Description("Tests create uri from request") public void getRemoteAddrFromRequestIfForwaredHeaderNotPresent() { - // known values + final URI knownRemoteClientIP = IpUtil.createHttpUri("127.0.0.1"); - // mock - when(requestMock.getHeader(HttpHeaders.X_FORWARDED_FOR)).thenReturn(null); + when(requestMock.getHeader(X_FORWARDED_FOR)).thenReturn(null); when(requestMock.getRemoteAddr()).thenReturn(knownRemoteClientIP.getHost()); - // test - final URI remoteAddr = IpUtil.getClientIpFromRequest(requestMock, "bumlux", true); + final URI remoteAddr = IpUtil.getClientIpFromRequest(requestMock, KNOWN_REQUEST_HEADER); // verify assertThat(remoteAddr).as("The remote address should be as the known client IP address") .isEqualTo(knownRemoteClientIP); - verify(requestMock, times(1)).getHeader("bumlux"); + verify(requestMock, times(1)).getHeader(KNOWN_REQUEST_HEADER); verify(requestMock, times(1)).getRemoteAddr(); } @Test @Description("Tests create uri from request with masked IP when IP tracking is disabled") public void maskRemoteAddrIfDisabled() { - // known values + final URI knownRemoteClientIP = IpUtil.createHttpUri("***"); - // mock - when(requestMock.getHeader(HttpHeaders.X_FORWARDED_FOR)).thenReturn(null); + when(requestMock.getHeader(X_FORWARDED_FOR)).thenReturn(null); when(requestMock.getRemoteAddr()).thenReturn(knownRemoteClientIP.getHost()); + when(securityPropertyMock.getClients()).thenReturn(clientMock); + when(clientMock.getRemoteIpHeader()).thenReturn(KNOWN_REQUEST_HEADER); + when(clientMock.isTrackRemoteIp()).thenReturn(false); - // test - final URI remoteAddr = IpUtil.getClientIpFromRequest(requestMock, "bumlux", false); + final URI remoteAddr = IpUtil.getClientIpFromRequest(requestMock, securityPropertyMock); - // verify assertThat(remoteAddr).as("The remote address should be as the known client IP address") .isEqualTo(knownRemoteClientIP); - verify(requestMock, times(0)).getHeader("bumlux"); + verify(requestMock, times(0)).getHeader(KNOWN_REQUEST_HEADER); verify(requestMock, times(0)).getRemoteAddr(); } @Test @Description("Tests create uri from x forward header") public void getRemoteAddrFromXForwardedForHeader() { - // known values + final URI knownRemoteClientIP = IpUtil.createHttpUri("10.99.99.1"); - // mock - when(requestMock.getHeader(HttpHeaders.X_FORWARDED_FOR)).thenReturn(knownRemoteClientIP.getHost()); + when(requestMock.getHeader(X_FORWARDED_FOR)).thenReturn(knownRemoteClientIP.getHost()); when(requestMock.getRemoteAddr()).thenReturn(null); - // test - final URI remoteAddr = IpUtil.getClientIpFromRequest(requestMock, "X-Forwarded-For", true); + final URI remoteAddr = IpUtil.getClientIpFromRequest(requestMock, "X-Forwarded-For"); - // verify assertThat(remoteAddr).as("The remote address should be as the known client IP address") .isEqualTo(knownRemoteClientIP); - verify(requestMock, times(1)).getHeader(HttpHeaders.X_FORWARDED_FOR); + verify(requestMock, times(1)).getHeader(X_FORWARDED_FOR); verify(requestMock, times(0)).getRemoteAddr(); } @Test @Description("Tests create http uri ipv4 and ipv6") public void testCreateHttpUri() { + final String ipv4 = "10.99.99.1"; URI httpUri = IpUtil.createHttpUri(ipv4); assertHttpUri(ipv4, httpUri); @@ -111,7 +116,6 @@ public class IpUtilTest { final String ipv6 = "0:0:0:0:0:0:0:1"; httpUri = IpUtil.createHttpUri(ipv6); assertHttpUri("[" + ipv6 + "]", httpUri); - } private void assertHttpUri(final String host, final URI httpUri) { @@ -124,6 +128,7 @@ public class IpUtilTest { @Test @Description("Tests create amqp uri ipv4 and ipv6") public void testCreateAmqpUri() { + final String ipv4 = "10.99.99.1"; URI amqpUri = IpUtil.createAmqpUri(ipv4, "path"); assertAmqpUri(ipv4, amqpUri); @@ -138,6 +143,7 @@ public class IpUtilTest { } private void assertAmqpUri(final String host, final URI amqpUri) { + assertTrue("The given URI is an AMQP scheme", IpUtil.isAmqpUri(amqpUri)); assertFalse("The given URI is not an HTTP scheme", IpUtil.isHttpUri(amqpUri)); assertEquals("The given host matches the URI host", host, amqpUri.getHost()); @@ -148,17 +154,19 @@ public class IpUtilTest { @Test @Description("Tests create invalid uri") public void testCreateInvalidUri() { + final String host = "10.99.99.1"; final URI testUri = IpUtil.createUri("test", host); + assertFalse("The given URI is not an AMQP address", IpUtil.isAmqpUri(testUri)); assertFalse("The given URI is not an HTTP address", IpUtil.isHttpUri(testUri)); assertEquals("The given host matches the URI host", host, testUri.getHost()); + try { IpUtil.createUri(":/", host); fail("Missing expected IllegalArgumentException due invalid URI"); } catch (final IllegalArgumentException e) { // expected } - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java index 1cfd28718..8ce3b8519 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java @@ -52,8 +52,8 @@ import com.vaadin.ui.UI; /** * Header of Software module table. */ -@SpringComponent @ViewScope +@SpringComponent public class SoftwareModuleTable extends AbstractNamedVersionTable { private static final long serialVersionUID = 6469417305487144809L; @@ -66,7 +66,7 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable refreshFilter()); + UI.getCurrent().access(this::refreshFilter); } } @@ -197,12 +197,12 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable showMetadataDetails((Long) itemId, nameVersionStr)); + manageMetaDataBtn.addClickListener(event -> showMetadataDetails((Long) itemId)); return manageMetaDataBtn; } }); } - + @Override protected List getTableVisibleColumns() { final List columnList = super.getTableVisibleColumns(); @@ -237,8 +237,7 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable updateProgress(event.getUploadStatus().getFileName(), event.getUploadStatus().getBytesRead(), - event.getUploadStatus().getContentLength(), event.getUploadStatus().getSoftwareModule())); + UI.getCurrent() + .access(() -> updateProgress(event.getUploadStatus().getFileName(), + event.getUploadStatus().getBytesRead(), event.getUploadStatus().getContentLength(), + event.getUploadStatus().getSoftwareModule())); } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STARTED) { UI.getCurrent().access(() -> onStartOfUpload(event)); } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FAILED) { - ui.access(() -> uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() - .getFailureReason(), event.getUploadStatus().getSoftwareModule())); + ui.access(() -> uploadFailed(event.getUploadStatus().getFileName(), + event.getUploadStatus().getFailureReason(), event.getUploadStatus().getSoftwareModule())); } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_SUCCESSFUL) { - UI.getCurrent().access( - () -> uploadSucceeded(event.getUploadStatus().getFileName(), event.getUploadStatus() - .getSoftwareModule())); + UI.getCurrent().access(() -> uploadSucceeded(event.getUploadStatus().getFileName(), + event.getUploadStatus().getSoftwareModule())); } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FINISHED) { - ui.access(() -> uploadSucceeded(event.getUploadStatus().getFileName(), event.getUploadStatus() - .getSoftwareModule())); + ui.access(() -> uploadSucceeded(event.getUploadStatus().getFileName(), + event.getUploadStatus().getSoftwareModule())); } } - private void onStartOfUpload(UploadStatusEvent event) { + private void onStartOfUpload(final UploadStatusEvent event) { uploadSessionStarted(); uploadStarted(event.getUploadStatus().getFileName(), event.getUploadStatus().getSoftwareModule()); } @@ -169,19 +169,19 @@ public class UploadStatusInfoWindow extends Window { } private void restoreState() { - Indexed container = grid.getContainerDataSource(); + final Indexed container = grid.getContainerDataSource(); if (container.getItemIds().isEmpty()) { container.removeAllItems(); - for (UploadStatusObject statusObject : artifactUploadState.getUploadedFileStatusList()) { - Item item = container.addItem(getItemid(statusObject.getFilename(), - statusObject.getSelectedSoftwareModule())); + for (final UploadStatusObject statusObject : artifactUploadState.getUploadedFileStatusList()) { + final Item item = container + .addItem(getItemid(statusObject.getFilename(), statusObject.getSelectedSoftwareModule())); item.getItemProperty(REASON).setValue(statusObject.getReason() != null ? statusObject.getReason() : ""); item.getItemProperty(STATUS).setValue(statusObject.getStatus()); item.getItemProperty(PROGRESS).setValue(statusObject.getProgress()); item.getItemProperty(FILE_NAME).setValue(statusObject.getFilename()); - SoftwareModule sw = statusObject.getSelectedSoftwareModule(); - item.getItemProperty(SPUILabelDefinitions.NAME_VERSION).setValue( - HawkbitCommonUtil.getFormattedNameVersion(sw.getName(), sw.getVersion())); + final SoftwareModule sw = statusObject.getSelectedSoftwareModule(); + item.getItemProperty(SPUILabelDefinitions.NAME_VERSION) + .setValue(HawkbitCommonUtil.getFormattedNameVersion(sw.getName(), sw.getVersion())); } if (artifactUploadState.isUploadCompleted()) { minimizeButton.setEnabled(false); @@ -209,7 +209,7 @@ public class UploadStatusInfoWindow extends Window { } private Grid createGrid() { - Grid statusGrid = new Grid(uploads); + final Grid statusGrid = new Grid(uploads); statusGrid.addStyleName(SPUIStyleDefinitions.UPLOAD_STATUS_GRID); statusGrid.setSelectionMode(SelectionMode.NONE); statusGrid.setHeaderVisible(true); @@ -219,7 +219,7 @@ public class UploadStatusInfoWindow extends Window { } private IndexedContainer getGridContainer() { - IndexedContainer uploadContainer = new IndexedContainer(); + final IndexedContainer uploadContainer = new IndexedContainer(); uploadContainer.addContainerProperty(STATUS, String.class, "Active"); uploadContainer.addContainerProperty(FILE_NAME, String.class, null); uploadContainer.addContainerProperty(PROGRESS, Double.class, 0D); @@ -329,7 +329,7 @@ public class UploadStatusInfoWindow extends Window { HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(), softwareModule.getVersion())); } grid.scrollToEnd(); - UploadStatusObject uploadStatus = new UploadStatusObject(filename, softwareModule); + final UploadStatusObject uploadStatus = new UploadStatusObject(filename, softwareModule); uploadStatus.setStatus("Active"); artifactUploadState.getUploadedFileStatusList().add(uploadStatus); } @@ -337,56 +337,53 @@ public class UploadStatusInfoWindow extends Window { void updateProgress(final String filename, final long readBytes, final long contentLength, final SoftwareModule softwareModule) { final Item item = uploads.getItem(getItemid(filename, softwareModule)); - double progress = (double) readBytes / (double) contentLength; + final double progress = (double) readBytes / (double) contentLength; if (item != null) { item.getItemProperty(PROGRESS).setValue(progress); } - List uploadStatusObjectList = (List) artifactUploadState - .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) - .collect(Collectors.toList()); + final List uploadStatusObjectList = artifactUploadState.getUploadedFileStatusList().stream() + .filter(e -> e.getFilename().equals(filename)).collect(Collectors.toList()); if (!uploadStatusObjectList.isEmpty()) { - UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); + final UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); uploadStatusObject.setProgress(progress); } } /** * Called when each file upload is success. - * + * * @param filename * of the uploaded file. * @param softwareModule * selected software module */ - public void uploadSucceeded(final String filename, SoftwareModule softwareModule) { + public void uploadSucceeded(final String filename, final SoftwareModule softwareModule) { final Item item = uploads.getItem(getItemid(filename, softwareModule)); - String status = "Finished"; + final String status = "Finished"; if (item != null) { item.getItemProperty(STATUS).setValue(status); } - List uploadStatusObjectList = (List) artifactUploadState - .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) - .collect(Collectors.toList()); + final List uploadStatusObjectList = artifactUploadState.getUploadedFileStatusList().stream() + .filter(e -> e.getFilename().equals(filename)).collect(Collectors.toList()); if (!uploadStatusObjectList.isEmpty()) { - UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); + final UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); uploadStatusObject.setStatus(status); uploadStatusObject.setProgress(1d); } } - void uploadFailed(final String filename, final String errorReason, SoftwareModule softwareModule) { + void uploadFailed(final String filename, final String errorReason, final SoftwareModule softwareModule) { errorOccured = true; - String status = "Failed"; + final String status = "Failed"; final Item item = uploads.getItem(getItemid(filename, softwareModule)); if (item != null) { item.getItemProperty(REASON).setValue(errorReason); item.getItemProperty(STATUS).setValue(status); } - List uploadStatusObjectList = (List) artifactUploadState - .getUploadedFileStatusList().stream().filter(e -> e.getFilename().equals(filename)) - .collect(Collectors.toList()); + final List uploadStatusObjectList = artifactUploadState.getUploadedFileStatusList().stream() + .filter(e -> e.getFilename().equals(filename)).collect(Collectors.toList()); if (!uploadStatusObjectList.isEmpty()) { - UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); + final UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); uploadStatusObject.setStatus(status); uploadStatusObject.setReason(errorReason); } @@ -428,8 +425,8 @@ public class UploadStatusInfoWindow extends Window { return resizeBtn; } - private void resizeWindow(ClickEvent event) { - if (event.getButton().getIcon() == FontAwesome.EXPAND) { + private void resizeWindow(final ClickEvent event) { + if (FontAwesome.EXPAND.equals(event.getButton().getIcon())) { event.getButton().setIcon(FontAwesome.COMPRESS); setWindowMode(WindowMode.MAXIMIZED); resetColumnWidth(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CoordinatesToColor.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CoordinatesToColor.java index d3b13adb3..09f88d655 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CoordinatesToColor.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CoordinatesToColor.java @@ -13,10 +13,6 @@ import com.vaadin.ui.AbstractColorPicker.Coordinates2Color; /** * Converts 2d-coordinates to a Color. - * - * - * - * */ public class CoordinatesToColor implements Coordinates2Color { @@ -30,32 +26,31 @@ public class CoordinatesToColor implements Coordinates2Color { @Override public int[] calculate(final Color color) { final float[] hsv = color.getHSV(); - final int x = Math.round(hsv[0] * 220f); - int y = 0; - y = calculateYCoordinateOfColor(hsv); + final int x = Math.round(hsv[0] * 220F); + final int y = calculateYCoordinateOfColor(hsv); return new int[] { x, y }; } - private Color calculateHSVColor(final int x, final int y) { - final float h = x / 220f; - float s = 1f; - float v = 1f; + private static Color calculateHSVColor(final int x, final int y) { + final float h = x / 220F; + float s = 1F; + float v = 1F; if (y < 110) { - s = y / 110f; + s = y / 110F; } else if (y > 110) { - v = 1f - (y - 110f) / 110f; + v = 1F - (y - 110F) / 110F; } return new Color(Color.HSVtoRGB(h, s, v)); } - private int calculateYCoordinateOfColor(final float[] hsv) { + private static int calculateYCoordinateOfColor(final float[] hsv) { int y; // lower half /* Assuming hsv[] array value will have in the range of 0 to 1 */ - if (hsv[1] < 1f) { - y = Math.round(hsv[1] * 110f); + if (hsv[1] < 1F) { + y = Math.round(hsv[1] * 110F); } else { - y = Math.round(110f - (hsv[1] + hsv[2]) * 110f); + y = Math.round(110F - (hsv[1] + hsv[2]) * 110F); } return y; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java index d3892a9dc..04fd2c316 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java @@ -33,45 +33,43 @@ import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** - * + * * DistributionSet Metadata details layout. * */ @SpringComponent @VaadinSessionScope -public class DistributionSetMetadatadetailslayout extends Table{ - +public class DistributionSetMetadatadetailslayout extends Table { + private static final long serialVersionUID = 2913758299611837718L; - - - private DistributionSetManagement distributionSetManagement; - - private DsMetadataPopupLayout dsMetadataPopupLayout; private static final String METADATA_KEY = "Key"; - - private static final String VIEW ="view"; + + private static final String VIEW = "view"; + + private transient DistributionSetManagement distributionSetManagement; + + private DsMetadataPopupLayout dsMetadataPopupLayout; private SpPermissionChecker permissionChecker; - + private transient EntityFactory entityFactory; private I18N i18n; - - private Long selectedDistSetId; - - /** - * - * @param i18n - * @param permissionChecker - * @param distributionSetManagement - * @param dsMetadataPopupLayout - */ + + private Long selectedDistSetId; + + /** + * + * @param i18n + * @param permissionChecker + * @param distributionSetManagement + * @param dsMetadataPopupLayout + */ public void init(final I18N i18n, final SpPermissionChecker permissionChecker, - final DistributionSetManagement distributionSetManagement, - final DsMetadataPopupLayout dsMetadataPopupLayout, - final EntityFactory entityFactory) { + final DistributionSetManagement distributionSetManagement, + final DsMetadataPopupLayout dsMetadataPopupLayout, final EntityFactory entityFactory) { this.i18n = i18n; this.permissionChecker = permissionChecker; this.distributionSetManagement = distributionSetManagement; @@ -80,45 +78,44 @@ public class DistributionSetMetadatadetailslayout extends Table{ createDSMetadataTable(); addCustomGeneratedColumns(); } - /** * Populate software module metadata. - * + * * @param distributionSet */ public void populateDSMetadata(final DistributionSet distributionSet) { removeAllItems(); if (null == distributionSet) { - return; + return; } selectedDistSetId = distributionSet.getId(); final List dsMetadataList = distributionSet.getMetadata(); if (null != dsMetadataList && !dsMetadataList.isEmpty()) { dsMetadataList.forEach(dsMetadata -> setDSMetadataProperties(dsMetadata)); } - + } - + /** - * Create metadata . - * + * Create metadata. + * * @param metadataKeyName */ - public void createMetadata(final String metadataKeyName){ + public void createMetadata(final String metadataKeyName) { final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource(); final Item item = metadataContainer.addItem(metadataKeyName); item.getItemProperty(METADATA_KEY).setValue(metadataKeyName); } - + /** * Delete metadata. - * + * * @param metadataKeyName */ - public void deleteMetadata(final String metadataKeyName){ + public void deleteMetadata(final String metadataKeyName) { final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource(); - metadataContainer.removeItem(metadataKeyName); + metadataContainer.removeItem(metadataKeyName); } private void createDSMetadataTable() { @@ -131,9 +128,9 @@ public class DistributionSetMetadatadetailslayout extends Table{ setContainerDataSource(getDistSetContainer()); setColumnHeaderMode(ColumnHeaderMode.EXPLICIT); addDSMetadataTableHeader(); - setSizeFull(); - //same as height of other tabs in details tabsheet - setHeight(116,Unit.PIXELS); + setSizeFull(); + // same as height of other tabs in details tabsheet + setHeight(116, Unit.PIXELS); } private IndexedContainer getDistSetContainer() { @@ -141,7 +138,7 @@ public class DistributionSetMetadatadetailslayout extends Table{ container.addContainerProperty(METADATA_KEY, String.class, ""); setColumnExpandRatio(METADATA_KEY, 0.7f); setColumnAlignment(METADATA_KEY, Align.LEFT); - + if (permissionChecker.hasUpdateDistributionPermission()) { container.addContainerProperty(VIEW, Label.class, ""); setColumnExpandRatio(VIEW, 0.2F); @@ -154,39 +151,36 @@ public class DistributionSetMetadatadetailslayout extends Table{ setColumnHeader(METADATA_KEY, i18n.get("header.key")); } - - private void setDSMetadataProperties(final DistributionSetMetadata dsMetadata){ + private void setDSMetadataProperties(final DistributionSetMetadata dsMetadata) { final Item item = getContainerDataSource().addItem(dsMetadata.getKey()); item.getItemProperty(METADATA_KEY).setValue(dsMetadata.getKey()); - + } - - private void addCustomGeneratedColumns() { - addGeneratedColumn(METADATA_KEY, - (source, itemId, columnId) -> customMetadataDetailButton((String) itemId)); + + private void addCustomGeneratedColumns() { + addGeneratedColumn(METADATA_KEY, (source, itemId, columnId) -> customMetadataDetailButton((String) itemId)); } private Button customMetadataDetailButton(final String metadataKey) { - final Button viewIcon = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, "View " - + metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class); + final Button viewIcon = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, + "View " + metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class); viewIcon.setData(metadataKey); viewIcon.addStyleName(ValoTheme.BUTTON_TINY + " " + ValoTheme.BUTTON_LINK + " " + "on-focus-no-border link" + " " + "text-style"); viewIcon.addClickListener(event -> showMetadataDetails(selectedDistSetId, metadataKey)); return viewIcon; } - + private static String getDetailLinkId(final String name) { - return new StringBuilder(SPUIComponentIdProvider.DS_METADATA_DETAIL_LINK).append('.').append(name) - .toString(); + return new StringBuilder(SPUIComponentIdProvider.DS_METADATA_DETAIL_LINK).append('.').append(name).toString(); } - - private void showMetadataDetails(final Long selectedDistSetId , final String metadataKey) { - DistributionSet distSet = distributionSetManagement.findDistributionSetById(selectedDistSetId); - + + private void showMetadataDetails(final Long selectedDistSetId, final String metadataKey) { + final DistributionSet distSet = distributionSetManagement.findDistributionSetById(selectedDistSetId); + /* display the window */ UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(distSet, - entityFactory.generateDistributionSetMetadata(distSet, metadataKey, "") )); + entityFactory.generateDistributionSetMetadata(distSet, metadataKey, ""))); } - + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java index aec0029d0..621bf3b8f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.common.filterlayout; +import static org.eclipse.hawkbit.ui.utils.SPUIDefinitions.NO_TAG_BUTTON_ID; + import java.util.ArrayList; import java.util.List; @@ -50,7 +52,7 @@ public abstract class AbstractFilterButtons extends Table { /** * Initialize layout of filter buttons. - * + * * @param filterButtonClickBehaviour * click behaviour of filter buttons. */ @@ -95,16 +97,12 @@ public abstract class AbstractFilterButtons extends Table { container.addContainerProperty(SPUILabelDefinitions.VAR_NAME, String.class, null, true, true); } - @SuppressWarnings("serial") protected void addColumn() { addGeneratedColumn(FILTER_BUTTON_COLUMN, (source, itemId, columnId) -> addGeneratedCell(itemId)); } - /** - * @param itemId - * @return - */ private DragAndDropWrapper addGeneratedCell(final Object itemId) { + final Item item = getItem(itemId); final Long id = (Long) item.getItemProperty(SPUILabelDefinitions.VAR_ID).getValue(); final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); @@ -116,16 +114,18 @@ public abstract class AbstractFilterButtons extends Table { ? item.getItemProperty(SPUILabelDefinitions.VAR_COLOR).getValue().toString() : DEFAULT_GREEN; final Button typeButton = createFilterButton(id, name, desc, color, itemId); typeButton.addClickListener(event -> filterButtonClickBehaviour.processFilterButtonClick(event)); - if (typeButton.getData().equals(SPUIDefinitions.NO_TAG_BUTTON_ID) && isNoTagSateSelected()) { - filterButtonClickBehaviour.setDefaultClickedButton(typeButton); - } else if (id != null && isClickedByDefault(name)) { + + if ((NO_TAG_BUTTON_ID.equals(typeButton.getData()) && isNoTagStateSelected()) + || (id != null && isClickedByDefault(name))) { + filterButtonClickBehaviour.setDefaultClickedButton(typeButton); } + return createDragAndDropWrapper(typeButton, name, id); } - protected boolean isNoTagSateSelected() { - return Boolean.FALSE; + protected boolean isNoTagStateSelected() { + return false; } private DragAndDropWrapper createDragAndDropWrapper(final Button tagButton, final String name, final Long id) { @@ -195,21 +195,21 @@ public abstract class AbstractFilterButtons extends Table { /** * Id of the buttons table to be used in test cases. - * + * * @return Id of the Button table. */ protected abstract String getButtonsTableId(); /** * create new lazyquery container to display the buttons. - * + * * @return reference of {@link LazyQueryContainer} */ protected abstract LazyQueryContainer createButtonsLazyQueryContainer(); /** * Check if button should be displayed as clicked by default. - * + * * @param buttonCaption * button caption * @return true if button is clicked @@ -218,7 +218,7 @@ public abstract class AbstractFilterButtons extends Table { /** * Get filter button Id. - * + * * @param name * @return */ @@ -226,7 +226,7 @@ public abstract class AbstractFilterButtons extends Table { /** * Get Drop Handler for Filter Buttons. - * + * * @return */ protected abstract DropHandler getFilterButtonDropHandler(); @@ -234,14 +234,14 @@ public abstract class AbstractFilterButtons extends Table { /** * Get prefix Id of Button Wrapper to be used for drag and drop, delete and * test cases. - * + * * @return prefix Id of Button Wrapper */ protected abstract String getButttonWrapperIdPrefix(); /** * Get info to be set for the button wrapper. - * + * * @return button wrapper info. */ protected abstract String getButtonWrapperData(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 8161c2895..9bfb81a27 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -15,9 +15,9 @@ import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.ui.common.UserDetailsFormatter; +import org.eclipse.hawkbit.ui.decorators.HeaderLayoutDecorator; import org.eclipse.hawkbit.ui.decorators.SPUIButtonDecorator; import org.eclipse.hawkbit.ui.decorators.SPUIComboBoxDecorator; -import org.eclipse.hawkbit.ui.decorators.HeaderLayoutDecorator; import org.eclipse.hawkbit.ui.decorators.SPUILabelDecorator; import org.eclipse.hawkbit.ui.decorators.SPUITextAreaDecorator; import org.eclipse.hawkbit.ui.decorators.SPUITextFieldDecorator; @@ -82,8 +82,6 @@ public final class SPUIComponentProvider { /** * Get HorizontalLayout UI component. * - * @param className - * as Layout * @return HorizontalLayout as UI */ public static HorizontalLayout getHorizontalLayout() { @@ -117,8 +115,7 @@ public final class SPUIComponentProvider { hLayout = layoutDecorator.decorate(hLayout); } catch (final InstantiationException | IllegalAccessException exception) { - LOG.error("Error occured while creating horizontal decorator " + HeaderLayoutDecorator.class, - exception); + LOG.error("Error occured while creating horizontal decorator " + HeaderLayoutDecorator.class, exception); } return hLayout; @@ -139,7 +136,7 @@ public final class SPUIComponentProvider { /** * Get window component. - * + * * @param caption * window caption * @param id @@ -154,7 +151,7 @@ public final class SPUIComponentProvider { /** * Get Label UI component. - * + * * @param caption * set the caption of the textfield * @param style @@ -182,7 +179,7 @@ public final class SPUIComponentProvider { /** * Get Label UI component. * - * + * * @param caption * set the caption of the textArea * @param style @@ -206,7 +203,7 @@ public final class SPUIComponentProvider { /** * Get Label UI component. - * + * * @param caption * caption of the combo box * @param height @@ -252,7 +249,7 @@ public final class SPUIComponentProvider { /** * Get Button - Factory Approach for decoration. - * + * * @param id * as string * @param buttonName @@ -289,7 +286,7 @@ public final class SPUIComponentProvider { /** * Get the style required. - * + * * @return String */ public static String getPinButtonStyle() { @@ -305,7 +302,7 @@ public final class SPUIComponentProvider { /** * Get DistributionSet Info Panel. - * + * * @param distributionSet * as DistributionSet * @param caption @@ -323,7 +320,7 @@ public final class SPUIComponentProvider { /** * Method to CreateName value labels. - * + * * @param label * as string * @param values @@ -356,7 +353,7 @@ public final class SPUIComponentProvider { /** * Create label which represents the {@link BaseEntity#getCreatedBy()} by * user name - * + * * @param i18n * the i18n * @param baseEntity @@ -371,7 +368,7 @@ public final class SPUIComponentProvider { /** * Create label which represents the * {@link BaseEntity#getLastModifiedBy()()} by user name - * + * * @param i18n * the i18n * @param baseEntity @@ -385,7 +382,7 @@ public final class SPUIComponentProvider { /** * Get Bold Text. - * + * * @param text * as String * @return String as bold @@ -396,7 +393,7 @@ public final class SPUIComponentProvider { /** * Get the layout for Target:Controller Attributes. - * + * * @param controllerAttibs * as Map * @return VerticalLayout @@ -407,7 +404,7 @@ public final class SPUIComponentProvider { /** * Get Tabsheet. - * + * * @return SPUITabSheet */ public static TabSheet getDetailsTabSheet() { @@ -416,7 +413,7 @@ public final class SPUIComponentProvider { /** * Layout of tabs in detail tabsheet. - * + * * @return VerticalLayout */ public static VerticalLayout getDetailTabLayout() { @@ -429,7 +426,7 @@ public final class SPUIComponentProvider { /** * Method to create a link. - * + * * @param id * of the link * @param name @@ -465,10 +462,10 @@ public final class SPUIComponentProvider { /** * Generates help/documentation links from within management UI. - * + * * @param uri * to documentation site - * + * * @return generated link */ public static Link getHelpLink(final String uri) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/RolloutRendererConnector.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/RolloutRendererConnector.java index 2175dea29..ca58648ac 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/RolloutRendererConnector.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/RolloutRendererConnector.java @@ -17,21 +17,22 @@ import com.vaadin.client.renderers.ClickableRenderer.RendererClickHandler; import com.vaadin.shared.ui.Connect; import elemental.json.JsonObject; + /** * A connector for {@link CustomObjectRenderer }. * */ @Connect(org.eclipse.hawkbit.ui.customrenderers.renderers.RolloutRenderer.class) public class RolloutRendererConnector extends ClickableRendererConnector { - private static final long serialVersionUID = 7734682321931830566L; + private static final long serialVersionUID = 7734682321931830566L; - public org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRenderer getRenderer() { - return (org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRenderer) super.getRenderer(); - } + @Override + public org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRenderer getRenderer() { + return (org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRenderer) super.getRenderer(); + } - @Override - protected HandlerRegistration addClickHandler( - RendererClickHandler handler) { + @Override + protected HandlerRegistration addClickHandler(final RendererClickHandler handler) { return getRenderer().addClickHandler(handler); - } + } } \ No newline at end of file diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/renderers/RolloutRendererData.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/renderers/RolloutRendererData.java index 6c751e6a2..7e212ea67 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/renderers/RolloutRendererData.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/renderers/RolloutRendererData.java @@ -11,52 +11,42 @@ package org.eclipse.hawkbit.ui.customrenderers.client.renderers; import java.io.Serializable; /** - * RendererData class with Name and Status. - * + * RendererData class with name and status. */ - public class RolloutRendererData implements Serializable { - private static final long serialVersionUID = -5018181529953620263L; - private String name; + private static final long serialVersionUID = -5018181529953620263L; - private String status; + private String name; - /** - * Initialize the RendererData. - */ - public RolloutRendererData() { + private String status; - } + /** + * Initialize the RendererData. + * + * @param name + * Name of the Rollout. + * @param status + * Status of Rollout. + */ + public RolloutRendererData(final String name, final String status) { + this.name = name; + this.status = status; + } - /** - * Initialize the RendererData. - * - * @param name - * Name of the Rollout. - * @param status - * Status of Rollout. - */ - public RolloutRendererData(String name, String status) { - super(); - this.name = name; - this.status = status; - } + public String getName() { + return name; + } - public String getName() { - return name; - } + public void setName(final String name) { + this.name = name; + } - public void setName(String name) { - this.name = name; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } + public String getStatus() { + return status; + } + public void setStatus(final String status) { + this.status = status; + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/renderers/RolloutRenderer.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/renderers/RolloutRenderer.java index 29663dd9d..8af3ccfc9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/renderers/RolloutRenderer.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/renderers/RolloutRenderer.java @@ -16,46 +16,44 @@ import com.vaadin.ui.renderers.ClickableRenderer; import elemental.json.JsonValue; /** - * Renders button with provided CustomObject. - * Used to display button with link. - * + * Renders button with provided CustomObject. Used to display button with link. */ - public class RolloutRenderer extends ClickableRenderer { - private static final long serialVersionUID = -8754180585906263554L; + private static final long serialVersionUID = -8754180585906263554L; - /** - * Creates a new custom object renderer. - */ - public RolloutRenderer() { - super(RolloutRendererData.class, null); - } - - /** - * Initialize custom object renderer with {@link Class} - * - * @param presentationType - * Class - */ + /** + * Creates a new custom object renderer. + */ + public RolloutRenderer() { + super(RolloutRendererData.class, null); + } - public RolloutRenderer(Class presentationType) { - super(presentationType); - } + /** + * Initialize custom object renderer with the given type. + * + * @param presentationType + * Class + */ - /** - * Creates a new custom object renderer and adds the given click listener to it. - * - * @param listener - * the click listener to register - */ - public RolloutRenderer(RendererClickListener listener) { - this(); - addClickListener(listener); - } + public RolloutRenderer(final Class presentationType) { + super(presentationType); + } - @Override - public JsonValue encode(RolloutRendererData resource) { - return super.encode(resource, RolloutRendererData.class); - } + /** + * Creates a new custom object renderer and adds the given click listener to + * it. + * + * @param listener + * the click listener to register + */ + public RolloutRenderer(final RendererClickListener listener) { + this(); + addClickListener(listener); + } + + @Override + public JsonValue encode(final RolloutRendererData resource) { + return super.encode(resource, RolloutRendererData.class); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java index 714f1f3a3..da60b83d1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java @@ -21,9 +21,6 @@ import com.vaadin.ui.Window; /** * Decorator for Window. - * - * - * */ public final class SPUIWindowDecorator { @@ -36,7 +33,7 @@ public final class SPUIWindowDecorator { /** * Decorates window based on type. - * + * * @param caption * window caption * @param id @@ -48,36 +45,38 @@ public final class SPUIWindowDecorator { public static CommonDialogWindow getWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final String helpLink, final AbstractLayout layout, - final I18N i18n) { - CommonDialogWindow window = null; - if (SPUIDefinitions.CUSTOM_METADATA_WINDOW.equals(type)) { - window = new CustomCommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener, layout, i18n); - window.setDraggable(true); - window.setClosable(true); - } else { - window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener, layout, i18n); - if (null != id) { - window.setId(id); - } - if (SPUIDefinitions.CONFIRMATION_WINDOW.equals(type)) { - window.setDraggable(false); - window.setClosable(true); - window.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION); + final I18N i18n) { - } else if (SPUIDefinitions.CREATE_UPDATE_WINDOW.equals(type)) { - window.setDraggable(true); - window.setClosable(true); - } - } - return window; - } + CommonDialogWindow window; + + if (SPUIDefinitions.CUSTOM_METADATA_WINDOW.equals(type)) { + window = new CustomCommonDialogWindow(caption, content, helpLink, saveButtonClickListener, + cancelButtonClickListener, layout, i18n); + window.setDraggable(true); + window.setClosable(true); + } else { + window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, + cancelButtonClickListener, layout, i18n); + if (null != id) { + window.setId(id); + } + if (SPUIDefinitions.CONFIRMATION_WINDOW.equals(type)) { + window.setDraggable(false); + window.setClosable(true); + window.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION); + + } else if (SPUIDefinitions.CREATE_UPDATE_WINDOW.equals(type)) { + window.setDraggable(true); + window.setClosable(true); + } + } + + return window; + } - /** * Decorates window based on type. - * + * * @param caption * window caption * @param id diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java index 9b819e1b4..fb7285764 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java @@ -117,5 +117,4 @@ public class DSTypeFilterButtons extends AbstractFilterButtons { private void refreshTypeTable() { setContainerDataSource(createButtonsLazyQueryContainer()); } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwMetadataPopupLayout.java index a6542cbd4..3ff0dd476 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwMetadataPopupLayout.java @@ -15,11 +15,9 @@ import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.common.AbstractMetadataPopupLayout; import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent; import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent.MetadataUIEvent; -import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.spring.annotation.SpringComponent; @@ -27,7 +25,6 @@ import com.vaadin.spring.annotation.ViewScope; /** * Pop up layout to display software module metadata. - * */ @SpringComponent @ViewScope @@ -39,39 +36,35 @@ public class SwMetadataPopupLayout extends AbstractMetadataPopupLayout getMetadataList() { return getSelectedEntity().getMetadata(); } - + /** * delete metadata for SWModule. */ @Override - protected void deleteMetadata(SoftwareModule entity, String key, String value) { - SoftwareModuleMetadata swMetadata = entityFactory.generateSoftwareModuleMetadata(entity, key, value); + protected void deleteMetadata(final SoftwareModule entity, final String key, final String value) { + final SoftwareModuleMetadata swMetadata = entityFactory.generateSoftwareModuleMetadata(entity, key, value); softwareManagement.deleteSoftwareModuleMetadata(entity, key); eventBus.publish(this, new MetadataEvent(MetadataUIEvent.DELETE_SOFTWARE_MODULE_METADATA, swMetadata)); } - + @Override protected boolean hasCreatePermission() { return permChecker.hasCreateDistributionPermission(); } - + @Override protected boolean hasUpdatePermission() { return permChecker.hasUpdateDistributionPermission(); } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterButtons.java index 4fd478bda..9fe3ec3f1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterButtons.java @@ -8,6 +8,11 @@ */ package org.eclipse.hawkbit.ui.distributions.smtype; +import static org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE; +import static org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE; +import static org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider.SW_MODULE_TYPE_TABLE_ID; +import static org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions.VAR_NAME; + import java.util.HashMap; import java.util.Map; @@ -19,7 +24,6 @@ import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; @@ -35,10 +39,9 @@ import com.vaadin.spring.annotation.ViewScope; /** * Software Module Type filter buttons. - * */ -@SpringComponent @ViewScope +@SpringComponent public class DistSMTypeFilterButtons extends AbstractFilterButtons { private static final long serialVersionUID = 6804534533362387433L; @@ -51,7 +54,7 @@ public class DistSMTypeFilterButtons extends AbstractFilterButtons { @Override protected String getButtonsTableId() { - return SPUIComponentIdProvider.SW_MODULE_TYPE_TABLE_ID; + return SW_MODULE_TYPE_TABLE_ID; } @Override @@ -60,7 +63,7 @@ public class DistSMTypeFilterButtons extends AbstractFilterButtons { final BeanQueryFactory typeQF = new BeanQueryFactory<>( SoftwareModuleTypeBeanQuery.class); typeQF.setQueryConfiguration(queryConfig); - return new LazyQueryContainer(new LazyQueryDefinition(true, 20, SPUILabelDefinitions.VAR_NAME), typeQF); + return new LazyQueryContainer(new LazyQueryDefinition(true, 20, VAR_NAME), typeQF); } @Override @@ -70,8 +73,8 @@ public class DistSMTypeFilterButtons extends AbstractFilterButtons { @Override protected boolean isClickedByDefault(final String typeName) { - return manageDistUIState.getSoftwareModuleFilters().getSoftwareModuleType().isPresent() - && manageDistUIState.getSoftwareModuleFilters().getSoftwareModuleType().get().getName().equals(typeName); + return manageDistUIState.getSoftwareModuleFilters().getSoftwareModuleType().isPresent() && manageDistUIState + .getSoftwareModuleFilters().getSoftwareModuleType().get().getName().equals(typeName); } @Override @@ -104,13 +107,16 @@ public class DistSMTypeFilterButtons extends AbstractFilterButtons { @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final SoftwareModuleTypeEvent event) { - if (event.getSoftwareModuleTypeEnum() == SoftwareModuleTypeEvent.SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE - || event.getSoftwareModuleTypeEnum() == SoftwareModuleTypeEvent.SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE - && event.getSoftwareModuleType() != null) { + if (isCreateOrUpdate(event) && event.getSoftwareModuleType() != null) { refreshTypeTable(); } } + private boolean isCreateOrUpdate(final SoftwareModuleTypeEvent event) { + return event.getSoftwareModuleTypeEnum() == ADD_SOFTWARE_MODULE_TYPE + || event.getSoftwareModuleTypeEnum() == UPDATE_SOFTWARE_MODULE_TYPE; + } + @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final SaveActionWindowEvent event) { if (event == SaveActionWindowEvent.SAVED_DELETE_SW_MODULE_TYPES) { @@ -121,6 +127,4 @@ public class DistSMTypeFilterButtons extends AbstractFilterButtons { private void refreshTypeTable() { setContainerDataSource(createButtonsLazyQueryContainer()); } - - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/state/ManageDistUIState.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/state/ManageDistUIState.java index 45ad7ac89..caac53147 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/state/ManageDistUIState.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/state/ManageDistUIState.java @@ -8,8 +8,9 @@ */ package org.eclipse.hawkbit.ui.distributions.state; +import static java.util.Collections.emptySet; + import java.io.Serializable; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -49,7 +50,7 @@ public class ManageDistUIState implements ManagmentEntityState selectedSoftwareModules = Collections.emptySet(); + private Set selectedSoftwareModules = emptySet(); private Set selectedDeleteDistSetTypes = new HashSet<>(); @@ -57,23 +58,23 @@ public class ManageDistUIState implements ManagmentEntityState deleteSofwareModulesList = new HashMap<>(); - private boolean swModuleTableMaximized = Boolean.FALSE; + private boolean swModuleTableMaximized; - private boolean dsTableMaximized = Boolean.FALSE; + private boolean dsTableMaximized; private final Map assignedSoftwareModuleDetails = new HashMap<>(); private final Map>> consolidatedDistSoftwarewList = new HashMap<>(); - private boolean noDataAvilableSwModule = Boolean.FALSE; + private boolean noDataAvilableSwModule; - private boolean noDataAvailableDist = Boolean.FALSE; + private boolean noDataAvailableDist; /** * @return the manageDistFilters @@ -117,6 +118,7 @@ public class ManageDistUIState implements ManagmentEntityState values) { selectedDistributions = values; } @@ -223,7 +225,7 @@ public class ManageDistUIState implements ManagmentEntityState discard(), null, mainLayout, i18n); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java index 9544776a6..f56cd0ae7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java @@ -118,12 +118,10 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat /** * RESET. - * - * @param event */ @Override - public void discard(final ClickEvent event) { - super.discard(event); + public void discard() { + super.discard(); resetDistTagValues(); } @@ -144,7 +142,7 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat /** * Select tag & set tag name & tag desc values corresponding to selected * tag. - * + * * @param distTagSelected * as the selected tag from combo */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java index deaace968..8b5ee85cf 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java @@ -121,7 +121,7 @@ public class DistributionTagButtons extends AbstractFilterButtons { } @Override - protected boolean isNoTagSateSelected() { + protected boolean isNoTagStateSelected() { return managementUIState.getDistributionTableFilters().isNoTagSelected(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index 83082be01..14b096fcf 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -391,22 +391,22 @@ public class BulkUploadHandler extends CustomComponent eventBus.publish(this, new BulkUploadValidationMessageEvent(errorMessage.toString())); } } - } - private void addNewTarget(final String controllerId, final String name) { - final String newControllerId = HawkbitCommonUtil.trimAndNullIfEmpty(controllerId); - if (mandatoryCheck(newControllerId) && duplicateCheck(newControllerId)) { - final String newName = HawkbitCommonUtil.trimAndNullIfEmpty(name); - final String newDesc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); + private void addNewTarget(final String controllerId, final String name) { + final String newControllerId = HawkbitCommonUtil.trimAndNullIfEmpty(controllerId); + if (mandatoryCheck(newControllerId) && duplicateCheck(newControllerId)) { + final String newName = HawkbitCommonUtil.trimAndNullIfEmpty(name); + final String newDesc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); + + /* create new target entity */ + final Target newTarget = entityFactory.generateTarget(newControllerId); + setTargetValues(newTarget, newName, newDesc); + targetManagement.createTarget(newTarget); + managementUIState.getTargetTableFilters().getBulkUpload().getTargetsCreated().add(newControllerId); + successfullTargetCount++; + } - /* create new target entity */ - final Target newTarget = entityFactory.generateTarget(newControllerId); - setTargetValues(newTarget, newName, newDesc); - targetManagement.createTarget(newTarget); - managementUIState.getTargetTableFilters().getBulkUpload().getTargetsCreated().add(newControllerId); - successfullTargetCount++; } - } private static void setTargetValues(final Target target, final String name, final String description) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java index e9d3f6e1e..c1287e978 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java @@ -131,7 +131,7 @@ public class TargetTagFilterButtons extends AbstractFilterButtons { } @Override - protected boolean isNoTagSateSelected() { + protected boolean isNoTagStateSelected() { return managementUIState.getTargetTableFilters().isNoTagSelected(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java index defcc82c0..4016d5fd7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java @@ -37,6 +37,7 @@ import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.UIScope; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; @@ -52,14 +53,11 @@ import com.vaadin.ui.themes.ValoTheme; * A responsive menu component providing user information and the controls for * primary navigation between the views. */ -@SpringComponent @UIScope +@SpringComponent public final class DashboardMenu extends CustomComponent { - private static final String STYLE_VISIBLE = "valo-menu-visible"; - public static final String ID = "dashboard-menu"; - public static final String REPORTS_BADGE_ID = "dashboard-menu-reports-badge"; - public static final String NOTIFICATIONS_BADGE_ID = "dashboard-menu-notifications-badge"; + private static final String ID = "dashboard-menu"; @Autowired private I18N i18n; @@ -208,13 +206,7 @@ public final class DashboardMenu extends CustomComponent { } private Component buildToggleButton() { - final Button valoMenuToggleButton = new Button("Menu", (ClickListener) event -> { - if (getCompositionRoot().getStyleName().contains(STYLE_VISIBLE)) { - getCompositionRoot().removeStyleName(STYLE_VISIBLE); - } else { - getCompositionRoot().addStyleName(STYLE_VISIBLE); - } - }); + final Button valoMenuToggleButton = new Button("Menu", new MenuToggleClickListenerMyClickListener()); valoMenuToggleButton.setIcon(FontAwesome.LIST); valoMenuToggleButton.addStyleName("valo-menu-toggle"); valoMenuToggleButton.addStyleName(ValoTheme.BUTTON_BORDERLESS); @@ -244,7 +236,7 @@ public final class DashboardMenu extends CustomComponent { /** * Returns all views which are currently accessible by the current logged in * user. - * + * * @return a list of all views which are currently visible and accessible * for the current logged in user */ @@ -264,7 +256,7 @@ public final class DashboardMenu extends CustomComponent { /** * Returns the view name for the start page after login. - * + * * @return the initialViewName of the start page */ public String getInitialViewName() { @@ -273,7 +265,7 @@ public final class DashboardMenu extends CustomComponent { /** * Is a View available. - * + * * @return the accessibleViewsEmpty no rights for any view a * view is available */ @@ -284,7 +276,7 @@ public final class DashboardMenu extends CustomComponent { /** * notifies the dashboard that the view has been changed and the button * needs to be re-styled. - * + * * @param event * the post view change event */ @@ -294,7 +286,7 @@ public final class DashboardMenu extends CustomComponent { /** * Returns the dashboard view type by a given view name. - * + * * @param viewName * the name of the view to retrieve * @return the dashboard view for a given viewname or {@code null} if view @@ -313,7 +305,7 @@ public final class DashboardMenu extends CustomComponent { /** * Is the given view accessible. - * + * * @param viewName * the view name * @return = denied, = accessible @@ -329,15 +321,28 @@ public final class DashboardMenu extends CustomComponent { return accessDeined; } + private class MenuToggleClickListenerMyClickListener implements ClickListener { + + private static final long serialVersionUID = 1L; + private static final String STYLE_VISIBLE = "valo-menu-visible"; + + @Override + public void buttonClick(final ClickEvent event) { + if (getCompositionRoot().getStyleName().contains(STYLE_VISIBLE)) { + getCompositionRoot().removeStyleName(STYLE_VISIBLE); + } else { + getCompositionRoot().addStyleName(STYLE_VISIBLE); + } + } + } + /** * An menu item button wrapper for the dashboard menu item. - * - * - * - * */ public static final class ValoMenuItemButton extends Button { + private static final long serialVersionUID = 1L; + private static final String STYLE_SELECTED = "selected"; private final DashboardMenuItem view; @@ -345,7 +350,7 @@ public final class DashboardMenu extends CustomComponent { /** * creates a new button in case of pressed switches to the given * {@code view}. - * + * * @param view * the view to switch to in case the button is pressed */ @@ -358,12 +363,11 @@ public final class DashboardMenu extends CustomComponent { /* Avoid double click */ setDisableOnClick(true); addClickListener(event -> event.getComponent().getUI().getNavigator().navigateTo(view.getViewName())); - } /** * notifies the button to change his style. - * + * * @param event * the post view change event */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/DistributionBarHelper.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/DistributionBarHelper.java index 4d46945ca..3d167d4cb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/DistributionBarHelper.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/DistributionBarHelper.java @@ -20,6 +20,7 @@ import org.vaadin.alump.distributionbar.gwt.client.GwtDistributionBar; * */ public final class DistributionBarHelper { + private static final String HTML_DIV_END = ""; private static final int PARENT_SIZE_IN_PCT = 100; private static final double MINIMUM_PART_SIZE = 10; private static final String DISTRIBUTION_BAR_PART_MAIN_STYLE = GwtDistributionBar.CLASSNAME + "-part"; @@ -38,23 +39,23 @@ public final class DistributionBarHelper { * * @return string of format "status1:count,status2:count" */ - public static String getDistributionBarAsHTMLString(Map statusTotalCountMap) { - StringBuilder htmlString = new StringBuilder(); - Map statusMapWithNonZeroValues = getStatusMapWithNonZeroValues(statusTotalCountMap); - Long totalValue = getTotalSizes(statusTotalCountMap); + public static String getDistributionBarAsHTMLString(final Map statusTotalCountMap) { + final StringBuilder htmlString = new StringBuilder(); + final Map statusMapWithNonZeroValues = getStatusMapWithNonZeroValues(statusTotalCountMap); + final Long totalValue = getTotalSizes(statusTotalCountMap); if (statusMapWithNonZeroValues.size() <= 0) { return getUnintialisedBar(); } int partIndex = 1; htmlString.append(getParentDivStart()); - for (Map.Entry entry : statusMapWithNonZeroValues.entrySet()) { + for (final Map.Entry entry : statusMapWithNonZeroValues.entrySet()) { if (entry.getValue() > 0) { htmlString.append(getPart(partIndex, entry.getKey(), entry.getValue(), totalValue, statusMapWithNonZeroValues.size())); partIndex++; } } - htmlString.append(getParentDivEnd()); + htmlString.append(HTML_DIV_END); return htmlString.toString(); } @@ -65,7 +66,7 @@ public final class DistributionBarHelper { * map with status and count * @return map with non zero values */ - public static Map getStatusMapWithNonZeroValues(Map statusTotalCountMap) { + public static Map getStatusMapWithNonZeroValues(final Map statusTotalCountMap) { return statusTotalCountMap.entrySet().stream().filter(p -> p.getValue() > 0) .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue())); } @@ -77,19 +78,20 @@ public final class DistributionBarHelper { * map with status and count details * @return tool tip */ - public static String getTooltip(Map statusCountMap) { - Map nonZeroStatusCountMap = DistributionBarHelper.getStatusMapWithNonZeroValues(statusCountMap); - StringBuilder tooltip = new StringBuilder(); - for (Entry entry : nonZeroStatusCountMap.entrySet()) { + public static String getTooltip(final Map statusCountMap) { + final Map nonZeroStatusCountMap = DistributionBarHelper + .getStatusMapWithNonZeroValues(statusCountMap); + final StringBuilder tooltip = new StringBuilder(); + for (final Entry entry : nonZeroStatusCountMap.entrySet()) { tooltip.append(entry.getKey().toString().toLowerCase()).append(" : ").append(entry.getValue()) .append("
    "); } return tooltip.toString(); } - private static String getPartStyle(int partIndex, int noOfParts, String customStyle) { - StringBuilder mainStyle = new StringBuilder(); - StringBuilder styleName = new StringBuilder(GwtDistributionBar.CLASSNAME); + private static String getPartStyle(final int partIndex, final int noOfParts, final String customStyle) { + final StringBuilder mainStyle = new StringBuilder(); + final StringBuilder styleName = new StringBuilder(GwtDistributionBar.CLASSNAME); if (noOfParts == 1) { styleName.append("-only"); } else if (partIndex == 1) { @@ -108,15 +110,16 @@ public final class DistributionBarHelper { return mainStyle.toString(); } - private static String getPartWidth(Long value, Long totalValue, int noOfParts) { + private static String getPartWidth(final Long value, final Long totalValue, final int noOfParts) { final double minTotalSize = MINIMUM_PART_SIZE * noOfParts; final double availableSize = PARENT_SIZE_IN_PCT - minTotalSize; - double val = MINIMUM_PART_SIZE + (double) value / totalValue * availableSize; + final double val = MINIMUM_PART_SIZE + (double) value / totalValue * availableSize; return String.format("%.3f", val) + "%"; } - private static String getPart(int partIndex, Status status, Long value, Long totalValue, int noOfParts) { - String partValue = status.toString().toLowerCase(); + private static String getPart(final int partIndex, final Status status, final Long value, final Long totalValue, + final int noOfParts) { + final String partValue = status.toString().toLowerCase(); return "
    " + value + "
    "; @@ -127,9 +130,9 @@ public final class DistributionBarHelper { + DISTRIBUTION_BAR_PART_VALUE_CLASSNAME + "\">uninitialized"; } - private static Long getTotalSizes(Map statusTotalCountMap) { + private static Long getTotalSizes(final Map statusTotalCountMap) { Long total = 0L; - for (Long value : statusTotalCountMap.values()) { + for (final Long value : statusTotalCountMap.values()) { total = total + value; } return total; @@ -139,8 +142,4 @@ public final class DistributionBarHelper { return "
    "; } - - private static String getParentDivEnd() { - return "
    "; - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 8a7d11df1..6a20bf9f0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -152,7 +152,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { /** * Get the window. - * + * * @param rolloutId * the rollout id * @return the window @@ -499,14 +499,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return errorThresoldPercent; } - private boolean validateFields() { - if (!noOfGroups.isValid() || !errorThreshold.isValid() || !triggerThreshold.isValid()) { - uiNotification.displayValidationError(i18n.get("message.correct.invalid.value")); - return false; - } - return true; - } - private boolean duplicateCheck() { if (rolloutManagement.findRolloutByName(getRolloutName()) != null) { uiNotification.displayValidationError( @@ -694,9 +686,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } /** - * + * * Populate rollout details. - * + * * @param rolloutId * rollout id */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupListGrid.java index 0d78763be..19df8b139 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupListGrid.java @@ -52,7 +52,7 @@ import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent; import com.vaadin.ui.renderers.HtmlRenderer; /** - * + * * Rollout group list grid component. * */ @@ -86,10 +86,10 @@ public class RolloutGroupListGrid extends AbstractGrid { } /** - * + * * Handles the RolloutGroupChangeEvent to refresh the item in the grid. - * - * + * + * * @param rolloutGroupChangeEvent * the event which contains the rollout group which has been * change @@ -242,6 +242,12 @@ public class RolloutGroupListGrid extends AbstractGrid { } } + private void onClickOfRolloutGroupName(final RendererClickEvent event) { + rolloutUIState + .setRolloutGroup(rolloutGroupManagement.findRolloutGroupWithDetailedStatus((Long) event.getItemId())); + eventBus.publish(this, RolloutEvent.SHOW_ROLLOUT_GROUP_TARGETS); + } + @Override protected void setHiddenColumns() { final List columnsToBeHidden = new ArrayList<>(); @@ -261,12 +267,6 @@ public class RolloutGroupListGrid extends AbstractGrid { return this::getDescription; } - private void onClickOfRolloutGroupName(final RendererClickEvent event) { - rolloutUIState - .setRolloutGroup(rolloutGroupManagement.findRolloutGroupWithDetailedStatus((Long) event.getItemId())); - eventBus.publish(this, RolloutEvent.SHOW_ROLLOUT_GROUP_TARGETS); - } - private void createRolloutGroupStatusToFontMap() { statusIconMap.put(RolloutGroupStatus.FINISHED, new StatusFontIcon(FontAwesome.CHECK_CIRCLE, SPUIStyleDefinitions.STATUS_ICON_GREEN)); @@ -311,7 +311,7 @@ public class RolloutGroupListGrid extends AbstractGrid { } /** - * + * * Converts {@link TotalTargetCountStatus} into formatted string with status * and count details. * @@ -346,7 +346,7 @@ public class RolloutGroupListGrid extends AbstractGrid { } /** - * + * * Converts {@link RolloutGroupStatus} to string. * */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java index 329318b0f..584f28931 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java @@ -161,13 +161,13 @@ public class AuthenticationConfigurationView extends BaseConfigurationView final CheckBox checkBox = (CheckBox) event.getProperty(); AuthenticationConfigurationItem configurationItem; - if (checkBox == gatewaySecTokenCheckBox) { + if (gatewaySecTokenCheckBox.equals(checkBox)) { configurationItem = gatewaySecurityTokenAuthenticationConfigurationItem; - } else if (checkBox == targetSecTokenCheckBox) { + } else if (targetSecTokenCheckBox.equals(checkBox)) { configurationItem = targetSecurityTokenAuthenticationConfigurationItem; - } else if (checkBox == certificateAuthCheckbox) { + } else if (certificateAuthCheckbox.equals(checkBox)) { configurationItem = certificateAuthenticationConfigurationItem; - } else if (checkBox == downloadAnonymousCheckBox) { + } else if (downloadAnonymousCheckBox.equals(checkBox)) { configurationItem = anonymousDownloadAuthenticationConfigurationItem; } else { return; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java index b5ac26d11..18ffda663 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java @@ -441,7 +441,7 @@ public final class HawkbitCommonUtil { */ public static float findRequiredExtraHeight(final float newBrowserHeight) { return newBrowserHeight > SPUIDefinitions.REQ_MIN_BROWSER_HEIGHT - ? newBrowserHeight - SPUIDefinitions.REQ_MIN_BROWSER_HEIGHT : 0; + ? (newBrowserHeight - SPUIDefinitions.REQ_MIN_BROWSER_HEIGHT) : 0; } /** @@ -453,7 +453,7 @@ public final class HawkbitCommonUtil { */ public static float findRequiredSwModuleExtraHeight(final float newBrowserHeight) { return newBrowserHeight > SPUIDefinitions.REQ_MIN_UPLOAD_BROWSER_HEIGHT - ? newBrowserHeight - SPUIDefinitions.REQ_MIN_UPLOAD_BROWSER_HEIGHT : 0; + ? (newBrowserHeight - SPUIDefinitions.REQ_MIN_UPLOAD_BROWSER_HEIGHT) : 0; } /** @@ -465,7 +465,7 @@ public final class HawkbitCommonUtil { */ public static float findRequiredSwModuleExtraWidth(final float newBrowserWidth) { return newBrowserWidth > SPUIDefinitions.REQ_MIN_UPLOAD_BROWSER_WIDTH - ? newBrowserWidth - SPUIDefinitions.REQ_MIN_UPLOAD_BROWSER_WIDTH : 0; + ? (newBrowserWidth - SPUIDefinitions.REQ_MIN_UPLOAD_BROWSER_WIDTH) : 0; } /** @@ -528,7 +528,7 @@ public final class HawkbitCommonUtil { */ public static float findExtraWidth(final float newBrowserWidth) { return newBrowserWidth > SPUIDefinitions.REQ_MIN_BROWSER_WIDTH - ? newBrowserWidth - SPUIDefinitions.REQ_MIN_BROWSER_WIDTH : 0; + ? (newBrowserWidth - SPUIDefinitions.REQ_MIN_BROWSER_WIDTH) : 0; } /** @@ -570,7 +570,7 @@ public final class HawkbitCommonUtil { final float requiredExtraWidth = findExtraWidth(newBrowserWidth); float expectedDistWidth = minTableWidth; if (requiredExtraWidth > 0) { - expectedDistWidth = expectedDistWidth + Math.round(requiredExtraWidth * 0.5f); + expectedDistWidth = expectedDistWidth + Math.round(requiredExtraWidth * 0.5F); } return expectedDistWidth; } @@ -741,6 +741,8 @@ public final class HawkbitCommonUtil { * base software module type * @param description * base software module description + * @param entityFactory + * the entity factory to create new entity instances * @return BaseSoftwareModule new base software module */ public static SoftwareModule addNewBaseSoftware(final EntityFactory entityFactory, final String bsname, diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java index f035c4995..c4091bde2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java @@ -273,10 +273,6 @@ public final class SPUIDefinitions { * New Target save icon id. */ public static final String NEW_TARGET_SAVE = "target.add.save"; - /** - * New Target discard icon id. - */ - // public static final String NEW_TARGET_DISCARD = "target.add.discard"; /** * New Target add icon id. */ @@ -1017,12 +1013,12 @@ public final class SPUIDefinitions { * Rollout action column property. */ public static final String ROLLOUT_ACTION = "rollout-action"; - + /** * DistributionSet Metadata tab Id */ public static final String DISTRIBUTIONSET_METADATA_TAB_ID = "distSet.metadata.tab.id"; - + /** * SoftwareModule Metadata tab Id */ @@ -1031,7 +1027,7 @@ public final class SPUIDefinitions { /*** * Custom window for metadata. */ - public static final String CUSTOM_METADATA_WINDOW = "custom.metadata.window"; + public static final String CUSTOM_METADATA_WINDOW = "custom.metadata.window"; /** * /** Constructor. From 196ce5643e02bc90ccf0b4c38bb2f636defb6474 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 15 Aug 2016 14:33:03 +0200 Subject: [PATCH 22/42] don't send amqp message when protocol is DDI Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java | 1 + .../java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java index 8d5c5e0b1..3a8690cb3 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java @@ -72,6 +72,7 @@ public class SimulatedDeviceFactory { final int pollDelaySec, final URL baseEndpoint, final String gatewayToken) { switch (protocol) { case DMF_AMQP: + spSenderService.createOrUpdateThing(tenant, id); return new DMFSimulatedDevice(id, tenant, spSenderService, pollDelaySec); case DDI_HTTP: final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger()) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java index 25e575cf1..4a81547c5 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java @@ -270,7 +270,6 @@ public class SimulatorView extends VerticalLayout implements View { final String deviceId = namePrefix + index; beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken))); - spSenderService.createOrUpdateThing(tenant, deviceId); } }, amqpProperties.isEnabled())); } From 9d54aa8c34c28754b714923131bb716153040445 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 15 Aug 2016 15:16:02 +0200 Subject: [PATCH 23/42] grammar corrected Signed-off-by: Michael Hirsch --- examples/hawkbit-device-simulator/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hawkbit-device-simulator/README.md b/examples/hawkbit-device-simulator/README.md index ba241601a..0d73f3f3f 100644 --- a/examples/hawkbit-device-simulator/README.md +++ b/examples/hawkbit-device-simulator/README.md @@ -27,7 +27,7 @@ This can be configured/disabled by spring boot properties ## hawkBit APIs The simulator supports `DDI` as well as the `DMF` integration APIs. -In case there is no AMQP message broker (like rabbitMQ) running, you can disable the AMQP support for the device simulator, so the simulator is not trying to connect to a amqp message broker. +In case there is no AMQP message broker (like rabbitMQ) running, you can disable the AMQP support for the device simulator, so the simulator is not trying to connect to an amqp message broker. Configuration property `hawkbit.device.simulator.amqp.enabled=true` ## Usage From 7164b33e941f950da25488874e62474561db7b05 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 15 Aug 2016 15:33:18 +0200 Subject: [PATCH 24/42] don't generate amqp devices at startup if amqp is disabled Signed-off-by: Michael Hirsch --- .../hawkbit/simulator/SimulatorStartup.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java index 486eb4b5e..69ff765d0 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java @@ -11,7 +11,7 @@ package org.eclipse.hawkbit.simulator; import java.net.MalformedURLException; import java.net.URL; -import org.eclipse.hawkbit.simulator.amqp.SpSenderService; +import org.eclipse.hawkbit.simulator.amqp.AmqpProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -32,24 +32,27 @@ public class SimulatorStartup implements ApplicationListener { for (int i = 0; i < autostart.getAmount(); i++) { final String deviceId = autostart.getName() + i; try { - repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(), - autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()), - autostart.getGatewayToken())); + if (amqpProperties.isEnabled()) { + repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(), + autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()), + autostart.getGatewayToken())); + } + } catch (final MalformedURLException e) { LOGGER.error("Creation of simulated device at startup failed.", e); } From a9e15041d82c24372cd88f4b3d88b8d40bbf7dd9 Mon Sep 17 00:00:00 2001 From: Dominic Schabel Date: Mon, 15 Aug 2016 13:32:57 +0200 Subject: [PATCH 25/42] Minor code improvements Signed-off-by: Dominic Schabel --- .../hawkbit/repository/FieldNameProvider.java | 7 +- .../model/EntityPropertyChangeListener.java | 4 +- .../artifacts/details/ArtifactBeanQuery.java | 8 +- .../smtable/BaseSwModuleBeanQuery.java | 4 +- .../common/AbstractMetadataPopupLayout.java | 4 +- .../components/SPTargetAttributesLayout.java | 12 +- .../client/renderers/RolloutRendererData.java | 7 + .../dstable/ManageDistBeanQuery.java | 4 +- .../smtable/SwModuleBeanQuery.java | 4 +- .../CustomTargetBeanQuery.java | 34 +- .../TargetFilterBeanQuery.java | 4 +- .../dstable/DistributionBeanQuery.java | 2 +- .../management/footer/CountMessageLabel.java | 21 +- .../targettable/TargetBeanQuery.java | 8 +- .../management/targettable/TargetTable.java | 93 ++--- .../ui/rollout/rollout/RolloutBeanQuery.java | 15 +- .../ui/rollout/rollout/RolloutListGrid.java | 36 +- .../rolloutgroup/RolloutGroupBeanQuery.java | 8 +- .../rolloutgroup/RolloutGroupListGrid.java | 30 +- .../hawkbit/ui/utils/HawkbitCommonUtil.java | 348 ++++-------------- 20 files changed, 209 insertions(+), 444 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java index 841f6d7e6..d8fd4281c 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java @@ -17,7 +17,9 @@ import java.util.Map; * which is used as string representation of the field, e.g. for sorting the * fields over REST. */ +@FunctionalInterface public interface FieldNameProvider { + /** * Separator for the sub attributes */ @@ -56,7 +58,6 @@ public interface FieldNameProvider { } /** - * * @return all sub entities attributes. */ default List getSubEntityAttributes() { @@ -64,7 +65,7 @@ public interface FieldNameProvider { } /** - * the database column for the key + * The database column for the key * * @return key fieldname */ @@ -73,7 +74,7 @@ public interface FieldNameProvider { } /** - * the database column for the value + * The database column for the value * * @return key fieldname */ diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java index 6b1385440..53b3dca25 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java @@ -22,7 +22,6 @@ import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEventAdapter; import org.eclipse.persistence.internal.sessions.ObjectChangeSet; @@ -46,7 +45,6 @@ public class EntityPropertyChangeListener extends DescriptorEventAdapter { afterCommit.afterCommit(() -> eventBus.post(new ActionCreatedEvent(action))); } } - } @Override @@ -63,7 +61,7 @@ public class EntityPropertyChangeListener extends DescriptorEventAdapter { } } - private Map getChangeSet(final DescriptorEvent event) { + private Map getChangeSet(final DescriptorEvent event) { final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet(); return changeSet.getChanges().stream().filter(record -> record instanceof DirectToFieldChangeRecord) .map(record -> (DirectToFieldChangeRecord) record) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java index 4ba722284..faf43b4ca 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.artifacts.details; +import static org.apache.commons.lang3.ArrayUtils.isEmpty; + import java.util.List; import java.util.Map; @@ -39,7 +41,7 @@ public class ArtifactBeanQuery extends AbstractBeanQuery { /** * Parametric Constructor. - * + * * @param definition * as Def * @param queryConfig @@ -53,11 +55,11 @@ public class ArtifactBeanQuery extends AbstractBeanQuery { final Object[] sortIds, final boolean[] sortStates) { super(definition, queryConfig, sortIds, sortStates); - if (HawkbitCommonUtil.mapCheckStrKey(queryConfig)) { + if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { baseSwModuleId = (Long) queryConfig.get(SPUIDefinitions.BY_BASE_SOFTWARE_MODULE); } - if (HawkbitCommonUtil.checkBolArray(sortStates)) { + if (isEmpty(sortStates)) { // Initalize Sor sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortIds[0]); // Add sort. diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/BaseSwModuleBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/BaseSwModuleBeanQuery.java index 29bea30eb..103481f89 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/BaseSwModuleBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/BaseSwModuleBeanQuery.java @@ -43,7 +43,7 @@ public class BaseSwModuleBeanQuery extends AbstractBeanQuery queryConfig, final Object[] sortIds, final boolean[] sortStates) { super(definition, queryConfig, sortIds, sortStates); - if (HawkbitCommonUtil.mapCheckStrKey(queryConfig)) { + if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { type = (SoftwareModuleType) queryConfig.get(SPUIDefinitions.BY_SOFTWARE_MODULE_TYPE); searchText = (String) queryConfig.get(SPUIDefinitions.FILTER_BY_TEXT); if (!Strings.isNullOrEmpty(searchText)) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java index ff1cc3db1..b9d48d321 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java @@ -407,9 +407,9 @@ public abstract class AbstractMetadataPopupLayout controllerAttibs) { targetAttributesLayout = new VerticalLayout(); @@ -44,7 +44,7 @@ public class SPTargetAttributesLayout { /** * Custom Decorate. - * + * * @param controllerAttibs */ private void decorate(final Map controllerAttibs) { @@ -52,7 +52,7 @@ public class SPTargetAttributesLayout { final Label title = new Label(i18n.get("label.target.controller.attrs"), ContentMode.HTML); title.addStyleName(SPUIDefinitions.TEXT_STYLE); targetAttributesLayout.addComponent(title); - if (HawkbitCommonUtil.mapCheckStrings(controllerAttibs)) { + if (HawkbitCommonUtil.isNotNullOrEmpty(controllerAttibs)) { for (final Map.Entry entry : controllerAttibs.entrySet()) { targetAttributesLayout.addComponent( SPUIComponentProvider.createNameValueLabel(entry.getKey() + ": ", entry.getValue())); @@ -62,7 +62,7 @@ public class SPTargetAttributesLayout { /** * GET Target Attributes Layout. - * + * * @return VerticalLayout as UI */ public VerticalLayout getTargetAttributesLayout() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/renderers/RolloutRendererData.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/renderers/RolloutRendererData.java index 7e212ea67..e72f81779 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/renderers/RolloutRendererData.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/client/renderers/RolloutRendererData.java @@ -21,6 +21,13 @@ public class RolloutRendererData implements Serializable { private String status; + /** + * Initialize the RendererData empty. + */ + public RolloutRendererData() { + // Needed by Vaadin for compiling the widget set. + } + /** * Initialize the RendererData. * diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java index a262f0d20..391d05048 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java @@ -50,7 +50,7 @@ public class ManageDistBeanQuery extends AbstractBeanQuery { private DistributionSetType distributionSetType = null; /** - * + * * @param definition * @param queryConfig * @param sortPropertyIds @@ -60,7 +60,7 @@ public class ManageDistBeanQuery extends AbstractBeanQuery { final Object[] sortPropertyIds, final boolean[] sortStates) { super(definition, queryConfig, sortPropertyIds, sortStates); - if (HawkbitCommonUtil.mapCheckStrKey(queryConfig)) { + if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { searchText = (String) queryConfig.get(SPUIDefinitions.FILTER_BY_TEXT); if (!Strings.isNullOrEmpty(searchText)) { searchText = String.format("%%%s%%", searchText); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleBeanQuery.java index 16636e64b..7222b1012 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleBeanQuery.java @@ -42,7 +42,7 @@ public class SwModuleBeanQuery extends AbstractBeanQuery /** * Parametric Constructor. - * + * * @param definition * as Def * @param queryConfig @@ -55,7 +55,7 @@ public class SwModuleBeanQuery extends AbstractBeanQuery public SwModuleBeanQuery(final QueryDefinition definition, final Map queryConfig, final Object[] sortIds, final boolean[] sortStates) { super(definition, queryConfig, sortIds, sortStates); - if (HawkbitCommonUtil.mapCheckStrKey(queryConfig)) { + if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { type = (SoftwareModuleType) queryConfig.get(SPUIDefinitions.BY_SOFTWARE_MODULE_TYPE); searchText = (String) queryConfig.get(SPUIDefinitions.FILTER_BY_TEXT); if (!Strings.isNullOrEmpty(searchText)) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java index 35f88f5a1..17eafc47a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.filtermanagement; +import static org.apache.commons.lang3.ArrayUtils.isEmpty; + import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -47,7 +49,7 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery { /** * Parametric Constructor. - * + * * @param definition * as Def * @param queryConfig @@ -61,10 +63,10 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery { final Object[] sortIds, final boolean[] sortStates) { super(definition, queryConfig, sortIds, sortStates); - if (HawkbitCommonUtil.mapCheckStrKey(queryConfig)) { + if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { filterQuery = (String) queryConfig.get(SPUIDefinitions.FILTER_BY_QUERY); } - if (HawkbitCommonUtil.checkBolArray(sortStates)) { + if (isEmpty(sortStates)) { // Initalize Sor sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortIds[0]); // Add sort. @@ -74,25 +76,12 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery { } } - /* - * (non-Javadoc) - * - * @see - * org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery#constructBean() - */ @Override protected ProxyTarget constructBean() { return new ProxyTarget(); } - /* - * (non-Javadoc) - * - * @see - * org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery#loadBeans(int, - * int) - */ @Override protected List loadBeans(final int startIndex, final int count) { Slice targetBeans; @@ -131,23 +120,11 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery { return proxyTargetBeans; } - /* - * (non-Javadoc) - * - * @see - * org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery#saveBeans(java - * .util.List, java.util.List, java.util.List) - */ @Override protected void saveBeans(final List arg0, final List arg1, final List arg2) { // CRUD operations on Target will be done through repository methods } - /* - * (non-Javadoc) - * - * @see org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery#size() - */ @Override public int size() { long size = 0; @@ -184,5 +161,4 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery { } return i18N; } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterBeanQuery.java index 4a2d6da6c..9231b1658 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterBeanQuery.java @@ -44,7 +44,7 @@ public class TargetFilterBeanQuery extends AbstractBeanQuery private transient TargetFilterQueryManagement targetFilterQueryManagement; /** - * + * * @param definition * @param queryConfig * @param sortPropertyIds @@ -53,7 +53,7 @@ public class TargetFilterBeanQuery extends AbstractBeanQuery public TargetFilterBeanQuery(final QueryDefinition definition, final Map queryConfig, final Object[] sortPropertyIds, final boolean[] sortStates) { super(definition, queryConfig, sortPropertyIds, sortStates); - if (HawkbitCommonUtil.mapCheckStrKey(queryConfig)) { + if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { searchText = (String) queryConfig.get(SPUIDefinitions.FILTER_BY_TEXT); if (!Strings.isNullOrEmpty(searchText)) { searchText = String.format("%%%s%%", searchText); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java index 63ed91250..82a73df72 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java @@ -65,7 +65,7 @@ public class DistributionBeanQuery extends AbstractBeanQuery final Object[] sortPropertyIds, final boolean[] sortStates) { super(definition, queryConfig, sortPropertyIds, sortStates); - if (HawkbitCommonUtil.mapCheckStrKey(queryConfig)) { + if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { distributionTags = (Collection) queryConfig.get(SPUIDefinitions.FILTER_BY_TAG); searchText = (String) queryConfig.get(SPUIDefinitions.FILTER_BY_TEXT); noTagClicked = (Boolean) queryConfig.get(SPUIDefinitions.FILTER_BY_NO_TAG); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java index fccee7cb5..b5282207a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java @@ -34,6 +34,7 @@ import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.annotation.EventBusListenerMethod; +import com.google.common.base.Strings; import com.vaadin.server.FontAwesome; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.spring.annotation.SpringComponent; @@ -43,7 +44,7 @@ import com.vaadin.ui.Label; /** * Count message label which display current filter details and details on * pinning. - * + * * */ @SpringComponent @@ -82,7 +83,7 @@ public class CountMessageLabel extends Label { /** * Event Listener to show the message count. - * + * * @param event */ @EventBusListenerMethod(scope = EventScope.SESSION) @@ -104,7 +105,7 @@ public class CountMessageLabel extends Label { /** * Event Listener for Pinning Distribution. - * + * * @param event */ @EventBusListenerMethod(scope = EventScope.SESSION) @@ -119,7 +120,7 @@ public class CountMessageLabel extends Label { } /** - * + * */ private void applyStyle() { /* Create label for Targets count message displaying below the table */ @@ -220,7 +221,7 @@ public class CountMessageLabel extends Label { /** * Get Status Message. - * + * * @param status * as status * @return String as msg. @@ -231,7 +232,7 @@ public class CountMessageLabel extends Label { /** * Get Tags Message. - * + * * @param noTargetTagSelected * @param tags * as tags @@ -244,18 +245,18 @@ public class CountMessageLabel extends Label { /** * Get Search Text Message. - * + * * @param searchTxt * as search text * @return String as msg. */ private static String getSerachMsg(final String searchTxt, final String param) { - return HawkbitCommonUtil.checkValidString(searchTxt) ? param : HawkbitCommonUtil.SP_STRING_SPACE; + return Strings.isNullOrEmpty(searchTxt) ? HawkbitCommonUtil.SP_STRING_SPACE : param; } /** * Get Dist set Message. - * + * * @param distId * as serach * @return String as msg. @@ -266,7 +267,7 @@ public class CountMessageLabel extends Label { /** * Get the custom target filter message. - * + * * @param targetFilterQuery * @param param * @return diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java index aa9f346a1..c5d8382b3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.management.targettable; +import static org.apache.commons.lang3.ArrayUtils.isEmpty; + import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -57,7 +59,7 @@ public class TargetBeanQuery extends AbstractBeanQuery { /** * Parametric Constructor. - * + * * @param definition * as Def * @param queryConfig @@ -71,7 +73,7 @@ public class TargetBeanQuery extends AbstractBeanQuery { final Object[] sortIds, final boolean[] sortStates) { super(definition, queryConfig, sortIds, sortStates); - if (HawkbitCommonUtil.mapCheckStrKey(queryConfig)) { + if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { status = (Collection) queryConfig.get(SPUIDefinitions.FILTER_BY_STATUS); targetTags = (String[]) queryConfig.get(SPUIDefinitions.FILTER_BY_TAG); noTagClicked = (Boolean) queryConfig.get(SPUIDefinitions.FILTER_BY_NO_TAG); @@ -84,7 +86,7 @@ public class TargetBeanQuery extends AbstractBeanQuery { pinnedDistId = (Long) queryConfig.get(SPUIDefinitions.ORDER_BY_DISTRIBUTION); } - if (HawkbitCommonUtil.checkBolArray(sortStates)) { + if (isEmpty(sortStates)) { // Initalize Sor sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortIds[0]); // Add sort. diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java index 4e43ea39b..a106b0302 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java @@ -8,6 +8,15 @@ */ package org.eclipse.hawkbit.ui.management.targettable; +import static org.eclipse.hawkbit.ui.management.event.TargetFilterEvent.FILTER_BY_DISTRIBUTION; +import static org.eclipse.hawkbit.ui.management.event.TargetFilterEvent.FILTER_BY_TAG; +import static org.eclipse.hawkbit.ui.management.event.TargetFilterEvent.FILTER_BY_TARGET_FILTER_QUERY; +import static org.eclipse.hawkbit.ui.management.event.TargetFilterEvent.FILTER_BY_TEXT; +import static org.eclipse.hawkbit.ui.management.event.TargetFilterEvent.REMOVE_FILTER_BY_DISTRIBUTION; +import static org.eclipse.hawkbit.ui.management.event.TargetFilterEvent.REMOVE_FILTER_BY_TAG; +import static org.eclipse.hawkbit.ui.management.event.TargetFilterEvent.REMOVE_FILTER_BY_TARGET_FILTER_QUERY; +import static org.eclipse.hawkbit.ui.management.event.TargetFilterEvent.REMOVE_FILTER_BY_TEXT; + import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -137,7 +146,7 @@ public class TargetTable extends AbstractTable { public void onEvents(final List events) { final Object firstEvent = events.get(0); if (TargetCreatedEvent.class.isInstance(firstEvent)) { - onTargetCreatedEvents(); + refreshTargets(); } else if (TargetInfoUpdateEvent.class.isInstance(firstEvent)) { onTargetInfoUpdateEvents((List) events); } else if (TargetDeletedEvent.class.isInstance(firstEvent)) { @@ -236,12 +245,6 @@ public class TargetTable extends AbstractTable { return targetTableContainer; } - /* - * (non-Javadoc) - * - * @see hawkbit.server.ui.common.table.AbstractTable#addContainerProperties - * (com.vaadin.data.Container ) - */ @Override protected void addContainerProperties(final Container container) { HawkbitCommonUtil.addTargetTableContainerProperties(container); @@ -263,10 +266,7 @@ public class TargetTable extends AbstractTable { @Override protected Object getItemIdToSelect() { - if (managementUIState.getSelectedTargetIdName().isPresent()) { - return managementUIState.getSelectedTargetIdName().get(); - } - return null; + return managementUIState.getSelectedTargetIdName().orElse(null); } @Override @@ -303,7 +303,6 @@ public class TargetTable extends AbstractTable { columnList.add(new TableColumn(SPUIDefinitions.TARGET_STATUS_PIN_TOGGLE_ICON, "", 0.0F)); } return columnList; - } @Override @@ -437,14 +436,8 @@ public class TargetTable extends AbstractTable { } private boolean isPinned(final String targetId) { - boolean result; - if (managementUIState.getDistributionTableFilters().getPinnedTargetId().isPresent() - && targetId.equals(managementUIState.getDistributionTableFilters().getPinnedTargetId().get())) { - result = true; - } else { - result = false; - } - return result; + return managementUIState.getDistributionTableFilters().getPinnedTargetId().isPresent() + && targetId.equals(managementUIState.getDistributionTableFilters().getPinnedTargetId().get()); } /** @@ -461,7 +454,6 @@ public class TargetTable extends AbstractTable { } else { unPinTarget(event.getButton()); } - } /** @@ -516,9 +508,7 @@ public class TargetTable extends AbstractTable { /** * Set style of target table. - * */ - @SuppressWarnings("serial") private void styleTargetTable() { setCellStyleGenerator((source, itemId, propertyId) -> null); } @@ -530,7 +520,6 @@ public class TargetTable extends AbstractTable { && isNoTagAssigned(event)) { tagAssignment(event); } - } private Boolean isNoTagAssigned(final DragAndDropEvent event) { @@ -727,24 +716,22 @@ public class TargetTable extends AbstractTable { } private static boolean checkFilterEvent(final TargetFilterEvent filterEvent) { - boolean isFilterEvent; - boolean isFilter; - boolean isRemoveFilters; - boolean isStatusFilter; - isFilter = filterEvent == TargetFilterEvent.FILTER_BY_TEXT || filterEvent == TargetFilterEvent.FILTER_BY_TAG - || filterEvent == TargetFilterEvent.FILTER_BY_DISTRIBUTION - || filterEvent == TargetFilterEvent.FILTER_BY_TARGET_FILTER_QUERY; + return isNormalFilter(filterEvent) || isRemoveFilterEvent(filterEvent) || isStatusFilterEvent(filterEvent); + } - isRemoveFilters = filterEvent == TargetFilterEvent.REMOVE_FILTER_BY_TEXT - || filterEvent == TargetFilterEvent.REMOVE_FILTER_BY_TAG - || filterEvent == TargetFilterEvent.REMOVE_FILTER_BY_DISTRIBUTION - || filterEvent == TargetFilterEvent.REMOVE_FILTER_BY_TARGET_FILTER_QUERY; - isStatusFilter = filterEvent == TargetFilterEvent.FILTER_BY_STATUS + private static boolean isStatusFilterEvent(final TargetFilterEvent filterEvent) { + return filterEvent == TargetFilterEvent.FILTER_BY_STATUS || filterEvent == TargetFilterEvent.REMOVE_FILTER_BY_STATUS; + } - isFilterEvent = isFilter || isRemoveFilters || isStatusFilter; + private static boolean isRemoveFilterEvent(final TargetFilterEvent filterEvent) { + return filterEvent == REMOVE_FILTER_BY_TEXT || filterEvent == REMOVE_FILTER_BY_TAG + || filterEvent == REMOVE_FILTER_BY_DISTRIBUTION || filterEvent == REMOVE_FILTER_BY_TARGET_FILTER_QUERY; + } - return isFilterEvent; + private static boolean isNormalFilter(final TargetFilterEvent filterEvent) { + return filterEvent == FILTER_BY_TEXT || filterEvent == FILTER_BY_TAG || filterEvent == FILTER_BY_DISTRIBUTION + || filterEvent == FILTER_BY_TARGET_FILTER_QUERY; } private String getTargetTableStyle(final Long assignedDistributionSetId, final Long installedDistributionSetId) { @@ -757,14 +744,8 @@ public class TargetTable extends AbstractTable { return SPUIDefinitions.HIGHTLIGHT_ORANGE; } return null; - } - /** - * @param itemId - * @param propertyId - * @return - */ private String createTargetTableStyle(final Object itemId, final Object propertyId) { if (null == propertyId) { final Item item = getItem(itemId); @@ -775,7 +756,6 @@ public class TargetTable extends AbstractTable { return getTargetTableStyle(assignedDistributionSetId, installedDistributionSetId); } return null; - } private void styleTargetTableOnPinning() { @@ -800,12 +780,6 @@ public class TargetTable extends AbstractTable { }); } - /** - * To add new target to the table on Top. - * - * @param newTarget - * as reference - */ private void refreshTargets() { final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource(); final int size = targetContainer.size(); @@ -864,9 +838,7 @@ public class TargetTable extends AbstractTable { } } // workaround until push is available for action history, re-select - // the - // updated target so - // the action history gets refreshed. + // the updated target so the action history gets refreshed. if (isLastSelectedTarget(targetIdName)) { lastSelectedTarget = target; } @@ -879,10 +851,6 @@ public class TargetTable extends AbstractTable { } } - private void onTargetCreatedEvents() { - refreshTargets(); - } - private List getTargetTableFilters(final Target target) { final TargetTableFilters targetTableFilters = managementUIState.getTargetTableFilters(); final List filters = new ArrayList<>(); @@ -901,7 +869,6 @@ public class TargetTable extends AbstractTable { */ @Override public void selectAll() { - // As Vaadin Table only returns the current ItemIds which are visible // you don't need to search explicit for them. setValue(getItemIds()); @@ -923,7 +890,6 @@ public class TargetTable extends AbstractTable { * Set total target count and count of targets truncated in target table. */ private void resetTargetCountDetails() { - final long size; final long totalTargetsCount = getTotalTargetsCount(); managementUIState.setTargetsCountAll(totalTargetsCount); @@ -931,11 +897,10 @@ public class TargetTable extends AbstractTable { String[] targetTags = null; Long distributionId = null; String searchText = null; - Boolean noTagClicked; Long pinnedDistId = null; if (isFilteredByTags()) { - targetTags = (String[]) managementUIState.getTargetTableFilters().getClickedTargetTags().toArray(); + targetTags = managementUIState.getTargetTableFilters().getClickedTargetTags().toArray(new String[0]); } if (isFilteredByStatus()) { status = managementUIState.getTargetTableFilters().getClickedStatusTargetTags(); @@ -946,12 +911,12 @@ public class TargetTable extends AbstractTable { if (isFilteredByText()) { searchText = String.format("%%%s%%", managementUIState.getTargetTableFilters().getSearchText().get()); } - noTagClicked = managementUIState.getTargetTableFilters().isNoTagSelected(); + final boolean noTagClicked = managementUIState.getTargetTableFilters().isNoTagSelected(); if (managementUIState.getTargetTableFilters().getPinnedDistId().isPresent()) { pinnedDistId = managementUIState.getTargetTableFilters().getPinnedDistId().get(); } - size = getTargetsCountWithFilter(totalTargetsCount, status, targetTags, distributionId, searchText, + final long size = getTargetsCountWithFilter(totalTargetsCount, status, targetTags, distributionId, searchText, noTagClicked, pinnedDistId); if (size > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutBeanQuery.java index 0bfa349d0..a1ab1024a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutBeanQuery.java @@ -8,10 +8,13 @@ */ package org.eclipse.hawkbit.ui.rollout.rollout; +import static org.apache.commons.lang3.ArrayUtils.isEmpty; + import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.ArrayUtils; import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -34,7 +37,7 @@ import org.vaadin.addons.lazyquerycontainer.QueryDefinition; import com.google.common.base.Strings; /** - * + * * Simple implementation of generics bean query which dynamically loads a batch * of {@link ProxyRollout} beans. * @@ -55,7 +58,7 @@ public class RolloutBeanQuery extends AbstractBeanQuery { /** * Parametric Constructor. - * + * * @param definition * as QueryDefinition * @param queryConfig @@ -71,7 +74,7 @@ public class RolloutBeanQuery extends AbstractBeanQuery { searchText = getSearchText(); - if (HawkbitCommonUtil.checkBolArray(sortStates)) { + if (isEmpty(sortStates)) { // Initalize Sor sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortIds[0]); // Add sort. @@ -95,7 +98,7 @@ public class RolloutBeanQuery extends AbstractBeanQuery { /* * (non-Javadoc) - * + * * @see * org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery#loadBeans(int, * int) @@ -149,7 +152,7 @@ public class RolloutBeanQuery extends AbstractBeanQuery { /* * (non-Javadoc) - * + * * @see * org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery#saveBeans(java * .util.List, java.util.List, java.util.List) @@ -164,7 +167,7 @@ public class RolloutBeanQuery extends AbstractBeanQuery { /* * (non-Javadoc) - * + * * @see org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery#size() */ @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index 9ebb1d065..be7339324 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -8,10 +8,15 @@ */ package org.eclipse.hawkbit.ui.rollout.rollout; +import static org.eclipse.hawkbit.ui.rollout.DistributionBarHelper.getTooltip; import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.HTML_LI_CLOSE_TAG; import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.HTML_LI_OPEN_TAG; import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.HTML_UL_CLOSE_TAG; import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.HTML_UL_OPEN_TAG; +import static org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions.ACTION; +import static org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions.VAR_DIST_NAME_VERSION; +import static org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions.VAR_STATUS; +import static org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS; import java.util.ArrayList; import java.util.Arrays; @@ -122,7 +127,7 @@ public class RolloutListGrid extends AbstractGrid { /** * Handles the RolloutChangeEvent to refresh the item in the grid. - * + * * @param rolloutChangeEvent * the event which contains the rollout which has been changed */ @@ -428,19 +433,22 @@ public class RolloutListGrid extends AbstractGrid { } private String getDescription(final CellReference cell) { - if (SPUILabelDefinitions.VAR_STATUS.equals(cell.getPropertyId())) { - return cell.getProperty().getValue().toString().toLowerCase(); - } else if (SPUILabelDefinitions.ACTION.equals(cell.getPropertyId())) { - return SPUILabelDefinitions.ACTION.toLowerCase(); + + String description = null; + + if (VAR_STATUS.equals(cell.getPropertyId())) { + description = cell.getProperty().getValue().toString().toLowerCase(); + } else if (ACTION.equals(cell.getPropertyId())) { + description = ACTION.toLowerCase(); } else if (ROLLOUT_RENDERER_DATA.equals(cell.getPropertyId())) { - return ((RolloutRendererData) cell.getProperty().getValue()).getName(); - } else if (SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS.equals(cell.getPropertyId())) { - return DistributionBarHelper - .getTooltip(((TotalTargetCountStatus) cell.getValue()).getStatusTotalCountMap()); - } else if (SPUILabelDefinitions.VAR_DIST_NAME_VERSION.equals(cell.getPropertyId())) { - return getDSDetails(cell.getItem()); + description = ((RolloutRendererData) cell.getProperty().getValue()).getName(); + } else if (VAR_TOTAL_TARGETS_COUNT_STATUS.equals(cell.getPropertyId())) { + description = getTooltip(((TotalTargetCountStatus) cell.getValue()).getStatusTotalCountMap()); + } else if (VAR_DIST_NAME_VERSION.equals(cell.getPropertyId())) { + description = getDSDetails(cell.getItem()); } - return null; + + return description; } private static String getDSDetails(final Item rolloutItem) { @@ -497,7 +505,7 @@ public class RolloutListGrid extends AbstractGrid { /** * Constructor - * + * * @param containerDataSource * the container */ @@ -548,7 +556,7 @@ public class RolloutListGrid extends AbstractGrid { } /** - * + * * Converter to convert {@link RolloutStatus} to string. * */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupBeanQuery.java index 5a37d1341..002adbe03 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupBeanQuery.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.ArrayUtils; import org.eclipse.hawkbit.repository.RolloutGroupManagement; import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.model.RolloutGroup; @@ -52,7 +53,7 @@ public class RolloutGroupBeanQuery extends AbstractBeanQuery /** * Parametric Constructor. - * + * * @param definition * as QueryDefinition * @param queryConfig @@ -68,7 +69,7 @@ public class RolloutGroupBeanQuery extends AbstractBeanQuery rolloutId = getRolloutId(); - if (HawkbitCommonUtil.checkBolArray(sortStates)) { + if (ArrayUtils.isEmpty(sortStates)) { // Initalize Sor sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortPropertyIds[0]); // Add sort. @@ -79,9 +80,6 @@ public class RolloutGroupBeanQuery extends AbstractBeanQuery } } - /** - * @return - */ private Long getRolloutId() { return getRolloutUIState().getRolloutId().isPresent() ? getRolloutUIState().getRolloutId().get() : null; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupListGrid.java index 19df8b139..1e66d1977 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupListGrid.java @@ -49,6 +49,7 @@ import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent; +import com.vaadin.ui.renderers.ClickableRenderer.RendererClickListener; import com.vaadin.ui.renderers.HtmlRenderer; /** @@ -238,16 +239,10 @@ public class RolloutGroupListGrid extends AbstractGrid { getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS).setRenderer(new HtmlRenderer(), new TotalTargetCountStatusConverter()); if (permissionChecker.hasRolloutTargetsReadPermission()) { - getColumn(ROLLOUT_RENDERER_DATA).setRenderer(new RolloutRenderer(this::onClickOfRolloutGroupName)); + getColumn(ROLLOUT_RENDERER_DATA).setRenderer(new RolloutRenderer(new RolloutGroupClickListener())); } } - private void onClickOfRolloutGroupName(final RendererClickEvent event) { - rolloutUIState - .setRolloutGroup(rolloutGroupManagement.findRolloutGroupWithDetailedStatus((Long) event.getItemId())); - eventBus.publish(this, RolloutEvent.SHOW_ROLLOUT_GROUP_TARGETS); - } - @Override protected void setHiddenColumns() { final List columnsToBeHidden = new ArrayList<>(); @@ -310,11 +305,22 @@ public class RolloutGroupListGrid extends AbstractGrid { }); } + private class RolloutGroupClickListener implements RendererClickListener { + + private static final long serialVersionUID = 1L; + + @Override + public void click(final RendererClickEvent event) { + rolloutUIState.setRolloutGroup( + rolloutGroupManagement.findRolloutGroupWithDetailedStatus((Long) event.getItemId())); + eventBus.publish(this, RolloutEvent.SHOW_ROLLOUT_GROUP_TARGETS); + } + } + /** * * Converts {@link TotalTargetCountStatus} into formatted string with status * and count details. - * */ class TotalTargetCountStatusConverter implements Converter { @@ -322,15 +328,13 @@ public class RolloutGroupListGrid extends AbstractGrid { @Override public TotalTargetCountStatus convertToModel(final String value, - final Class targetType, final Locale locale) - throws com.vaadin.data.util.converter.Converter.ConversionException { + final Class targetType, final Locale locale) { return null; } @Override public String convertToPresentation(final TotalTargetCountStatus value, - final Class targetType, final Locale locale) - throws com.vaadin.data.util.converter.Converter.ConversionException { + final Class targetType, final Locale locale) { return DistributionBarHelper.getDistributionBarAsHTMLString(value.getStatusTotalCountMap()); } @@ -346,9 +350,7 @@ public class RolloutGroupListGrid extends AbstractGrid { } /** - * * Converts {@link RolloutGroupStatus} to string. - * */ class RolloutGroupStatusConverter implements Converter { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java index 18ffda663..3270e07b4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java @@ -8,15 +8,12 @@ */ package org.eclipse.hawkbit.ui.utils; -import java.io.FileOutputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.TimeZone; import org.eclipse.hawkbit.repository.EntityFactory; @@ -30,10 +27,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; -import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus.Status; import org.eclipse.hawkbit.ui.rollout.StatusFontIcon; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; @@ -53,9 +47,6 @@ import com.vaadin.ui.UI; /** * Common util class. - * - * - * */ public final class HawkbitCommonUtil { @@ -78,13 +69,11 @@ public final class HawkbitCommonUtil { public static final String HTML_UL_CLOSE_TAG = ""; public static final String HTML_UL_OPEN_TAG = "
      "; - private static final Logger LOG = LoggerFactory.getLogger(HawkbitCommonUtil.class); - private static final String JS_DRAG_COUNT_REM_CHILD = " if(x) { document.head.removeChild(x); } "; - public static final String DIV_DESCRIPTION = "

      "; + public static final String DIV_DESCRIPTION_START = "

      "; - public static final String DIV_CLOSE = "

      "; + public static final String DIV_DESCRIPTION_END = "

      "; private static final String DRAG_COUNT_ELEMENT = "var x = document.getElementById('sp-drag-count'); "; private static final String CLOSE_BRACE = "\"; }';"; @@ -112,129 +101,25 @@ public final class HawkbitCommonUtil { private static final String ASSIGN_DIST_SET = "assignedDistributionSet"; private static final String INSTALL_DIST_SET = "installedDistributionSet"; - /** - * Define empty string. - */ - /** - * Private Constructor. - */ private HawkbitCommonUtil() { } /** - * Check Map is valid. - * - * @param mapCheck - * as Map - * @return boolean as flag + * Check wether the given map is not {@code null} and not empty. + * + * @param mapToCheck + * the map to validate + * @return {@code true} if the given map is not {@code null} and not empty. + * Otherwise {@code false} */ - public static boolean mapCheckObjKey(final Map mapCheck) { - boolean validMap = false; - if (mapCheck != null && !mapCheck.isEmpty()) { - validMap = true; - } - - return validMap; - } - - /** - * Check Map is valid. - * - * @param mapCheck - * as Map - * @return boolean as flag - */ - public static boolean mapCheckStrKey(final Map mapCheck) { - boolean validMap = false; - if (mapCheck != null && !mapCheck.isEmpty()) { - validMap = true; - } - - return validMap; - } - - /** - * Check Map is valid. - * - * @param mapCheck - * as Map - * @return boolean as flag - */ - public static boolean mapCheckStrings(final Map mapCheck) { - boolean validMap = false; - if (mapCheck != null && !mapCheck.isEmpty()) { - validMap = true; - } - - return validMap; - } - - /** - * Check List is valid. - * - * @param listCheck - * as List - * @return boolean as flag - */ - public static boolean listCheckObj(final List listCheck) { - boolean validList = false; - if (listCheck != null && !listCheck.isEmpty()) { - validList = true; - } - - return validList; - } - - /** - * Check Boolean Array is valid. - * - * @param bolArray - * as List - * @return boolean as flag - */ - public static boolean checkBolArray(final boolean[] bolArray) { - boolean validBolArray = false; - if (bolArray != null && bolArray.length > 0) { - validBolArray = true; - } - - return validBolArray; - } - - /** - * Check String null, return empty. - * - * @param nString - * as String - * @return String - */ - public static String getEmptyString(final String nString) { - String emptyStr = SP_STRING_SPACE; - if (nString != null && nString.length() > 0) { - emptyStr = nString; - } - return emptyStr; - } - - /** - * Check valid String. - * - * @param nString - * as String - * @return boolean as flag - */ - public static boolean checkValidString(final String nString) { - boolean strValid = false; - if (nString != null && nString.length() > 0) { - strValid = true; - } - return strValid; + public static boolean isNotNullOrEmpty(final Map mapToCheck) { + return mapToCheck != null && !mapToCheck.isEmpty(); } /** * Trim the text and convert into null in case of empty string. - * + * * @param text * as text to be trimed * @return null if the text is null or if the text is blank, text.trim() if @@ -251,7 +136,7 @@ public final class HawkbitCommonUtil { /** * Concatenate the given text all the string arguments with the given * delimiter. - * + * * @param delimiter * the delimiter text to be used while concatenation. * @param texts @@ -277,7 +162,7 @@ public final class HawkbitCommonUtil { /** * Returns the input text within html bold tag ... - * + * * @param text * is the text to be converted in to Bold * @return null if the input text param is null returns text with ... @@ -296,16 +181,13 @@ public final class HawkbitCommonUtil { /** * Get target label Id. - * + * * @param controllerId * as String * @return String as label name */ public static String getTargetLabelId(final String controllerId) { - final StringBuilder labelId = new StringBuilder("target"); - labelId.append('.'); - labelId.append(controllerId); - return labelId.toString(); + return new StringBuilder("target").append('.').append(controllerId).toString(); } /** @@ -318,12 +200,7 @@ public final class HawkbitCommonUtil { * @return String distribution label id */ public static String getDistributionLabelId(final String name, final String version) { - final StringBuilder labelId = new StringBuilder("dist"); - labelId.append('.'); - labelId.append(name); - labelId.append('.'); - labelId.append(version); - return labelId.toString(); + return new StringBuilder("dist").append('.').append(name).append('.').append(version).toString(); } /** @@ -336,12 +213,7 @@ public final class HawkbitCommonUtil { * @return String software module label id */ public static String getSwModuleLabelId(final String name, final String version) { - final StringBuilder labelId = new StringBuilder("swModule"); - labelId.append('.'); - labelId.append(name); - labelId.append('.'); - labelId.append(version); - return labelId.toString(); + return new StringBuilder("swModule").append('.').append(name).append('.').append(version).toString(); } /** @@ -354,28 +226,26 @@ public final class HawkbitCommonUtil { * @return String */ public static String getSwModuleNameDescLabel(final String name, final String desc) { - final StringBuilder labelDesc = new StringBuilder(); - labelDesc.append(DIV_DESCRIPTION + getBoldHTMLText(getFormattedName(name)) + "
      " + getFormattedName(desc)); - labelDesc.append(DIV_CLOSE); - return labelDesc.toString(); + return new StringBuilder().append( + DIV_DESCRIPTION_START + getBoldHTMLText(getFormattedName(name)) + "
      " + getFormattedName(desc)) + .append(DIV_DESCRIPTION_END).toString(); } /** * Get Label for Artifact Details. - * + * * @param name * @return */ public static String getArtifactoryDetailsLabelId(final String name) { - final StringBuilder labelDesc = new StringBuilder(); - labelDesc.append(DIV_DESCRIPTION + "Artifact Details of " + getBoldHTMLText(getFormattedName(name))); - labelDesc.append(DIV_CLOSE); - return labelDesc.toString(); + return new StringBuilder() + .append(DIV_DESCRIPTION_START + "Artifact Details of " + getBoldHTMLText(getFormattedName(name))) + .append(DIV_DESCRIPTION_END).toString(); } /** * Get Label for Artifact Details. - * + * * @param caption * as caption of the details * @param name @@ -383,28 +253,26 @@ public final class HawkbitCommonUtil { * @return */ public static String getSoftwareModuleName(final String caption, final String name) { - final StringBuilder labelDesc = new StringBuilder(); - labelDesc.append(DIV_DESCRIPTION + caption + " : " + getBoldHTMLText(getFormattedName(name))); - labelDesc.append(DIV_CLOSE); - return labelDesc.toString(); + return new StringBuilder() + .append(DIV_DESCRIPTION_START + caption + " : " + getBoldHTMLText(getFormattedName(name))) + .append(DIV_DESCRIPTION_END).toString(); } /** * Get Label for Action History Details. - * + * * @param name * @return */ public static String getActionHistoryLabelId(final String name) { - final StringBuilder labelDesc = new StringBuilder(); - labelDesc.append(DIV_DESCRIPTION + "Action History For " + getBoldHTMLText(getFormattedName(name))); - labelDesc.append(DIV_CLOSE); - return labelDesc.toString(); + return new StringBuilder() + .append(DIV_DESCRIPTION_START + "Action History For " + getBoldHTMLText(getFormattedName(name))) + .append(DIV_DESCRIPTION_END).toString(); } /** * Get tool tip for Poll status. - * + * * @param pollStatus * @param i18N * @return @@ -434,7 +302,7 @@ public final class HawkbitCommonUtil { /** * Find extra height required to increase by all the components to utilize * the full height of browser for the responsive UI. - * + * * @param newBrowserHeight * as current browser height. * @return extra height required to increase. @@ -600,17 +468,16 @@ public final class HawkbitCommonUtil { * @return String name */ public static String removePrefix(final String text, final String prefix) { - String str = null; - if (null != text) { - str = text.replaceFirst(prefix, ""); + if (text != null) { + return text.replaceFirst(prefix, ""); } - return str; + return null; } /** * Create javascript to display number of targets or distributions your are * dragging in the drag image. - * + * * @param count * @return */ @@ -630,7 +497,7 @@ public final class HawkbitCommonUtil { /** * Get formatted label.Appends ellipses if content does not fit the label. - * + * * @param labelContent * content * @return Label @@ -640,7 +507,6 @@ public final class HawkbitCommonUtil { labelValue.setSizeFull(); labelValue.addStyleName(SPUIDefinitions.TEXT_STYLE); labelValue.addStyleName("label-style"); - return labelValue; } @@ -669,14 +535,11 @@ public final class HawkbitCommonUtil { final float extraBrowserHeight = HawkbitCommonUtil.findRequiredSwModuleExtraHeight(newHeight); final float tableHeight = SPUIDefinitions.MIN_UPLOAD_ARTIFACT_TABLE_HEIGHT + extraBrowserHeight; artifactDetailsLayout.setHeight(tableHeight, Unit.PIXELS); - } /** * Set height of artifact details table and drop area layout. * - * @param dropLayout - * drop area layout * @param artifactDetailsLayout * artifact details table * @param newHeight @@ -687,28 +550,11 @@ public final class HawkbitCommonUtil { final float tableHeight = SPUIDefinitions.MIN_TARGET_DIST_TABLE_HEIGHT + HawkbitCommonUtil.findRequiredExtraHeight(newHeight) + 62; artifactDetailsLayout.setHeight(tableHeight, Unit.PIXELS); - - } - - /** - * Close output stream. - * - * @param fos - * out stream to be closed - */ - public static void closeOutoutStream(final FileOutputStream fos) { - try { - if (fos != null) { - fos.close(); - } - } catch (final IOException ioe) { - LOG.error("Colud not close output stream", ioe); - } } /** * Duplicate check - Unique Key. - * + * * @param name * as string * @param version @@ -721,16 +567,12 @@ public final class HawkbitCommonUtil { final SoftwareManagement swMgmtService = SpringContextHelper.getBean(SoftwareManagement.class); final SoftwareModule swModule = swMgmtService.findSoftwareModuleByNameAndVersion(name, version, swMgmtService.findSoftwareModuleTypeByName(type)); - boolean duplicate = false; - if (swModule != null) { - duplicate = true; - } - return duplicate; + return swModule != null; } /** * Add new base software module. - * + * * @param bsname * base software module name * @param bsversion @@ -773,20 +615,16 @@ public final class HawkbitCommonUtil { * @return */ public static String getDistributionNameAndVersion(final String distName, final String distVersion) { - final StringBuilder stringBuilder = new StringBuilder(distName); - stringBuilder.append(':').append(distVersion); - return stringBuilder.toString(); + return new StringBuilder(distName).append(':').append(distVersion).toString(); } /** * Display Target Tag action message. - * + * * @param tagName * as tag name * @param result * as TargetTagAssigmentResult - * @param tagsClickedList - * as clicked tag list * @param i18n * I18N * @return message @@ -827,7 +665,7 @@ public final class HawkbitCommonUtil { /** * Create a lazy query container for the given query bean factory with empty * configurations. - * + * * @param queryFactory * is reference of {@link BeanQueryFactory} on which lazy container should create. @@ -841,9 +679,9 @@ public final class HawkbitCommonUtil { } /** - * + * * Create lazy query container for DS type. - * + * * @param queryFactory * @return LazyQueryContainer */ @@ -856,7 +694,7 @@ public final class HawkbitCommonUtil { /** * Set distribution table column properties. - * + * * @param container * table container */ @@ -874,7 +712,7 @@ public final class HawkbitCommonUtil { /** * Reset the software module table rows highlight css. - * + * * @return javascript to rest software module table rows highlight css. */ public static String getScriptSMHighlightReset() { @@ -883,73 +721,66 @@ public final class HawkbitCommonUtil { /** * Highlight software module rows with the color of sw-type. - * + * * @param colorCSS * color to generate the css script. * @return javascript to append software module table rows with highlighted * color. */ public static String getScriptSMHighlightWithColor(final String colorCSS) { - final StringBuilder scriptBuilder = new StringBuilder(); - scriptBuilder.append(SM_HIGHLIGHT_SCRIPT_CURRENT).append("smHighlightStyle = smHighlightStyle + \"") - .append(colorCSS).append("\";").append(SM_HIGHLIGHT_SCRIPT_APPEND); - return scriptBuilder.toString(); + return new StringBuilder().append(SM_HIGHLIGHT_SCRIPT_CURRENT) + .append("smHighlightStyle = smHighlightStyle + \"").append(colorCSS).append("\";") + .append(SM_HIGHLIGHT_SCRIPT_APPEND).toString(); } /** * Get javascript to reflect new color selection in color picker preview for * name and description fields . - * + * * @param colorPickedPreview * changed color * @return javascript for the selected color. */ public static String changeToNewSelectedPreviewColor(final String colorPickedPreview) { - final StringBuilder scriptBuilder = new StringBuilder(); - scriptBuilder.append(NEW_PREVIEW_COLOR_REMOVE_SCRIPT).append(NEW_PREVIEW_COLOR_CREATE_SCRIPT) + return new StringBuilder().append(NEW_PREVIEW_COLOR_REMOVE_SCRIPT).append(NEW_PREVIEW_COLOR_CREATE_SCRIPT) .append("var newColorPreviewStyle = \".v-app .new-tag-name{ border: solid 3px ") .append(colorPickedPreview) .append(" !important; width:138px; margin-left:2px !important; box-shadow:none !important; } \"; ") .append("newColorPreviewStyle = newColorPreviewStyle + \".v-app .new-tag-desc{ border: solid 3px ") .append(colorPickedPreview) .append(" !important; width:138px; height:75px !important; margin-top:4px !important; margin-left:2px !important;;box-shadow:none !important;} \"; ") - .append(NEW_PREVIEW_COLOR_SET_STYLE_SCRIPT); - return scriptBuilder.toString(); + .append(NEW_PREVIEW_COLOR_SET_STYLE_SCRIPT).toString(); } /** * Get javascript to reflect new color selection for preview button. - * + * * @param color * changed color * @return javascript for the selected color. */ public static String getPreviewButtonColorScript(final String color) { - final StringBuilder scriptBuilder = new StringBuilder(); - scriptBuilder.append(PREVIEW_BUTTON_COLOR_REMOVE_SCRIPT).append(PREVIEW_BUTTON_COLOR_CREATE_SCRIPT) + return new StringBuilder().append(PREVIEW_BUTTON_COLOR_REMOVE_SCRIPT).append(PREVIEW_BUTTON_COLOR_CREATE_SCRIPT) .append("var tagColorPreviewStyle = \".v-app .tag-color-preview{ height: 15px !important; padding: 0 10px !important; border: 0px !important; margin-left:12px !important; margin-top: 4px !important; border-width: 0 !important; background: ") .append(color) .append(" } .v-app .tag-color-preview:after{ border-color: none !important; box-shadow:none !important;} \"; ") - .append(PREVIEW_BUTTON_COLOR_SET_STYLE_SCRIPT); - return scriptBuilder.toString(); + .append(PREVIEW_BUTTON_COLOR_SET_STYLE_SCRIPT).toString(); } /** * Java script to display drop hints for tags. - * + * * @return javascript */ public static String dispTargetTagsDropHintScript() { final String targetDropStyle = "document.getElementById('show-filter-drop-hint').innerHTML = '." + UI.getCurrent().getTheme() + " .target-tag-drop-hint { border: 1px dashed #26547a !important; }';"; - final StringBuilder scriptBuilder = new StringBuilder(); - scriptBuilder.append(TARGET_TAG_DROP_CREATE_SCRIPT).append(targetDropStyle); - return scriptBuilder.toString(); + return new StringBuilder().append(TARGET_TAG_DROP_CREATE_SCRIPT).append(targetDropStyle).toString(); } /** * Java script to hide drop hints for tags. - * + * * @return javascript */ public static String hideTargetTagsDropHintScript() { @@ -958,20 +789,18 @@ public final class HawkbitCommonUtil { /** * Java script to display drop hint for Delete button. - * + * * @return javascript */ public static String dispDeleteDropHintScript() { final String deleteTagDropStyle = "document.getElementById('show-delete-drop-hint').innerHTML = '." + UI.getCurrent().getTheme() + " .show-delete-drop-hint { border: 1px dashed #26547a !important; }';"; - final StringBuilder scriptBuilder = new StringBuilder(); - scriptBuilder.append(DELETE_DROP_CREATE_SCRIPT).append(deleteTagDropStyle); - return scriptBuilder.toString(); + return new StringBuilder().append(DELETE_DROP_CREATE_SCRIPT).append(deleteTagDropStyle).toString(); } /** * Java script to hide drop hint for delete button. - * + * * @return javascript */ public static String hideDeleteDropHintScript() { @@ -979,9 +808,8 @@ public final class HawkbitCommonUtil { } /** - * * Add target table container properties. - * + * * @param container * table container */ @@ -1013,13 +841,11 @@ public final class HawkbitCommonUtil { targetTableContainer.addContainerProperty(ASSIGN_DIST_SET, DistributionSet.class, null, false, true); targetTableContainer.addContainerProperty(INSTALL_DIST_SET, DistributionSet.class, null, false, true); - } /** - * * Apply style for status label in target table. - * + * * @param targetTable * target table * @param pinBtn @@ -1049,7 +875,7 @@ public final class HawkbitCommonUtil { /** * Set status progress bar value. - * + * * @param bar * DistributionBar * @param statusName @@ -1068,7 +894,7 @@ public final class HawkbitCommonUtil { /** * Initialize status progress bar with values and number of parts on load. - * + * * @param bar * DistributionBar * @param item @@ -1087,7 +913,6 @@ public final class HawkbitCommonUtil { 0); HawkbitCommonUtil.setBarPartSize(bar, TotalTargetCountStatus.Status.FINISHED.toString().toLowerCase(), 0, 1); - } else { bar.setNumberOfParts(6); setProgressBarDetails(bar, item); @@ -1097,7 +922,7 @@ public final class HawkbitCommonUtil { /** * Formats the finished percentage of a rollout group into a string with one * digit after comma. - * + * * @param rolloutGroup * the rollout group * @param finishedPercentage @@ -1126,7 +951,7 @@ public final class HawkbitCommonUtil { /** * Reset the values of status progress bar on change of values. - * + * * @param bar * DistributionBar * @param item @@ -1150,38 +975,17 @@ public final class HawkbitCommonUtil { } private static boolean isNoTargets(final Long... statusCount) { - if (Arrays.asList(statusCount).stream().filter(value -> value > 0).toArray().length > 0) { - return false; - } - return true; + return (Arrays.asList(statusCount).stream().filter(value -> value > 0).toArray().length) == 0; } private static Long getStatusCount(final String propertName, final Item item) { return (Long) item.getItemProperty(propertName).getValue(); } - /** - * Get the formatted string of status and target count details. - * - * @param details - * details of status and count - * @return String - */ - public static String getFormattedString(final Map details) { - final StringBuilder val = new StringBuilder(); - if (details == null || details.isEmpty()) { - return null; - } - for (final Entry entry : details.entrySet()) { - val.append(entry.getKey()).append(":").append(entry.getValue()).append(","); - } - return val.substring(0, val.length() - 1); - } - /** * Returns a formatted string as needed by label custom render .This string * holds the properties of a status label. - * + * * @param value * label value * @param style @@ -1198,13 +1002,12 @@ public final class HawkbitCommonUtil { if (!Strings.isNullOrEmpty(style)) { val.append("style:").append(style).append(","); } - val.append("id:").append(id); - return val.toString(); + return val.append("id:").append(id).toString(); } /** * Receive the code point of a given StatusFontIcon. - * + * * @param statusFontIcon * the status font icon * @return the code point of the StatusFontIcon @@ -1216,5 +1019,4 @@ public final class HawkbitCommonUtil { return statusFontIcon.getFontIcon() != null ? Integer.toString(statusFontIcon.getFontIcon().getCodepoint()) : null; } - } From ce2bdf82df45ae41df4250242cb691e5e8c0406c Mon Sep 17 00:00:00 2001 From: Dominic Schabel Date: Tue, 16 Aug 2016 09:45:19 +0200 Subject: [PATCH 26/42] Ignored test removed Signed-off-by: Dominic Schabel --- .../rest/resource/MgmtTargetResourceTest.java | 64 ------------------- 1 file changed, 64 deletions(-) diff --git a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index f647106af..57e2c096d 100644 --- a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -52,9 +52,7 @@ import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; import org.eclipse.hawkbit.rest.util.JsonBuilder; import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter; import org.eclipse.hawkbit.util.IpUtil; -import org.json.JSONException; import org.json.JSONObject; -import org.junit.Ignore; import org.junit.Test; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Slice; @@ -80,7 +78,6 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { private static final String TARGET_DESCRIPTION_TEST = "created in test"; - // json paths private static final String JSON_PATH_ROOT = "$"; // fields, attributes @@ -633,69 +630,8 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { final String knownName = "someName"; createSingleTarget(knownControllerId, knownName); - // test - mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId + "/installedDS")) .andExpect(status().isNoContent()).andExpect(content().string("")); - - } - - @Test - @Ignore - public void getInstalledDistributionSetOfTarget() throws JSONException, Exception { - // create first a target which can be retrieved by rest interface - final String knownControllerId = "1"; - final String knownName = "someName"; - createSingleTarget(knownControllerId, knownName); - final DistributionSet ds = testdataFactory.createDistributionSet(""); - // assign ds to target - final Long actionId = deploymentManagement.assignDistributionSet(ds.getId(), knownControllerId).getActions() - .get(0); - // give feedback, so installedDS is in SNYC - feedbackToByInSync(actionId); - // test - - final SoftwareModule os = ds.findFirstModuleByType(osType); - final SoftwareModule jvm = ds.findFirstModuleByType(runtimeType); - final SoftwareModule bApp = ds.findFirstModuleByType(appType); - mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId + "/installedDS")) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(jsonPath(JSON_PATH_ID, equalTo(ds.getId().intValue()))) - .andExpect(jsonPath(JSON_PATH_NAME, equalTo(ds.getName()))) - .andExpect(jsonPath(JSON_PATH_DESCRIPTION, equalTo(ds.getDescription()))) - // os - .andExpect( - jsonPath("$modules.[?(@.type==" + osType.getKey() + ")][0].id", equalTo(os.getId().intValue()))) - .andExpect(jsonPath("$modules.[?(@.type==" + osType.getKey() + ")][0].name", equalTo(os.getName()))) - .andExpect(jsonPath("$modules.[?(@.type==" + osType.getKey() + ")][0].description", - equalTo(os.getDescription()))) - .andExpect( - jsonPath("$modules.[?(@.type==" + osType.getKey() + ")][0].version", equalTo(os.getVersion()))) - .andExpect(jsonPath("$modules.[?(@.type==" + osType.getKey() + ")][0].vendor", equalTo(os.getVendor()))) - .andExpect(jsonPath("$modules.[?(@.type==" + osType.getKey() + ")][0].type", equalTo("os"))) - // jvm - .andExpect(jsonPath("$modules.[?(@.type==" + runtimeType.getKey() + ")][0].id", - equalTo(jvm.getId().intValue()))) - .andExpect( - jsonPath("$modules.[?(@.type==" + runtimeType.getKey() + ")][0].name", equalTo(jvm.getName()))) - .andExpect(jsonPath("$modules.[?(@.type==" + runtimeType.getKey() + ")][0].description", - equalTo(jvm.getDescription()))) - .andExpect(jsonPath("$modules.[?(@.type==" + runtimeType.getKey() + ")][0].version", - equalTo(jvm.getVersion()))) - .andExpect(jsonPath("$modules.[?(@.type==" + runtimeType.getKey() + ")][0].vendor", - equalTo(jvm.getVendor()))) - .andExpect(jsonPath("$modules.[?(@.type==" + runtimeType.getKey() + ")][0].type", equalTo("runtime"))) - // baseApp - .andExpect(jsonPath("$modules.[?(@.type==" + appType.getKey() + ")][0].id", - equalTo(bApp.getId().intValue()))) - .andExpect(jsonPath("$modules.[?(@.type==" + appType.getKey() + ")][0].name", equalTo(bApp.getName()))) - .andExpect(jsonPath("$modules.[?(@.type==" + appType.getKey() + ")][0].description", - equalTo(bApp.getDescription()))) - .andExpect(jsonPath("$modules.[?(@.type==" + appType.getKey() + ")][0].version", - equalTo(bApp.getVersion()))) - .andExpect( - jsonPath("$modules.[?(@.type==" + appType.getKey() + ")][0].vendor", equalTo(bApp.getVendor()))) - .andExpect(jsonPath("$modules.[?(@.type==" + appType.getKey() + ")][0].type", equalTo("application"))); } @Test From 4e7f547392d006b7cbb1e6b1f0cc33d079c992a2 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 16 Aug 2016 11:46:42 +0200 Subject: [PATCH 27/42] Add a WindowBuilder for the dialogs Signed-off-by: SirWayne --- .../SoftwareModuleAddUpdateWindow.java | 9 +- .../common/AbstractMetadataPopupLayout.java | 10 +- .../hawkbit/ui/common/CommonDialogWindow.java | 3 +- .../footer/AbstractDeleteActionsLayout.java | 8 +- .../ui/components/SPUIComponentProvider.java | 17 --- .../ui/decorators/SPUIWindowDecorator.java | 107 ------------------ .../AbstractCreateUpdateTagLayout.java | 8 +- .../DistributionAddUpdateWindowLayout.java | 9 +- .../TargetAddUpdateWindowLayout.java | 8 +- .../TargetBulkUpdateWindowLayout.java | 6 +- .../rollout/AddUpdateRolloutWindowLayout.java | 8 +- 11 files changed, 41 insertions(+), 152 deletions(-) delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index c8eb74313..52f377366 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -18,9 +18,9 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -181,8 +181,11 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se setCompositionRoot(formLayout); - window = SPUIWindowDecorator.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), null, null, formLayout, i18n); + window = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW) + .caption(i18n.get("upload.caption.add.new.swmodule")).content(this) + .saveButtonClickListener(event -> saveOrUpdate()).layout(formLayout).i18n(i18n) + .buildCommonDialogWindow(); + window.getButtonsLayout().removeStyleName("actionButtonsMargin"); nameTextField.setEnabled(!editSwModule); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java index b9d48d321..972722d36 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java @@ -16,10 +16,10 @@ import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.MetaData; import org.eclipse.hawkbit.repository.model.NamedVersionedEntity; +import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -115,9 +115,11 @@ public abstract class AbstractMetadataPopupLayout onSave(), event -> onCancel(), null, mainLayout, - i18n); + + metadataWindow = new WindowBuilder(SPUIDefinitions.CUSTOM_METADATA_WINDOW) + .caption(getMetadataCaption(nameVersion)).content(this).saveButtonClickListener(event -> onSave()) + .cancelButtonClickListener(event -> onCancel()).layout(mainLayout).i18n(i18n).buildCommonDialogWindow(); + metadataWindow.setId(SPUIComponentIdProvider.METADATA_POPUP_ID); metadataWindow.setHeight(550, Unit.PIXELS); metadataWindow.setWidth(800, Unit.PIXELS); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 25c4bfc94..34abbeb90 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.common; import static com.google.common.base.Preconditions.checkNotNull; -import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -70,7 +69,7 @@ import com.vaadin.ui.themes.ValoTheme; * corner and a save and cancel button at the bottom. Is not intended to reuse. * */ -public class CommonDialogWindow extends Window implements Serializable { +public class CommonDialogWindow extends Window { private static final long serialVersionUID = 1L; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java index b324f0325..a0d6e108a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java @@ -12,6 +12,7 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmall; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; @@ -215,11 +216,10 @@ public abstract class AbstractDeleteActionsLayout extends VerticalLayout impleme if (!hasUnsavedActions()) { return; } - unsavedActionsWindow = SPUIComponentProvider.getWindow(getUnsavedActionsWindowCaption(), - SPUIComponentIdProvider.SAVE_ACTIONS_POPUP, SPUIDefinitions.CONFIRMATION_WINDOW); + unsavedActionsWindow = new WindowBuilder(SPUIDefinitions.CONFIRMATION_WINDOW) + .caption(getUnsavedActionsWindowCaption()).id(SPUIComponentIdProvider.CONFIRMATION_POPUP_ID) + .content(getUnsavedActionsWindowContent()).buildWindow(); unsavedActionsWindow.addCloseListener(event -> unsavedActionsWindowClosed()); - unsavedActionsWindow.setContent(getUnsavedActionsWindowContent()); - unsavedActionsWindow.setId(SPUIComponentIdProvider.CONFIRMATION_POPUP_ID); UI.getCurrent().addWindow(unsavedActionsWindow); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 9bfb81a27..1d8880d91 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -21,7 +21,6 @@ import org.eclipse.hawkbit.ui.decorators.SPUIComboBoxDecorator; import org.eclipse.hawkbit.ui.decorators.SPUILabelDecorator; import org.eclipse.hawkbit.ui.decorators.SPUITextAreaDecorator; import org.eclipse.hawkbit.ui.decorators.SPUITextFieldDecorator; -import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.slf4j.Logger; @@ -42,7 +41,6 @@ import com.vaadin.ui.TabSheet; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; /** @@ -134,21 +132,6 @@ public final class SPUIComponentProvider { return SPUILabelDecorator.getDeocratedLabel(name, type); } - /** - * Get window component. - * - * @param caption - * window caption - * @param id - * window id - * @param type - * type of window - * @return Window - */ - public static Window getWindow(final String caption, final String id, final String type) { - return SPUIWindowDecorator.getDeocratedWindow(caption, id, type); - } - /** * Get Label UI component. * diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java deleted file mode 100644 index da60b83d1..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java +++ /dev/null @@ -1,107 +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.ui.decorators; - -import org.eclipse.hawkbit.ui.common.CommonDialogWindow; -import org.eclipse.hawkbit.ui.common.CustomCommonDialogWindow; -import org.eclipse.hawkbit.ui.utils.I18N; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; - -import com.vaadin.ui.AbstractLayout; -import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.Component; -import com.vaadin.ui.Window; - -/** - * Decorator for Window. - */ -public final class SPUIWindowDecorator { - - /** - * Private Constructor. - */ - private SPUIWindowDecorator() { - - } - - /** - * Decorates window based on type. - * - * @param caption - * window caption - * @param id - * window id - * @param type - * window type - * @return Window - */ - public static CommonDialogWindow getWindow(final String caption, final String id, final String type, - final Component content, final ClickListener saveButtonClickListener, - final ClickListener cancelButtonClickListener, final String helpLink, final AbstractLayout layout, - final I18N i18n) { - - CommonDialogWindow window; - - if (SPUIDefinitions.CUSTOM_METADATA_WINDOW.equals(type)) { - window = new CustomCommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener, layout, i18n); - window.setDraggable(true); - window.setClosable(true); - } else { - window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener, layout, i18n); - if (null != id) { - window.setId(id); - } - if (SPUIDefinitions.CONFIRMATION_WINDOW.equals(type)) { - window.setDraggable(false); - window.setClosable(true); - window.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION); - - } else if (SPUIDefinitions.CREATE_UPDATE_WINDOW.equals(type)) { - window.setDraggable(true); - window.setClosable(true); - } - } - - return window; - } - - /** - * Decorates window based on type. - * - * @param caption - * window caption - * @param id - * window id - * @param type - * window type - * @return Window - */ - public static Window getDeocratedWindow(final String caption, final String id, final String type) { - final Window window = new Window(caption); - window.setSizeUndefined(); - window.setModal(true); - window.setResizable(false); - if (null != id) { - window.setId(id); - } - if (SPUIDefinitions.CONFIRMATION_WINDOW.equals(type)) { - window.setDraggable(false); - window.setClosable(true); - window.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION); - - } else if (SPUIDefinitions.CREATE_UPDATE_WINDOW.equals(type)) { - window.setDraggable(true); - window.setClosable(false); - } - return window; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 33ec3f52d..91b11146a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -19,8 +19,8 @@ import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerLayout; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; +import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -460,8 +460,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent public CommonDialogWindow getWindow() { reset(); - window = SPUIWindowDecorator.getWindow(getWindowCaption(), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, - this::save, cancleEvent -> discard(), null, mainLayout, i18n); + window = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).caption(getWindowCaption()).content(this) + .saveButtonClickListener(this::save).cancelButtonClickListener(event -> discard()).layout(mainLayout) + .i18n(i18n).buildCommonDialogWindow(); + return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 069b9b407..12ed73cc8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -22,9 +22,9 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.management.event.DragEvent; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; @@ -325,8 +325,11 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { resetComponents(); populateDistSetTypeNameCombo(); populateValuesOfDistribution(editDistId); - window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.dist"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), null, null, formLayout, i18n); + + window = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).caption(i18n.get("caption.add.new.dist")) + .content(this).saveButtonClickListener(event -> saveDistribution()).layout(formLayout).i18n(i18n) + .buildCommonDialogWindow(); + window.getButtonsLayout().removeStyleName("actionButtonsMargin"); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 2b08c4dbf..84c933cba 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -16,9 +16,9 @@ import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; +import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator; import org.eclipse.hawkbit.ui.management.event.DragEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; @@ -166,8 +166,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); - window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), null, null, formLayout, i18n); + window = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).caption(i18n.get("caption.add.new.target")) + .content(this).saveButtonClickListener(event -> saveTargetListner()).layout(formLayout).i18n(i18n) + .buildCommonDialogWindow(); + return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index b77576411..3e2100483 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -19,6 +19,7 @@ import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.common.DistributionSetIdName; +import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.management.dstable.DistributionBeanQuery; @@ -357,10 +358,11 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { */ public Window getWindow() { managementUIState.setBulkUploadWindowMinimised(false); - bulkUploadWindow = SPUIComponentProvider.getWindow("", null, SPUIDefinitions.CREATE_UPDATE_WINDOW); + + bulkUploadWindow = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).caption("").content(this) + .buildWindow(); bulkUploadWindow.addStyleName("bulk-upload-window"); bulkUploadWindow.setImmediate(true); - bulkUploadWindow.setContent(this); if (isNoBulkUploadInProgress()) { bulkUploader.getUpload().setEnabled(true); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 6a20bf9f0..bd18ea113 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -30,8 +30,8 @@ import org.eclipse.hawkbit.repository.model.RolloutGroupConditions; import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.DistributionSetIdName; +import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator; import org.eclipse.hawkbit.ui.filtermanagement.TargetFilterBeanQuery; import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout; import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout.ActionTypeOption; @@ -165,9 +165,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public CommonDialogWindow getWindow() { resetComponents(); - return SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), null, - uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); + return new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).caption(i18n.get("caption.configure.rollout")) + .content(this).saveButtonClickListener(event -> onRolloutSave()).layout(this).i18n(i18n) + .helpLink(uiProperties.getLinks().getDocumentation().getRolloutView()).buildCommonDialogWindow(); } /** From d3d07046ecfebeebc9285b8b0f5eca8b889fc080 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 16 Aug 2016 11:47:24 +0200 Subject: [PATCH 28/42] Add a WindowBuilder for the dialogs Signed-off-by: SirWayne --- .../ui/common/builder/WindowBuilder.java | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/WindowBuilder.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/WindowBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/WindowBuilder.java new file mode 100644 index 000000000..c18d117db --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/WindowBuilder.java @@ -0,0 +1,187 @@ +package org.eclipse.hawkbit.ui.common.builder; + +import org.eclipse.hawkbit.ui.common.CommonDialogWindow; +import org.eclipse.hawkbit.ui.common.CustomCommonDialogWindow; +import org.eclipse.hawkbit.ui.utils.I18N; +import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; + +import com.vaadin.ui.AbstractLayout; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Component; +import com.vaadin.ui.Window; + +/** + * Builder for Window. + */ +public class WindowBuilder { + + private String caption; + private Component content; + private ClickListener saveButtonClickListener; + private ClickListener cancelButtonClickListener; + private String helpLink; + private AbstractLayout layout; + private I18N i18n; + private final String type; + private String id; + + /** + * Constructor. + * + * @param type + * window type + */ + public WindowBuilder(final String type) { + this.type = type; + } + + /** + * Set the caption. + * + * @param caption + * the caption + * @return the window builder + */ + public WindowBuilder caption(final String caption) { + this.caption = caption; + return this; + } + + /** + * Set the content. + * + * @param content + * the content + * @return the window builder + */ + public WindowBuilder content(final Component content) { + this.content = content; + return this; + } + + /** + * Set the saveButtonClickListener. + * + * @param saveButtonClickListener + * the saveButtonClickListener + * @return the window builder + */ + public WindowBuilder saveButtonClickListener(final ClickListener saveButtonClickListener) { + this.saveButtonClickListener = saveButtonClickListener; + return this; + } + + /** + * Set the cancelButtonClickListener. + * + * @param cancelButtonClickListener + * the cancelButtonClickListener + * @return the window builder + */ + public WindowBuilder cancelButtonClickListener(final ClickListener cancelButtonClickListener) { + this.cancelButtonClickListener = cancelButtonClickListener; + return this; + } + + /** + * Set the helpLink. + * + * @param helpLink + * the helpLink + * @return the window builder + */ + public WindowBuilder helpLink(final String helpLink) { + this.helpLink = helpLink; + return this; + } + + /** + * Set the layout. + * + * @param layout + * the layout + * @return the window builder + */ + public WindowBuilder layout(final AbstractLayout layout) { + this.layout = layout; + return this; + } + + /** + * Set the i18n. + * + * @param i18n + * the i18n + * @return the window builder + */ + public WindowBuilder i18n(final I18N i18n) { + this.i18n = i18n; + return this; + } + + /** + * @param id + * the id to set * @return the window builder + */ + public WindowBuilder id(final String id) { + this.id = id; + return this; + } + + /** + * Build the common dialog window. + * + * @return the window. + */ + public CommonDialogWindow buildCommonDialogWindow() { + CommonDialogWindow window; + + if (SPUIDefinitions.CUSTOM_METADATA_WINDOW.equals(type)) { + window = new CustomCommonDialogWindow(caption, content, helpLink, saveButtonClickListener, + cancelButtonClickListener, layout, i18n); + window.setDraggable(true); + window.setClosable(true); + return window; + } + window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, cancelButtonClickListener, + layout, i18n); + + decorateWindow(window); + + return window; + + } + + private void decorateWindow(final Window window) { + if (id != null) { + window.setId(id); + } + + if (SPUIDefinitions.CONFIRMATION_WINDOW.equals(type)) { + window.setDraggable(false); + window.setClosable(true); + window.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION); + + } else if (SPUIDefinitions.CREATE_UPDATE_WINDOW.equals(type)) { + window.setDraggable(true); + window.setClosable(true); + } + } + + /** + * Build window based on type. + * + * @return Window + */ + public Window buildWindow() { + final Window window = new Window(caption); + window.setContent(content); + window.setSizeUndefined(); + window.setModal(true); + window.setResizable(false); + + decorateWindow(window); + return window; + } +} From 79e0cccfa9ebe85c84b3905941f57e957d86cf88 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 16 Aug 2016 12:29:14 +0200 Subject: [PATCH 29/42] remove not used class Signed-off-by: Michael Hirsch --- .../jpa/model/DescriptorEventDetails.java | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java deleted file mode 100644 index 091b2eb77..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.repository.jpa.model; - -import org.eclipse.persistence.descriptors.DescriptorEvent; - -/** - * - * Holds details of action(Create/Update) and @link{DescriptorEvent}. - * - */ -public class DescriptorEventDetails { - - enum ActionType { - CREATE, UPDATE; - } - - private final DescriptorEvent descriptorEvent; - - private final ActionType actiontype; - - /** - * Constructor - * - * @param actionType - * Action type - * @param descriptorEvent - * Descriptor Event - */ - public DescriptorEventDetails(final ActionType actionType, final DescriptorEvent descriptorEvent) { - this.descriptorEvent = descriptorEvent; - this.actiontype = actionType; - } - - public DescriptorEvent getDescriptorEvent() { - return descriptorEvent; - } - - public ActionType getActiontype() { - return actiontype; - } - -} From 9e1754126ed295e2c020f70b5fa6daf053d509fd Mon Sep 17 00:00:00 2001 From: Dominic Schabel Date: Tue, 16 Aug 2016 12:51:15 +0200 Subject: [PATCH 30/42] Added missing NOT and did some small other code improvements Signed-off-by: Dominic Schabel --- .../targettable/TargetBeanQuery.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java index c5d8382b3..93d627ee8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java @@ -9,6 +9,10 @@ package org.eclipse.hawkbit.ui.management.targettable; import static org.apache.commons.lang3.ArrayUtils.isEmpty; +import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.isNotNullOrEmpty; +import static org.eclipse.hawkbit.ui.utils.SPUIDefinitions.TARGET_TABLE_CREATE_AT_SORT_ORDER; +import static org.springframework.data.domain.Sort.Direction.ASC; +import static org.springframework.data.domain.Sort.Direction.DESC; import java.util.ArrayList; import java.util.Collection; @@ -32,7 +36,6 @@ import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; -import org.springframework.data.domain.Sort.Direction; import org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery; import org.vaadin.addons.lazyquerycontainer.QueryDefinition; @@ -41,11 +44,12 @@ import com.google.common.base.Strings; /** * Simple implementation of generics bean query which dynamically loads a batch * of beans. - * */ public class TargetBeanQuery extends AbstractBeanQuery { + private static final long serialVersionUID = -5645680058303167558L; - private Sort sort = new Sort(SPUIDefinitions.TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt"); + + private Sort sort = new Sort(TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt"); private transient Collection status = null; private String[] targetTags = null; private Long distributionId = null; @@ -71,9 +75,10 @@ public class TargetBeanQuery extends AbstractBeanQuery { */ public TargetBeanQuery(final QueryDefinition definition, final Map queryConfig, final Object[] sortIds, final boolean[] sortStates) { + super(definition, queryConfig, sortIds, sortStates); - if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { + if (isNotNullOrEmpty(queryConfig)) { status = (Collection) queryConfig.get(SPUIDefinitions.FILTER_BY_STATUS); targetTags = (String[]) queryConfig.get(SPUIDefinitions.FILTER_BY_TAG); noTagClicked = (Boolean) queryConfig.get(SPUIDefinitions.FILTER_BY_NO_TAG); @@ -86,12 +91,12 @@ public class TargetBeanQuery extends AbstractBeanQuery { pinnedDistId = (Long) queryConfig.get(SPUIDefinitions.ORDER_BY_DISTRIBUTION); } - if (isEmpty(sortStates)) { - // Initalize Sor - sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortIds[0]); - // Add sort. + if (!isEmpty(sortStates)) { + + sort = new Sort(sortStates[0] ? ASC : DESC, (String) sortIds[0]); + for (int targetId = 1; targetId < sortIds.length; targetId++) { - sort.and(new Sort(sortStates[targetId] ? Direction.ASC : Direction.DESC, (String) sortIds[targetId])); + sort.and(new Sort(sortStates[targetId] ? ASC : DESC, (String) sortIds[targetId])); } } } @@ -222,5 +227,4 @@ public class TargetBeanQuery extends AbstractBeanQuery { } return i18N; } - } From 5e485694628a1e4d38d03df060e33c1086ac3182 Mon Sep 17 00:00:00 2001 From: Dominic Schabel Date: Tue, 16 Aug 2016 13:41:15 +0200 Subject: [PATCH 31/42] Found another place where a NOT was missing Signed-off-by: Dominic Schabel --- .../ui/artifacts/details/ArtifactBeanQuery.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java index faf43b4ca..d08474a5a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java @@ -9,6 +9,9 @@ package org.eclipse.hawkbit.ui.artifacts.details; import static org.apache.commons.lang3.ArrayUtils.isEmpty; +import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.isNotNullOrEmpty; +import static org.springframework.data.domain.Sort.Direction.ASC; +import static org.springframework.data.domain.Sort.Direction.DESC; import java.util.List; import java.util.Map; @@ -17,7 +20,6 @@ import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.OffsetBasedPageRequest; import org.eclipse.hawkbit.repository.model.LocalArtifact; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.springframework.data.domain.Page; @@ -53,18 +55,18 @@ public class ArtifactBeanQuery extends AbstractBeanQuery { */ public ArtifactBeanQuery(final QueryDefinition definition, final Map queryConfig, final Object[] sortIds, final boolean[] sortStates) { + super(definition, queryConfig, sortIds, sortStates); - if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { + if (isNotNullOrEmpty(queryConfig)) { baseSwModuleId = (Long) queryConfig.get(SPUIDefinitions.BY_BASE_SOFTWARE_MODULE); } - if (isEmpty(sortStates)) { - // Initalize Sor - sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortIds[0]); - // Add sort. + if (!isEmpty(sortStates)) { + sort = new Sort(sortStates[0] ? ASC : DESC, (String) sortIds[0]); + for (int targetId = 1; targetId < sortIds.length; targetId++) { - sort.and(new Sort(sortStates[targetId] ? Direction.ASC : Direction.DESC, (String) sortIds[targetId])); + sort.and(new Sort(sortStates[targetId] ? ASC : DESC, (String) sortIds[targetId])); } } } From a51bf0ac029389425215135fe84874789efec44f Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 16 Aug 2016 14:38:21 +0200 Subject: [PATCH 32/42] Add LabelBuilder Signed-off-by: SirWayne --- .../details/ArtifactDetailsLayout.java | 5 +- .../CreateUpdateSoftwareTypeLayout.java | 6 +- .../common/AbstractMetadataPopupLayout.java | 4 +- .../ui/common/builder/LabelBuilder.java | 111 ++++++++++++++++++ .../ui/common/builder/WindowBuilder.java | 8 ++ .../AbstractConfirmationWindowLayout.java | 9 +- .../AbstractTableDetailsLayout.java | 4 +- .../filterlayout/AbstractFilterHeader.java | 3 +- .../ui/common/table/AbstractTableHeader.java | 5 +- .../ui/components/SPUIComponentProvider.java | 76 ------------ .../ui/components/SPUIHorizontalLayout.java | 49 -------- .../ui/decorators/SPUILabelDecorator.java | 65 ---------- .../CreateOrUpdateFilterHeader.java | 8 +- .../CreateOrUpdateFilterTable.java | 4 +- .../filtermanagement/TargetFilterHeader.java | 4 +- .../AbstractCreateUpdateTagLayout.java | 5 +- .../ui/layouts/CreateUpdateTypeLayout.java | 6 +- .../actionhistory/ActionHistoryHeader.java | 7 +- .../actionhistory/ActionHistoryTable.java | 12 +- .../targettag/FilterByStatusLayout.java | 6 +- .../rollout/AddUpdateRolloutWindowLayout.java | 9 +- .../ui/rollout/rollout/RolloutListHeader.java | 6 +- .../rolloutgroup/RolloutGroupsListHeader.java | 4 +- .../RolloutGroupTargetsListHeader.java | 4 +- ...AuthenticationTenantConfigurationItem.java | 5 +- ...ficateAuthenticationConfigurationItem.java | 5 +- ...yTokenAuthenticationConfigurationItem.java | 4 +- .../ui/utils/SPUILabelDefinitions.java | 12 -- .../ui/utils/SPUIComponentProviderTest.java | 20 ---- 29 files changed, 185 insertions(+), 281 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/LabelBuilder.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIHorizontalLayout.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUILabelDecorator.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java index c62637117..8408f7c74 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java @@ -24,6 +24,7 @@ import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.common.ConfirmationDialog; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -149,8 +150,8 @@ public class ArtifactDetailsLayout extends VerticalLayout { final SoftwareModule softwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); labelStr = HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(), softwareModule.getVersion()); } - titleOfArtifactDetails = SPUIComponentProvider.getLabel( - HawkbitCommonUtil.getArtifactoryDetailsLabelId(labelStr), SPUILabelDefinitions.SP_WIDGET_CAPTION); + titleOfArtifactDetails = new LabelBuilder().name(HawkbitCommonUtil.getArtifactoryDetailsLabelId(labelStr)) + .buildCaptionLabel(); titleOfArtifactDetails.setContentMode(ContentMode.HTML); titleOfArtifactDetails.setSizeFull(); titleOfArtifactDetails.setImmediate(true); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 06fb8ed18..f57bef2d1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -18,6 +18,7 @@ import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; @@ -74,8 +75,9 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { singleAssignStr = i18n.get("label.singleAssign.type"); multiAssignStr = i18n.get("label.multiAssign.type"); - singleAssign = SPUIComponentProvider.getLabel(singleAssignStr, null); - multiAssign = SPUIComponentProvider.getLabel(multiAssignStr, null); + singleAssign = new LabelBuilder().name(singleAssignStr).buildLabel(); + + multiAssign = new LabelBuilder().name(multiAssignStr).buildLabel(); tagName = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_NAME, true, "", i18n.get("textfield.name"), true, diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java index 972722d36..d3893e40d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java @@ -16,6 +16,7 @@ import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.MetaData; import org.eclipse.hawkbit.repository.model.NamedVersionedEntity; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer; @@ -24,7 +25,6 @@ import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; @@ -303,7 +303,7 @@ public abstract class AbstractMetadataPopupLayout extends } private Label createHeaderCaption() { - return SPUIComponentProvider.getLabel(getDefaultCaption(), SPUILabelDefinitions.SP_WIDGET_CAPTION); + return new LabelBuilder().name(getDefaultCaption()).buildCaptionLabel(); } protected VerticalLayout getTabLayout() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterHeader.java index ae497e41e..104d602dd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterHeader.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.common.filterlayout; import org.eclipse.hawkbit.repository.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -91,7 +92,7 @@ public abstract class AbstractFilterHeader extends VerticalLayout { } private Label createHeaderCaption() { - return SPUIComponentProvider.getLabel(getTitle(), SPUILabelDefinitions.SP_WIDGET_CAPTION); + return new LabelBuilder().name(getTitle()).buildCaptionLabel(); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java index 3631b6678..54fee678f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java @@ -12,6 +12,7 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -203,9 +204,7 @@ public abstract class AbstractTableHeader extends VerticalLayout { } private Label createHeaderCaption() { - final Label captionLabel = SPUIComponentProvider.getLabel(getHeaderCaption(), - SPUILabelDefinitions.SP_WIDGET_CAPTION); - return captionLabel; + return new LabelBuilder().name(getHeaderCaption()).buildCaptionLabel(); } private TextField createSearchField() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 1d8880d91..063a5325f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -15,10 +15,8 @@ import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.ui.common.UserDetailsFormatter; -import org.eclipse.hawkbit.ui.decorators.HeaderLayoutDecorator; import org.eclipse.hawkbit.ui.decorators.SPUIButtonDecorator; import org.eclipse.hawkbit.ui.decorators.SPUIComboBoxDecorator; -import org.eclipse.hawkbit.ui.decorators.SPUILabelDecorator; import org.eclipse.hawkbit.ui.decorators.SPUITextAreaDecorator; import org.eclipse.hawkbit.ui.decorators.SPUITextFieldDecorator; import org.eclipse.hawkbit.ui.utils.I18N; @@ -33,7 +31,6 @@ import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Button; import com.vaadin.ui.CheckBox; import com.vaadin.ui.ComboBox; -import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Link; import com.vaadin.ui.Panel; @@ -59,79 +56,6 @@ public final class SPUIComponentProvider { } - /** - * @param className - * @return - */ - public static HorizontalLayout getHorizontalLayout(final Class className) { - HorizontalLayout hLayout = null; - try { - - hLayout = className.newInstance(); - } catch (final InstantiationException exception) { - LOG.error("Error occured while creating HorizontalLayout-" + className, exception); - } catch (final IllegalAccessException exception) { - LOG.error("Error occured while acessing HorizontalLayout-" + className, exception); - } - - return hLayout; - } - - /** - * Get HorizontalLayout UI component. - * - * @return HorizontalLayout as UI - */ - public static HorizontalLayout getHorizontalLayout() { - HorizontalLayout hLayout = null; - try { - hLayout = HorizontalLayout.class.newInstance(); - } catch (final InstantiationException exception) { - LOG.error("Error occured while creating HorizontalLayout-", exception); - } catch (final IllegalAccessException exception) { - LOG.error("Error occured while acessing HorizontalLayout-", exception); - } - - return hLayout; - } - - /** - * @param tableHeaderLayoutDecorator - * @return - */ - public static HorizontalLayout getHeaderLayout( - final Class tableHeaderLayoutDecorator) { - // Do we really need this??? - HorizontalLayout hLayout = getHorizontalLayout(new SPUIHorizontalLayout().getUiHorizontalLayout().getClass()); - - if (tableHeaderLayoutDecorator == null) { - return hLayout; - } - - try { - final HeaderLayoutDecorator layoutDecorator = tableHeaderLayoutDecorator.newInstance(); - hLayout = layoutDecorator.decorate(hLayout); - - } catch (final InstantiationException | IllegalAccessException exception) { - LOG.error("Error occured while creating horizontal decorator " + HeaderLayoutDecorator.class, exception); - } - - return hLayout; - } - - /** - * Get Label UI component. - * - * @param name - * label caption - * @param type - * string simple|Confirm|Message - * @return Label - */ - public static Label getLabel(final String name, final String type) { - return SPUILabelDecorator.getDeocratedLabel(name, type); - } - /** * Get Label UI component. * diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIHorizontalLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIHorizontalLayout.java deleted file mode 100644 index 33d040330..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIHorizontalLayout.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.components; - -import com.vaadin.ui.HorizontalLayout; - -/** - * Plain Horizontal Layout. - * - * - * - */ - -public class SPUIHorizontalLayout { - private final HorizontalLayout uiHorizontalLayout; - - /** - * Default constructor. - */ - public SPUIHorizontalLayout() { - uiHorizontalLayout = new HorizontalLayout(); - decorate(); - } - - /** - * Decorate. - */ - private void decorate() { - uiHorizontalLayout.setImmediate(false); - uiHorizontalLayout.setMargin(false); - uiHorizontalLayout.setSpacing(true); - - } - - /** - * Get HorizontalLayout. - * - * @return HorizontalLayout as UI - */ - public HorizontalLayout getUiHorizontalLayout() { - return uiHorizontalLayout; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUILabelDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUILabelDecorator.java deleted file mode 100644 index a42b51566..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUILabelDecorator.java +++ /dev/null @@ -1,65 +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.ui.decorators; - -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; - -import com.vaadin.shared.ui.label.ContentMode; -import com.vaadin.ui.Label; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Simple Decorator for the label. - * - * - * - * - * - */ -public final class SPUILabelDecorator { - - /** - * Private Constructor. - */ - private SPUILabelDecorator() { - - } - - /** - * Simple decorator. - * - * @param name - * as String - * @param type - * as String - * @return Label - */ - public static Label getDeocratedLabel(final String name, final String type) { - final Label spUILabel = new Label(name); - // Set style. - final StringBuilder style = new StringBuilder(ValoTheme.LABEL_SMALL); - style.append(' '); - style.append(ValoTheme.LABEL_BOLD); - spUILabel.addStyleName(style.toString()); - if (SPUILabelDefinitions.SP_WIDGET_CAPTION.equalsIgnoreCase(type)) { - spUILabel.setValue(name); - spUILabel.addStyleName("header-caption"); - } else if (SPUILabelDefinitions.SP_LABEL_MESSAGE.equalsIgnoreCase(type)) { - spUILabel.setContentMode(ContentMode.HTML); - spUILabel.addStyleName(SPUILabelDefinitions.SP_LABEL_MESSAGE_STYLE); - } else { - spUILabel.setImmediate(false); - spUILabel.setWidth("-1px"); - spUILabel.setHeight("-1px"); - } - - return spUILabel; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java index 1023d98ed..a5ff7be66 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java @@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.ui.UiProperties; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -217,10 +218,9 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button breadcrumbButton = createBreadcrumbButton(); - headerCaption = SPUIComponentProvider.getLabel(SPUILabelDefinitions.VAR_CREATE_FILTER, - SPUILabelDefinitions.SP_WIDGET_CAPTION); + headerCaption = new LabelBuilder().name(SPUILabelDefinitions.VAR_CREATE_FILTER).buildCaptionLabel(); - nameLabel = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); + nameLabel = new LabelBuilder().name("").buildLabel(); nameLabel.setId(SPUIComponentIdProvider.TARGET_FILTER_QUERY_NAME_LABEL_ID); nameTextField = createNameTextField(); @@ -307,7 +307,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button breadcrumbLayout = new HorizontalLayout(); breadcrumbLayout.addComponent(breadcrumbButton); breadcrumbLayout.addComponent(new Label(">")); - breadcrumbName = SPUIComponentProvider.getLabel(null, SPUILabelDefinitions.SP_WIDGET_CAPTION); + breadcrumbName = new LabelBuilder().buildCaptionLabel(); breadcrumbLayout.addComponent(breadcrumbName); breadcrumbName.addStyleName("breadcrumbPaddingLeft"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterTable.java index bb5707c40..e447a257a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterTable.java @@ -19,7 +19,7 @@ import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; import org.eclipse.hawkbit.ui.utils.AssignInstalledDSTooltipGenerator; @@ -209,7 +209,7 @@ public class CreateOrUpdateFilterTable extends Table { final Item row1 = getItem(itemId); final TargetUpdateStatus targetStatus = (TargetUpdateStatus) row1 .getItemProperty(SPUILabelDefinitions.VAR_TARGET_STATUS).getValue(); - final Label label = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); + final Label label = new LabelBuilder().name("").buildLabel(); label.setContentMode(ContentMode.HTML); if (targetStatus == TargetUpdateStatus.PENDING) { label.setDescription("Pending"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java index b5d796ebb..32347ae24 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.ui.filtermanagement; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -78,8 +79,7 @@ public class TargetFilterHeader extends VerticalLayout { } private Label createHeaderCaption() { - return SPUIComponentProvider.getLabel(SPUIDefinitions.TARGET_FILTER_LIST_HEADER_CAPTION, - SPUILabelDefinitions.SP_WIDGET_CAPTION); + return new LabelBuilder().name(SPUIDefinitions.TARGET_FILTER_LIST_HEADER_CAPTION).buildCaptionLabel(); } private void buildLayout() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 91b11146a..bd62a0cb0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -19,6 +19,7 @@ import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerLayout; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; @@ -147,8 +148,8 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent createTagStr = i18n.get("label.create.tag"); updateTagStr = i18n.get("label.update.tag"); - comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag"), null); - colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag.color"), null); + comboLabel = new LabelBuilder().name(i18n.get("label.choose.tag")).buildLabel(); + colorLabel = new LabelBuilder().name(i18n.get("label.choose.tag.color")).buildLabel(); colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); tagName = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index f25a4b485..e15dcffc3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -13,6 +13,7 @@ import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -56,8 +57,9 @@ public abstract class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayo createTypeStr = i18n.get("label.create.type"); updateTypeStr = i18n.get("label.update.type"); - comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type"), null); - colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type.color"), null); + comboLabel = new LabelBuilder().name(i18n.get("label.choose.type")).buildLabel(); + colorLabel = new LabelBuilder().name(i18n.get("label.choose.type.color")).buildLabel(); + colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); tagNameComboBox = SPUIComponentProvider.getComboBox(i18n.get("label.combobox.type"), "", "", null, null, false, diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryHeader.java index 828b61d43..22551f28c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryHeader.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.management.actionhistory; import javax.annotation.PostConstruct; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -17,7 +18,6 @@ import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; @@ -63,8 +63,9 @@ public class ActionHistoryHeader extends VerticalLayout { private void buildComponent() { // create default title - it will be shown even when no data is // available - titleOfActionHistory = SPUIComponentProvider.getLabel(HawkbitCommonUtil.getArtifactoryDetailsLabelId(""), - SPUILabelDefinitions.SP_WIDGET_CAPTION); + titleOfActionHistory = new LabelBuilder().name(HawkbitCommonUtil.getArtifactoryDetailsLabelId("")) + .buildCaptionLabel(); + titleOfActionHistory.setImmediate(true); titleOfActionHistory.setContentMode(ContentMode.HTML); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java index ffc7d1e3a..71c489aa0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java @@ -25,6 +25,7 @@ import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.ActionWithStatusCount; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.ui.common.ConfirmationDialog; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -36,7 +37,6 @@ import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.UINotification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -357,7 +357,7 @@ public class ActionHistoryTable extends TreeTable { private Component getForcedColumn(final Object itemId) { final Action actionWithActiveStatus = (Action) hierarchicalContainer.getItem(itemId) .getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED).getValue(); - final Label actionLabel = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); + final Label actionLabel = new LabelBuilder().name("").buildCaptionLabel(); actionLabel.setContentMode(ContentMode.HTML); actionLabel.setStyleName("action-history-table-col-forced-label"); if (actionWithActiveStatus != null && actionWithActiveStatus.getActionType() == ActionType.FORCED) { @@ -522,7 +522,7 @@ public class ActionHistoryTable extends TreeTable { * @return Label as UI */ private Label getStatusIcon(final Action.Status status) { - final Label label = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); + final Label label = new LabelBuilder().name("").buildLabel(); final String statusIconPending = "statusIconPending"; label.setContentMode(ContentMode.HTML); if (Action.Status.FINISHED == status) { @@ -576,7 +576,7 @@ public class ActionHistoryTable extends TreeTable { final long currentTimeMillis = System.currentTimeMillis(); final HorizontalLayout hLayout = new HorizontalLayout(); - final Label autoForceLabel = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); + final Label autoForceLabel = new LabelBuilder().name("").buildLabel(); actionLabel.setValue(FontAwesome.BOLT.getHtml()); autoForceLabel.setContentMode(ContentMode.HTML); @@ -608,8 +608,8 @@ public class ActionHistoryTable extends TreeTable { * as String * @return Labeal as UI */ - private Label createActiveStatusLabel(final String activeValue, final boolean endedWithError) { - final Label label = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); + private static Label createActiveStatusLabel(final String activeValue, final boolean endedWithError) { + final Label label = new LabelBuilder().name("").buildLabel(); label.setContentMode(ContentMode.HTML); if (SPUIDefinitions.SCHEDULED.equals(activeValue)) { label.setDescription("Scheduled"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/FilterByStatusLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/FilterByStatusLayout.java index 27a53bfed..67f74d064 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/FilterByStatusLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/FilterByStatusLayout.java @@ -12,6 +12,7 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmall; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; @@ -20,7 +21,6 @@ import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIButtonDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventScope; @@ -84,8 +84,8 @@ public class FilterByStatusLayout extends VerticalLayout implements Button.Click addStyleName("target-status-filters"); setMargin(false); - final Label targetFilterStatusLabel = SPUIComponentProvider.getLabel(i18n.get("label.filter.by.status"), - SPUILabelDefinitions.SP_LABEL_SIMPLE); + final Label targetFilterStatusLabel = new LabelBuilder().name(i18n.get("label.filter.by.status")).buildLabel(); + targetFilterStatusLabel.addStyleName("target-status-filters-title"); addComponent(targetFilterStatusLabel); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index bd18ea113..2e0399225 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -30,6 +30,7 @@ import org.eclipse.hawkbit.repository.model.RolloutGroupConditions; import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.DistributionSetIdName; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.filtermanagement.TargetFilterBeanQuery; @@ -258,7 +259,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private Label getLabel(final String key) { - return SPUIComponentProvider.getLabel(i18n.get(key), SPUILabelDefinitions.SP_LABEL_SIMPLE); + return new LabelBuilder().name(i18n.get(key)).buildLabel(); } private TextField getTextfield(final String key) { @@ -266,7 +267,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); } - private Label getPercentHintLabel() { + private static Label getPercentHintLabel() { final Label percentSymbol = new Label("%"); percentSymbol.addStyleName(ValoTheme.LABEL_TINY + " " + ValoTheme.LABEL_BOLD); percentSymbol.setSizeUndefined(); @@ -295,7 +296,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private Label createGroupSizeLabel() { - final Label groupSize = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); + final Label groupSize = new LabelBuilder().name("").buildLabel(); groupSize.addStyleName(ValoTheme.LABEL_TINY + " " + "rollout-target-count-message"); groupSize.setImmediate(true); groupSize.setVisible(false); @@ -315,7 +316,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private Label createTotalTargetsLabel() { - final Label targetCountLabel = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); + final Label targetCountLabel = new LabelBuilder().name("").buildLabel(); targetCountLabel.addStyleName(ValoTheme.LABEL_TINY + " " + "rollout-target-count-message"); targetCountLabel.setImmediate(true); targetCountLabel.setVisible(false); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java index 81608d42d..f0f14432b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java @@ -11,13 +11,12 @@ package org.eclipse.hawkbit.ui.rollout.rollout; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.grid.AbstractGridHeader; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent; import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; @@ -134,8 +133,7 @@ public class RolloutListHeader extends AbstractGridHeader { @Override protected HorizontalLayout getHeaderCaptionLayout() { - final Label headerCaption = SPUIComponentProvider.getLabel(getHeaderCaption(), - SPUILabelDefinitions.SP_WIDGET_CAPTION); + final Label headerCaption = new LabelBuilder().name(getHeaderCaption()).buildCaptionLabel(); final HorizontalLayout headerCaptionLayout = new HorizontalLayout(); headerCaptionLayout.addComponent(headerCaption); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java index 9e4d18143..2e01a7c05 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.ui.rollout.rolloutgroup; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.grid.AbstractGridHeader; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -18,7 +19,6 @@ import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent; import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventScope; @@ -149,7 +149,7 @@ public class RolloutGroupsListHeader extends AbstractGridHeader { @Override protected HorizontalLayout getHeaderCaptionLayout() { - headerCaption = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_WIDGET_CAPTION); + headerCaption = new LabelBuilder().name("").buildCaptionLabel(); headerCaption.setId(SPUIComponentIdProvider.ROLLOUT_GROUP_HEADER_CAPTION); final Button rolloutsListViewLink = SPUIComponentProvider.getButton(null, "", "", null, false, null, SPUIButtonStyleSmallNoBorder.class); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListHeader.java index c22bed8dd..965e1e9b2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListHeader.java @@ -12,6 +12,7 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.grid.AbstractGridHeader; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -19,7 +20,6 @@ import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent; import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventScope; @@ -164,7 +164,7 @@ public class RolloutGroupTargetsListHeader extends AbstractGridHeader { @Override protected HorizontalLayout getHeaderCaptionLayout() { - headerCaption = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_WIDGET_CAPTION); + headerCaption = new LabelBuilder().name("").buildCaptionLabel(); headerCaption.setStyleName(ValoTheme.LABEL_BOLD + " " + ValoTheme.LABEL_SMALL); final Button rolloutsListViewLink = SPUIComponentProvider.getButton(null, "", "", null, false, null, SPUIButtonStyleSmallNoBorder.class); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java index 4f222f080..a31de899f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java @@ -13,9 +13,8 @@ import java.util.List; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.utils.I18N; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.ui.VerticalLayout; @@ -58,7 +57,7 @@ abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLay */ protected void init(final String labelText) { setImmediate(true); - addComponent(SPUIComponentProvider.getLabel(i18n.get(labelText), SPUILabelDefinitions.SP_LABEL_SIMPLE)); + addComponent(new LabelBuilder().name(i18n.get(labelText)).buildLabel()); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java index 872bdef29..d7203772a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java @@ -12,8 +12,8 @@ import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.spring.annotation.SpringComponent; @@ -61,8 +61,7 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti final HorizontalLayout caRootAuthorityLayout = new HorizontalLayout(); caRootAuthorityLayout.setSpacing(true); - final Label caRootAuthorityLabel = SPUIComponentProvider.getLabel("SSL Issuer Hash:", - SPUILabelDefinitions.SP_LABEL_SIMPLE); + final Label caRootAuthorityLabel = new LabelBuilder().name("SSL Issuer Hash:").buildLabel(); caRootAuthorityLabel.setDescription( "The SSL Issuer iRules.X509 hash, to validate against the controller request certifcate."); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java index 31e910ddc..572cfe763 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java @@ -13,6 +13,7 @@ import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmall; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -87,8 +88,7 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac gatewaytokenBtn.setIcon(FontAwesome.REFRESH); gatewaytokenBtn.addClickListener(event -> generateGatewayToken()); - gatewayTokenkeyLabel = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); - gatewayTokenkeyLabel.setId("gatewaysecuritytokenkey"); + gatewayTokenkeyLabel = new LabelBuilder().id("gatewaysecuritytokenkey").name("").buildLabel(); gatewayTokenkeyLabel.addStyleName("gateway-token-label"); gatewayTokenkeyLabel.setImmediate(true); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java index 22d680872..a5bb24831 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java @@ -20,18 +20,6 @@ import com.vaadin.ui.themes.ValoTheme; */ public final class SPUILabelDefinitions { - /** - * Label - Table. - */ - public static final String SP_WIDGET_CAPTION = "Label-table"; - /** - * Label - Simple. - */ - public static final String SP_LABEL_SIMPLE = "Label-simple"; - /** - * Label - Message. - */ - public static final String SP_LABEL_MESSAGE = "Label-message"; /** * Label - Message hint. */ diff --git a/hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/utils/SPUIComponentProviderTest.java b/hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/utils/SPUIComponentProviderTest.java index f818bc15d..9fc6c5855 100644 --- a/hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/utils/SPUIComponentProviderTest.java +++ b/hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/utils/SPUIComponentProviderTest.java @@ -15,9 +15,7 @@ import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorderUH; import org.junit.Test; -import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Button; -import com.vaadin.ui.Label; import ru.yandex.qatools.allure.annotations.Features; import ru.yandex.qatools.allure.annotations.Stories; @@ -46,22 +44,4 @@ public class SPUIComponentProviderTest { assertThat(placeHolderButton.getStyleName()).isEqualTo(SPUIButtonDefinitions.SP_BUTTON_STATUS_STYLE); } - /** - * Test case for check Label factory. - * - * @throws Exception - */ - @Test - public void checkLabelFactory() throws Exception { - - Label placeHolderLabel = null; - placeHolderLabel = SPUIComponentProvider.getLabel("TestTable", SPUILabelDefinitions.SP_WIDGET_CAPTION); - assertThat(placeHolderLabel).isInstanceOf(Label.class); - assertThat(placeHolderLabel.getValue()).isEqualTo("TestTable"); - assertThat(placeHolderLabel.getContentMode()).isNotEqualTo(ContentMode.HTML); - placeHolderLabel = SPUIComponentProvider.getLabel("TestMSG", SPUILabelDefinitions.SP_LABEL_MESSAGE); - assertThat(placeHolderLabel.getValue()).isEqualTo("TestMSG"); - assertThat(placeHolderLabel.getContentMode()).isEqualTo(ContentMode.HTML); - } - } From 8ccc9811a8b27d2a099aab501ea15fabaf63353d Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 16 Aug 2016 14:51:36 +0200 Subject: [PATCH 33/42] Add LabelBuilder Signed-off-by: SirWayne --- .../ui/common/builder/LabelBuilder.java | 21 +++---------------- .../actionhistory/ActionHistoryTable.java | 4 +--- .../rollout/AddUpdateRolloutWindowLayout.java | 20 +++++------------- .../rolloutgroup/RolloutGroupsListHeader.java | 4 ++-- 4 files changed, 11 insertions(+), 38 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/LabelBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/LabelBuilder.java index 576c95c15..12d50149a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/LabelBuilder.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/LabelBuilder.java @@ -8,14 +8,11 @@ */ package org.eclipse.hawkbit.ui.common.builder; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; - -import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Label; import com.vaadin.ui.themes.ValoTheme; /** - * Simple Decorator for the label. + * Label Builder. * */ public class LabelBuilder { @@ -57,7 +54,7 @@ public class LabelBuilder { } /** - * Simple builder. + * Build caption label. * * @return Label */ @@ -69,19 +66,7 @@ public class LabelBuilder { } /** - * Simple builder. - * - * @return Label - */ - public Label buildMessageLabel() { - final Label label = createLabel(); - label.setContentMode(ContentMode.HTML); - label.addStyleName(SPUILabelDefinitions.SP_LABEL_MESSAGE_STYLE); - return label; - } - - /** - * Simple builder. + * Build label. * * @return Label */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java index 71c489aa0..357ef04dc 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java @@ -576,13 +576,11 @@ public class ActionHistoryTable extends TreeTable { final long currentTimeMillis = System.currentTimeMillis(); final HorizontalLayout hLayout = new HorizontalLayout(); - final Label autoForceLabel = new LabelBuilder().name("").buildLabel(); + final Label autoForceLabel = new LabelBuilder().name("").id("action.history.table.timedforceId").buildLabel(); actionLabel.setValue(FontAwesome.BOLT.getHtml()); autoForceLabel.setContentMode(ContentMode.HTML); autoForceLabel.setValue(FontAwesome.HISTORY.getHtml()); - // setted Id for TimedForced. - autoForceLabel.setId("action.history.table.timedforceId"); hLayout.addComponent(actionLabel); hLayout.addComponent(autoForceLabel); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 2e0399225..7679869a5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -283,28 +283,27 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { populateTargetFilterQuery(); noOfGroups = createNoOfGroupsField(); - groupSizeLabel = createGroupSizeLabel(); + groupSizeLabel = createCountLabel(); triggerThreshold = createTriggerThreshold(); errorThreshold = createErrorThreshold(); description = createDescription(); errorThresholdOptionGroup = createErrorThresholdOptionGroup(); setDefaultSaveStartGroupOption(); actionTypeOptionGroupLayout.selectDefaultOption(); - totalTargetsLabel = createTotalTargetsLabel(); + totalTargetsLabel = createCountLabel(); targetFilterQuery = createTargetFilterQuery(); actionTypeOptionGroupLayout.addStyleName(SPUIStyleDefinitions.ROLLOUT_ACTION_TYPE_LAYOUT); } - private Label createGroupSizeLabel() { - final Label groupSize = new LabelBuilder().name("").buildLabel(); + private static Label createCountLabel() { + final Label groupSize = new LabelBuilder().visible(false).name("").buildLabel(); groupSize.addStyleName(ValoTheme.LABEL_TINY + " " + "rollout-target-count-message"); groupSize.setImmediate(true); - groupSize.setVisible(false); groupSize.setSizeUndefined(); return groupSize; } - private TextArea createTargetFilterQuery() { + private static TextArea createTargetFilterQuery() { final TextArea filterField = SPUIComponentProvider.getTextArea(null, "text-area-style", ValoTheme.TEXTFIELD_TINY, false, null, null, SPUILabelDefinitions.TARGET_FILTER_QUERY_TEXT_FIELD_LENGTH); @@ -315,15 +314,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return filterField; } - private Label createTotalTargetsLabel() { - final Label targetCountLabel = new LabelBuilder().name("").buildLabel(); - targetCountLabel.addStyleName(ValoTheme.LABEL_TINY + " " + "rollout-target-count-message"); - targetCountLabel.setImmediate(true); - targetCountLabel.setVisible(false); - targetCountLabel.setSizeUndefined(); - return targetCountLabel; - } - private OptionGroup createErrorThresholdOptionGroup() { final OptionGroup errorThresoldOptions = new OptionGroup(); for (final ERRORTHRESOLDOPTIONS option : ERRORTHRESOLDOPTIONS.values()) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java index 2e01a7c05..2549db85b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java @@ -149,8 +149,8 @@ public class RolloutGroupsListHeader extends AbstractGridHeader { @Override protected HorizontalLayout getHeaderCaptionLayout() { - headerCaption = new LabelBuilder().name("").buildCaptionLabel(); - headerCaption.setId(SPUIComponentIdProvider.ROLLOUT_GROUP_HEADER_CAPTION); + headerCaption = new LabelBuilder().id(SPUIComponentIdProvider.ROLLOUT_GROUP_HEADER_CAPTION).name("") + .buildCaptionLabel(); final Button rolloutsListViewLink = SPUIComponentProvider.getButton(null, "", "", null, false, null, SPUIButtonStyleSmallNoBorder.class); rolloutsListViewLink.setStyleName(ValoTheme.LINK_SMALL + " " + "on-focus-no-border link rollout-caption-links"); From 6db64dd5df7ae3fd8a896290812ccf1f681fa73d Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 16 Aug 2016 15:27:45 +0200 Subject: [PATCH 34/42] Merge master Signed-off-by: SirWayne --- .../hawkbit/repository/jpa/model/JpaDistributionSet.java | 6 +++--- .../jpa/model/helper/EntityPropertyChangeHelper.java | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index 0fa2d0c33..661474668 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -34,7 +34,7 @@ import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent.PropertyChange; import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; @@ -299,8 +299,8 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen @Override public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { - final Map.Values> changeSet = EntityPropertyChangeHelper - .getChangeSet(JpaDistributionSet.class, descriptorEvent); + final Map changeSet = EntityPropertyChangeHelper.getChangeSet(JpaDistributionSet.class, + descriptorEvent); EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(this)); if (changeSet.containsKey(DELETED_PROPERTY)) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java index 2be398e24..9e759640d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java @@ -11,7 +11,7 @@ package org.eclipse.hawkbit.repository.jpa.model.helper; import java.util.Map; import java.util.stream.Collectors; -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent.PropertyChange; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.internal.sessions.ObjectChangeSet; @@ -32,15 +32,14 @@ public class EntityPropertyChangeHelper { * @param event * @return the map of the changeSet */ - public static Map.Values> getChangeSet( - final Class clazz, final DescriptorEvent event) { + public static Map getChangeSet(final Class clazz, + final DescriptorEvent event) { final T rolloutGroup = clazz.cast(event.getObject()); final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet(); return changeSet.getChanges().stream().filter(record -> record instanceof DirectToFieldChangeRecord) .map(record -> (DirectToFieldChangeRecord) record) .collect(Collectors.toMap(record -> record.getAttribute(), - record -> new AbstractPropertyChangeEvent(rolloutGroup, null).new Values( - record.getOldValue(), record.getNewValue()))); + record -> new PropertyChange(record.getOldValue(), record.getNewValue()))); } } From 876c5996173de83753a6a4759cb20397180203ed Mon Sep 17 00:00:00 2001 From: Dominic Schabel Date: Tue, 16 Aug 2016 15:28:45 +0200 Subject: [PATCH 35/42] Found another place where a NOT was missing Signed-off-by: Dominic Schabel --- .../CustomTargetBeanQuery.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java index e82c6560e..f7670e316 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java @@ -9,6 +9,10 @@ package org.eclipse.hawkbit.ui.filtermanagement; import static org.apache.commons.lang3.ArrayUtils.isEmpty; +import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.isNotNullOrEmpty; +import static org.eclipse.hawkbit.ui.utils.SPUIDefinitions.FILTER_BY_QUERY; +import static org.springframework.data.domain.Sort.Direction.ASC; +import static org.springframework.data.domain.Sort.Direction.DESC; import java.util.ArrayList; import java.util.List; @@ -63,22 +67,22 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery { final Object[] sortIds, final boolean[] sortStates) { super(definition, queryConfig, sortIds, sortStates); - if (HawkbitCommonUtil.isNotNullOrEmpty(queryConfig)) { - filterQuery = (String) queryConfig.get(SPUIDefinitions.FILTER_BY_QUERY); + if (isNotNullOrEmpty(queryConfig)) { + filterQuery = (String) queryConfig.get(FILTER_BY_QUERY); } - if (isEmpty(sortStates)) { - // Initalize Sor - sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortIds[0]); - // Add sort. + + if (!isEmpty(sortStates)) { + + sort = new Sort(sortStates[0] ? ASC : DESC, (String) sortIds[0]); + for (int targetId = 1; targetId < sortIds.length; targetId++) { - sort.and(new Sort(sortStates[targetId] ? Direction.ASC : Direction.DESC, (String) sortIds[targetId])); + sort.and(new Sort(sortStates[targetId] ? ASC : DESC, (String) sortIds[targetId])); } } } @Override protected ProxyTarget constructBean() { - return new ProxyTarget(); } From 1094c3c12ff58a205be71c0ba2b9f66af63f2d29 Mon Sep 17 00:00:00 2001 From: Dominic Schabel Date: Tue, 16 Aug 2016 16:11:15 +0200 Subject: [PATCH 36/42] Found another place where a NOT was missing Signed-off-by: Dominic Schabel --- .../ui/rollout/rollout/RolloutBeanQuery.java | 7 +++---- .../rolloutgroup/RolloutGroupBeanQuery.java | 17 ++++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutBeanQuery.java index a1ab1024a..e13be8f3f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutBeanQuery.java @@ -14,7 +14,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.apache.commons.lang3.ArrayUtils; import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -74,10 +73,10 @@ public class RolloutBeanQuery extends AbstractBeanQuery { searchText = getSearchText(); - if (isEmpty(sortStates)) { - // Initalize Sor + if (!isEmpty(sortStates)) { + sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortIds[0]); - // Add sort. + for (int targetId = 1; targetId < sortIds.length; targetId++) { sort.and(new Sort(sortStates[targetId] ? Direction.ASC : Direction.DESC, (String) sortIds[targetId])); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupBeanQuery.java index 002adbe03..ab66b425d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupBeanQuery.java @@ -8,11 +8,14 @@ */ package org.eclipse.hawkbit.ui.rollout.rolloutgroup; +import static org.apache.commons.lang3.ArrayUtils.isEmpty; +import static org.springframework.data.domain.Sort.Direction.ASC; +import static org.springframework.data.domain.Sort.Direction.DESC; + import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.apache.commons.lang3.ArrayUtils; import org.eclipse.hawkbit.repository.RolloutGroupManagement; import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.model.RolloutGroup; @@ -65,17 +68,17 @@ public class RolloutGroupBeanQuery extends AbstractBeanQuery */ public RolloutGroupBeanQuery(final QueryDefinition definition, final Map queryConfig, final Object[] sortPropertyIds, final boolean[] sortStates) { + super(definition, queryConfig, sortPropertyIds, sortStates); rolloutId = getRolloutId(); - if (ArrayUtils.isEmpty(sortStates)) { - // Initalize Sor - sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortPropertyIds[0]); - // Add sort. + if (!isEmpty(sortStates)) { + + sort = new Sort(sortStates[0] ? ASC : DESC, (String) sortPropertyIds[0]); + for (int targetId = 1; targetId < sortPropertyIds.length; targetId++) { - sort.and(new Sort(sortStates[targetId] ? Direction.ASC : Direction.DESC, - (String) sortPropertyIds[targetId])); + sort.and(new Sort(sortStates[targetId] ? ASC : DESC, (String) sortPropertyIds[targetId])); } } } From 1d825f9c74363c2d691980292460bd0b2a37c1a8 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 16 Aug 2016 17:33:06 +0200 Subject: [PATCH 37/42] Add a textfield builder Signed-off-by: SirWayne --- .../jpa/JpaDistributionSetManagement.java | 13 +- .../SoftwareModuleAddUpdateWindow.java | 24 ++- .../CreateUpdateSoftwareTypeLayout.java | 17 +- .../upload/UploadConfirmationWindow.java | 23 ++- .../common/AbstractMetadataPopupLayout.java | 7 +- .../ui/common/builder/TextFieldBuilder.java | 170 ++++++++++++++++++ .../DistributionSetMetadatadetailslayout.java | 2 +- .../ui/common/grid/AbstractGridHeader.java | 19 +- .../ui/common/table/AbstractTableHeader.java | 17 +- .../ui/components/SPUIComponentProvider.java | 30 ---- .../ui/decorators/SPUITextFieldDecorator.java | 88 --------- .../CreateUpdateDistSetTypeLayout.java | 19 +- .../CreateOrUpdateFilterHeader.java | 15 +- .../filtermanagement/TargetFilterHeader.java | 14 +- .../AbstractCreateUpdateTagLayout.java | 9 +- .../DistributionAddUpdateWindowLayout.java | 20 +-- .../TargetAddUpdateWindowLayout.java | 23 +-- .../rollout/AddUpdateRolloutWindowLayout.java | 44 +++-- ...ficateAuthenticationConfigurationItem.java | 7 +- ...yTokenAuthenticationConfigurationItem.java | 14 +- .../ui/utils/SPUILabelDefinitions.java | 4 - 21 files changed, 294 insertions(+), 285 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/TextFieldBuilder.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUITextFieldDecorator.java diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index 8736fefd7..e170ccad7 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -483,7 +483,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { if (distributionSetMetadataRepository.exists(metadata.getId())) { throwMetadataKeyAlreadyExists(metadata.getId().getKey()); } - + touch(metadata.getDistributionSet()); return distributionSetMetadataRepository.save(metadata); } @@ -515,7 +515,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { findOne(metadata.getDistributionSet(), metadata.getKey()); // touch it to update the lock revision because we are modifying the // DS indirectly - touch(metadata.getDistributionSet());; + touch(metadata.getDistributionSet()); return distributionSetMetadataRepository.save(metadata); } @@ -528,8 +528,11 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { } /** - * Method to get the latest distribution set based on ds ID after the metadata changes for that distribution set. - * @param distributionSet Distribution set + * Method to get the latest distribution set based on ds ID after the + * metadata changes for that distribution set. + * + * @param distributionSet + * Distribution set */ private void touch(final DistributionSet distributionSet) { final DistributionSet latestDistributionSet = findDistributionSetById(distributionSet.getId()); @@ -552,7 +555,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override public List findDistributionSetMetadataByDistributionSetId(final Long distributionSetId) { - return new ArrayList(distributionSetMetadataRepository + return new ArrayList<>(distributionSetMetadataRepository .findAll((Specification) (root, query, cb) -> cb.equal( root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id), distributionSetId))); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 52f377366..65310e6d3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -118,21 +119,13 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se } private void createRequiredComponents() { - /* name textfield */ - nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, - true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - nameTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_NAME); - /* version text field */ - versionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", - ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, - SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - versionTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VERSION); + nameTextField = createTextField("textfield.name", SPUIComponentIdProvider.SOFT_MODULE_NAME); - /* Vendor text field */ - vendorTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.vendor"), "", ValoTheme.TEXTFIELD_TINY, - false, null, i18n.get("textfield.vendor"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - vendorTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VENDOR); + versionTextField = createTextField("textfield.version", SPUIComponentIdProvider.SOFT_MODULE_VERSION); + + vendorTextField = createTextField("textfield.vendor", SPUIComponentIdProvider.SOFT_MODULE_VENDOR); + vendorTextField.setRequired(false); descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"), @@ -148,6 +141,11 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se populateTypeNameCombo(); } + private TextField createTextField(final String in18Key, final String id) { + return new TextFieldBuilder().caption(i18n.get(in18Key)).required(true).prompt(i18n.get(in18Key)) + .immediate(true).id(id).buildTextField(); + } + private void populateTypeNameCombo() { typeComboBox.setContainerDataSource(HawkbitCommonUtil.createLazyQueryContainer( new BeanQueryFactory(SoftwareModuleTypeBeanQuery.class))); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index f57bef2d1..63f93807a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -19,6 +19,7 @@ import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareMo import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; @@ -36,6 +37,7 @@ import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; +import com.vaadin.ui.TextField; import com.vaadin.ui.components.colorpicker.ColorChangeListener; import com.vaadin.ui.themes.ValoTheme; @@ -79,15 +81,9 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { multiAssign = new LabelBuilder().name(multiAssignStr).buildLabel(); - tagName = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", - ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_NAME, true, "", i18n.get("textfield.name"), true, - SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - tagName.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_NAME); + tagName = createTextField("textfield.name", SPUIDefinitions.NEW_SOFTWARE_TYPE_NAME, SPUIDefinitions.TYPE_NAME); - typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", - ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_KEY, true, "", i18n.get("textfield.key"), true, - SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - typeKey.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_KEY); + typeKey = createTextField("textfield.key", SPUIDefinitions.NEW_SOFTWARE_TYPE_KEY, SPUIDefinitions.TYPE_KEY); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "", @@ -99,6 +95,11 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { singleMultiOptionGroup(); } + private TextField createTextField(final String in18Key, final String id, final String styleName) { + return new TextFieldBuilder().caption(i18n.get(in18Key)).styleName(ValoTheme.TEXTFIELD_TINY + " " + styleName) + .required(true).prompt(i18n.get(in18Key)).immediate(true).id(id).buildTextField(); + } + @Override protected void buildLayout() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationWindow.java index e5a9b72fc..c89ad723b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationWindow.java @@ -26,6 +26,7 @@ import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.artifacts.state.CustomFile; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleTiny; @@ -248,29 +249,27 @@ public class UploadConfirmationWindow implements Button.ClickListener { deleteIcon.setData(itemId); newItem.getItemProperty(ACTION).setValue(deleteIcon); - final TextField sha1 = SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, false, null, - null, true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - sha1.setId(swNameVersion + "/" + customFile.getFileName() + "/sha1"); + final TextField sha1 = createTextField(swNameVersion + "/" + customFile.getFileName() + "/sha1"); - final TextField md5 = SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, false, null, - null, true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - md5.setId(swNameVersion + "/" + customFile.getFileName() + "/md5"); + final TextField md5 = createTextField(swNameVersion + "/" + customFile.getFileName() + "/md5"); + + createTextField(swNameVersion + "/" + customFile.getFileName() + "/customFileName"); - final TextField customFileName = SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, - false, null, null, true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - customFileName.setId(swNameVersion + "/" + customFile.getFileName() + "/customFileName"); newItem.getItemProperty(SHA1_CHECKSUM).setValue(sha1); newItem.getItemProperty(MD5_CHECKSUM).setValue(md5); newItem.getItemProperty(CUSTOM_FILE).setValue(customFile); } } + private static TextField createTextField(final String id) { + return new TextFieldBuilder().immediate(true).id(id).buildTextField(); + } + private void addFileNameLayout(final Item newItem, final String baseSoftwareModuleNameVersion, final String customFileName, final String itemId) { final HorizontalLayout horizontalLayout = new HorizontalLayout(); - final TextField fileNameTextField = SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, - false, null, null, true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - fileNameTextField.setId(baseSoftwareModuleNameVersion + "/" + customFileName + "/customFileName"); + final TextField fileNameTextField = createTextField( + baseSoftwareModuleNameVersion + "/" + customFileName + "/customFileName"); fileNameTextField.setData(baseSoftwareModuleNameVersion + "/" + customFileName); fileNameTextField.setValue(customFileName); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java index d3893e40d..8b80dee31 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java @@ -17,6 +17,7 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.MetaData; import org.eclipse.hawkbit.repository.model.NamedVersionedEntity; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer; @@ -206,9 +207,9 @@ public abstract class AbstractMetadataPopupLayout onKeyChange(event)); keyField.setTextChangeEventMode(TextChangeEventMode.EAGER); keyField.setWidth("100%"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/TextFieldBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/TextFieldBuilder.java new file mode 100644 index 000000000..ebb9806d3 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/TextFieldBuilder.java @@ -0,0 +1,170 @@ +/** + * 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.ui.common.builder; + +import org.apache.commons.lang3.StringUtils; + +import com.vaadin.event.FieldEvents.TextChangeListener; +import com.vaadin.server.Sizeable.Unit; +import com.vaadin.ui.AbstractTextField.TextChangeEventMode; +import com.vaadin.ui.TextField; +import com.vaadin.ui.themes.ValoTheme; + +/** + * Textfield builder. + * + */ +public class TextFieldBuilder { + + private static final int TEXT_FIELD_DEFAULT_MAX_LENGTH = 64; + + private String caption; + private String style; + private String styleName = ValoTheme.TEXTFIELD_TINY; + private String prompt; + private String id; + private boolean immediate; + private boolean required; + private int maxLengthAllowed = TEXT_FIELD_DEFAULT_MAX_LENGTH; + + /** + * @param caption + * the caption to set + * @return the builder + */ + public TextFieldBuilder caption(final String caption) { + this.caption = caption; + return this; + } + + /** + * @param style + * the style to set * @return the builder + * @return the builder + */ + public TextFieldBuilder style(final String style) { + this.style = style; + return this; + } + + /** + * @param styleName + * the styleName to set + * @return the builder + */ + public TextFieldBuilder styleName(final String styleName) { + this.styleName = styleName; + return this; + } + + /** + * @param required + * the required to set + * @return the builder + */ + public TextFieldBuilder required(final boolean required) { + this.required = required; + return this; + } + + /** + * @param prompt + * the prompt to set + * @return the builder + */ + public TextFieldBuilder prompt(final String prompt) { + this.prompt = prompt; + return this; + } + + /** + * @param immediate + * the immediate to set + * @return the builder + */ + public TextFieldBuilder immediate(final boolean immediate) { + this.immediate = immediate; + return this; + } + + /** + * @param maxLengthAllowed + * the maxLengthAllowed to set + * @return the builder + */ + public TextFieldBuilder maxLengthAllowed(final int maxLengthAllowed) { + this.maxLengthAllowed = maxLengthAllowed; + return this; + } + + /** + * @param id + * the id to set + * @return the builder + */ + public TextFieldBuilder id(final String id) { + this.id = id; + return this; + } + + /** + * Build a textfield + * + * @return textfield + */ + public TextField buildTextField() { + final TextField textField = new TextField(); + textField.addStyleName(ValoTheme.TEXTFIELD_SMALL); + textField.setRequired(required); + textField.setImmediate(immediate); + + if (StringUtils.isNotEmpty(caption)) { + textField.setCaption(caption); + } + + if (StringUtils.isNotEmpty(style)) { + textField.setStyleName(style); + } + + if (StringUtils.isNotEmpty(styleName)) { + textField.addStyleName(styleName); + } + if (StringUtils.isNotEmpty(prompt)) { + textField.setInputPrompt(prompt); + } + + if (maxLengthAllowed > 0) { + textField.setMaxLength(maxLengthAllowed); + } + + if (StringUtils.isNotEmpty(id)) { + textField.setId(id); + } + + return textField; + } + + /** + * Create a search text field. + * + * @param textChangeListener + * listener when text is changed. + * @return the textfield + */ + public TextField createSearchField(final TextChangeListener textChangeListener) { + final TextField textField = style("filter-box").styleName("text-style filter-box-hide").buildTextField(); + textField.setWidth(100.0F, Unit.PERCENTAGE); + textField.addTextChangeListener(textChangeListener); + textField.setTextChangeEventMode(TextChangeEventMode.LAZY); + // 1 seconds timeout. + textField.setTextChangeTimeout(1000); + return textField; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java index e4e0bd650..bcac6033b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java @@ -48,7 +48,7 @@ public class DistributionSetMetadatadetailslayout extends Table { private static final String VIEW = "view"; - private DistributionSetManagement distributionSetManagement; + private transient DistributionSetManagement distributionSetManagement; private DsMetadataPopupLayout dsMetadataPopupLayout; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridHeader.java index 4ba8ec464..ebbaea4d9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridHeader.java @@ -8,16 +8,15 @@ */ package org.eclipse.hawkbit.ui.common.grid; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import com.google.common.base.Strings; import com.vaadin.server.FontAwesome; -import com.vaadin.ui.AbstractTextField.TextChangeEventMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.HorizontalLayout; @@ -61,7 +60,8 @@ public abstract class AbstractGridHeader extends VerticalLayout { private void createComponents() { headerCaptionLayout = getHeaderCaptionLayout(); if (isRollout()) { - searchField = createSearchField(); + searchField = new TextFieldBuilder().id(getSearchBoxId()) + .createSearchField(event -> searchBy(event.getText())); searchResetIcon = createSearchResetIcon(); addButton = createAddButton(); } @@ -92,7 +92,7 @@ public abstract class AbstractGridHeader extends VerticalLayout { addStyleName("no-border-bottom"); } - private HorizontalLayout createHeaderFilterIconLayout() { + private static HorizontalLayout createHeaderFilterIconLayout() { final HorizontalLayout titleFilterIconsLayout = new HorizontalLayout(); titleFilterIconsLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE); titleFilterIconsLayout.setSpacing(false); @@ -101,17 +101,6 @@ public abstract class AbstractGridHeader extends VerticalLayout { return titleFilterIconsLayout; } - private TextField createSearchField() { - final TextField textField = SPUIComponentProvider.getTextField("", "filter-box", "text-style filter-box-hide", - false, "", "", false, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - textField.setId(getSearchBoxId()); - textField.setWidth(100.0f, Unit.PERCENTAGE); - textField.addTextChangeListener(event -> searchBy(event.getText())); - textField.setTextChangeEventMode(TextChangeEventMode.LAZY); - textField.setTextChangeTimeout(1000); - return textField; - } - private SPUIButton createSearchResetIcon() { final SPUIButton button = (SPUIButton) SPUIComponentProvider.getButton(getSearchRestIconId(), "", "", null, false, FontAwesome.SEARCH, SPUIButtonStyleSmallNoBorder.class); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java index 54fee678f..8df142d7c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java @@ -13,20 +13,19 @@ import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; import com.vaadin.event.dd.DropHandler; import com.vaadin.server.FontAwesome; -import com.vaadin.ui.AbstractTextField.TextChangeEventMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.DragAndDropWrapper; @@ -87,7 +86,7 @@ public abstract class AbstractTableHeader extends VerticalLayout { private void createComponents() { headerCaption = createHeaderCaption(); - searchField = createSearchField(); + searchField = new TextFieldBuilder().id(getSearchBoxId()).createSearchField(event -> searchBy(event.getText())); searchResetIcon = createSearchResetIcon(); @@ -207,18 +206,6 @@ public abstract class AbstractTableHeader extends VerticalLayout { return new LabelBuilder().name(getHeaderCaption()).buildCaptionLabel(); } - private TextField createSearchField() { - final TextField textField = SPUIComponentProvider.getTextField("", "filter-box", "text-style filter-box-hide", - false, "", "", false, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - textField.setId(getSearchBoxId()); - textField.setWidth(100.0f, Unit.PERCENTAGE); - textField.addTextChangeListener(event -> searchBy(event.getText())); - textField.setTextChangeEventMode(TextChangeEventMode.LAZY); - // 1 seconds timeout. - textField.setTextChangeTimeout(1000); - return textField; - } - private SPUIButton createSearchResetIcon() { final SPUIButton button = (SPUIButton) SPUIComponentProvider.getButton(getSearchRestIconId(), "", "", null, false, FontAwesome.SEARCH, SPUIButtonStyleSmallNoBorder.class); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 063a5325f..1c56ac1d0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -18,7 +18,6 @@ import org.eclipse.hawkbit.ui.common.UserDetailsFormatter; import org.eclipse.hawkbit.ui.decorators.SPUIButtonDecorator; import org.eclipse.hawkbit.ui.decorators.SPUIComboBoxDecorator; import org.eclipse.hawkbit.ui.decorators.SPUITextAreaDecorator; -import org.eclipse.hawkbit.ui.decorators.SPUITextFieldDecorator; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.slf4j.Logger; @@ -36,7 +35,6 @@ import com.vaadin.ui.Link; import com.vaadin.ui.Panel; import com.vaadin.ui.TabSheet; import com.vaadin.ui.TextArea; -import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; @@ -56,34 +54,6 @@ public final class SPUIComponentProvider { } - /** - * Get Label UI component. - * - * @param caption - * set the caption of the textfield - * @param style - * set style - * @param styleName - * add style - * @param required - * to set field as mandatory - * @param data - * component data - * @param prompt - * prompt user for input - * @param immediate - * set component's immediate mode specified mode - * @param maxLengthAllowed - * maximum characters allowed - * @return TextField text field - */ - public static TextField getTextField(final String caption, final String style, final String styleName, - final boolean required, final String data, final String prompt, final boolean immediate, - final int maxLengthAllowed) { - return SPUITextFieldDecorator.decorate(caption, style, styleName, required, data, prompt, immediate, - maxLengthAllowed); - } - /** * Get Label UI component. * * diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUITextFieldDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUITextFieldDecorator.java deleted file mode 100644 index 647b1d5aa..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUITextFieldDecorator.java +++ /dev/null @@ -1,88 +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.ui.decorators; - -import org.apache.commons.lang3.StringUtils; - -import com.vaadin.ui.TextField; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Decorate TextField with required style. - * - * - * - */ -public final class SPUITextFieldDecorator { - - /** - * Constructor. - */ - private SPUITextFieldDecorator() { - - } - - /** - * - * @param caption - * set the caption of the textfield - * @param style - * set style - * @param styleName - * add style - * @param required - * to set field as mandatory - * @param data - * component data - * @param prompt - * prompt user for input - * @param immediate - * as for display - * @param maxLengthAllowed - * maximum characters allowed - * @return Text field as decorated - */ - public static TextField decorate(final String caption, final String style, final String styleName, - final boolean required, final String data, final String prompt, final boolean immediate, - final int maxLengthAllowed) { - final TextField spUITxtFld = new TextField(); - if (StringUtils.isNotEmpty(caption)) { - spUITxtFld.setCaption(caption); - } - // Default settings - spUITxtFld.setRequired(false); - spUITxtFld.addStyleName(ValoTheme.TEXTFIELD_SMALL); - if (required) { - spUITxtFld.setRequired(true); - } - if (immediate) { - spUITxtFld.setImmediate(true); - } - // Add style - if (StringUtils.isNotEmpty(style)) { - spUITxtFld.setStyleName(style); - } - // Add style Name - if (StringUtils.isNotEmpty(styleName)) { - spUITxtFld.addStyleName(styleName); - } - if (StringUtils.isNotEmpty(prompt)) { - spUITxtFld.setInputPrompt(prompt); - } - if (StringUtils.isNotEmpty(data)) { - spUITxtFld.setData(data); - } - if (maxLengthAllowed > 0) { - spUITxtFld.setMaxLength(maxLengthAllowed); - } - - return spUITxtFld; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 65e52d448..0aa613fea 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; @@ -45,6 +46,7 @@ import com.vaadin.ui.CheckBox; import com.vaadin.ui.Component; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Table; +import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; @@ -84,15 +86,11 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { super.createRequiredComponents(); - tagName = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", - ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_NAME, true, "", - i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - tagName.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_NAME); + tagName = createTextField("textfield.name", SPUIDefinitions.DIST_SET_TYPE_NAME, + SPUIDefinitions.NEW_DISTRIBUTION_TYPE_NAME); - typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", - ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_KEY, true, "", i18n.get("textfield.key"), - true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - typeKey.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_KEY); + typeKey = createTextField("textfield.key", SPUIDefinitions.DIST_SET_TYPE_KEY, + SPUIDefinitions.NEW_DISTRIBUTION_TYPE_KEY); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "", @@ -102,6 +100,11 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { tagDesc.setNullRepresentation(""); } + private TextField createTextField(final String in18Key, final String id, final String styleName) { + return new TextFieldBuilder().caption(i18n.get(in18Key)).styleName(ValoTheme.TEXTFIELD_TINY + " " + styleName) + .required(true).prompt(i18n.get(in18Key)).immediate(true).id(id).buildTextField(); + } + @Override protected void buildLayout() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java index a5ff7be66..7a5f6065e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java @@ -19,6 +19,7 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -249,10 +250,9 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button } private TextField createNameTextField() { - final TextField nameField = SPUIComponentProvider.getTextField(i18n.get("textfield.customfiltername"), "", - ValoTheme.TEXTFIELD_TINY, false, null, i18n.get("textfield.customfiltername"), true, - SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - nameField.setId(SPUIComponentIdProvider.CUSTOM_FILTER_ADD_NAME); + final TextField nameField = new TextFieldBuilder().caption(i18n.get("textfield.customfiltername")) + .prompt(i18n.get("textfield.customfiltername")).immediate(true) + .id(SPUIComponentIdProvider.CUSTOM_FILTER_ADD_NAME).buildTextField(); nameField.setPropertyDataSource(nameLabel); nameField.addTextChangeListener(this::onFilterNameChange); return nameField; @@ -450,10 +450,9 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button return button; } - private TextField createSearchField() { - final TextField textField = SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, false, "", - "", true, SPUILabelDefinitions.TARGET_FILTER_QUERY_TEXT_FIELD_LENGTH); - textField.setId("custom.query.text.Id"); + private static TextField createSearchField() { + final TextField textField = new TextFieldBuilder().immediate(true).id("custom.query.text.Id") + .maxLengthAllowed(SPUILabelDefinitions.TARGET_FILTER_QUERY_TEXT_FIELD_LENGTH).buildTextField(); textField.addStyleName("target-filter-textfield"); textField.setWidth(900.0F, Unit.PIXELS); textField.setTextChangeEventMode(TextChangeEventMode.LAZY); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java index 32347ae24..a1c5e9993 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java @@ -12,6 +12,7 @@ import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -19,7 +20,6 @@ import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; @@ -27,7 +27,6 @@ import org.vaadin.spring.events.EventBus; import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.AbstractTextField.TextChangeEventMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.HorizontalLayout; @@ -121,14 +120,9 @@ public class TargetFilterHeader extends VerticalLayout { } private TextField createSearchField() { - final TextField campSearchTextField = SPUIComponentProvider.getTextField(null, "filter-box", - "text-style filter-box-hide", false, "", "", false, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - campSearchTextField.setId("target.filter.search.text.Id"); - campSearchTextField.setWidth(500.0f, Unit.PIXELS); - campSearchTextField.addTextChangeListener(event -> searchBy(event.getText())); - campSearchTextField.setTextChangeEventMode(TextChangeEventMode.LAZY); - // 1 seconds timeout. - campSearchTextField.setTextChangeTimeout(1000); + final TextField campSearchTextField = new TextFieldBuilder().id("target.filter.search.text.Id") + .createSearchField(event -> searchBy(event.getText())); + campSearchTextField.setWidth(500.0F, Unit.PIXELS); return campSearchTextField; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index bd62a0cb0..ed2495d35 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -20,6 +20,7 @@ import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerLayout; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; @@ -152,10 +153,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorLabel = new LabelBuilder().name(i18n.get("label.choose.tag.color")).buildLabel(); colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); - tagName = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", - ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_NAME, true, "", i18n.get("textfield.name"), true, - SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - tagName.setId(SPUIDefinitions.NEW_TARGET_TAG_NAME); + tagName = new TextFieldBuilder().caption(i18n.get("textfield.name")) + .styleName(ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_NAME).required(true) + .prompt(i18n.get("textfield.name")).immediate(true).id(SPUIDefinitions.NEW_TARGET_TAG_NAME) + .buildTextField(); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"), diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 6a40d8101..80badb249 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -25,6 +25,7 @@ import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -124,16 +125,8 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { * Create required UI components. */ private void createRequiredComponents() { - distNameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, - true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - distNameTextField.setId(SPUIComponentIdProvider.DIST_ADD_NAME); - distNameTextField.setNullRepresentation(""); - - distVersionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", - ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, - SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - distVersionTextField.setId(SPUIComponentIdProvider.DIST_ADD_VERSION); - distVersionTextField.setNullRepresentation(""); + distNameTextField = createTextField("textfield.name", SPUIComponentIdProvider.DIST_ADD_NAME); + distVersionTextField = createTextField("textfield.version", SPUIComponentIdProvider.DIST_ADD_VERSION); distsetTypeNameComboBox = SPUIComponentProvider.getComboBox(i18n.get("label.combobox.type"), "", "", null, "", false, "", i18n.get("label.combobox.type")); @@ -154,6 +147,13 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { reqMigStepCheckbox.setId(SPUIComponentIdProvider.DIST_ADD_MIGRATION_CHECK); } + private TextField createTextField(final String in18Key, final String id) { + final TextField buildTextField = new TextFieldBuilder().caption(i18n.get(in18Key)).required(true) + .prompt(i18n.get(in18Key)).immediate(true).id(id).buildTextField(); + buildTextField.setNullRepresentation(""); + return buildTextField; + } + /** * Get the LazyQueryContainer instance for DistributionSetTypes. * diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 84c933cba..d6f78909b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -16,6 +16,7 @@ import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -82,15 +83,9 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } private void createRequiredComponents() { - /* Textfield for controller Id */ - controllerIDTextField = SPUIComponentProvider.getTextField(i18n.get("prompt.target.id"), "", - ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("prompt.target.id"), true, - SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - controllerIDTextField.setId(SPUIComponentIdProvider.TARGET_ADD_CONTROLLER_ID); - /* Textfield for target name */ - nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, - false, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - nameTextField.setId(SPUIComponentIdProvider.TARGET_ADD_NAME); + controllerIDTextField = createTextField("prompt.target.id", SPUIComponentIdProvider.TARGET_ADD_CONTROLLER_ID); + nameTextField = createTextField("textfield.name", SPUIComponentIdProvider.TARGET_ADD_NAME); + nameTextField.setRequired(false); /* Textarea for target description */ descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", @@ -100,12 +95,12 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { descTextArea.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY); } - private void buildLayout() { + private TextField createTextField(final String in18Key, final String id) { + return new TextFieldBuilder().caption(i18n.get(in18Key)).required(true).prompt(i18n.get(in18Key)) + .immediate(true).id(id).buildTextField(); + } - /* - * The main layout of the window contains mandatory info, textboxes - * (controller Id, name & description) and action buttons layout - */ + private void buildLayout() { setSizeUndefined(); formLayout = new FormLayout(); formLayout.addComponent(controllerIDTextField); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 7679869a5..261c4f68e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -31,6 +31,7 @@ import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.filtermanagement.TargetFilterBeanQuery; @@ -262,9 +263,17 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return new LabelBuilder().name(i18n.get(key)).buildLabel(); } - private TextField getTextfield(final String key) { - return SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, false, null, i18n.get(key), true, - SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); + private TextField createTextField(final String in18Key, final String id) { + return new TextFieldBuilder().prompt(i18n.get(in18Key)).immediate(true).id(id).buildTextField(); + } + + private TextField createIntegerTextField(final String in18Key, final String id) { + final TextField textField = createTextField(in18Key, id); + textField.setNullRepresentation(""); + textField.setConverter(new StringToIntegerConverter()); + textField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER)); + textField.setSizeUndefined(); + return textField; } private static Label getPercentHintLabel() { @@ -514,39 +523,26 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private TextField createErrorThreshold() { - final TextField errorField = getTextfield("prompt.error.threshold"); - errorField.setNullRepresentation(""); + final TextField errorField = createIntegerTextField("prompt.error.threshold", + SPUIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_ID); errorField.addValidator(new ThresholdFieldValidator()); - errorField.setConverter(new StringToIntegerConverter()); - errorField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER)); - errorField.setId(SPUIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_ID); errorField.setMaxLength(7); - errorField.setSizeUndefined(); return errorField; } private TextField createTriggerThreshold() { - final TextField thresholdField = getTextfield("prompt.tigger.threshold"); - thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID); - thresholdField.setNullRepresentation(""); + final TextField thresholdField = createIntegerTextField("prompt.tigger.threshold", + SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID); thresholdField.addValidator(new ThresholdFieldValidator()); - thresholdField.setConverter(new StringToIntegerConverter()); - thresholdField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER)); - thresholdField.setSizeUndefined(); - thresholdField.setMaxLength(3); return thresholdField; } private TextField createNoOfGroupsField() { - final TextField noOfGroupsField = getTextfield("prompt.number.of.groups"); - noOfGroupsField.setId(SPUIComponentIdProvider.ROLLOUT_NO_OF_GROUPS_ID); + final TextField noOfGroupsField = createIntegerTextField("prompt.number.of.groups", + SPUIComponentIdProvider.ROLLOUT_NO_OF_GROUPS_ID); noOfGroupsField.addValidator(new GroupNumberValidator()); - noOfGroupsField.setSizeUndefined(); noOfGroupsField.setMaxLength(3); - noOfGroupsField.setConverter(new StringToIntegerConverter()); - noOfGroupsField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER)); noOfGroupsField.addValueChangeListener(this::onGroupNumberChange); - noOfGroupsField.setNullRepresentation(""); return noOfGroupsField; } @@ -584,8 +580,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private TextField createRolloutNameField() { - final TextField rolloutNameField = getTextfield("textfield.name"); - rolloutNameField.setId(SPUIComponentIdProvider.ROLLOUT_NAME_FIELD_ID); + final TextField rolloutNameField = createTextField("textfield.name", + SPUIComponentIdProvider.ROLLOUT_NAME_FIELD_ID); rolloutNameField.setSizeUndefined(); return rolloutNameField; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java index d7203772a..50b3a33a5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java @@ -13,7 +13,7 @@ import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.spring.annotation.SpringComponent; @@ -22,7 +22,6 @@ import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.themes.ValoTheme; /** * This class represents the UI item for the certificate authenticated by an @@ -65,10 +64,8 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti caRootAuthorityLabel.setDescription( "The SSL Issuer iRules.X509 hash, to validate against the controller request certifcate."); - caRootAuthorityTextField = SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, false, null, - "", true, 128); + caRootAuthorityTextField = new TextFieldBuilder().immediate(true).maxLengthAllowed(128).buildTextField(); caRootAuthorityTextField.setWidth("500px"); - caRootAuthorityTextField.setImmediate(true); caRootAuthorityTextField.addTextChangeListener(event -> caRootAuthorityChanged()); caRootAuthorityLayout.addComponent(caRootAuthorityLabel); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java index 572cfe763..28cf7e242 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java @@ -14,9 +14,9 @@ import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmall; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.server.FontAwesome; @@ -46,12 +46,12 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac private Label gatewayTokenkeyLabel; - private boolean configurationEnabled = false; - private boolean configurationEnabledChange = false; + private boolean configurationEnabled; + private boolean configurationEnabledChange; - private boolean keyNameChanged = false; + private boolean keyNameChanged; - private boolean keyChanged = false; + private boolean keyChanged; private VerticalLayout detailLayout; @@ -75,9 +75,7 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac detailLayout = new VerticalLayout(); detailLayout.setImmediate(true); - gatewayTokenNameTextField = SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, false, null, - "", true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); - gatewayTokenNameTextField.setImmediate(true); + gatewayTokenNameTextField = new TextFieldBuilder().immediate(true).buildTextField(); // hide text field until we support multiple gateway tokens for a tenan gatewayTokenNameTextField.setVisible(false); gatewayTokenNameTextField.addTextChangeListener(event -> doKeyNameChanged()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java index a5bb24831..f3619d92a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java @@ -268,10 +268,6 @@ public final class SPUILabelDefinitions { */ public static final String UPDATE_CUSTOM_FILTER = "Update Custom Filter"; - /** - * Text area and text field max allowed length. - */ - public static final int TEXT_FIELD_MAX_LENGTH = 64; /** * Text area and text field max allowed length. */ From 7ea17c54f18987376b2db9c47cb6145d14ab4e76 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Wed, 17 Aug 2016 09:02:04 +0200 Subject: [PATCH 38/42] Add TextBuilderArea Signed-off-by: SirWayne --- .../SoftwareModuleAddUpdateWindow.java | 8 +- .../CreateUpdateSoftwareTypeLayout.java | 11 +- .../common/AbstractMetadataPopupLayout.java | 8 +- .../builder/AbstractTextFieldBuilder.java | 151 ++++++++++++++++++ .../ui/common/builder/TextAreaBuilder.java | 37 +++++ .../ui/common/builder/TextFieldBuilder.java | 138 +++------------- .../ui/common/grid/AbstractGridHeader.java | 3 +- .../ui/common/table/AbstractTableHeader.java | 4 +- .../ui/components/SPUIComponentProvider.java | 26 --- .../ui/decorators/SPUITextAreaDecorator.java | 81 ---------- .../CreateUpdateDistSetTypeLayout.java | 10 +- .../filtermanagement/TargetFilterHeader.java | 3 +- .../AbstractCreateUpdateTagLayout.java | 12 +- .../DistributionAddUpdateWindowLayout.java | 8 +- .../TargetAddUpdateWindowLayout.java | 12 +- .../TargetBulkUpdateWindowLayout.java | 8 +- .../rollout/AddUpdateRolloutWindowLayout.java | 15 +- .../ui/utils/SPUILabelDefinitions.java | 5 - 18 files changed, 254 insertions(+), 286 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/AbstractTextFieldBuilder.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/TextAreaBuilder.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUITextAreaDecorator.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 65310e6d3..25d579717 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.builder.TextAreaBuilder; import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; @@ -127,10 +128,9 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se vendorTextField = createTextField("textfield.vendor", SPUIComponentIdProvider.SOFT_MODULE_VENDOR); vendorTextField.setRequired(false); - descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", - ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"), - SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); - descTextArea.setId(SPUIComponentIdProvider.ADD_SW_MODULE_DESCRIPTION); + descTextArea = new TextAreaBuilder().caption(i18n.get("textfield.description")).style("text-area-style") + .prompt(i18n.get("textfield.description")).id(SPUIComponentIdProvider.ADD_SW_MODULE_DESCRIPTION) + .buildTextField(); typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true, null, i18n.get("upload.swmodule.type")); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 63f93807a..e1c665751 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -19,8 +19,8 @@ import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareMo import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.builder.TextAreaBuilder; import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; @@ -85,11 +85,10 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { typeKey = createTextField("textfield.key", SPUIDefinitions.NEW_SOFTWARE_TYPE_KEY, SPUIDefinitions.TYPE_KEY); - tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", - ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "", - i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); - tagDesc.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_DESC); - tagDesc.setImmediate(true); + tagDesc = new TextAreaBuilder().caption(i18n.get("textfield.description")) + .styleName(ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC) + .prompt(i18n.get("textfield.description")).immediate(true).id(SPUIDefinitions.NEW_SOFTWARE_TYPE_DESC) + .buildTextField(); tagDesc.setNullRepresentation(""); singleMultiOptionGroup(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java index 8b80dee31..c89dff4b6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java @@ -17,6 +17,7 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.MetaData; import org.eclipse.hawkbit.repository.model.NamedVersionedEntity; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.builder.TextAreaBuilder; import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -49,7 +50,6 @@ import com.vaadin.ui.TextField; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent; -import com.vaadin.ui.themes.ValoTheme; /** * @@ -217,9 +217,9 @@ public abstract class AbstractMetadataPopupLayout + * the concrete text component + */ +public abstract class AbstractTextFieldBuilder { + + private String caption; + private String style; + private String styleName; + private String prompt; + private String id; + private boolean immediate; + private boolean required; + private int maxLengthAllowed; + + /** + * @param caption + * the caption to set + * @return the builder + */ + public AbstractTextFieldBuilder caption(final String caption) { + this.caption = caption; + return this; + } + + /** + * @param style + * the style to set * @return the builder + * @return the builder + */ + public AbstractTextFieldBuilder style(final String style) { + this.style = style; + return this; + } + + /** + * @param styleName + * the styleName to set + * @return the builder + */ + public AbstractTextFieldBuilder styleName(final String styleName) { + this.styleName = styleName; + return this; + } + + /** + * @param required + * the required to set + * @return the builder + */ + public AbstractTextFieldBuilder required(final boolean required) { + this.required = required; + return this; + } + + /** + * @param prompt + * the prompt to set + * @return the builder + */ + public AbstractTextFieldBuilder prompt(final String prompt) { + this.prompt = prompt; + return this; + } + + /** + * @param immediate + * the immediate to set + * @return the builder + */ + public AbstractTextFieldBuilder immediate(final boolean immediate) { + this.immediate = immediate; + return this; + } + + /** + * @param maxLengthAllowed + * the maxLengthAllowed to set + * @return the builder + */ + public AbstractTextFieldBuilder maxLengthAllowed(final int maxLengthAllowed) { + this.maxLengthAllowed = maxLengthAllowed; + return this; + } + + /** + * @param id + * the id to set + * @return the builder + */ + public AbstractTextFieldBuilder id(final String id) { + this.id = id; + return this; + } + + /** + * Build a textfield + * + * @return textfield + */ + public E buildTextField() { + final E textComponent = createTextComponent(); + + textComponent.setRequired(required); + textComponent.setImmediate(immediate); + + if (StringUtils.isNotEmpty(caption)) { + textComponent.setCaption(caption); + } + + if (StringUtils.isNotEmpty(style)) { + textComponent.setStyleName(style); + } + + if (StringUtils.isNotEmpty(styleName)) { + textComponent.addStyleName(styleName); + } + if (StringUtils.isNotEmpty(prompt)) { + textComponent.setInputPrompt(prompt); + } + + if (maxLengthAllowed > 0) { + textComponent.setMaxLength(maxLengthAllowed); + } + + if (StringUtils.isNotEmpty(id)) { + textComponent.setId(id); + } + + return textComponent; + } + + protected abstract E createTextComponent(); + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/TextAreaBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/TextAreaBuilder.java new file mode 100644 index 000000000..d75b408d4 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/TextAreaBuilder.java @@ -0,0 +1,37 @@ +/** + * 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.ui.common.builder; + +import com.vaadin.ui.TextArea; +import com.vaadin.ui.themes.ValoTheme; + +/** + * TextArea builder. + * + */ +public class TextAreaBuilder extends AbstractTextFieldBuilder