From 5e879ed80e40ecbd2ac7966779e14165db6497ec Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 13 Apr 2016 13:00:23 +0200 Subject: [PATCH 01/47] Filter icon not centered Signed-off-by: Melanie Retter --- .../hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 97d2bf031..b41f3dfe9 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 @@ -290,7 +290,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button searchLayout.setSpacing(false); searchLayout.addComponents(validationIcon, queryTextField); searchLayout.addStyleName("custom-search-layout"); - searchLayout.setComponentAlignment(validationIcon, Alignment.MIDDLE_CENTER); + searchLayout.setComponentAlignment(validationIcon, Alignment.TOP_CENTER); final HorizontalLayout iconLayout = new HorizontalLayout(); iconLayout.setSizeUndefined(); From 993dab2eedffb414a379b75d86384c686d5f9081 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 13 Apr 2016 14:12:58 +0200 Subject: [PATCH 02/47] Labels/Icons are placed differently in vertical alignment Signed-off-by: Melanie Retter --- .../common/detailslayout/AbstractTableDetailsLayout.java | 8 ++++---- .../hawkbit/ui/common/table/AbstractTableHeader.java | 7 +++---- .../java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) 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 969436904..3c153cb77 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 @@ -152,18 +152,18 @@ public abstract class AbstractTableDetailsLayout extends final HorizontalLayout nameEditLayout = new HorizontalLayout(); nameEditLayout.setWidth(100.0f, Unit.PERCENTAGE); nameEditLayout.addComponent(caption); - nameEditLayout.setComponentAlignment(caption, Alignment.MIDDLE_LEFT); + nameEditLayout.setComponentAlignment(caption, Alignment.TOP_LEFT); if (hasEditPermission()) { nameEditLayout.addComponent(editButton); - nameEditLayout.setComponentAlignment(editButton, Alignment.MIDDLE_RIGHT); + nameEditLayout.setComponentAlignment(editButton, Alignment.TOP_RIGHT); } nameEditLayout.setExpandRatio(caption, 1.0f); nameEditLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE); addComponent(nameEditLayout); - setComponentAlignment(nameEditLayout, Alignment.MIDDLE_CENTER); + setComponentAlignment(nameEditLayout, Alignment.TOP_CENTER); addComponent(detailsTab); - setComponentAlignment(nameEditLayout, Alignment.MIDDLE_CENTER); + setComponentAlignment(nameEditLayout, Alignment.TOP_CENTER); setSizeFull(); setHeightUndefined(); 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 b4709ccd1..0c5407316 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 @@ -44,7 +44,7 @@ import com.vaadin.ui.VerticalLayout; public abstract class AbstractTableHeader extends VerticalLayout { private static final long serialVersionUID = 4881626370291837175L; - + @Autowired protected I18N i18n; @@ -53,7 +53,6 @@ public abstract class AbstractTableHeader extends VerticalLayout { @Autowired protected transient EventBus.SessionEventBus eventbus; - private Label headerCaption; @@ -83,7 +82,7 @@ public abstract class AbstractTableHeader extends VerticalLayout { restoreState(); eventbus.subscribe(this); } - + @PreDestroy void destroy() { eventbus.unsubscribe(this); @@ -195,7 +194,7 @@ public abstract class AbstractTableHeader extends VerticalLayout { dropHintDropFilterLayout.setExpandRatio(dropFilterLayout, 1.0f); } addComponent(dropHintDropFilterLayout); - setComponentAlignment(dropHintDropFilterLayout, Alignment.MIDDLE_CENTER); + setComponentAlignment(dropHintDropFilterLayout, Alignment.TOP_CENTER); addStyleName("bordered-layout"); addStyleName("no-border-bottom"); } 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 bbbba8cec..dd8c0e5f9 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 @@ -139,7 +139,7 @@ public final class DashboardMenu extends CustomComponent { final Label logo = new Label("" + i18n.get("menu.title") + "", ContentMode.HTML); logo.setSizeUndefined(); final HorizontalLayout logoWrapper = new HorizontalLayout(logo); - logoWrapper.setComponentAlignment(logo, Alignment.MIDDLE_CENTER); + logoWrapper.setComponentAlignment(logo, Alignment.TOP_CENTER); logoWrapper.addStyleName("valo-menu-title"); return logoWrapper; } From 256877faddb99a7f7529819fad4399cdd1550343 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 13 Apr 2016 16:42:34 +0200 Subject: [PATCH 03/47] Reflect tag color change immediatly after popup is closed. (Deployment Management) Correct one spelling mistake in method name. Signed-off-by: Melanie Retter --- .../artifacts/smtype/CreateUpdateSoftwareTypeLayout.java | 6 +++--- .../management/targettag/CreateUpdateTargetTagLayout.java | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) 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 dc6d1081e..ecc0ad79d 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 @@ -612,7 +612,7 @@ public class CreateUpdateSoftwareTypeLayout extends CustomComponent implements C */ private void crateNewSWModuleType() { int assignNumber = 0; - final String colorPicked = getColorPickedSting(); + final String colorPicked = getColorPickedString(); final String typeNameValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeName.getValue()); final String typeKeyValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeKey.getValue()); final String typeDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeDesc.getValue()); @@ -649,7 +649,7 @@ public class CreateUpdateSoftwareTypeLayout extends CustomComponent implements C * * @return String of color picked value. */ - private String getColorPickedSting() { + private String getColorPickedString() { return "rgb(" + getSelPreview().getColor().getRed() + "," + getSelPreview().getColor().getGreen() + "," + getSelPreview().getColor().getBlue() + ")"; } @@ -675,7 +675,7 @@ public class CreateUpdateSoftwareTypeLayout extends CustomComponent implements C existingType.setDescription(null != typeDescValue ? typeDescValue : null); - existingType.setColour(getColorPickedSting()); + existingType.setColour(getColorPickedString()); swTypeManagementService.updateSoftwareModuleType(existingType); uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { existingType.getName() })); closeWindow(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java index 51ac77f10..aee07afc4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java @@ -183,7 +183,7 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout { * Create new tag. */ private void crateNewTag() { - final String colorPicked = getColorPickedSting(); + final String colorPicked = getColorPickedString(); final String tagNameValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagName.getValue()); final String tagDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue()); if (null != tagNameValue) { @@ -214,10 +214,11 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout { if (null != nameUpdateValue) { targetObj.setName(nameUpdateValue); targetObj.setDescription(null != descUpdateValue ? descUpdateValue : null); - targetObj.setColour(getColorPickedSting()); + targetObj.setColour(getColorPickedString()); tagManagement.updateTargetTag(targetObj); uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { targetObj.getName() })); closeWindow(); + eventBus.publish(this, new TargetTagUpdateEvent(targetObj)); } else { uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); } @@ -244,7 +245,7 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout { * * @return String of color picked value. */ - private String getColorPickedSting() { + private String getColorPickedString() { return "rgb(" + getSelPreview().getColor().getRed() + "," + getSelPreview().getColor().getGreen() + "," + getSelPreview().getColor().getBlue() + ")"; } From 66914de984f023322fef427d16cdb2c57dd4f3dc Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 26 Apr 2016 10:58:24 +0200 Subject: [PATCH 04/47] Set default behavior of our repository transaction isolation level to READ_UNCOMMITED. Signed-off-by: Kai Zimmermann --- .../hawkbit/repository/ActionRepository.java | 11 ++-- .../repository/ActionStatusRepository.java | 3 +- .../repository/ArtifactManagement.java | 39 ++++++-------- .../repository/BaseEntityRepository.java | 8 ++- .../repository/ControllerManagement.java | 23 +++++---- .../repository/DeploymentManagement.java | 41 +++++++-------- .../repository/DistributionSetManagement.java | 51 ++++++++++--------- .../DistributionSetMetadataRepository.java | 3 +- .../repository/DistributionSetRepository.java | 9 ++-- .../DistributionSetTagRepository.java | 7 ++- .../DistributionSetTypeRepository.java | 6 +-- .../EclipseLinkTargetInfoRepository.java | 10 ++-- .../ExternalArtifactProviderRepository.java | 6 +-- .../ExternalArtifactRepository.java | 5 +- .../repository/LocalArtifactRepository.java | 3 +- .../hawkbit/repository/ReportManagement.java | 13 ++--- .../repository/RolloutGroupManagement.java | 10 ++-- .../repository/RolloutGroupRepository.java | 3 +- .../hawkbit/repository/RolloutManagement.java | 25 +++++---- .../hawkbit/repository/RolloutRepository.java | 5 +- .../RolloutTargetGroupRepository.java | 5 +- .../repository/SoftwareManagement.java | 31 +++++------ .../SoftwareModuleMetadataRepository.java | 5 +- .../repository/SoftwareModuleRepository.java | 7 ++- .../SoftwareModuleTypeRepository.java | 6 +-- .../hawkbit/repository/SystemManagement.java | 13 ++--- .../hawkbit/repository/TagManagement.java | 26 ++++------ .../TargetFilterQueryManagement.java | 11 ++-- .../TargetFilterQueryRepository.java | 5 +- .../repository/TargetInfoRepository.java | 10 ++-- .../hawkbit/repository/TargetManagement.java | 31 +++++------ .../hawkbit/repository/TargetRepository.java | 13 +++-- .../repository/TargetTagRepository.java | 7 ++- .../TenantConfigurationManagement.java | 7 +-- .../TenantConfigurationRepository.java | 3 +- .../repository/TenantMetaDataRepository.java | 6 +-- 36 files changed, 229 insertions(+), 238 deletions(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionRepository.java index 8221fa0ca..742a7d731 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionRepository.java @@ -29,13 +29,14 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * {@link Action} repository. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface ActionRepository extends BaseEntityRepository, JpaSpecificationExecutor { /** * Retrieves an Action with all lazy attributes. @@ -172,7 +173,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * active */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Query("UPDATE Action a SET a.active = false WHERE a IN :keySet AND a.target IN :targetsIds") void setToInactive(@Param("keySet") List keySet, @Param("targetsIds") List targetsIds); @@ -191,7 +192,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * the current status of the actions which are affected */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Query("UPDATE Action a SET a.status = :statusToSet WHERE a.target IN :targetsIds AND a.active = :active AND a.status = :currentStatus AND a.distributionSet.requiredMigrationStep = false") void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("targetsIds") List targetIds, @Param("active") boolean active, @Param("currentStatus") Action.Status currentStatus); @@ -211,7 +212,7 @@ public interface ActionRepository extends BaseEntityRepository, Jp * the current status of the actions which are affected */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Query("UPDATE Action a SET a.status = :statusToSet WHERE a.rollout = :rollout AND a.active = :active AND a.status = :currentStatus") void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("rollout") Rollout rollout, @Param("active") boolean active, @Param("currentStatus") Action.Status currentStatus); @@ -386,6 +387,4 @@ public interface ActionRepository extends BaseEntityRepository, Jp @Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM Action a WHERE a.rolloutGroup.id IN ?1 GROUP BY a.rolloutGroup.id, a.status") List getStatusCountByRolloutGroupId(List rolloutGroupId); - // Asha-ends here - } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionStatusRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionStatusRepository.java index 2705b9ac6..2a0e8cfb3 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionStatusRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ActionStatusRepository.java @@ -16,13 +16,14 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * {@link ActionStatus} repository. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface ActionStatusRepository extends BaseEntityRepository, JpaSpecificationExecutor { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java index 145287fbf..a8a9b5ee5 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java @@ -43,17 +43,15 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.hateoas.Identifiable; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; /** - * service for {@link Artifact} management operations. - * - * - * + * Service for {@link Artifact} management operations. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated @Service public class ArtifactManagement { @@ -108,7 +106,7 @@ public class ArtifactManagement { * if check against provided SHA1 checksum failed */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public LocalArtifact createLocalArtifact(@NotNull final InputStream stream, @NotNull final Long moduleId, @NotEmpty final String filename, final String providedMd5Sum, final String providedSha1Sum, @@ -138,7 +136,7 @@ public class ArtifactManagement { return storeArtifactMetadata(softwareModule, filename, result, existing); } - private LocalArtifact checkForExistingArtifact(final String filename, final boolean overrideExisting, + private static LocalArtifact checkForExistingArtifact(final String filename, final boolean overrideExisting, final SoftwareModule softwareModule) { if (softwareModule.getLocalArtifactByFilename(filename).isPresent()) { if (overrideExisting) { @@ -222,9 +220,7 @@ public class ArtifactManagement { artifact.setSize(result.getSize()); LOG.debug("storing new artifact into repository {}", artifact); - final LocalArtifact artifactPersisted = localArtifactRepository.save(artifact); - - return artifactPersisted; + return localArtifactRepository.save(artifact); } /** @@ -242,7 +238,7 @@ public class ArtifactManagement { * @return created {@link ExternalArtifactProvider} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public ExternalArtifactProvider createExternalArtifactProvider(@NotEmpty final String name, final String description, @NotNull final String basePath, final String defaultUrlSuffix) { @@ -268,16 +264,13 @@ public class ArtifactManagement { * if {@link SoftwareModule} with given ID does not exist */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public ExternalArtifact createExternalArtifact(@NotNull final ExternalArtifactProvider externalRepository, final String urlSuffix, @NotNull final Long moduleId) { final SoftwareModule module = getModuleAndThrowExceptionIfThatFails(moduleId); - final ExternalArtifact result = externalArtifactRepository - .save(new ExternalArtifact(externalRepository, urlSuffix, module)); - - return result; + return externalArtifactRepository.save(new ExternalArtifact(externalRepository, urlSuffix, module)); } /** @@ -290,7 +283,7 @@ public class ArtifactManagement { * */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) public void deleteLocalArtifact(@NotNull final Long id) { final LocalArtifact existing = localArtifactRepository.findOne(id); @@ -313,7 +306,7 @@ public class ArtifactManagement { * the related local artifact */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) public void deleteGridFsArtifact(@NotNull final LocalArtifact existing) { if (existing == null) { @@ -350,7 +343,7 @@ public class ArtifactManagement { * */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) public void deleteExternalArtifact(@NotNull final Long id) { final ExternalArtifact existing = externalArtifactRepository.findOne(id); @@ -425,17 +418,17 @@ public class ArtifactManagement { * @param filename * of the artifact * @param overrideExisting - * to true if the artifact binary can be overdiden + * to true if the artifact binary can be overridden * if it already exists * @param contentType * the contentType of the file * * @return uploaded {@link LocalArtifact} * - * @throw ArtifactUploadFailedException if upload failes + * @throw ArtifactUploadFailedException if upload fails */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public LocalArtifact createLocalArtifact(final InputStream inputStream, final Long moduleId, final String filename, final boolean overrideExisting, final String contentType) { @@ -461,7 +454,7 @@ public class ArtifactManagement { * @throw ArtifactUploadFailedException if upload failes */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public LocalArtifact createLocalArtifact(final InputStream inputStream, final Long moduleId, final String filename, final boolean overrideExisting) { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/BaseEntityRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/BaseEntityRepository.java index 2b4de2b81..16f80596d 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/BaseEntityRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/BaseEntityRepository.java @@ -14,21 +14,19 @@ import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * Command repository operations for all {@link TenantAwareBaseEntity}s. * - * - * - * * @param * type if the entity type * @param * of the entity type */ @NoRepositoryBean -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface BaseEntityRepository extends PagingAndSortingRepository { @@ -39,7 +37,7 @@ public interface BaseEntityRepository spec = (targetRoot, query, cb) -> cb.equal(targetRoot.get(Target_.controllerId), @@ -271,7 +272,7 @@ public class ControllerManagement { * @return the updated TargetInfo */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) public TargetInfo updateTargetStatus(@NotNull final TargetInfo targetInfo, final TargetUpdateStatus status, final Long lastTargetQuery, final URI address) { @@ -300,7 +301,7 @@ public class ControllerManagement { * */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) public Action addCancelActionStatus(@NotNull final ActionStatus actionStatus, final Action action) { @@ -346,7 +347,7 @@ public class ControllerManagement { * inserted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) public Action addUpdateActionStatus(@NotNull final ActionStatus actionStatus, final Action action) { @@ -454,7 +455,7 @@ public class ControllerManagement { */ @Modifying @NotNull - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) public Target updateControllerAttributes(@NotEmpty final String targetid, @NotNull final Map data) { final Target target = targetRepository.findByControllerId(targetid); @@ -492,7 +493,7 @@ public class ControllerManagement { * {@link Status#RETRIEVED} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) public Action registerRetrieved(final Action action, final String message) { return handleRegisterRetrieved(action, message); @@ -556,7 +557,7 @@ public class ControllerManagement { */ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) public void addActionStatusMessage(final ActionStatus statusMessage) { actionStatusRepository.save(statusMessage); } @@ -573,7 +574,7 @@ public class ControllerManagement { * @return the security context of the target, in case no target exists for * the given controllerId {@code null} is returned */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) public String getSecurityTokenByControllerId(final String controllerId) { final Target target = targetRepository.findByControllerId(controllerId); return target != null ? target.getSecurityToken() : null; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index 77f71bebf..3eedee415 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -67,6 +67,7 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -78,7 +79,7 @@ import com.google.common.eventbus.EventBus; * * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated @Service public class DeploymentManagement { @@ -133,7 +134,7 @@ public class DeploymentManagement { * {@link SoftwareModuleType} are not assigned as define by the * {@link DistributionSetType}. * */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) @@ -167,7 +168,7 @@ public class DeploymentManagement { * {@link DistributionSetType}. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) public DistributionSetAssignmentResult assignDistributionSet(@NotNull final Long dsID, @@ -195,7 +196,7 @@ public class DeploymentManagement { * {@link DistributionSetType}. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) public DistributionSetAssignmentResult assignDistributionSet(@NotNull final Long dsID, final ActionType actionType, @@ -219,7 +220,7 @@ public class DeploymentManagement { * {@link DistributionSetType}. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) public DistributionSetAssignmentResult assignDistributionSet(@NotNull final Long dsID, @@ -243,8 +244,8 @@ public class DeploymentManagement { * a list of all targets and their action type * @param rollout * the rollout for this assignment - * @param rolloutgroup - * the rolloutgroup for this assignment + * @param rolloutGroup + * the rollout group for this assignment * @return the assignment result * * @throw IncompleteDistributionSetException if mandatory @@ -252,7 +253,7 @@ public class DeploymentManagement { * {@link DistributionSetType}. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) public DistributionSetAssignmentResult assignDistributionSet(@NotNull final Long dsID, @@ -276,8 +277,8 @@ public class DeploymentManagement { * a list of all targets and their action type * @param rollout * the rollout for this assignment - * @param rolloutgroup - * the rolloutgroup for this assignment + * @param rolloutGroup + * the rollout group for this assignment * @return the assignment result * * @throw IncompleteDistributionSetException if mandatory @@ -389,8 +390,8 @@ public class DeploymentManagement { softwareModules)); } - private Action createTargetAction(final Map targetsWithActionMap, final Target target, - final DistributionSet set, final Rollout rollout, final RolloutGroup rolloutGroup) { + private static Action createTargetAction(final Map targetsWithActionMap, + final Target target, final DistributionSet set, final Rollout rollout, final RolloutGroup rolloutGroup) { final Action actionForTarget = new Action(); final TargetWithActionType targetWithActionType = targetsWithActionMap.get(target.getControllerId()); actionForTarget.setActionType(targetWithActionType.getActionType()); @@ -512,7 +513,7 @@ public class DeploymentManagement { * action */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public Action cancelAction(@NotNull final Action action, @NotNull final Target target) { LOG.debug("cancelAction({}, {})", action, target); @@ -569,7 +570,7 @@ public class DeploymentManagement { * in case the given action is not active */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public Action forceQuitAction(@NotNull final Action action) { final Action mergedAction = entityManager.merge(action); @@ -614,7 +615,7 @@ public class DeploymentManagement { * the rolloutgroup for this action */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public void createScheduledAction(final List targets, final DistributionSet distributionSet, final ActionType actionType, final long forcedTime, final Rollout rollout, @@ -648,7 +649,7 @@ public class DeploymentManagement { * @return the action which has been started */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) public Action startScheduledAction(@NotNull final Action action) { @@ -911,7 +912,7 @@ public class DeploymentManagement { * @return the updated or the found {@link TargetAction} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public Action forceTargetAction(final Long actionId) { final Action action = actionRepository.findOne(actionId); @@ -923,7 +924,7 @@ public class DeploymentManagement { } /** - * retrieves all the {@link ActionStatus} entries of the given + * Retrieves all the {@link ActionStatus} entries of the given * {@link Action} and {@link Target}. * * @param pageReq @@ -981,11 +982,11 @@ public class DeploymentManagement { * @param rollout * the rollout the actions belong to * @param rolloutGroupParent - * the parent rolloutgroup the actions should reference + * the parent rollout group the actions should reference * @param actionStatus * the status the actions have * @return the actions referring a specific rollout and a specific parent - * rolloutgroup in a specific status + * rollout group in a specific status */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index 8bee7c703..db1ade60e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -59,6 +59,7 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -69,7 +70,7 @@ import com.google.common.eventbus.EventBus; * Business facade for managing the {@link DistributionSet}s. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated @Service public class DistributionSetManagement { @@ -142,7 +143,7 @@ public class DistributionSetManagement { * the assignment outcome. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty final List sets, @@ -164,7 +165,7 @@ public class DistributionSetManagement { * the assignment outcome. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty final Collection dsIds, @@ -229,7 +230,7 @@ public class DistributionSetManagement { * @throw DataDependencyViolationException in case of illegal update */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public DistributionSet updateDistributionSet(@NotNull final DistributionSet ds) { checkNotNull(ds.getId()); @@ -254,7 +255,7 @@ public class DistributionSetManagement { * to delete */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) public void deleteDistributionSet(@NotNull final DistributionSet set) { deleteDistributionSet(set.getId()); @@ -269,7 +270,7 @@ public class DistributionSetManagement { * to be deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) public void deleteDistributionSet(@NotEmpty final Long... distributionSetIDs) { final List toHardDelete = new ArrayList<>(); @@ -310,7 +311,7 @@ public class DistributionSetManagement { * {@link SoftwareModule}s. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public DistributionSet createDistributionSet(@NotNull final DistributionSet dSet) { prepareDsSave(dSet); @@ -344,7 +345,7 @@ public class DistributionSetManagement { * {@link SoftwareModule}s. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public List createDistributionSets(@NotNull final Iterable distributionSets) { for (final DistributionSet ds : distributionSets) { @@ -366,7 +367,7 @@ public class DistributionSetManagement { * @return the updated {@link DistributionSet}. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public DistributionSet assignSoftwareModules(@NotNull final DistributionSet ds, final Set softwareModules) { @@ -388,7 +389,7 @@ public class DistributionSetManagement { * @return the updated {@link DistributionSet}. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public DistributionSet unassignSoftwareModule(@NotNull final DistributionSet ds, final SoftwareModule softwareModule) { @@ -413,7 +414,7 @@ public class DistributionSetManagement { * s while the DS type is already in use. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public DistributionSetType updateDistributionSetType(@NotNull final DistributionSetType dsType) { checkNotNull(dsType.getId()); @@ -715,7 +716,7 @@ public class DistributionSetManagement { * @return created {@link Entity} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public DistributionSetType createDistributionSetType(@NotNull final DistributionSetType type) { if (type.getId() != null) { @@ -732,7 +733,7 @@ public class DistributionSetManagement { * to delete */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) public void deleteDistributionSetType(@NotNull final DistributionSetType type) { @@ -755,7 +756,7 @@ public class DistributionSetManagement { * in case the meta data entry already exists for the specific * key */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public DistributionSetMetadata createDistributionSetMetadata(@NotNull final DistributionSetMetadata metadata) { @@ -780,7 +781,7 @@ public class DistributionSetManagement { * in case one of the meta data entry already exists for the * specific key */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public List createDistributionSetMetadata( @@ -802,7 +803,7 @@ public class DistributionSetManagement { * in case the meta data entry does not exists and cannot be * updated */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public DistributionSetMetadata updateDistributionSetMetadata(@NotNull final DistributionSetMetadata metadata) { @@ -820,7 +821,7 @@ public class DistributionSetManagement { * @param id * the ID of the distribution set meta data to delete */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public void deleteDistributionSetMetadata(@NotNull final DsMetadataCompositeKey id) { @@ -913,7 +914,7 @@ public class DistributionSetManagement { * @return created {@link Entity} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public List createDistributionSetTypes(@NotNull final Collection types) { return types.stream().map(this::createDistributionSetType).collect(Collectors.toList()); @@ -926,7 +927,7 @@ public class DistributionSetManagement { * @param softwareModules */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public void checkDistributionSetAlreadyUse(final DistributionSet distributionSet) { checkDistributionSetSoftwareModulesIsAllowedToModify(distributionSet); @@ -992,14 +993,14 @@ public class DistributionSetManagement { } } - private Boolean isDSWithNoTagSelected(final DistributionSetFilter distributionSetFilter) { + private static Boolean isDSWithNoTagSelected(final DistributionSetFilter distributionSetFilter) { if (distributionSetFilter.getSelectDSWithNoTag() != null && distributionSetFilter.getSelectDSWithNoTag()) { return true; } return false; } - private Boolean isTagsSelected(final DistributionSetFilter distributionSetFilter) { + private static Boolean isTagsSelected(final DistributionSetFilter distributionSetFilter) { if (distributionSetFilter.getTagNames() != null && !distributionSetFilter.getTagNames().isEmpty()) { return true; } @@ -1033,7 +1034,7 @@ public class DistributionSetManagement { } } - private void throwMetadataKeyAlreadyExists(final String metadataKey) { + private static void throwMetadataKeyAlreadyExists(final String metadataKey) { throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists"); } @@ -1048,7 +1049,7 @@ public class DistributionSetManagement { * @return list of assigned ds */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public List assignTag(@NotEmpty final Collection dsIds, @@ -1077,7 +1078,7 @@ public class DistributionSetManagement { * @return list of unassigned ds */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public List unAssignAllDistributionSetsByTag(@NotNull final DistributionSetTag tag) { @@ -1095,7 +1096,7 @@ public class DistributionSetManagement { * @return the unassigned ds or if no ds is unassigned */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public DistributionSet unAssignTag(@NotNull final Long dsId, @NotNull final DistributionSetTag distributionSetTag) { final List allDs = findDistributionSetListWithDetails(Arrays.asList(dsId)); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetMetadataRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetMetadataRepository.java index 1ff6c1ca5..c042a32d0 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetMetadataRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetMetadataRepository.java @@ -12,6 +12,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DsMetadataCompositeKey; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** @@ -20,7 +21,7 @@ import org.springframework.transaction.annotation.Transactional; * * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface DistributionSetMetadataRepository extends PagingAndSortingRepository, JpaSpecificationExecutor { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetRepository.java index 1a59fdca7..f2138bb2d 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetRepository.java @@ -21,6 +21,7 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** @@ -29,7 +30,7 @@ import org.springframework.transaction.annotation.Transactional; * * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface DistributionSetRepository extends BaseEntityRepository, JpaSpecificationExecutor { @@ -50,7 +51,7 @@ public interface DistributionSetRepository * to be deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Query("update DistributionSet d set d.deleted = 1 where d.id in :ids") void deleteDistributionSet(@Param("ids") Long... ids); @@ -62,7 +63,7 @@ public interface DistributionSetRepository * @return number of affected/deleted records */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 @Query("DELETE FROM DistributionSet d WHERE d.id IN ?1") int deleteByIdIn(Collection ids); @@ -82,7 +83,7 @@ public interface DistributionSetRepository * yet to an {@link UpdateAction}, i.e. unused. * * @param ids - * to searcgh for + * to search for * @return */ @Query("select ac.distributionSet.id from Action ac where ac.distributionSet.id in :ids") diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagRepository.java index c00713fc4..8521a96b9 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagRepository.java @@ -15,15 +15,14 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.TargetTag; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * {@link TargetTag} repository. * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface DistributionSetTagRepository extends BaseEntityRepository, JpaSpecificationExecutor { /** @@ -34,7 +33,7 @@ public interface DistributionSetTagRepository * @return 1 if tag was deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) Long deleteByName(final String tagName); /** diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeRepository.java index b9da6b3cc..289dd6c09 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeRepository.java @@ -14,16 +14,14 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * {@link PagingAndSortingRepository} for {@link DistributionSetType}. * - * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface DistributionSetTypeRepository extends BaseEntityRepository, JpaSpecificationExecutor { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/EclipseLinkTargetInfoRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/EclipseLinkTargetInfoRepository.java index c9be0bf38..e37a51d6c 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/EclipseLinkTargetInfoRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/EclipseLinkTargetInfoRepository.java @@ -13,7 +13,6 @@ import java.util.List; import javax.persistence.EntityManager; import javax.persistence.Query; -import javax.transaction.Transactional; import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; @@ -21,16 +20,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.jpa.repository.Modifying; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; /** * Custom repository implementation as standard spring repository fails as of * https://bugs.eclipse.org/bugs/show_bug.cgi?id=415027 . * - * - * */ @Service -@Transactional +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public class EclipseLinkTargetInfoRepository implements TargetInfoRepository { @Autowired @@ -38,6 +37,7 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository { @Override @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) public void setTargetUpdateStatus(final TargetUpdateStatus status, final List targets) { final Query query = entityManager.createQuery( "update TargetInfo ti set ti.updateStatus = :status where ti.targetId in :targets and ti.updateStatus != :status"); @@ -48,6 +48,7 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository { @Override @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) public S save(final S entity) { @@ -61,6 +62,7 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository { @Override @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) public void deleteByTargetIdIn(final Collection targetIDs) { final javax.persistence.Query query = entityManager diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactProviderRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactProviderRepository.java index 05634ef63..d0802d242 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactProviderRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactProviderRepository.java @@ -9,16 +9,14 @@ package org.eclipse.hawkbit.repository; import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * Repository for {@link ExternalArtifactProvider}. * - * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface ExternalArtifactProviderRepository extends BaseEntityRepository { } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactRepository.java index c7ece2445..d20da8013 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ExternalArtifactRepository.java @@ -11,15 +11,14 @@ package org.eclipse.hawkbit.repository; import org.eclipse.hawkbit.repository.model.ExternalArtifact; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * {@link ExternalArtifact} repository. * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface ExternalArtifactRepository extends BaseEntityRepository { /** diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/LocalArtifactRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/LocalArtifactRepository.java index 5bbac1dd1..4c106957d 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/LocalArtifactRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/LocalArtifactRepository.java @@ -15,13 +15,14 @@ import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Query; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * {@link LocalArtifact} repository. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface LocalArtifactRepository extends BaseEntityRepository { /** diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ReportManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ReportManagement.java index b95664d8f..326442283 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ReportManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ReportManagement.java @@ -48,14 +48,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; /** - * Service layer for generating SP reportings. + * Service layer for generating hawkBit reports. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated @Service public class ReportManagement { @@ -404,7 +405,7 @@ public class ReportManagement { return innerOuterReport; } - private final class InnerOuter { + private static final class InnerOuter { final DSName name; long count; final List outer; @@ -433,9 +434,6 @@ public class ReportManagement { /** * Object contains the name and the id of an entity. * - * - * - * */ private static final class DSName { @@ -510,9 +508,6 @@ public class ReportManagement { * Return DateTypes. */ public static final class DateTypes implements Serializable { - /** - * - */ private static final long serialVersionUID = 1L; private static final PerMonth PER_MONTH = new PerMonth(); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java index 54ff37e87..d204154d0 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupManagement.java @@ -43,6 +43,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -52,7 +53,7 @@ import org.springframework.validation.annotation.Validated; */ @Validated @Service -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public class RolloutGroupManagement { @Autowired @@ -189,7 +190,7 @@ public class RolloutGroupManagement { final ListJoin rolloutTargetJoin = root.join(Target_.rolloutTargetGroup); return criteriaBuilder.and(specification.toPredicate(root, query, criteriaBuilder), criteriaBuilder.equal(rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup), rolloutGroup)); - } , page); + }, page); } /** @@ -213,7 +214,7 @@ public class RolloutGroupManagement { return targetRepository.findByActionsRolloutGroup(rolloutGroup, page); } - private boolean isRolloutStatusReady(final RolloutGroup rolloutGroup) { + private static boolean isRolloutStatusReady(final RolloutGroup rolloutGroup) { return rolloutGroup != null && RolloutStatus.READY.equals(rolloutGroup.getRollout().getStatus()); } @@ -259,5 +260,4 @@ public class RolloutGroupManagement { .collect(Collectors.toList()); return new PageImpl<>(targetWithActionStatus, pageRequest, totalCount); } - -} \ No newline at end of file +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupRepository.java index cf3f3d729..e0cb4cc27 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupRepository.java @@ -18,12 +18,13 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * The repository interface for the {@link RolloutGroup} model. */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface RolloutGroupRepository extends BaseEntityRepository, JpaSpecificationExecutor { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java index 1573048ec..efead853e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java @@ -58,6 +58,7 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.TransactionTemplate; @@ -72,7 +73,7 @@ import org.springframework.validation.annotation.Validated; @Validated @Service @EnableScheduling -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public class RolloutManagement { private static final Logger LOGGER = LoggerFactory.getLogger(RolloutManagement.class); @@ -199,7 +200,7 @@ public class RolloutManagement { * @throws IllegalArgumentException * in case the given groupSize is zero or lower. */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) public Rollout createRollout(final Rollout rollout, final int amountGroup, @@ -242,7 +243,7 @@ public class RolloutManagement { * @return the created rollout entity in state * {@link RolloutStatus#CREATING} */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) public Rollout createRolloutAsync(final Rollout rollout, final int amountGroup, @@ -280,7 +281,7 @@ public class RolloutManagement { return rolloutRepository.save(rollout); } - private void verifyRolloutGroupParameter(final int amountGroup) { + private static void verifyRolloutGroupParameter(final int amountGroup) { if (amountGroup <= 0) { throw new IllegalArgumentException("the amountGroup must be greater than zero"); } else if (amountGroup > 500) { @@ -362,11 +363,13 @@ public class RolloutManagement { * @param rollout * the rollout to be started * + * @return started rollout + * * @throws RolloutIllegalStateException * if given rollout is not in {@link RolloutStatus#READY}. Only * ready rollouts can be started. */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) @@ -389,6 +392,8 @@ public class RolloutManagement { * @param rollout * the rollout to be started * + * @return the started rollout + * * @throws RolloutIllegalStateException * if given rollout is not in {@link RolloutStatus#READY}. Only * ready rollouts can be started. @@ -468,7 +473,7 @@ public class RolloutManagement { * if given rollout is not in {@link RolloutStatus#RUNNING}. * Only running rollouts can be paused. */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) @@ -498,7 +503,7 @@ public class RolloutManagement { * if given rollout is not in {@link RolloutStatus#PAUSED}. Only * paused rollouts can be resumed. */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) @@ -540,7 +545,7 @@ public class RolloutManagement { * this check. This check is only applied if the last check is * less than (lastcheck-delay). */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) @@ -783,7 +788,7 @@ public class RolloutManagement { * @return Rollout updated rollout */ @NotNull - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) public Rollout updateRollout(@NotNull final Rollout rollout) { @@ -845,7 +850,7 @@ public class RolloutManagement { } } - private void checkIfRolloutCanStarted(final Rollout rollout, final Rollout mergedRollout) { + private static void checkIfRolloutCanStarted(final Rollout rollout, final Rollout mergedRollout) { if (!(RolloutStatus.READY.equals(mergedRollout.getStatus()))) { throw new RolloutIllegalStateException("Rollout can only be started in state ready but current state is " + rollout.getStatus().name().toLowerCase()); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutRepository.java index 9c4318a3f..5a22f5ab5 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutRepository.java @@ -18,12 +18,13 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * The repository interface for the {@link Rollout} model. */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface RolloutRepository extends BaseEntityRepository, JpaSpecificationExecutor { /** @@ -40,7 +41,7 @@ public interface RolloutRepository extends BaseEntityRepository, * @return the count of the updated rows. Zero if no row has been updated */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Query("UPDATE Rollout r SET r.lastCheck = :lastCheck WHERE r.lastCheck < (:lastCheck - :delay) AND r.status=:status") int updateLastCheck(@Param("lastCheck") final long lastCheck, @Param("delay") final long delay, @Param("status") final RolloutStatus status); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutTargetGroupRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutTargetGroupRepository.java index 6564e2c1f..14d9b8353 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutTargetGroupRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutTargetGroupRepository.java @@ -12,11 +12,14 @@ import org.eclipse.hawkbit.repository.model.RolloutTargetGroup; import org.eclipse.hawkbit.repository.model.RolloutTargetGroupId; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; /** - * + * Spring data repository for {@link RolloutTargetGroup}. * */ +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface RolloutTargetGroupRepository extends CrudRepository, JpaSpecificationExecutor { } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java index 384353b8e..d719667ed 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java @@ -52,6 +52,7 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -62,7 +63,7 @@ import com.google.common.collect.Sets; * Business facade for managing {@link SoftwareModule}s. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated @Service public class SoftwareManagement { @@ -108,7 +109,7 @@ public class SoftwareManagement { * of {@link SoftwareModule#getId()} is null */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public SoftwareModule updateSoftwareModule(@NotNull final SoftwareModule sm) { checkNotNull(sm.getId()); @@ -138,7 +139,7 @@ public class SoftwareManagement { * @return updated {@link Entity} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public SoftwareModuleType updateSoftwareModuleType(@NotNull final SoftwareModuleType sm) { checkNotNull(sm.getId()); @@ -283,7 +284,7 @@ public class SoftwareManagement { * is the {@link SoftwareModule} to be deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) public void deleteSoftwareModule(@NotNull final SoftwareModule bsm) { @@ -314,10 +315,10 @@ public class SoftwareManagement { * Deletes {@link SoftwareModule}s which is any if the given ids. * * @param ids - * of the Software Moduels to be deleted + * of the Software Modules to be deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) public void deleteSoftwareModules(@NotNull final Iterable ids) { final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); @@ -579,7 +580,7 @@ public class SoftwareManagement { return new SliceImpl<>(resultList); } - private List> buildSpecificationList(final String searchText, + private static List> buildSpecificationList(final String searchText, final SoftwareModuleType type) { final List> specList = new ArrayList<>(); if (!Strings.isNullOrEmpty(searchText)) { @@ -700,7 +701,7 @@ public class SoftwareManagement { * @return created {@link Entity} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public SoftwareModuleType createSoftwareModuleType(@NotNull final SoftwareModuleType type) { if (type.getId() != null) { @@ -718,7 +719,7 @@ public class SoftwareManagement { * @return created {@link Entity} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public List createSoftwareModuleType(@NotNull final Collection types) { return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); @@ -731,7 +732,7 @@ public class SoftwareManagement { * to delete */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) public void deleteSoftwareModuleType(@NotNull final SoftwareModuleType type) { @@ -785,7 +786,7 @@ public class SoftwareManagement { * in case the meta data entry already exists for the specific * key */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public SoftwareModuleMetadata createSoftwareModuleMetadata(@NotNull final SoftwareModuleMetadata metadata) { @@ -810,7 +811,7 @@ public class SoftwareManagement { * in case one of the meta data entry already exists for the * specific key */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public List createSoftwareModuleMetadata( @@ -832,7 +833,7 @@ public class SoftwareManagement { * in case the meta data entry does not exists and cannot be * updated */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public SoftwareModuleMetadata updateSoftwareModuleMetadata(@NotNull final SoftwareModuleMetadata metadata) { @@ -851,7 +852,7 @@ public class SoftwareManagement { * @param id * the ID of the software module meta data to delete */ - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public void deleteSoftwareModuleMetadata(@NotNull final SwMetadataCompositeKey id) { @@ -925,7 +926,7 @@ public class SoftwareManagement { } } - private void throwMetadataKeyAlreadyExists(final String metadataKey) { + private static void throwMetadataKeyAlreadyExists(final String metadataKey) { throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists"); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleMetadataRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleMetadataRepository.java index 0d80e1932..c40a96e92 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleMetadataRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleMetadataRepository.java @@ -16,15 +16,14 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * {@link SoftwareModuleMetadata} repository. * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface SoftwareModuleMetadataRepository extends PagingAndSortingRepository, JpaSpecificationExecutor { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleRepository.java index d70e8226f..95b01c270 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleRepository.java @@ -21,15 +21,14 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * {@link SoftwareModule} repository. * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface SoftwareModuleRepository extends BaseEntityRepository, JpaSpecificationExecutor { @@ -69,7 +68,7 @@ public interface SoftwareModuleRepository * */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Query("UPDATE SoftwareModule b SET b.deleted = 1, b.lastModifiedAt = :lastModifiedAt, b.lastModifiedBy = :lastModifiedBy WHERE b.id IN :ids") void deleteSoftwareModule(@Param("lastModifiedAt") Long modifiedAt, @Param("lastModifiedBy") String modifiedBy, @Param("ids") final Long... ids); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeRepository.java index 44b85b06b..ac9425a08 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeRepository.java @@ -12,16 +12,14 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * Repository for {@link SoftwareModuleType}. * - * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface SoftwareModuleTypeRepository extends BaseEntityRepository, JpaSpecificationExecutor { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index 5577e1d61..2492930f2 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -35,6 +35,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -43,7 +44,7 @@ import org.springframework.validation.annotation.Validated; * Central system management operations of the SP server. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated @Service public class SystemManagement { @@ -179,7 +180,7 @@ public class SystemManagement { * @return */ @Cacheable(value = "tenantMetadata", key = "#tenant.toUpperCase()") - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @NotNull public TenantMetaData getTenantMetadata(@NotNull final String tenant) { @@ -218,7 +219,7 @@ public class SystemManagement { * to delete */ @CacheEvict(value = { "tenantMetadata" }, key = "#tenant.toUpperCase()") - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN) // tenant independent @@ -250,7 +251,7 @@ public class SystemManagement { * @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} */ @Cacheable(value = "tenantMetadata", keyGenerator = "tenantKeyGenerator") - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @NotNull public TenantMetaData getTenantMetadata() { @@ -279,7 +280,7 @@ public class SystemManagement { // suspend the transaction here to do a read-request against the medata // table, when the current // tenant is not cached anyway already. - @Transactional(propagation = Propagation.NOT_SUPPORTED) + @Transactional(propagation = Propagation.NOT_SUPPORTED, isolation = Isolation.READ_UNCOMMITTED) public String currentTenant() { final String initialTenantCreation = createInitialTenant.get(); if (initialTenantCreation == null) { @@ -298,7 +299,7 @@ public class SystemManagement { * @return updated {@link TenantMetaData} entity */ @CachePut(value = "tenantMetadata", key = "#metaData.tenant.toUpperCase()") - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @NotNull public TenantMetaData updateTenantMetadata(@NotNull final TenantMetaData metaData) { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TagManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TagManagement.java index e0ab951ac..8db9773e6 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TagManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TagManagement.java @@ -38,21 +38,17 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import com.google.common.eventbus.EventBus; /** - * - * Mangement service class for {@link Tag}s. - * - * - * - * + * Management service class for {@link Tag}s. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated @Service public class TagManagement { @@ -102,7 +98,7 @@ public class TagManagement { * if given object already exists */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET) public TargetTag createTargetTag(@NotNull final TargetTag targetTag) { @@ -133,7 +129,7 @@ public class TagManagement { * if given object has already an ID. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET) public List createTargetTags(@NotNull final Iterable targetTags) { @@ -155,7 +151,7 @@ public class TagManagement { * tag name of the {@link TargetTag} to be deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_TARGET) public void deleteTargetTag(@NotEmpty final String targetTagName) { final TargetTag tag = targetTagRepository.findByNameEquals(targetTagName); @@ -220,7 +216,7 @@ public class TagManagement { * @return the new {@link TargetTag} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public TargetTag updateTargetTag(@NotNull final TargetTag targetTag) { @@ -254,7 +250,7 @@ public class TagManagement { * */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public DistributionSetTag createDistributionSetTag(@NotNull final DistributionSetTag distributionSetTag) { if (null != distributionSetTag.getId()) { @@ -282,7 +278,7 @@ public class TagManagement { * if a given entity already exists */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) public List createDistributionSetTags( @NotNull final Iterable distributionSetTags) { @@ -306,7 +302,7 @@ public class TagManagement { * to be deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) public void deleteDistributionSetTag(@NotEmpty final String tagName) { final DistributionSetTag tag = distributionSetTagRepository.findByNameEquals(tagName); @@ -335,7 +331,7 @@ public class TagManagement { * of {@link DistributionSetTag#getName()} is null */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) public DistributionSetTag updateDistributionSetTag(@NotNull final DistributionSetTag distributionSetTag) { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagement.java index c55127d0f..4f7c91da3 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryManagement.java @@ -26,6 +26,7 @@ import org.springframework.data.jpa.domain.Specifications; import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import org.springframework.validation.annotation.Validated; @@ -35,10 +36,8 @@ import com.google.common.base.Strings; /** * Business service facade for managing {@link TargetFilterQuery}s. * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated @Service public class TargetFilterQueryManagement { @@ -53,7 +52,7 @@ public class TargetFilterQueryManagement { * @return the created {@link TargetFilterQuery} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET) public TargetFilterQuery createTargetFilterQuery(@NotNull final TargetFilterQuery customTargetFilter) { @@ -71,7 +70,7 @@ public class TargetFilterQueryManagement { * IDs of target filter query to be deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_TARGET) public void deleteTargetFilterQuery(@NotNull final Long targetFilterQueryId) { targetFilterQueryRepository.delete(targetFilterQueryId); @@ -161,7 +160,7 @@ public class TargetFilterQueryManagement { * @return the updated {@link TargetFilterQuery} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public TargetFilterQuery updateTargetFilterQuery(@NotNull final TargetFilterQuery targetFilterQuery) { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryRepository.java index b9bfcc8b6..3604785cd 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryRepository.java @@ -12,13 +12,14 @@ import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.springframework.data.domain.Page; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** - * + * Spring data repositories for {@link TargetFilterQuery}s. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface TargetFilterQueryRepository extends BaseEntityRepository, JpaSpecificationExecutor { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetInfoRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetInfoRepository.java index 4582b7397..436f1e7b6 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetInfoRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetInfoRepository.java @@ -12,7 +12,6 @@ import java.util.Collection; import java.util.List; import javax.persistence.Entity; -import javax.transaction.Transactional; import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; @@ -20,15 +19,16 @@ import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; /** * Usually a JPA spring data repository to handle {@link TargetInfo} entity. * However, do to an eclipselink bug with spring boot now a regular interface * that is implemented by {@link EclipseLinkTargetInfoRepository}. * - * - * */ +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface TargetInfoRepository { /** @@ -41,7 +41,7 @@ public interface TargetInfoRepository { * to set it for */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Query("update TargetInfo ti set ti.updateStatus = :status where ti.targetId in :targets and ti.updateStatus != :status") void setTargetUpdateStatus(@Param("status") TargetUpdateStatus status, @Param("targets") List targets); @@ -63,7 +63,7 @@ public interface TargetInfoRepository { * to delete */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) void deleteByTargetIdIn(final Collection targetIDs); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java index 0e0e474b2..4d6540acf 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java @@ -62,6 +62,7 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import org.springframework.validation.annotation.Validated; @@ -74,7 +75,7 @@ import com.google.common.eventbus.EventBus; * Business service facade for managing {@link Target}s. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated @Service public class TargetManagement { @@ -260,7 +261,7 @@ public class TargetManagement { * @return the updated {@link Target} */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_CONTROLLER) @@ -278,7 +279,7 @@ public class TargetManagement { * @return the updated {@link Target}s */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_CONTROLLER) @@ -294,7 +295,7 @@ public class TargetManagement { * the technical IDs of the targets to be deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_TARGET) public void deleteTargets(@NotEmpty final Long... targetIDs) { // we need to select the target IDs first to check the if the targetIDs @@ -527,11 +528,11 @@ public class TargetManagement { * @param targets * to toggle for * @param tag - * to toogle - * @return TagAssigmentResult with all metadata of the assigment outcome. + * to toggle + * @return TagAssigmentResult with all metadata of the assignment outcome. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public TargetTagAssignmentResult toggleTagAssignment(@NotEmpty final List targets, @@ -553,7 +554,7 @@ public class TargetManagement { * @return TagAssigmentResult with all metadata of the assigment outcome. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public TargetTagAssignmentResult toggleTagAssignment(@NotEmpty final Collection targetIds, @@ -596,7 +597,7 @@ public class TargetManagement { * @return list of assigned targets */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public List assignTag(@NotEmpty final Collection targetIds, @NotNull final TargetTag tag) { @@ -635,7 +636,7 @@ public class TargetManagement { * @return list of unassigned targets */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public List unAssignAllTargetsByTag(@NotNull final TargetTag tag) { @@ -652,7 +653,7 @@ public class TargetManagement { * @return the unassigned target or if no target is unassigned */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public Target unAssignTag(@NotNull final String controllerID, @NotNull final TargetTag targetTag) { final List allTargets = targetRepository @@ -934,7 +935,7 @@ public class TargetManagement { * @return */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_CONTROLLER) @@ -972,7 +973,7 @@ public class TargetManagement { * */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_CONTROLLER) @@ -996,7 +997,7 @@ public class TargetManagement { * already exist. */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET) public List createTargets(@NotNull final List targets) { @@ -1028,7 +1029,7 @@ public class TargetManagement { * @return newly created target */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @NotNull @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET) public List createTargets(@NotNull final Collection targets, diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetRepository.java index 35ba39660..5e37902ab 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetRepository.java @@ -27,15 +27,14 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * {@link Target} repository. * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface TargetRepository extends BaseEntityRepository, JpaSpecificationExecutor { /** @@ -64,7 +63,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp * to be deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 @Query("DELETE FROM Target t WHERE t.id IN ?1") void deleteByIdIn(final Collection targetIDs); @@ -153,7 +152,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp */ @Override @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) List save(Iterable entities); @@ -167,7 +166,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp */ @Override @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) S save(S entity); @@ -276,7 +275,7 @@ public interface TargetRepository extends BaseEntityRepository, Jp * to update */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Query("UPDATE Target t SET t.assignedDistributionSet = :set, t.lastModifiedAt = :lastModifiedAt, t.lastModifiedBy = :lastModifiedBy WHERE t.id IN :targets") void setAssignedDistributionSet(@Param("set") DistributionSet set, @Param("lastModifiedAt") Long modifiedAt, @Param("lastModifiedBy") String modifiedBy, @Param("targets") Collection targets); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetTagRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetTagRepository.java index a81ed81ab..e0f03ee78 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetTagRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TargetTagRepository.java @@ -13,15 +13,14 @@ import java.util.List; import org.eclipse.hawkbit.repository.model.TargetTag; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * {@link TargetTag} repository. * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface TargetTagRepository extends BaseEntityRepository, JpaSpecificationExecutor { @@ -33,7 +32,7 @@ public interface TargetTagRepository * @return 1 if tag was deleted */ @Modifying - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) Long deleteByName(final String tagName); /** diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index e311cf288..bd63a827a 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -24,13 +24,14 @@ import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.env.Environment; 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; /** * Central tenant configuration management operations of the SP server. */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Validated public class TenantConfigurationManagement implements EnvironmentAware { @@ -221,7 +222,7 @@ public class TenantConfigurationManagement implements EnvironmentAware { * if the property cannot be converted to the given */ @CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) public TenantConfigurationValue addOrUpdateConfiguration(final TenantConfigurationKey configurationKey, @@ -264,7 +265,7 @@ public class TenantConfigurationManagement implements EnvironmentAware { * the configuration key to be deleted */ @CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") - @Transactional + @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) public void deleteConfiguration(final TenantConfigurationKey configurationKey) { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationRepository.java index dd741697b..0497ea924 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationRepository.java @@ -11,13 +11,14 @@ package org.eclipse.hawkbit.repository; import java.util.List; import org.eclipse.hawkbit.repository.model.TenantConfiguration; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * The spring-data repository for the entity {@link TenantConfiguration}. * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface TenantConfigurationRepository extends BaseEntityRepository { /** diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantMetaDataRepository.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantMetaDataRepository.java index 08d672803..4aa4c48dc 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantMetaDataRepository.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantMetaDataRepository.java @@ -12,16 +12,14 @@ import java.util.List; import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; /** * repository for operations on {@link TenantMetaData} entity. * - * - * - * */ -@Transactional(readOnly = true) +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) public interface TenantMetaDataRepository extends PagingAndSortingRepository { /** From 328d5ab2b0698cfd997e0e721d7b4be24185d637 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 26 Apr 2016 11:07:15 +0200 Subject: [PATCH 05/47] Set complex assignment operations to READ_COMMITED to ensure consitent updates. Signed-off-by: Kai Zimmermann --- .../hawkbit/repository/DeploymentManagement.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index 3eedee415..834c37f81 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -134,7 +134,7 @@ public class DeploymentManagement { * {@link SoftwareModuleType} are not assigned as define by the * {@link DistributionSetType}. * */ - @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Transactional(isolation = Isolation.READ_COMMITTED) @Modifying @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) @@ -168,7 +168,7 @@ public class DeploymentManagement { * {@link DistributionSetType}. */ @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Transactional(isolation = Isolation.READ_COMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) public DistributionSetAssignmentResult assignDistributionSet(@NotNull final Long dsID, @@ -220,7 +220,7 @@ public class DeploymentManagement { * {@link DistributionSetType}. */ @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Transactional(isolation = Isolation.READ_COMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) public DistributionSetAssignmentResult assignDistributionSet(@NotNull final Long dsID, @@ -253,7 +253,7 @@ public class DeploymentManagement { * {@link DistributionSetType}. */ @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Transactional(isolation = Isolation.READ_COMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) public DistributionSetAssignmentResult assignDistributionSet(@NotNull final Long dsID, @@ -513,7 +513,7 @@ public class DeploymentManagement { * action */ @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Transactional(isolation = Isolation.READ_COMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public Action cancelAction(@NotNull final Action action, @NotNull final Target target) { LOG.debug("cancelAction({}, {})", action, target); @@ -570,7 +570,7 @@ public class DeploymentManagement { * in case the given action is not active */ @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Transactional(isolation = Isolation.READ_COMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public Action forceQuitAction(@NotNull final Action action) { final Action mergedAction = entityManager.merge(action); @@ -615,7 +615,7 @@ public class DeploymentManagement { * the rolloutgroup for this action */ @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Transactional(isolation = Isolation.READ_COMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) public void createScheduledAction(final List targets, final DistributionSet distributionSet, final ActionType actionType, final long forcedTime, final Rollout rollout, @@ -649,7 +649,7 @@ public class DeploymentManagement { * @return the action which has been started */ @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Transactional(isolation = Isolation.READ_COMMITTED) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) public Action startScheduledAction(@NotNull final Action action) { From 9be6aa6e18f01d500d61f8531a1329d8cac03749 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 28 Apr 2016 14:12:07 +0200 Subject: [PATCH 06/47] remove special coap-auth-token filter for coap-downloads Signed-off-by: Michael Hirsch --- .../amqp/AmqpControllerAuthentfication.java | 2 - .../dmf/json/model/TenantSecurityToken.java | 2 - .../CoapAnonymousPreAuthenticatedFilter.java | 37 ------------------- 3 files changed, 41 deletions(-) delete mode 100644 hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/CoapAnonymousPreAuthenticatedFilter.java diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java index 9d120c17b..91d07de37 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java @@ -17,7 +17,6 @@ import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken; import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.security.CoapAnonymousPreAuthenticatedFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousDownload; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousFilter; @@ -97,7 +96,6 @@ public class AmqpControllerAuthentfication { filterChain.add(anonymousDownloadFilter); filterChain.add(new ControllerPreAuthenticatedAnonymousFilter(ddiSecruityProperties)); - filterChain.add(new CoapAnonymousPreAuthenticatedFilter()); } /** diff --git a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java index ccc3a5b42..e4f41bc46 100644 --- a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java +++ b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java @@ -26,8 +26,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class TenantSecurityToken { public static final String AUTHORIZATION_HEADER = "Authorization"; - public static final String COAP_AUTHORIZATION_HEADER = "Coap-Authorization"; - public static final String COAP_TOKEN_VALUE = "CoapToken"; @JsonProperty private final String tenant; diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/CoapAnonymousPreAuthenticatedFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/CoapAnonymousPreAuthenticatedFilter.java deleted file mode 100644 index 36a444c43..000000000 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/CoapAnonymousPreAuthenticatedFilter.java +++ /dev/null @@ -1,37 +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.security; - -import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken; - -/** - * A Filter for device which download via coap. - * - * - * - */ -public class CoapAnonymousPreAuthenticatedFilter implements PreAuthenficationFilter { - - @Override - public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) { - return new HeaderAuthentication(secruityToken.getControllerId(), TenantSecurityToken.COAP_TOKEN_VALUE); - } - - @Override - public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) { - return new HeaderAuthentication(secruityToken.getControllerId(), TenantSecurityToken.COAP_TOKEN_VALUE); - } - - @Override - public boolean isEnable(final TenantSecurityToken secruityToken) { - final String authHeader = secruityToken.getHeader(TenantSecurityToken.COAP_AUTHORIZATION_HEADER); - return TenantSecurityToken.COAP_TOKEN_VALUE.equals(authHeader); - } - -} From 1438d3ef2b3baa8da460ad5c4a582c224408f24f Mon Sep 17 00:00:00 2001 From: venu1278 Date: Mon, 2 May 2016 15:32:40 +0530 Subject: [PATCH 07/47] displaying assigned installed ds tooltip in Deployment View Signed-off-by: venu1278 --- .../eclipse/hawkbit/ui/management/targettable/TargetTable.java | 1 + 1 file changed, 1 insertion(+) 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 6232ebcf8..55603b4d2 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 @@ -340,6 +340,7 @@ public class TargetTable extends AbstractTable implements i18n.get("header.assigned.ds"), 0.1F)); columnList.add(new TableColumn(SPUILabelDefinitions.INSTALLED_DISTRIBUTION_NAME_VER, i18n.get("header.installed.ds"), 0.1F)); + setItemDescriptionGenerator(new AssignInstalledDSTooltipGenerator()); } return columnList; From 054dca1a64ff649adbea1c12cf3eaa57ed94cbd1 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 2 May 2016 17:08:01 +0200 Subject: [PATCH 08/47] Added driver hint --- examples/hawkbit-example-app/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/hawkbit-example-app/README.md b/examples/hawkbit-example-app/README.md index ecbec93c3..2b8e60643 100644 --- a/examples/hawkbit-example-app/README.md +++ b/examples/hawkbit-example-app/README.md @@ -13,7 +13,11 @@ We have have described several options for you to get access to the example. ``` java -jar examples/hawkbit-example-app/target/hawkbit-example-app-*-SNAPSHOT.jar ``` + +(Note: if you intend to user another database than H2 you have to add the JDBC driver to your class path). + Or: + ``` run org eclipse.hawkbit.app.Start ``` From 6763cb9aff208aa6b079685ec543ca4802416af7 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 2 May 2016 17:08:43 +0200 Subject: [PATCH 09/47] Grammar --- examples/hawkbit-example-app/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hawkbit-example-app/README.md b/examples/hawkbit-example-app/README.md index 2b8e60643..cfd15c433 100644 --- a/examples/hawkbit-example-app/README.md +++ b/examples/hawkbit-example-app/README.md @@ -14,7 +14,7 @@ We have have described several options for you to get access to the example. java -jar examples/hawkbit-example-app/target/hawkbit-example-app-*-SNAPSHOT.jar ``` -(Note: if you intend to user another database than H2 you have to add the JDBC driver to your class path). +_(Note: you have to add the JDBC driver also to your class path if you intend to use another database than H2.)_ Or: From ecc21025328d520c73b7dc8bb8ca8be4f2af0f26 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 2 May 2016 17:14:53 +0200 Subject: [PATCH 10/47] Added credential hint --- examples/hawkbit-example-app/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/hawkbit-example-app/README.md b/examples/hawkbit-example-app/README.md index cfd15c433..068acdd15 100644 --- a/examples/hawkbit-example-app/README.md +++ b/examples/hawkbit-example-app/README.md @@ -4,9 +4,9 @@ The hawkBit example application is a standalone spring-boot application with an We have have described several options for you to get access to the example. ## Try out the example application in our hawkBit sandbox on Bluemix -- try out Management UI https://hawkbit.eu-gb.mybluemix.net/UI -- try out Management API https://hawkbit.eu-gb.mybluemix.net/rest/v1/targets (don't forget basic auth header) -- try out DDI API https://hawkbit.eu-gb.mybluemix.net/DEFAULT/controller/v1/MYTESTDEVICE +- try out Management UI https://hawkbit.eu-gb.mybluemix.net/UI (username: admin, passwd: admin) +- try out Management API https://hawkbit.eu-gb.mybluemix.net/rest/v1/targets (don't forget basic auth header; username: admin, passwd: admin) +- try out DDI API https://hawkbit.eu-gb.mybluemix.net/DEFAULT/controller/v1/MYTESTDEVICE (authentication disabled) ## On your own workstation ### Run From 2c5969b0809e8e3d837368c3a9d6f234bcd2330c Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 2 May 2016 18:07:23 +0200 Subject: [PATCH 11/47] Fixed a few spellings --- README.md | 8 ++++---- hawkbit-core/README.md | 3 +++ .../PreAuthTokenSourceTrustAuthenticationProvider.java | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 hawkbit-core/README.md diff --git a/README.md b/README.md index 0a9b0b4c6..ff93c9285 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,10 @@ $ java -jar ./examples/hawkbit-mgmt-api-client/target/hawkbit-mgmt-api-client-#v # Modules -`hawkbit-core` : core elements. -`hawkbit-security-core` : core security elements. -`hawkbit-security-integration` : security integration elements to integrate security into hawkbit. -`hawkbit-artifact-repository-mongo` : artifact repository implementation to mongoDB. +`hawkbit-core` : internal interfaces and utility classes.. +`hawkbit-security-core` : authentication and authorization. +`hawkbit-security-integration` : authentication and authorization integrated with the APIs. +`hawkbit-artifact-repository-mongo` : artifact repository implementation to MongoDB. `hawkbit-autoconfigure` : spring-boot auto-configuration. `hawkbit-dmf-api` : API for the Device Management Integration. `hawkbit-dmf-amqp` : AMQP endpoint implementation for the DMF API. diff --git a/hawkbit-core/README.md b/hawkbit-core/README.md new file mode 100644 index 000000000..bf75314d1 --- /dev/null +++ b/hawkbit-core/README.md @@ -0,0 +1,3 @@ +# hawkBit Core + +Various internal interfaces and utility classes. \ No newline at end of file diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java index b81b76e5c..b4960737d 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java @@ -24,11 +24,11 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; /** - * An spring authentication provider which supportes authentication tokens of + * An spring authentication provider which supports authentication tokens of * type {@link PreAuthenticatedAuthenticationToken} created by the * {@link ControllerPreAuthenticatedSecurityHeaderFilter}. * - * Addtionally to the authentication token providing the principal and the + * Additionally to the authentication token providing the principal and the * credentials which must be match, this authentication provider can also check * the remote IP address of the request. * From 426d95394b289ddc52d2c08e05f18bcfba9cdd7d Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 2 May 2016 18:13:26 +0200 Subject: [PATCH 12/47] Fixed broken merge. Signed-off-by: Kai Zimmermann --- .../org/eclipse/hawkbit/repository/RolloutManagement.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java index 13e37abed..09decfc03 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java @@ -59,10 +59,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.annotation.Isolation; -<<<<<<< HEAD -======= import org.springframework.transaction.annotation.Propagation; ->>>>>>> eclipse/master import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.TransactionTemplate; @@ -287,8 +284,8 @@ public class RolloutManagement { } } - private Rollout createRolloutGroupsInNewTransaction(final int amountOfGroups, final RolloutGroupConditions conditions, - final Rollout savedRollout) { + private Rollout createRolloutGroupsInNewTransaction(final int amountOfGroups, + final RolloutGroupConditions conditions, final Rollout savedRollout) { final DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setName("creatingRollout"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); From f3236a57db88525ea13b2c88f40368d09876c8fe Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 3 May 2016 08:28:19 +0200 Subject: [PATCH 13/47] Fixed sonar issue for Long equal check. Signed-off-by: Kai Zimmermann --- .../java/org/eclipse/hawkbit/repository/ArtifactManagement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java index a8a9b5ee5..024ec11cb 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java @@ -317,7 +317,7 @@ public class ArtifactManagement { for (final LocalArtifact lArtifact : localArtifactRepository .findByGridFsFileName(existing.getGridFsFileName())) { if (!lArtifact.getSoftwareModule().isDeleted() - && lArtifact.getSoftwareModule().getId() != existing.getSoftwareModule().getId()) { + && Long.compare(lArtifact.getSoftwareModule().getId(), existing.getSoftwareModule().getId()) != 0) { artifactIsOnlyUsedByOneSoftwareModule = false; break; } From dbc70ae374d7c78ceef93c5aa958f2d4ed8dccd7 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 3 May 2016 09:25:07 +0200 Subject: [PATCH 14/47] Added targetToken to DMF update message. Signed-off-by: Kai Zimmermann --- examples/hawkbit-mgmt-api-client/pom.xml | 2 +- .../amqp/AmqpMessageDispatcherService.java | 1 + .../amqp/AmqpMessageHandlerService.java | 3 ++- .../AmqpMessageDispatcherServiceTest.java | 20 +++++++++++-------- .../amqp/AmqpMessageHandlerServiceTest.java | 9 +++++---- .../json/model/DownloadAndUpdateRequest.java | 15 +++++++++++--- .../TargetAssignDistributionSetEvent.java | 12 ++++++++--- .../repository/DeploymentManagement.java | 9 +++++---- 8 files changed, 47 insertions(+), 24 deletions(-) diff --git a/examples/hawkbit-mgmt-api-client/pom.xml b/examples/hawkbit-mgmt-api-client/pom.xml index 9aaf53dc6..77e35df83 100644 --- a/examples/hawkbit-mgmt-api-client/pom.xml +++ b/examples/hawkbit-mgmt-api-client/pom.xml @@ -18,7 +18,7 @@ jar hawkbit-mgmt-api-client - hawkBit Management API example client + hawkBit :: Management API example client diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java index 19e0cbadf..02c72228c 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java @@ -82,6 +82,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { .getSoftwareModules(); final DownloadAndUpdateRequest downloadAndUpdateRequest = new DownloadAndUpdateRequest(); downloadAndUpdateRequest.setActionId(targetAssignDistributionSetEvent.getActionId()); + downloadAndUpdateRequest.setTargetToken(targetAssignDistributionSetEvent.getTargetToken()); for (final org.eclipse.hawkbit.repository.model.SoftwareModule softwareModule : modules) { final SoftwareModule amqpSoftwareModule = convertToAmqpSoftwareModule(controllerId, softwareModule); 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 447a8ffca..da7c10800 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 @@ -305,7 +305,8 @@ public class AmqpMessageHandlerService extends BaseAmqpService { final List softwareModuleList = controllerManagement .findSoftwareModulesByDistributionSet(distributionSet); eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(), - target.getControllerId(), action.getId(), softwareModuleList, target.getTargetInfo().getAddress())); + target.getControllerId(), action.getId(), softwareModuleList, target.getTargetInfo().getAddress(), + target.getSecurityToken())); } diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java index f2c3d254c..ec6ed05b0 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java @@ -58,6 +58,12 @@ import ru.yandex.qatools.allure.annotations.Stories; @Stories("AmqpMessage Dispatcher Service Test") public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWithMongoDB { + private static final String TENANT = "default"; + + private static final URI AMQP_URI = IpUtil.createAmqpUri("vHost", "mytest"); + + private static final String TEST_TOKEN = "testToken"; + private AmqpMessageDispatcherService amqpMessageDispatcherService; private RabbitTemplate rabbitTemplate; @@ -89,8 +95,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit @Description("Verfies that download and install event with no software modul works") public void testSendDownloadRequesWithEmptySoftwareModules() { final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent( - 1L, "default", CONTROLLER_ID, 1l, new ArrayList(), - IpUtil.createAmqpUri("vHost", "mytest")); + 1L, TENANT, CONTROLLER_ID, 1L, new ArrayList(), AMQP_URI, TEST_TOKEN); amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent); final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress()); final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage); @@ -104,7 +109,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit final DistributionSet dsA = TestDataUtil.generateDistributionSet("", softwareManagement, distributionSetManagement); final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent( - 1L, "default", CONTROLLER_ID, 1l, dsA.getModules(), IpUtil.createAmqpUri("vHost", "mytest")); + 1L, TENANT, CONTROLLER_ID, 1L, dsA.getModules(), AMQP_URI, TEST_TOKEN); amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent); final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress()); final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage); @@ -143,7 +148,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit Mockito.when(rabbitTemplate.convertSendAndReceive(any())).thenReturn(receivedList); final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent( - 1L, "default", CONTROLLER_ID, 1l, dsA.getModules(), IpUtil.createAmqpUri("vHost", "mytest")); + 1L, TENANT, CONTROLLER_ID, 1L, dsA.getModules(), AMQP_URI, TEST_TOKEN); amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent); final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress()); final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage); @@ -162,7 +167,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit @Description("Verfies that send cancel event works") public void testSendCancelRequest() { final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent( - 1L, "default", CONTROLLER_ID, 1l, IpUtil.createAmqpUri("vHost", "mytest")); + 1L, TENANT, CONTROLLER_ID, 1L, AMQP_URI); amqpMessageDispatcherService .targetCancelAssignmentToDistributionSet(cancelTargetAssignmentDistributionSetEvent); final Message sendMessage = createArgumentCapture(cancelTargetAssignmentDistributionSetEvent.getTargetAdress()); @@ -187,13 +192,12 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit downloadAndUpdateRequest.getActionId(), Long.valueOf(1)); assertEquals("The topic of the event shuold contain DOWNLOAD_AND_INSTALL", EventTopic.DOWNLOAD_AND_INSTALL, sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TOPIC)); + assertEquals("Security token of target", downloadAndUpdateRequest.getTargetToken(), TEST_TOKEN); + return downloadAndUpdateRequest; } - /** - * @param sendMessage - */ private void assertEventMessage(final Message sendMessage) { assertNotNull("The message should not be null", sendMessage); diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index 19a7be3bc..18ee0bde4 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -339,14 +339,14 @@ public class AmqpMessageHandlerServiceTest { @Test @Description("Tests TODO") - public void lookupNextUpdateActionAfterFinished() throws IllegalArgumentException, IllegalAccessException { + public void lookupNextUpdateActionAfterFinished() throws IllegalAccessException { // Mock final Action action = createActionWithTarget(22L, Status.FINISHED); when(controllerManagementMock.findActionWithDetails(Matchers.any())).thenReturn(action); when(controllerManagementMock.addUpdateActionStatus(Matchers.any(), Matchers.any())).thenReturn(action); // for the test the same action can be used - final List actionList = new ArrayList(); + final List actionList = new ArrayList<>(); actionList.add(action); when(controllerManagementMock.findActionByTargetAndActive(Matchers.any())).thenReturn(actionList); @@ -372,6 +372,8 @@ public class AmqpMessageHandlerServiceTest { assertThat(targetAssignDistributionSetEvent.getControllerId()).as("event has wrong controller id") .isEqualTo("target1"); + assertThat(targetAssignDistributionSetEvent.getTargetToken()).as("targetoken not filled correctly") + .isEqualTo(action.getTarget().getSecurityToken()); assertThat(targetAssignDistributionSetEvent.getActionId()).as("event has wrong action id").isEqualTo(22L); assertThat(targetAssignDistributionSetEvent.getSoftwareModules()).as("event has wrong sofware modules") .isEqualTo(softwareModuleList); @@ -411,8 +413,7 @@ public class AmqpMessageHandlerServiceTest { return softwareModuleList; } - private Action createActionWithTarget(final Long targetId, final Status status) - throws IllegalArgumentException, IllegalAccessException { + private Action createActionWithTarget(final Long targetId, final Status status) throws IllegalAccessException { // is needed for the creation of targets initalizeSecurityTokenGenerator(); diff --git a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DownloadAndUpdateRequest.java b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DownloadAndUpdateRequest.java index 4344c5416..f34bab6dd 100644 --- a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DownloadAndUpdateRequest.java +++ b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DownloadAndUpdateRequest.java @@ -19,15 +19,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** * JSON representation of download and update request. * - * - * - * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public class DownloadAndUpdateRequest { @JsonProperty private Long actionId; + + @JsonProperty + private String targetToken; + @JsonProperty private final List softwareModules = new LinkedList<>(); @@ -39,6 +40,14 @@ public class DownloadAndUpdateRequest { this.actionId = correlator; } + public String getTargetToken() { + return targetToken; + } + + public void setTargetToken(final String targetToken) { + this.targetToken = targetToken; + } + public List getSoftwareModules() { return softwareModules; } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetAssignDistributionSetEvent.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetAssignDistributionSetEvent.java index b286ac6ea..68b3f1289 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetAssignDistributionSetEvent.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetAssignDistributionSetEvent.java @@ -16,8 +16,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; /** * Event that gets sent when a distribution set gets assigned to a target. * - * - * */ public class TargetAssignDistributionSetEvent extends AbstractEvent { @@ -25,6 +23,7 @@ public class TargetAssignDistributionSetEvent extends AbstractEvent { private final String controllerId; private final Long actionId; private final URI targetAdress; + private final String targetToken; /** * Creates a new {@link TargetAssignDistributionSetEvent}. @@ -41,14 +40,18 @@ public class TargetAssignDistributionSetEvent extends AbstractEvent { * the software modules which have been assigned to the target * @param targetAdress * the targetAdress of the target + * @param targetToken + * the authentication token of the target */ public TargetAssignDistributionSetEvent(final long revision, final String tenant, final String controllerId, - final Long actionId, final Collection softwareModules, final URI targetAdress) { + final Long actionId, final Collection softwareModules, final URI targetAdress, + final String targetToken) { super(revision, tenant); this.controllerId = controllerId; this.actionId = actionId; this.softwareModules = softwareModules; this.targetAdress = targetAdress; + this.targetToken = targetToken; } /** @@ -77,4 +80,7 @@ public class TargetAssignDistributionSetEvent extends AbstractEvent { return targetAdress; } + public String getTargetToken() { + return targetToken; + } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index 77f71bebf..e64eeab13 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -389,8 +389,8 @@ public class DeploymentManagement { softwareModules)); } - private Action createTargetAction(final Map targetsWithActionMap, final Target target, - final DistributionSet set, final Rollout rollout, final RolloutGroup rolloutGroup) { + private static Action createTargetAction(final Map targetsWithActionMap, + final Target target, final DistributionSet set, final Rollout rollout, final RolloutGroup rolloutGroup) { final Action actionForTarget = new Action(); final TargetWithActionType targetWithActionType = targetsWithActionMap.get(target.getControllerId()); actionForTarget.setActionType(targetWithActionType.getActionType()); @@ -421,13 +421,14 @@ public class DeploymentManagement { afterCommit.afterCommit(() -> { eventBus.post(new TargetInfoUpdateEvent(target.getTargetInfo())); eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(), - target.getControllerId(), actionId, softwareModules, target.getTargetInfo().getAddress())); + target.getControllerId(), actionId, softwareModules, target.getTargetInfo().getAddress(), + target.getSecurityToken())); }); } /** * Removes {@link UpdateAction}s that are no longer necessary and sends - * cancelations to the controller. + * cancellations to the controller. * * @param myTarget * to override {@link UpdateAction}s From 85263e475db3b40f0f63b48e25958f1b9ebaba0d Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 3 May 2016 09:48:55 +0200 Subject: [PATCH 15/47] use correct term for token. Similar to mgmt API. Signed-off-by: Kai Zimmermann --- .../hawkbit/amqp/AmqpMessageDispatcherService.java | 2 +- .../hawkbit/amqp/AmqpMessageDispatcherServiceTest.java | 2 +- .../dmf/json/model/DownloadAndUpdateRequest.java | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java index 02c72228c..32bcb02a5 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java @@ -82,7 +82,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { .getSoftwareModules(); final DownloadAndUpdateRequest downloadAndUpdateRequest = new DownloadAndUpdateRequest(); downloadAndUpdateRequest.setActionId(targetAssignDistributionSetEvent.getActionId()); - downloadAndUpdateRequest.setTargetToken(targetAssignDistributionSetEvent.getTargetToken()); + downloadAndUpdateRequest.setTargetSecurityToken(targetAssignDistributionSetEvent.getTargetToken()); for (final org.eclipse.hawkbit.repository.model.SoftwareModule softwareModule : modules) { final SoftwareModule amqpSoftwareModule = convertToAmqpSoftwareModule(controllerId, softwareModule); diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java index ec6ed05b0..4e0852ff3 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java @@ -192,7 +192,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit downloadAndUpdateRequest.getActionId(), Long.valueOf(1)); assertEquals("The topic of the event shuold contain DOWNLOAD_AND_INSTALL", EventTopic.DOWNLOAD_AND_INSTALL, sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TOPIC)); - assertEquals("Security token of target", downloadAndUpdateRequest.getTargetToken(), TEST_TOKEN); + assertEquals("Security token of target", downloadAndUpdateRequest.getTargetSecurityToken(), TEST_TOKEN); return downloadAndUpdateRequest; diff --git a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DownloadAndUpdateRequest.java b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DownloadAndUpdateRequest.java index f34bab6dd..88cb80975 100644 --- a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DownloadAndUpdateRequest.java +++ b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DownloadAndUpdateRequest.java @@ -27,7 +27,7 @@ public class DownloadAndUpdateRequest { private Long actionId; @JsonProperty - private String targetToken; + private String targetSecurityToken; @JsonProperty private final List softwareModules = new LinkedList<>(); @@ -40,12 +40,12 @@ public class DownloadAndUpdateRequest { this.actionId = correlator; } - public String getTargetToken() { - return targetToken; + public String getTargetSecurityToken() { + return targetSecurityToken; } - public void setTargetToken(final String targetToken) { - this.targetToken = targetToken; + public void setTargetSecurityToken(final String targetSecurityToken) { + this.targetSecurityToken = targetSecurityToken; } public List getSoftwareModules() { From a4832c5bcd979c54759abb68fdc78438a737921a Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 3 May 2016 14:48:09 +0200 Subject: [PATCH 16/47] Style improvement Signed-off-by: Melanie Retter --- .../themes/hawkbit/customstyles/target-filter-query.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/target-filter-query.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/target-filter-query.scss index b29483da1..33ae2dd85 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/target-filter-query.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/target-filter-query.scss @@ -28,12 +28,12 @@ .error-icon{ color:$success-icon-color !important; - padding:2px; + padding-left:2px !important; } .success-icon{ color:$error-icon-color !important; - padding:2px; + padding-left:2px !important; } .on-focus-no-border:focus::after{ From 2177271a49e6cdcee6f692e9048bb26e430f9e79 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 3 May 2016 15:44:03 +0200 Subject: [PATCH 17/47] Added save (auto) close. Signed-off-by: Kai Zimmermann --- .../eclipse/hawkbit/artifact/repository/ArtifactStore.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java index 6981834b4..94b093cb3 100644 --- a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java +++ b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java @@ -200,9 +200,9 @@ public class ArtifactStore implements ArtifactRepository { String sha1Hash; // compute digest final MessageDigest md = MessageDigest.getInstance("SHA-1"); - final DigestOutputStream dos = new DigestOutputStream(os, md); - ByteStreams.copy(stream, dos); - dos.close(); + try (final DigestOutputStream dos = new DigestOutputStream(os, md)) { + ByteStreams.copy(stream, dos); + } sha1Hash = BaseEncoding.base16().lowerCase().encode(md.digest()); if (providedSHA1Sum != null && !providedSHA1Sum.equalsIgnoreCase(sha1Hash)) { throw new HashNotMatchException( From 7c4351faa55b18e919b256dba4368e82a6adaad6 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 3 May 2016 15:44:46 +0200 Subject: [PATCH 18/47] Fixed wrong handling of multi line message status. Signed-off-by: Kai Zimmermann --- .../org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java | 5 ++--- 1 file changed, 2 insertions(+), 3 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 da7c10800..f26d7f3f7 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 @@ -337,9 +337,8 @@ public class AmqpMessageHandlerService extends BaseAmqpService { final Action action = checkActionExist(message, actionUpdateStatus); final ActionStatus actionStatus = new ActionStatus(); - final List messageText = actionUpdateStatus.getMessage(); - final String messageString = String.join(", ", messageText); - actionStatus.addMessage(messageString); + actionUpdateStatus.getMessage().forEach(actionStatus::addMessage); + actionStatus.setAction(action); actionStatus.setOccurredAt(System.currentTimeMillis()); From f32f612e839ad6fa3feccf604e673e8b627f6c32 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 3 May 2016 15:56:16 +0200 Subject: [PATCH 19/47] Improved readability of action status messages that are created by the update server itself. Signed-off-by: Kai Zimmermann --- .../repository/ControllerManagement.java | 9 ++++++--- .../controller/ArtifactStoreController.java | 6 ++++-- .../hawkbit/controller/RootController.java | 17 ++++++++++------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java index dc097a7e3..58ae2ad97 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java @@ -63,6 +63,8 @@ public class ControllerManagement { private static final Logger LOG = LoggerFactory.getLogger(ControllerManagement.class); private static final Logger LOG_DOS = LoggerFactory.getLogger("server-security.dos"); + public static final String SERVER_MESSAGE_PREFIX = "Update Server: "; + @Autowired private EntityManager entityManager; @@ -341,13 +343,14 @@ public class ControllerManagement { break; case CANCELED: case FINISHED: - // in case of successful cancelation we also report the success at + // in case of successful cancellation we also report the success at // the canceled action itself. - actionStatus.addMessage("Cancelation completion is finished sucessfully."); + actionStatus.addMessage( + ControllerManagement.SERVER_MESSAGE_PREFIX + "Cancellation completion is finished sucessfully."); deploymentManagement.successCancellation(action); break; case RETRIEVED: - actionStatus.addMessage("Cancelation request retrieved"); + actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Cancellation request retrieved."); break; default: } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/ArtifactStoreController.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/ArtifactStoreController.java index c2dbd3ba5..a36443024 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/ArtifactStoreController.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/ArtifactStoreController.java @@ -143,9 +143,11 @@ public class ArtifactStoreController { actionStatus.setStatus(Status.DOWNLOAD); if (range != null) { - actionStatus.addMessage("It is a partial download request: " + range); + actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads range " + range + + " of: " + request.getRequestURI()); } else { - actionStatus.addMessage("Target downloads"); + actionStatus.addMessage( + ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI()); } controllerManagement.addActionStatusMessage(actionStatus); return action; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java index f704acd5e..000e1e2e5 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java @@ -216,9 +216,11 @@ public class RootController { statusMessage.setStatus(Status.DOWNLOAD); if (range != null) { - statusMessage.addMessage("It is a partial download request: " + range); + statusMessage.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads range " + range + + " of: " + request.getRequestURI()); } else { - statusMessage.addMessage("Controller downloads"); + statusMessage.addMessage( + ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI()); } controllerManagement.addActionStatusMessage(statusMessage); return action; @@ -388,13 +390,13 @@ public class RootController { LOG.debug("Controller confirmed cancel (actionid: {}, targetid: {}) as we got {} report.", actionid, targetid, feedback.getStatus().getExecution()); actionStatus.setStatus(Status.CANCELED); - actionStatus.addMessage("Controller confirmed cancelation"); + actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target confirmed cancelation"); break; case REJECTED: LOG.info("Controller reported internal error (actionid: {}, targetid: {}) as we got {} report.", actionid, targetid, feedback.getStatus().getExecution()); actionStatus.setStatus(Status.WARNING); - actionStatus.addMessage("Controller reported internal ERROR and REJECTED update."); + actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target REJECTED update."); break; case CLOSED: handleClosedUpdateStatus(feedback, targetid, actionid, actionStatus); @@ -421,7 +423,8 @@ public class RootController { LOG.debug("Controller reported intermediate status (actionid: {}, targetid: {}) as we got {} report.", actionid, targetid, feedback.getStatus().getExecution()); actionStatus.setStatus(Status.RUNNING); - actionStatus.addMessage("Controller reported: " + feedback.getStatus().getExecution()); + actionStatus.addMessage( + ControllerManagement.SERVER_MESSAGE_PREFIX + "Target reported: " + feedback.getStatus().getExecution()); } private static void handleClosedUpdateStatus(final ActionFeedback feedback, final String targetid, @@ -430,10 +433,10 @@ public class RootController { feedback.getStatus().getExecution()); if (feedback.getStatus().getResult().getFinished() == FinalResult.FAILURE) { actionStatus.setStatus(Status.ERROR); - actionStatus.addMessage("Controller reported CLOSED with ERROR!"); + actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target reported CLOSED with ERROR!"); } else { actionStatus.setStatus(Status.FINISHED); - actionStatus.addMessage("Controller reported CLOSED with OK!"); + actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target reported CLOSED with OK!"); } } From c4f368ee40a287cf9ecf80ad919c8d13a0258221 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 3 May 2016 16:11:02 +0200 Subject: [PATCH 20/47] float values - capital F Signed-off-by: Melanie Retter --- .../ui/common/detailslayout/AbstractTableDetailsLayout.java | 2 +- .../hawkbit/ui/common/table/AbstractTableHeader.java | 6 +++--- .../java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) 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 3c153cb77..f471abf33 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 @@ -157,7 +157,7 @@ public abstract class AbstractTableDetailsLayout extends nameEditLayout.addComponent(editButton); nameEditLayout.setComponentAlignment(editButton, Alignment.TOP_RIGHT); } - nameEditLayout.setExpandRatio(caption, 1.0f); + nameEditLayout.setExpandRatio(caption, 1.0F); nameEditLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE); addComponent(nameEditLayout); 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 0c5407316..b137594f8 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 @@ -170,8 +170,8 @@ public abstract class AbstractTableHeader extends VerticalLayout { } titleFilterIconsLayout.addComponent(maxMinIcon); titleFilterIconsLayout.setComponentAlignment(maxMinIcon, Alignment.TOP_RIGHT); - titleFilterIconsLayout.setExpandRatio(headerCaption, 0.4f); - titleFilterIconsLayout.setExpandRatio(searchField, 0.6f); + titleFilterIconsLayout.setExpandRatio(headerCaption, 0.4F); + titleFilterIconsLayout.setExpandRatio(searchField, 0.6F); addComponent(titleFilterIconsLayout); @@ -191,7 +191,7 @@ public abstract class AbstractTableHeader extends VerticalLayout { dropHintDropFilterLayout.addComponent(dropFilterLayout); dropHintDropFilterLayout.setComponentAlignment(dropFilterLayout, Alignment.TOP_CENTER); - dropHintDropFilterLayout.setExpandRatio(dropFilterLayout, 1.0f); + dropHintDropFilterLayout.setExpandRatio(dropFilterLayout, 1.0F); } addComponent(dropHintDropFilterLayout); setComponentAlignment(dropHintDropFilterLayout, Alignment.TOP_CENTER); 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 dd8c0e5f9..9d2c0d246 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 @@ -117,7 +117,7 @@ public final class DashboardMenu extends CustomComponent { menus.setComponentAlignment(links, Alignment.BOTTOM_CENTER); menus.setExpandRatio(links, 1.0f); menuContent.addComponent(menus); - menuContent.setExpandRatio(menus, 1.0f); + menuContent.setExpandRatio(menus, 1.0F); dashboardMenuLayout.addComponent(menuContent); return dashboardMenuLayout; @@ -264,7 +264,7 @@ public final class DashboardMenu extends CustomComponent { private VerticalLayout buildMenuItems() { final VerticalLayout menuItemsLayout = new VerticalLayout(); menuItemsLayout.addStyleName("valo-menuitems"); - menuItemsLayout.setHeight(100.0f, Unit.PERCENTAGE); + menuItemsLayout.setHeight(100.0F, Unit.PERCENTAGE); final List accessibleViews = getAccessibleViews(); if (accessibleViews.isEmpty()) { From 7e941cf64d9ba2c2204b751c01b62c7d431ad2f2 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 3 May 2016 16:16:36 +0200 Subject: [PATCH 21/47] Teached simulator to download artifacts including SHA1 hash check and targetToken usage. Signed-off-by: Kai Zimmermann --- examples/hawkbit-device-simulator/pom.xml | 13 +- .../simulator/AbstractSimulatedDevice.java | 42 ++--- .../hawkbit/simulator/DDISimulatedDevice.java | 50 +++--- .../hawkbit/simulator/DMFSimulatedDevice.java | 5 +- .../simulator/DeviceSimulatorUpdater.java | 152 ++++++++++++++++-- .../simulator/NextPollTimeController.java | 18 +-- .../simulator/SimulatedDeviceFactory.java | 13 +- .../hawkbit/simulator/UpdateStatus.java | 58 +++++++ .../simulator/amqp/SpReceiverService.java | 15 +- .../simulator/amqp/SpSenderService.java | 53 +++--- .../simulator/event/ProgressUpdate.java | 2 - .../hawkbit/simulator/ui/SimulatorView.java | 98 +++++------ 12 files changed, 333 insertions(+), 186 deletions(-) create mode 100644 examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/UpdateStatus.java diff --git a/examples/hawkbit-device-simulator/pom.xml b/examples/hawkbit-device-simulator/pom.xml index c74eace3e..33d165584 100644 --- a/examples/hawkbit-device-simulator/pom.xml +++ b/examples/hawkbit-device-simulator/pom.xml @@ -1,4 +1,3 @@ - - 4.0.0 @@ -133,6 +133,15 @@ spring-boot-configuration-processor true + + org.scala-lang + scala-library + 2.10.4 + + + org.apache.httpcomponents + httpclient + diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java index 474acb6c4..890f43367 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.simulator; +import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus; + /** * The bean of a simulated device which can be stored in the * {@link DeviceSimulatorRepository} or shown in the UI. @@ -22,16 +24,15 @@ public abstract class AbstractSimulatedDevice { private Status status; private double progress; private String swversion = "unknown"; - private ResponseStatus responseStatus = ResponseStatus.SUCCESSFUL; + private UpdateStatus updateStatus = new UpdateStatus(ResponseStatus.SUCCESSFUL, "Simulation complete!"); private Protocol protocol = Protocol.DMF_AMQP; + private String targetSecurityToken; private int nextPollCounterSec; /** * Enum definition of the protocol to be used for the simulated device. * - * @author Michael Hirsch - * */ public enum Protocol { /** @@ -69,24 +70,6 @@ public abstract class AbstractSimulatedDevice { ERROR; } - /** - * The status to response to the hawkbit update server if an simulated - * update process should be respond with successful or failure update. - * - * @author Michael Hirsch - * - */ - public enum ResponseStatus { - /** - * updated has been successful and response the successful update. - */ - SUCCESSFUL, - /** - * updated has been not successful and response the error update. - */ - ERROR; - } - /** * empty constructor. */ @@ -158,12 +141,12 @@ public abstract class AbstractSimulatedDevice { this.swversion = swversion; } - public ResponseStatus getResponseStatus() { - return responseStatus; + public UpdateStatus getUpdateStatus() { + return updateStatus; } - public void setResponseStatus(final ResponseStatus responseStatus) { - this.responseStatus = responseStatus; + public void setUpdateStatus(final UpdateStatus updateStatus) { + this.updateStatus = updateStatus; } public Protocol getProtocol() { @@ -177,4 +160,13 @@ public abstract class AbstractSimulatedDevice { public void setNextPollCounterSec(final int nextPollDelayInSec) { this.nextPollCounterSec = nextPollDelayInSec; } + + public String getTargetSecurityToken() { + return targetSecurityToken; + } + + public void setTargetSecurityToken(final String targetSecurityToken) { + this.targetSecurityToken = targetSecurityToken; + } + } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DDISimulatedDevice.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DDISimulatedDevice.java index b58d3a413..26e613dd9 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DDISimulatedDevice.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DDISimulatedDevice.java @@ -8,8 +8,6 @@ */ package org.eclipse.hawkbit.simulator; -import java.util.concurrent.ScheduledExecutorService; - import org.eclipse.hawkbit.simulator.http.ControllerResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,7 +16,7 @@ import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.PathNotFoundException; /** - * @author Michael Hirsch + * A simulated device using the DDI API of the hawkBit update server. * */ public class DDISimulatedDevice extends AbstractSimulatedDevice { @@ -26,12 +24,12 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice { private static final Logger LOGGER = LoggerFactory.getLogger(DDISimulatedDevice.class); private final int pollDelaySec; - private final ScheduledExecutorService pollthreadpool; private final ControllerResource controllerResource; + private final DeviceSimulatorUpdater deviceUpdater; + private volatile boolean removed; private volatile Long currentActionId; - private final DeviceSimulatorUpdater deviceUpdater; /** * @param id @@ -42,18 +40,14 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice { * the delay of the poll interval in sec * @param controllerResource * the http controller resource - * @param pollthreadpool - * the threadpool for polling endpoint * @param deviceUpdater * the service to update devices */ public DDISimulatedDevice(final String id, final String tenant, final int pollDelaySec, - final ControllerResource controllerResource, final ScheduledExecutorService pollthreadpool, - final DeviceSimulatorUpdater deviceUpdater) { + final ControllerResource controllerResource, final DeviceSimulatorUpdater deviceUpdater) { super(id, tenant, Protocol.DDI_HTTP); this.pollDelaySec = pollDelaySec; this.controllerResource = controllerResource; - this.pollthreadpool = pollthreadpool; this.deviceUpdater = deviceUpdater; setNextPollCounterSec(pollDelaySec); } @@ -76,27 +70,12 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice { final String basePollJson = controllerResource.get(getTenant(), getId()); try { final String href = JsonPath.parse(basePollJson).read("_links.deploymentBase.href"); - final long actionId = Long.parseLong(href.substring(href.lastIndexOf("/") + 1, href.indexOf("?"))); + final long actionId = Long.parseLong(href.substring(href.lastIndexOf('/') + 1, href.indexOf('?'))); if (currentActionId == null) { final String deploymentJson = controllerResource.getDeployment(getTenant(), getId(), actionId); final String swVersion = JsonPath.parse(deploymentJson).read("deployment.chunks[0].version"); currentActionId = actionId; - deviceUpdater.startUpdate(getTenant(), getId(), actionId, swVersion, (device, actionId1) -> { - switch (device.getResponseStatus()) { - case SUCCESSFUL: - controllerResource.postSuccessFeedback(getTenant(), getId(), - actionId1); - break; - case ERROR: - controllerResource.postErrorFeedback(getTenant(), getId(), - actionId1); - break; - default: - throw new IllegalStateException( - "simulated device has an unknown response status + " + device.getResponseStatus()); - } - currentActionId = null; - }); + startDdiUpdate(actionId, swVersion); } } catch (final PathNotFoundException e) { // href might not be in the json response, so ignore @@ -106,4 +85,21 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice { } } + + private void startDdiUpdate(final long actionId, final String swVersion) { + deviceUpdater.startUpdate(getTenant(), getId(), actionId, swVersion, null, null, (device, actionId1) -> { + switch (device.getUpdateStatus().getResponseStatus()) { + case SUCCESSFUL: + controllerResource.postSuccessFeedback(getTenant(), getId(), actionId1); + break; + case ERROR: + controllerResource.postErrorFeedback(getTenant(), getId(), actionId1); + break; + default: + throw new IllegalStateException("simulated device has an unknown response status + " + + device.getUpdateStatus().getResponseStatus()); + } + currentActionId = null; + }); + } } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DMFSimulatedDevice.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DMFSimulatedDevice.java index b9fdc827c..6b79a85b8 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DMFSimulatedDevice.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DMFSimulatedDevice.java @@ -9,10 +9,7 @@ package org.eclipse.hawkbit.simulator; /** - * An simulated device using the DMF API of the hawkbit update server. - * - * @author Michael Hirsch - * + * A simulated device using the DMF API of the hawkBit update server. */ public class DMFSimulatedDevice extends AbstractSimulatedDevice { 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 afc3a2569..12ff7dbd2 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,27 +8,52 @@ */ package org.eclipse.hawkbit.simulator; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.security.DigestOutputStream; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; 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; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLContextBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.eclipse.hawkbit.dmf.json.model.Artifact; +import org.eclipse.hawkbit.dmf.json.model.SoftwareModule; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; +import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus; import org.eclipse.hawkbit.simulator.amqp.SpSenderService; import org.eclipse.hawkbit.simulator.event.InitUpdate; import org.eclipse.hawkbit.simulator.event.ProgressUpdate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.google.common.eventbus.EventBus; +import com.google.common.io.BaseEncoding; +import com.google.common.io.ByteStreams; /** - * @author Michael Hirsch + * Update simulation handler. * */ @Service public class DeviceSimulatorUpdater { + private static final Logger LOGGER = LoggerFactory.getLogger(DeviceSimulatorUpdater.class); private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(4); @@ -54,14 +79,18 @@ public class DeviceSimulatorUpdater { * @param actionId * the actionId from the hawkbit update server to start the * update. - * @param swVersion + * @param modules * the software module version from the hawkbit update server + * @param swVersion + * the software version as static value in case modules is null + * @param targetSecurityToken + * the target security token for download authentication * @param callback * the callback which gets called when the simulated update * process has been finished */ public void startUpdate(final String tenant, final String id, final long actionId, final String swVersion, - final UpdaterCallback callback) { + final List modules, final String targetSecurityToken, final UpdaterCallback callback) { AbstractSimulatedDevice device = repository.get(tenant, id); // plug and play - non existing device will be auto created @@ -70,11 +99,18 @@ public class DeviceSimulatorUpdater { } device.setProgress(0.0); - device.setSwversion(swVersion); + + if (modules == null) { + device.setSwversion(swVersion); + } else { + device.setSwversion(modules.stream().map(sm -> sm.getModuleVersion()).collect(Collectors.joining(", "))); + } + device.setTargetSecurityToken(targetSecurityToken); eventbus.post(new InitUpdate(device)); - threadPool.schedule(new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback), - 2_000, TimeUnit.MILLISECONDS); + threadPool.schedule( + new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback, modules), 2_000, + TimeUnit.MILLISECONDS); } private static final class DeviceSimulatorUpdateThread implements Runnable { @@ -85,38 +121,130 @@ public class DeviceSimulatorUpdater { private final long actionId; private final EventBus eventbus; private final UpdaterCallback callback; + private final List modules; private DeviceSimulatorUpdateThread(final AbstractSimulatedDevice device, final SpSenderService spSenderService, - final long actionId, final EventBus eventbus, final UpdaterCallback callback) { + final long actionId, final EventBus eventbus, final UpdaterCallback callback, + final List modules) { this.device = device; this.spSenderService = spSenderService; this.actionId = actionId; this.eventbus = eventbus; this.callback = callback; + this.modules = modules; } @Override public void run() { + if (device.getProgress() <= 0 && modules != null) { + device.setUpdateStatus(simulateDownloads(device.getTargetSecurityToken())); + if (device.getUpdateStatus().getResponseStatus().equals(ResponseStatus.ERROR)) { + callback.updateFinished(device, actionId); + eventbus.post(new ProgressUpdate(device)); + return; + } + } + final double newProgress = device.getProgress() + 0.2; device.setProgress(newProgress); if (newProgress < 1.0) { threadPool.schedule( - new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback), + new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback, modules), rndSleep.nextInt(5_000), TimeUnit.MILLISECONDS); } else { callback.updateFinished(device, actionId); } eventbus.post(new ProgressUpdate(device)); } + + private UpdateStatus simulateDownloads(final String targetToken) { + final List status = new ArrayList<>(); + + LOGGER.info("Simulate downloads for {}", device.getId()); + + modules.forEach(module -> module.getArtifacts() + .forEach(artifact -> handleArtifacts(targetToken, status, artifact))); + + final UpdateStatus result = new UpdateStatus(ResponseStatus.SUCCESSFUL); + result.getStatusMessages().add("Simulation complete!"); + status.forEach(download -> { + result.getStatusMessages().addAll(download.getStatusMessages()); + if (download.getResponseStatus().equals(ResponseStatus.ERROR)) { + result.setResponseStatus(ResponseStatus.ERROR); + } + }); + + LOGGER.info("Download simulations complete for {}", device.getId()); + + return result; + } + + private static void handleArtifacts(final String targetToken, final List status, + final Artifact artifact) { + artifact.getUrls().entrySet().forEach(entry -> { + switch (entry.getKey()) { + case HTTPS: + status.add(downloadUrl(entry.getValue(), targetToken, artifact.getHashes().getSha1())); + break; + default: + // not supported yet + break; + } + }); + } + + private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash) { + LOGGER.debug("Downloading " + url); + + long overallread = 0; + try { + final CloseableHttpClient httpclient = createHttpClientThatAcceptsAllServerCerts(); + final HttpGet request = new HttpGet(url); + request.addHeader("TargetToken", targetToken); + + final String sha1HashResult; + try (final CloseableHttpResponse response = httpclient.execute(request)) { + final File tempFile = File.createTempFile("uploadFile", null); + final MessageDigest md = MessageDigest.getInstance("SHA-1"); + + try (final DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(tempFile), md)) { + overallread = ByteStreams.copy(response.getEntity().getContent(), dos); + sha1HashResult = BaseEncoding.base16().lowerCase().encode(md.digest()); + } finally { + tempFile.delete(); + } + } + + if (!sha1Hash.equals(sha1HashResult)) { + final String message = "Download " + url + " failed with SHA1 hash missmatch (Expected: " + sha1Hash + + " but got: " + sha1HashResult + ")"; + LOGGER.debug(message); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + + } catch (IOException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { + LOGGER.error("Failed to download {}", url, e); + return new UpdateStatus(ResponseStatus.ERROR, "Failed to download " + url + ": " + e.getMessage()); + } + + final String message = "Downloaded " + url + " (" + overallread + " bytes)"; + LOGGER.debug(message); + return new UpdateStatus(ResponseStatus.SUCCESSFUL, message); + } + + private static CloseableHttpClient createHttpClientThatAcceptsAllServerCerts() + throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { + final SSLContextBuilder builder = new SSLContextBuilder(); + builder.loadTrustMaterial(null, (chain, authType) -> true); + final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } } /** * Callback interface which is called when the simulated update process has * been finished and the caller of starting the simulated update process can - * send the result to the hawkbit update server back. - * - * @author Michael Hirsch - * + * send the result to the hawkBit update server back. * */ @FunctionalInterface public interface UpdaterCallback { diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/NextPollTimeController.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/NextPollTimeController.java index 9c78ec65a..956d6d36a 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/NextPollTimeController.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/NextPollTimeController.java @@ -26,9 +26,6 @@ import com.google.common.eventbus.EventBus; /** * Poll time trigger which executes the {@link DDISimulatedDevice#poll()} every * second. - * - * @author Michael Hirsch - * */ @Component public class NextPollTimeController { @@ -59,16 +56,15 @@ public class NextPollTimeController { devices.forEach(device -> { int nextCounter = device.getNextPollCounterSec() - 1; - if (nextCounter < 0) { - if (device instanceof DDISimulatedDevice) { - try { - pollService.submit(() -> ((DDISimulatedDevice) device).poll()); - } catch (final IllegalStateException e) { - LOGGER.trace("Device could not be polled", e); - } - nextCounter = ((DDISimulatedDevice) device).getPollDelaySec(); + if (nextCounter < 0 && device instanceof DDISimulatedDevice) { + try { + pollService.submit(() -> ((DDISimulatedDevice) device).poll()); + } catch (final IllegalStateException e) { + LOGGER.trace("Device could not be polled", e); } + nextCounter = ((DDISimulatedDevice) device).getPollDelaySec(); } + device.setNextPollCounterSec(nextCounter); }); eventBus.post(new NextPollCounterUpdate(devices)); 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 d3e080806..f29aad001 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 @@ -9,8 +9,6 @@ package org.eclipse.hawkbit.simulator; import java.net.URL; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; import org.eclipse.hawkbit.simulator.http.ControllerResource; @@ -24,15 +22,9 @@ import feign.Logger; /** * The simulated device factory to create either {@link DMFSimulatedDevice} or * {@link DDISimulatedDevice#}. - * - * @author Michael Hirsch - * */ @Service public class SimulatedDeviceFactory { - - private static final ScheduledExecutorService pollThreadPool = Executors.newScheduledThreadPool(4); - @Autowired private DeviceSimulatorUpdater deviceUpdater; @@ -47,7 +39,8 @@ public class SimulatedDeviceFactory { * the protocol of the device * @return the created simulated device */ - public AbstractSimulatedDevice createSimulatedDevice(final String id, final String tenant, final Protocol protocol) { + public AbstractSimulatedDevice createSimulatedDevice(final String id, final String tenant, + final Protocol protocol) { return createSimulatedDevice(id, tenant, protocol, 30, null, null); } @@ -80,7 +73,7 @@ public class SimulatedDeviceFactory { final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger()) .requestInterceptor(new GatewayTokenInterceptor(gatewayToken)).logLevel(Logger.Level.BASIC) .target(ControllerResource.class, baseEndpoint.toString()); - return new DDISimulatedDevice(id, tenant, pollDelaySec, controllerResource, pollThreadPool, deviceUpdater); + return new DDISimulatedDevice(id, tenant, pollDelaySec, controllerResource, deviceUpdater); default: throw new IllegalArgumentException("Protocol " + protocol + " unknown"); } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/UpdateStatus.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/UpdateStatus.java new file mode 100644 index 000000000..49e9947d7 --- /dev/null +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/UpdateStatus.java @@ -0,0 +1,58 @@ +/** + * 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.simulator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Update status of the simulated update. + * + */ +public class UpdateStatus { + private ResponseStatus responseStatus = ResponseStatus.SUCCESSFUL; + private final List statusMessages = new ArrayList<>(); + + public UpdateStatus(final ResponseStatus responseStatus) { + this.responseStatus = responseStatus; + } + + public UpdateStatus(final ResponseStatus responseStatus, final String message) { + this(responseStatus); + statusMessages.add(message); + } + + public ResponseStatus getResponseStatus() { + return responseStatus; + } + + public void setResponseStatus(final ResponseStatus responseStatus) { + this.responseStatus = responseStatus; + } + + public List getStatusMessages() { + return statusMessages; + } + + /** + * The status to response to the hawkBit update server if an simulated + * update process should be respond with successful or failure update. + */ + public enum ResponseStatus { + /** + * updated has been successful and response the successful update. + */ + SUCCESSFUL, + /** + * updated has been not successful and response the error update. + */ + ERROR; + } + +} \ No newline at end of file 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 f22839422..12e540fc9 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 @@ -25,6 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Component; +import com.google.common.collect.Lists; + /** * Handle all incoming Messages from hawkBit update server. * @@ -109,7 +111,7 @@ public class SpReceiverService extends ReceiverService { final Long actionId = convertMessage(message, Long.class); final SimulatedUpdate update = new SimulatedUpdate(tenant, thingId, actionId); - spSenderService.finishUpdateProcess(update, "Simulation canceled"); + spSenderService.finishUpdateProcess(update, Lists.newArrayList("Simulation canceled")); } private void handleUpdateProcess(final Message message, final String thingId) { @@ -120,19 +122,20 @@ public class SpReceiverService extends ReceiverService { final DownloadAndUpdateRequest downloadAndUpdateRequest = convertMessage(message, DownloadAndUpdateRequest.class); final Long actionId = downloadAndUpdateRequest.getActionId(); + final String targetSecurityToken = downloadAndUpdateRequest.getTargetSecurityToken(); - deviceUpdater.startUpdate(tenant, thingId, actionId, - downloadAndUpdateRequest.getSoftwareModules().get(0).getModuleVersion(), (device, actionId1) -> { - switch (device.getResponseStatus()) { + deviceUpdater.startUpdate(tenant, thingId, actionId, null, downloadAndUpdateRequest.getSoftwareModules(), + targetSecurityToken, (device, actionId1) -> { + switch (device.getUpdateStatus().getResponseStatus()) { case SUCCESSFUL: spSenderService.finishUpdateProcess( new SimulatedUpdate(device.getTenant(), device.getId(), actionId1), - "Simulation complete!"); + device.getUpdateStatus().getStatusMessages()); break; case ERROR: spSenderService.finishUpdateProcessWithError( new SimulatedUpdate(device.getTenant(), device.getId(), actionId1), - "Simulation complete with error!"); + device.getUpdateStatus().getStatusMessages()); break; default: break; diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpSenderService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpSenderService.java index 2358bf013..1ced8c2fd 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpSenderService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpSenderService.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.simulator.amqp; +import java.util.List; import java.util.Map; import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings; @@ -23,13 +24,9 @@ import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; /** - * Sender service to send message to SP. - * - * - * + * Sender service to send messages to update server. */ @Service public class SpSenderService extends SenderService { @@ -59,8 +56,9 @@ public class SpSenderService extends SenderService { * @param description * a description according the update process */ - public void finishUpdateProcess(final SimulatedUpdate update, final String description) { - final Message updateResultMessage = createUpdateResultMessage(update, ActionStatus.FINISHED, description); + public void finishUpdateProcess(final SimulatedUpdate update, final List updateResultMessages) { + final Message updateResultMessage = createUpdateResultMessage(update, ActionStatus.FINISHED, + updateResultMessages); sendMessage(spExchange, updateResultMessage); } @@ -72,9 +70,9 @@ public class SpSenderService extends SenderService { * @param messageDescription * a description according the update process */ - public void finishUpdateProcessWithError(final SimulatedUpdate update, final String messageDescription) { - sendErrorgMessage(update, messageDescription); - LOGGER.debug("Update process finished with error \"{}\" reported by thing {}", messageDescription, + public void finishUpdateProcessWithError(final SimulatedUpdate update, final List updateResultMessages) { + sendErrorgMessage(update, updateResultMessages); + LOGGER.debug("Update process finished with error \"{}\" reported by thing {}", updateResultMessages, update.getThingId()); } @@ -88,8 +86,8 @@ public class SpSenderService extends SenderService { * @param actionId * the ID of the action for the error message */ - public void sendErrorMessage(final String tenant, final String messageDescription, final Long actionId) { - final Message message = createActionStatusMessage(tenant, ActionStatus.ERROR, messageDescription, actionId); + public void sendErrorMessage(final String tenant, final List updateResultMessages, final Long actionId) { + final Message message = createActionStatusMessage(tenant, ActionStatus.ERROR, updateResultMessages, actionId); sendMessage(spExchange, message); } @@ -101,8 +99,8 @@ public class SpSenderService extends SenderService { * @param warningMessage * a warning description */ - public void sendWarningMessage(final SimulatedUpdate update, final String warningMessage) { - final Message message = createActionStatusMessage(update, warningMessage, ActionStatus.WARNING); + public void sendWarningMessage(final SimulatedUpdate update, final List updateResultMessages) { + final Message message = createActionStatusMessage(update, updateResultMessages, ActionStatus.WARNING); sendMessage(spExchange, message); } @@ -119,8 +117,8 @@ public class SpSenderService extends SenderService { * the cached value */ public void sendActionStatusMessage(final String tenant, final ActionStatus actionStatus, - final String actionMessage, final Long actionId) { - final Message message = createActionStatusMessage(tenant, actionStatus, actionMessage, actionId); + final List updateResultMessages, final Long actionId) { + final Message message = createActionStatusMessage(tenant, actionStatus, updateResultMessages, actionId); sendMessage(message); } @@ -162,11 +160,11 @@ public class SpSenderService extends SenderService { * * @param context * the current context - * @param messageDescription - * a description according the update process + * @param updateResultMessages + * a list of descriptions according the update process */ - private void sendErrorgMessage(final SimulatedUpdate update, final String messageDescription) { - final Message message = createActionStatusMessage(update, messageDescription, ActionStatus.ERROR); + private void sendErrorgMessage(final SimulatedUpdate update, final List updateResultMessages) { + final Message message = createActionStatusMessage(update, updateResultMessages, ActionStatus.ERROR); sendMessage(spExchange, message); } @@ -183,7 +181,7 @@ public class SpSenderService extends SenderService { * the cacheValue value */ private Message createActionStatusMessage(final String tenant, final ActionStatus actionStatus, - final String actionMessage, final Long actionId) { + final List updateResultMessages, final Long actionId) { final MessageProperties messageProperties = new MessageProperties(); final Map headers = messageProperties.getHeaders(); final ActionUpdateStatus actionUpdateStatus = new ActionUpdateStatus(); @@ -192,15 +190,14 @@ public class SpSenderService extends SenderService { headers.put(MessageHeaderKey.TENANT, tenant); headers.put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name()); headers.put(MessageHeaderKey.CONTENT_TYPE, MessageProperties.CONTENT_TYPE_JSON); - if (!StringUtils.isEmpty(actionMessage)) { - actionUpdateStatus.getMessage().add(actionMessage); - } + actionUpdateStatus.getMessage().addAll(updateResultMessages); + actionUpdateStatus.setActionId(actionId); return convertMessage(actionUpdateStatus, messageProperties); } private Message createUpdateResultMessage(final SimulatedUpdate cacheValue, final ActionStatus actionStatus, - final String updateResultMessage) { + final List updateResultMessages) { final MessageProperties messageProperties = new MessageProperties(); final Map headers = messageProperties.getHeaders(); final ActionUpdateStatus actionUpdateStatus = new ActionUpdateStatus(); @@ -209,14 +206,14 @@ public class SpSenderService extends SenderService { headers.put(MessageHeaderKey.TENANT, cacheValue.getTenant()); headers.put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name()); headers.put(MessageHeaderKey.CONTENT_TYPE, MessageProperties.CONTENT_TYPE_JSON); - actionUpdateStatus.getMessage().add(updateResultMessage); + actionUpdateStatus.getMessage().addAll(updateResultMessages); actionUpdateStatus.setActionId(cacheValue.getActionId()); return convertMessage(actionUpdateStatus, messageProperties); } - private Message createActionStatusMessage(final SimulatedUpdate update, final String messageDescription, + private Message createActionStatusMessage(final SimulatedUpdate update, final List updateResultMessages, final ActionStatus status) { - return createActionStatusMessage(update.getTenant(), status, messageDescription, update.getActionId()); + return createActionStatusMessage(update.getTenant(), status, updateResultMessages, update.getActionId()); } } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/event/ProgressUpdate.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/event/ProgressUpdate.java index 3e34a0fa1..6c18e61ac 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/event/ProgressUpdate.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/event/ProgressUpdate.java @@ -13,8 +13,6 @@ import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice; /** * Event definition object which is published if the simulated device updated * its update progress. - * - * @author Michael Hirsch * */ public class ProgressUpdate { 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 28ad0eaa9..455702501 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 @@ -8,21 +8,19 @@ */ package org.eclipse.hawkbit.simulator.ui; -import java.net.URL; import java.util.List; import java.util.Locale; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; -import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.ResponseStatus; 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.SpSenderService; import org.eclipse.hawkbit.simulator.event.InitUpdate; import org.eclipse.hawkbit.simulator.event.NextPollCounterUpdate; import org.eclipse.hawkbit.simulator.event.ProgressUpdate; -import org.eclipse.hawkbit.simulator.ui.GenerateDialog.GenerateDialogCallback; import org.springframework.beans.factory.annotation.Autowired; import com.google.common.collect.Lists; @@ -52,8 +50,6 @@ import com.vaadin.ui.renderers.ProgressBarRenderer; * Vaadin view which allows to generate devices through the DMF API and show the * current simulated devices in a grid with their current status and update * progress. - * - * @author Michael Hirsch * */ @SpringView(name = "") @@ -153,18 +149,12 @@ public class SimulatorView extends VerticalLayout implements View { @Subscribe public void pollCounterUpdate(final NextPollCounterUpdate update) { final List devices = update.getDevices(); - this.getUI().access(new Runnable() { - - @Override - public void run() { - devices.forEach(device -> { - final BeanItem item = beanContainer.getItem(device.getId()); - if (item != null) { - item.getItemProperty("nextPollCounterSec").setValue(device.getNextPollCounterSec()); - } - }); + this.getUI().access(() -> devices.forEach(device -> { + final BeanItem item = beanContainer.getItem(device.getId()); + if (item != null) { + item.getItemProperty("nextPollCounterSec").setValue(device.getNextPollCounterSec()); } - }); + })); } /** @@ -176,18 +166,14 @@ public class SimulatorView extends VerticalLayout implements View { @Subscribe public void initUpdate(final InitUpdate update) { final AbstractSimulatedDevice device = update.getDevice(); - this.getUI().access(new Runnable() { - - @Override - public void run() { - final BeanItem item = beanContainer.getItem(device.getId()); - if (item != null) { - item.getItemProperty("progress").setValue(device.getProgress()); - item.getItemProperty("status").setValue(Status.PEDNING); - item.getItemProperty("swversion").setValue(device.getSwversion()); - } - + this.getUI().access(() -> { + final BeanItem item = beanContainer.getItem(device.getId()); + if (item != null) { + item.getItemProperty("progress").setValue(device.getProgress()); + item.getItemProperty("status").setValue(Status.PEDNING); + item.getItemProperty("swversion").setValue(device.getSwversion()); } + }); } @@ -200,29 +186,26 @@ public class SimulatorView extends VerticalLayout implements View { @Subscribe public void progessUpdate(final ProgressUpdate update) { final AbstractSimulatedDevice device = update.getDevice(); - this.getUI().access(new Runnable() { - @Override - public void run() { - final BeanItem item = beanContainer.getItem(device.getId()); - if (item != null) { - item.getItemProperty("progress").setValue(device.getProgress()); - if (device.getProgress() >= 1) { - switch (device.getResponseStatus()) { - case SUCCESSFUL: - item.getItemProperty("status").setValue(Status.FINISH); - break; - case ERROR: - item.getItemProperty("status").setValue(Status.ERROR); - break; - default: - item.getItemProperty("status").setValue(Status.UNKNWON); - } - } else { - item.getItemProperty("status").setValue(Status.PEDNING); + this.getUI().access(() -> { + final BeanItem item = beanContainer.getItem(device.getId()); + if (item != null) { + item.getItemProperty("progress").setValue(device.getProgress()); + if (device.getProgress() >= 1) { + switch (device.getUpdateStatus().getResponseStatus()) { + case SUCCESSFUL: + item.getItemProperty("status").setValue(Status.FINISH); + break; + case ERROR: + item.getItemProperty("status").setValue(Status.ERROR); + break; + default: + item.getItemProperty("status").setValue(Status.UNKNWON); } + } else { + item.getItemProperty("status").setValue(Status.PEDNING); } - } + }); } @@ -246,18 +229,15 @@ public class SimulatorView extends VerticalLayout implements View { } private void openGenerateDialog() { - UI.getCurrent().addWindow(new GenerateDialog(new GenerateDialogCallback() { - @Override - public void okButton(final String namePrefix, final String tenant, final int amount, final int pollDelay, - final URL basePollUrl, final String gatewayToken, final Protocol protocol) { - for (int index = 0; index < amount; index++) { - final String deviceId = namePrefix + index; - beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId, - tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken))); - spSenderService.createOrUpdateThing(tenant, deviceId); - } - } - })); + UI.getCurrent().addWindow( + new GenerateDialog((namePrefix, tenant, amount, pollDelay, basePollUrl, gatewayToken, protocol) -> { + for (int index = 0; index < amount; index++) { + final String deviceId = namePrefix + index; + beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId, + tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken))); + spSenderService.createOrUpdateThing(tenant, deviceId); + } + })); } private Converter createProtocolConverter() { From 16350c5e15395960f884081e70db4e94c8400920 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 3 May 2016 18:34:16 +0200 Subject: [PATCH 22/47] Made URL generator configurable. Signed-off-by: Kai Zimmermann --- .../simulator/DeviceSimulatorUpdater.java | 1 + .../application-cloudsandbox.properties | 4 ++ .../src/main/resources/application.properties | 15 ++++-- .../hawkbit/api/ArtifactUrlHandler.java | 8 +++- .../api/ArtifactUrlHandlerProperties.java | 48 +++++++++++++++++++ .../api/PropertyBasedArtifactUrlHandler.java | 11 +++++ .../amqp/AmqpMessageDispatcherService.java | 28 +++++++---- .../hawkbit/dmf/json/model/ArtifactHash.java | 4 -- .../eclipse/hawkbit/TestConfiguration.java | 2 +- .../controller/DataConversionHelper.java | 38 ++++++++------- 10 files changed, 122 insertions(+), 37 deletions(-) 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 12ff7dbd2..3d33b61f8 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 @@ -183,6 +183,7 @@ public class DeviceSimulatorUpdater { final Artifact artifact) { artifact.getUrls().entrySet().forEach(entry -> { switch (entry.getKey()) { + case HTTP: case HTTPS: status.add(downloadUrl(entry.getValue(), targetToken, artifact.getHashes().getSha1())); break; diff --git a/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties b/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties index ecf71da41..b740c2959 100644 --- a/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties +++ b/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties @@ -8,3 +8,7 @@ # vaadin.servlet.productionMode=true + +hawkbit.artifact.url.coap.enabled=false +hawkbit.artifact.url.http.enabled=false +hawkbit.artifact.url.https.enabled=true diff --git a/examples/hawkbit-example-app/src/main/resources/application.properties b/examples/hawkbit-example-app/src/main/resources/application.properties index 64661d2ec..6e05b6b5a 100644 --- a/examples/hawkbit-example-app/src/main/resources/application.properties +++ b/examples/hawkbit-example-app/src/main/resources/application.properties @@ -7,15 +7,22 @@ # http://www.eclipse.org/legal/epl-v10.html # +# DDI authentication configuration hawkbit.server.ddi.security.authentication.anonymous.enabled=true -hawkbit.server.ddi.security.authentication.targettoken.enabled=false -hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false +hawkbit.server.ddi.security.authentication.targettoken.enabled=true +hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=true -spring.profiles.active=amqp +# Download URL generation config +hawkbit.artifact.url.coap.enabled=false +hawkbit.artifact.url.http.enabled=true +hawkbit.artifact.url.http.port=8080 +hawkbit.artifact.url.https.enabled=false +## Vaadin configuration vaadin.servlet.productionMode=false -## Configuration for RabbitMQ integration +## Configuration for DMF/RabbitMQ integration +spring.profiles.active=amqp spring.rabbitmq.username=guest spring.rabbitmq.password=guest spring.rabbitmq.virtualHost=/ diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandler.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandler.java index 522444961..03492122c 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandler.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandler.java @@ -13,7 +13,6 @@ package org.eclipse.hawkbit.api; * URLs to specific artifacts. * */ -@FunctionalInterface public interface ArtifactUrlHandler { /** @@ -34,4 +33,11 @@ public interface ArtifactUrlHandler { */ String getUrl(String controllerId, final Long softwareModuleId, final String filename, final String sha1Hash, final UrlProtocol protocol); + + /** + * @param protocol + * to check support for + * @return true of the handler supports given protocol. + */ + boolean protocolSupported(UrlProtocol protocol); } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java index 33fe8651e..50f3f4cad 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java @@ -78,6 +78,12 @@ public class ArtifactUrlHandlerProperties { * @return the pattern to build the URL. */ String getPattern(); + + /** + * @return true if the {@link ProtocolProperties} is + * enabled. + */ + boolean isEnabled(); } /** @@ -93,6 +99,20 @@ public class ArtifactUrlHandlerProperties { */ private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}"; + /** + * Enables HTTP URI generation in DDI and DMF. + */ + private boolean enabled = true; + + @Override + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } + @Override public String getHostname() { return hostname; @@ -143,6 +163,20 @@ public class ArtifactUrlHandlerProperties { */ private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}"; + /** + * Enables HTTPS URI generation in DDI and DMF. + */ + private boolean enabled = true; + + @Override + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } + @Override public String getHostname() { return hostname; @@ -193,6 +227,20 @@ public class ArtifactUrlHandlerProperties { */ private String pattern = "{protocol}://{ip}:{port}/fw/{tenant}/{targetId}/sha1/{artifactSHA1}"; + /** + * Enables CoAP URI generation in DMF. + */ + private boolean enabled = true; + + @Override + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } + @Override public String getHostname() { return hostname; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java index 174086613..0072f2fbd 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java @@ -84,4 +84,15 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler { return replaceMap; } + @Override + public boolean protocolSupported(final UrlProtocol protocol) { + final String protocolString = protocol.name().toLowerCase(); + final ProtocolProperties properties = urlHandlerProperties.getProperties(protocolString); + if (properties == null || properties.getPattern() == null) { + return false; + } + + return properties.isEnabled(); + } + } diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java index 32bcb02a5..dae5772e6 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java @@ -155,18 +155,26 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { private Artifact convertArtifact(final String targetId, final LocalArtifact localArtifact) { final Artifact artifact = new Artifact(); - artifact.getUrls().put(Artifact.UrlProtocol.COAP, - artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(), - localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.COAP)); - artifact.getUrls().put(Artifact.UrlProtocol.HTTP, - artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(), - localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTP)); - artifact.getUrls().put(Artifact.UrlProtocol.HTTPS, - artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(), - localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTPS)); + if (artifactUrlHandler.protocolSupported(UrlProtocol.COAP)) { + artifact.getUrls().put(Artifact.UrlProtocol.COAP, + artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(), + localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.COAP)); + } + + if (artifactUrlHandler.protocolSupported(UrlProtocol.HTTP)) { + artifact.getUrls().put(Artifact.UrlProtocol.HTTP, + artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(), + localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTP)); + } + + if (artifactUrlHandler.protocolSupported(UrlProtocol.HTTPS)) { + artifact.getUrls().put(Artifact.UrlProtocol.HTTPS, + artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(), + localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTPS)); + } artifact.setFilename(localArtifact.getFilename()); - artifact.setHashes(new ArtifactHash(localArtifact.getSha1Hash(), null)); + artifact.setHashes(new ArtifactHash(localArtifact.getSha1Hash(), localArtifact.getMd5Hash())); artifact.setSize(localArtifact.getSize()); return artifact; } diff --git a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/ArtifactHash.java b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/ArtifactHash.java index 5ddb48e4f..6f86fe4a4 100644 --- a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/ArtifactHash.java +++ b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/ArtifactHash.java @@ -13,10 +13,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** * JSON representation of artifact hash. - * - * - * - * */ public class ArtifactHash { diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java index 70372fac2..d96856557 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java @@ -79,7 +79,7 @@ public class TestConfiguration implements AsyncConfigurer { } /** - * Bean for the downlod id cache. + * Bean for the download id cache. * * @return the cache */ diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/DataConversionHelper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/DataConversionHelper.java index e035c47ee..15c2592df 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/DataConversionHelper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/DataConversionHelper.java @@ -31,7 +31,6 @@ import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactHash; import org.eclipse.hawkbit.tenancy.TenantAware; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.hateoas.Link; import com.google.common.base.Charsets; @@ -40,10 +39,6 @@ import com.google.common.base.Charsets; * Utility class for the Controller API. */ public final class DataConversionHelper { - - @Autowired - ArtifactUrlHandler artifactUrlHandler; - // utility class, private constructor. private DataConversionHelper() { @@ -55,7 +50,6 @@ public final class DataConversionHelper { .map(module -> new Chunk(mapChunkLegacyKeys(module.getType().getKey()), module.getVersion(), module.getName(), createArtifacts(targetid, module, artifactUrlHandler))) .collect(Collectors.toList()); - } private static String mapChunkLegacyKeys(final String key) { @@ -76,29 +70,39 @@ public final class DataConversionHelper { * of the target * @param module * the software module + * * @return a list of artifacts or a empty list. Cannot be . */ public static List createArtifacts(final String targetid, final org.eclipse.hawkbit.repository.model.SoftwareModule module, final ArtifactUrlHandler artifactUrlHandler) { final List files = new ArrayList<>(); - module.getLocalArtifacts().forEach(artifact -> { - final Artifact file = new Artifact(); - file.setHashes(new ArtifactHash(artifact.getSha1Hash(), artifact.getMd5Hash())); - file.setFilename(artifact.getFilename()); - file.setSize(artifact.getSize()); + module.getLocalArtifacts() + .forEach(artifact -> files.add(createArtifact(targetid, artifactUrlHandler, artifact))); + return files; + } + + private static Artifact createArtifact(final String targetid, final ArtifactUrlHandler artifactUrlHandler, + final LocalArtifact artifact) { + final Artifact file = new Artifact(); + file.setHashes(new ArtifactHash(artifact.getSha1Hash(), artifact.getMd5Hash())); + file.setFilename(artifact.getFilename()); + file.setSize(artifact.getSize()); + + if (artifactUrlHandler.protocolSupported(UrlProtocol.HTTP)) { final String linkHttp = artifactUrlHandler.getUrl(targetid, artifact.getSoftwareModule().getId(), artifact.getFilename(), artifact.getSha1Hash(), UrlProtocol.HTTP); + file.add(new Link(linkHttp).withRel("download-http")); + file.add(new Link(linkHttp + ControllerConstants.ARTIFACT_MD5_DWNL_SUFFIX).withRel("md5sum-http")); + } + + if (artifactUrlHandler.protocolSupported(UrlProtocol.HTTPS)) { final String linkHttps = artifactUrlHandler.getUrl(targetid, artifact.getSoftwareModule().getId(), artifact.getFilename(), artifact.getSha1Hash(), UrlProtocol.HTTPS); file.add(new Link(linkHttps).withRel("download")); file.add(new Link(linkHttps + ControllerConstants.ARTIFACT_MD5_DWNL_SUFFIX).withRel("md5sum")); - file.add(new Link(linkHttp).withRel("download-http")); - file.add(new Link(linkHttp + ControllerConstants.ARTIFACT_MD5_DWNL_SUFFIX).withRel("md5sum-http")); - - files.add(file); - }); - return files; + } + return file; } static ControllerBase fromTarget(final Target target, final List actions, From ffece302de197fa587a0932e1e35169c5433da26 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 4 May 2016 08:28:11 +0200 Subject: [PATCH 23/47] https config for cloud. Signed-off-by: Kai Zimmermann --- .../src/main/resources/application-cloudsandbox.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties b/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties index b740c2959..a0cad4e9b 100644 --- a/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties +++ b/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties @@ -12,3 +12,5 @@ vaadin.servlet.productionMode=true hawkbit.artifact.url.coap.enabled=false hawkbit.artifact.url.http.enabled=false hawkbit.artifact.url.https.enabled=true +hawkbit.artifact.url.https.pattern={protocol}://{hostname}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName} +hawkbit.artifact.url.https.hostname=hawkbit.eu-gb.mybluemix.net \ No newline at end of file From 882c689a51c13e032676a1912fe97fa9e707f919 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 4 May 2016 12:13:26 +0200 Subject: [PATCH 24/47] Migrated sonar false positives from qube into code. Signed-off-by: Kai Zimmermann --- .../java/org/eclipse/hawkbit/app/Start.java | 5 ++++- .../hawkbit/simulator/DeviceSimulator.java | 4 ++-- .../simulator/amqp/SpReceiverService.java | 2 ++ .../java/org/eclipse/hawkbit/app/Start.java | 4 ++++ .../builder/DistributionSetBuilder.java | 3 ++- .../builder/DistributionSetTypeBuilder.java | 3 ++- .../resource/builder/RolloutBuilder.java | 2 ++ .../builder/SoftwareModuleBuilder.java | 2 ++ .../builder/SoftwareModuleTypeBuilder.java | 2 ++ .../client/resource/builder/TagBuilder.java | 2 ++ .../resource/builder/TargetBuilder.java | 2 ++ .../repository/MongoConfiguration.java | 2 ++ ...istributedResourceBundleMessageSource.java | 5 ++--- ...ConfigurationPollingDurationValidator.java | 2 ++ .../ExceptionMappingAspectHandler.java | 2 ++ .../eventbus/EntityChangeEventListener.java | 9 ++++++-- ...ansactionCommitDefaultServiceExecutor.java | 3 +++ .../repository/DeploymentManagement.java | 3 +++ .../hawkbit/repository/SystemManagement.java | 2 ++ .../hawkbit/repository/rsql/RSQLUtility.java | 14 +++++++----- ...TenantUserPasswordAuthenticationToken.java | 6 ++--- .../org/eclipse/hawkbit/ui/UiProperties.java | 4 ++++ .../ui/artifacts/upload/UploadHandler.java | 22 ++----------------- .../FilterQueryValidation.java | 6 ++--- ...eateUpdateDistributionTagLayoutWindow.java | 10 +++++---- .../dstag/DistributionTagButtons.java | 6 +++++ .../CreateUpdateTargetTagLayout.java | 6 +++++ .../targettag/TargetTagFilterButtons.java | 6 +++++ 28 files changed, 93 insertions(+), 46 deletions(-) diff --git a/examples/hawkbit-custom-theme-example/src/main/java/org/eclipse/hawkbit/app/Start.java b/examples/hawkbit-custom-theme-example/src/main/java/org/eclipse/hawkbit/app/Start.java index 1c4c5d32d..abf2740fa 100644 --- a/examples/hawkbit-custom-theme-example/src/main/java/org/eclipse/hawkbit/app/Start.java +++ b/examples/hawkbit-custom-theme-example/src/main/java/org/eclipse/hawkbit/app/Start.java @@ -22,14 +22,17 @@ import org.springframework.context.annotation.Import; @SpringBootApplication @Import({ RepositoryApplicationConfiguration.class }) @EnableHawkbitManagedSecurityConfiguration +// Exception squid:S1118 - Spring boot standard behavior +@SuppressWarnings({ "squid:S1118" }) public class Start { - /** * Main method to start the spring-boot application. * * @param args * the VM arguments. */ + // Exception squid:S2095 - Spring boot standard behavior + @SuppressWarnings({ "squid:S2095" }) public static void main(final String[] args) { SpringApplication.run(Start.class, args); } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulator.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulator.java index 944ba1d07..370d6af62 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulator.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulator.java @@ -21,8 +21,6 @@ import com.vaadin.spring.annotation.EnableVaadin; /** * The main-method to start the Spring-Boot application. * - * - * */ @SpringBootApplication @EnableVaadin @@ -46,6 +44,8 @@ public class DeviceSimulator { * @param args * the args */ + // Exception squid:S2095 - Spring boot standard behavior + @SuppressWarnings({ "squid:S2095" }) public static void main(final String[] args) { SpringApplication.run(DeviceSimulator.class, args); } 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 f22839422..b85a51b4b 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 @@ -88,6 +88,8 @@ public class SpReceiverService extends ReceiverService { if (eventHeader == null) { logAndThrowMessageError(message, "Event Topic is not set"); } + // Exception squid:S2259 - Checked before + @SuppressWarnings({ "squid:S2259" }) final EventTopic eventTopic = EventTopic.valueOf(eventHeader.toString()); switch (eventTopic) { case DOWNLOAD_AND_INSTALL: diff --git a/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/Start.java b/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/Start.java index a517dbb08..b08ae50d8 100644 --- a/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/Start.java +++ b/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/Start.java @@ -26,6 +26,8 @@ import org.springframework.context.annotation.Import; @EnableHawkbitManagedSecurityConfiguration @EnableRestResources @EnableDirectDeviceApi +// Exception squid:S1118 - Spring boot standard behavior +@SuppressWarnings({ "squid:S1118" }) public class Start { /** @@ -34,6 +36,8 @@ public class Start { * @param args * the VM arguments. */ + // Exception squid:S2095 - Spring boot standard behavior + @SuppressWarnings({ "squid:S2095" }) public static void main(final String[] args) { SpringApplication.run(Start.class, args); } diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java index 358cff0db..01acdac72 100644 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java @@ -18,8 +18,9 @@ import com.google.common.collect.Lists; /** * Builder pattern for building {@link DistributionSetRequestBodyPost}. */ +// Exception squid:S1701 - builder pattern +@SuppressWarnings({ "squid:S1701" }) public class DistributionSetBuilder { - private String name; private String version; private String type; diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java index 752834c7d..ff03bb442 100644 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java @@ -21,8 +21,9 @@ import com.google.common.collect.Lists; * Builder pattern for building {@link DistributionSetTypeRequestBodyPost}. * */ +// Exception squid:S1701 - builder pattern +@SuppressWarnings({ "squid:S1701" }) public class DistributionSetTypeBuilder { - private String key; private String name; private final List mandatorymodules = Lists.newArrayList(); diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java index 2e01e0ba2..e9203fc39 100644 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java @@ -17,6 +17,8 @@ import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutRestRequestBody; * Builder pattern for building {@link RolloutRestRequestBody}. * */ +// Exception squid:S1701 - builder pattern +@SuppressWarnings({ "squid:S1701" }) public class RolloutBuilder { private String name; diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java index 4bbfd92b4..169a159d0 100644 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java @@ -21,6 +21,8 @@ import com.google.common.collect.Lists; * Builder pattern for building {@link SoftwareModuleRequestBodyPost}. * */ +// Exception squid:S1701 - builder pattern +@SuppressWarnings({ "squid:S1701" }) public class SoftwareModuleBuilder { private String name; diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java index a6472f0a0..e27cedc72 100644 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java @@ -21,6 +21,8 @@ import com.google.common.collect.Lists; * Builder pattern for building {@link SoftwareModuleRequestBodyPost}. * */ +// Exception squid:S1701 - builder pattern +@SuppressWarnings({ "squid:S1701" }) public class SoftwareModuleTypeBuilder { private String key; diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java index 6f2eb3248..32f7c1107 100644 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java @@ -19,6 +19,8 @@ import com.google.common.collect.Lists; * Builder pattern for building {@link TagRequestBodyPut}. * */ +// Exception squid:S1701 - builder pattern +@SuppressWarnings({ "squid:S1701" }) public class TagBuilder { private String name; diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java index e496407e1..aba1188dc 100644 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java @@ -21,6 +21,8 @@ import com.google.common.collect.Lists; * Builder pattern for building {@link TargetRequestBody}. * */ +// Exception squid:S1701 - builder pattern +@SuppressWarnings({ "squid:S1701" }) public class TargetBuilder { private String controllerId; diff --git a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/MongoConfiguration.java b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/MongoConfiguration.java index 02fb22725..e01c6a455 100644 --- a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/MongoConfiguration.java +++ b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/MongoConfiguration.java @@ -71,6 +71,8 @@ public class MongoConfiguration extends AbstractMongoConfiguration { @Override @Bean @ConditionalOnMissingBean + // Closed by pre-destroy + @SuppressWarnings({ "squid:S2095" }) public Mongo mongo() throws UnknownHostException { final MongoClientURI uri = new MongoClientURI(properties.getUri(), createBuilderOutOfOptions(options)); diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/DistributedResourceBundleMessageSource.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/DistributedResourceBundleMessageSource.java index 0b0847652..859bf28d6 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/DistributedResourceBundleMessageSource.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/DistributedResourceBundleMessageSource.java @@ -22,11 +22,10 @@ import org.springframework.core.io.support.ResourcePatternResolver; * This resource bundles using specified basenames, to resource loading. This * MessageSource implementation supports more than 1 properties file with the * same name. All properties files will be merged. - * - * - * */ public class DistributedResourceBundleMessageSource extends ReloadableResourceBundleMessageSource { + // Follows our upper case convention + @SuppressWarnings({ "squid:S2387" }) private static final Logger LOGGER = LoggerFactory.getLogger(DistributedResourceBundleMessageSource.class); private static final String PROPERTIES_SUFFIX = ".properties"; private ResourceLoader resourceLoader; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java index 11c9666e8..376ba8877 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java @@ -39,6 +39,8 @@ public class TenantConfigurationPollingDurationValidator implements TenantConfig } @Override + // Exception squid:S1166 - Hide origin exception + @SuppressWarnings({ "squid:S1166" }) public void validate(final Object tenantConfigurationObject) { TenantConfigurationValidator.super.validate(tenantConfigurationObject); final String tenantConfigurationString = (String) tenantConfigurationObject; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/aspects/ExceptionMappingAspectHandler.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/aspects/ExceptionMappingAspectHandler.java index 3824ae80f..c3da509aa 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/aspects/ExceptionMappingAspectHandler.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/aspects/ExceptionMappingAspectHandler.java @@ -90,6 +90,8 @@ 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" }) public void catchAndWrapJpaExceptionsService(final Exception ex) throws Throwable { LOG.trace("exception occured", ex); Exception translatedAccessException = translateEclipseLinkExceptionIfPossible(ex); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/EntityChangeEventListener.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/EntityChangeEventListener.java index 0a19d2edb..7bfbd957e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/EntityChangeEventListener.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/EntityChangeEventListener.java @@ -20,9 +20,9 @@ import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor; import org.eclipse.hawkbit.repository.TargetRepository; -import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; 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; @@ -67,6 +67,8 @@ public class EntityChangeEventListener { * {@link ProceedingJoinPoint#proceed()} */ @Around("execution(* org.eclipse.hawkbit.repository.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(); @@ -92,6 +94,8 @@ public class EntityChangeEventListener { * {@link ProceedingJoinPoint#proceed()} */ @Around("execution(* org.eclipse.hawkbit.repository.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(); @@ -111,8 +115,9 @@ public class EntityChangeEventListener { * in case exception happens in the * {@link ProceedingJoinPoint#proceed()} */ - @SuppressWarnings("unchecked") @Around("execution(* org.eclipse.hawkbit.repository.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(); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/executor/AfterTransactionCommitDefaultServiceExecutor.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/executor/AfterTransactionCommitDefaultServiceExecutor.java index 38ad38345..0d65b291e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/executor/AfterTransactionCommitDefaultServiceExecutor.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/executor/AfterTransactionCommitDefaultServiceExecutor.java @@ -29,6 +29,8 @@ public class AfterTransactionCommitDefaultServiceExecutor extends TransactionSyn private static final ThreadLocal> THREAD_LOCAL_RUNNABLES = new ThreadLocal<>(); @Override + // Exception squid:S1217 - Is aspectJ proxy + @SuppressWarnings({ "squid:S1217" }) public void afterCommit() { final List afterCommitRunnables = THREAD_LOCAL_RUNNABLES.get(); LOGGER.debug("Transaction successfully committed, executing {} runnables", afterCommitRunnables.size()); @@ -60,6 +62,7 @@ public class AfterTransactionCommitDefaultServiceExecutor extends TransactionSyn } @Override + @SuppressWarnings({ "squid:S1217" }) public void afterCompletion(final int status) { final String transactionStatus = status == STATUS_COMMITTED ? "COMMITTED" : "ROLLEDBACK"; LOGGER.debug("Transaction completed after commit with status {}", transactionStatus); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index 77f71bebf..350a8f89a 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -198,6 +198,9 @@ public class DeploymentManagement { @Transactional @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true) + // Exception squid:S2095: see + // https://jira.sonarsource.com/browse/SONARJAVA-1478 + @SuppressWarnings({ "squid:S2095" }) public DistributionSetAssignmentResult assignDistributionSet(@NotNull final Long dsID, final ActionType actionType, final long forcedTimestamp, @NotEmpty final String... targetIDs) { return assignDistributionSet(dsID, Arrays.stream(targetIDs) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index be370cf2d..4a3206859 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -341,6 +341,8 @@ public class SystemManagement { */ private class CurrentTenantKeyGenerator implements KeyGenerator { @Override + // Exception squid:S923 - override + @SuppressWarnings({ "squid:S923" }) public Object generate(final Object target, final Method method, final Object... params) { final String initialTenantCreation = createInitialTenant.get(); if (initialTenantCreation == null) { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/rsql/RSQLUtility.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/rsql/RSQLUtility.java index c2ed5f900..4edc46623 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/rsql/RSQLUtility.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/rsql/RSQLUtility.java @@ -66,10 +66,6 @@ import cz.jirutka.rsql.parser.ast.RSQLVisitor; *
  • name==targetId1,description==plugAndPlay,updateStatus==UNKNOWN
  • *
  • name==targetId1 or description==plugAndPlay or updateStatus==UNKNOWN
  • * - * - * - * - * */ public final class RSQLUtility { @@ -279,6 +275,9 @@ public final class RSQLUtility { } @Override + // Exception squid:S2095 - see + // https://jira.sonarsource.com/browse/SONARJAVA-1478 + @SuppressWarnings({ "squid:S2095" }) public List visit(final ComparisonNode node, final String param) { A fieldName = null; try { @@ -304,6 +303,9 @@ public final class RSQLUtility { return mapToPredicate(node, fieldPath, node.getArguments(), transformedValue, fieldName); } + // Exception squid:S2095 - see + // https://jira.sonarsource.com/browse/SONARJAVA-1478 + @SuppressWarnings({ "squid:S2095" }) private List getExpectedFieldList() { final List expectedFieldList = Arrays.stream(enumType.getEnumConstants()) .filter(enumField -> enumField.getSubEntityAttributes().isEmpty()).map(enumField -> { @@ -390,7 +392,9 @@ public final class RSQLUtility { } } - @SuppressWarnings({ "rawtypes", "unchecked" }) + // Exception squid:S2095 - see + // https://jira.sonarsource.com/browse/SONARJAVA-1478 + @SuppressWarnings({ "rawtypes", "unchecked", "squid:S2095" }) private Object transformEnumValue(final ComparisonNode node, final String value, final Class javaType) { final Class tmpEnumType = (Class) javaType; diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/TenantUserPasswordAuthenticationToken.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/TenantUserPasswordAuthenticationToken.java index 3bacfac6f..77beaa698 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/TenantUserPasswordAuthenticationToken.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/TenantUserPasswordAuthenticationToken.java @@ -19,12 +19,10 @@ import org.springframework.security.core.GrantedAuthority; * */ public class TenantUserPasswordAuthenticationToken extends UsernamePasswordAuthenticationToken { - - /** - * - */ private static final long serialVersionUID = 1L; + // Exception squid:S1948 - no need to be Serializable + @SuppressWarnings({ "squid:S1948" }) final Object tenant; /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java index da4e2d50e..cc880fca8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java @@ -37,6 +37,8 @@ public class UiProperties { /** * Demo user password. */ + // Exception squid:S2068 - Empty password + @SuppressWarnings({ "squid:S2068" }) private String password = ""; public String getPassword() { @@ -64,6 +66,7 @@ public class UiProperties { } } + /** * Links to potentially other systems (e.g. support, user management, * documentation etc.). @@ -227,6 +230,7 @@ public class UiProperties { } } + /** * Configuration of login view. * diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java index 8c1feeb33..77207bd50 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java @@ -37,20 +37,12 @@ import com.vaadin.ui.Upload.SucceededListener; * {@link StreamVariable} upload variants. * * The handler manages the output to the user and at the same time ensures that - * the upload does not exceed the configued max file size. - * - * - * - * - * + * the upload does not exceed the configured max file size. * */ public class UploadHandler implements StreamVariable, Receiver, SucceededListener, FailedListener, FinishedListener, ProgressListener, StartedListener { - /** - * - */ private static final long serialVersionUID = 1L; private static final Logger LOG = LoggerFactory.getLogger(UploadHandler.class); @@ -108,7 +100,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene public OutputStream receiveUpload(final String fileName, final String mimeType) { this.fileName = fileName; this.mimeType = mimeType; - //reset has directory flag before upload + // reset has directory flag before upload view.setHasDirectory(false); try { if (view.checkIfSoftwareModuleIsSelected()) { @@ -343,11 +335,6 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene } } - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ @Override public int hashCode() { final int prime = 31; @@ -356,11 +343,6 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene return result; } - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ @Override public boolean equals(final Object obj) { if (this == obj) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterQueryValidation.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterQueryValidation.java index d3ec6245d..4f528c74a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterQueryValidation.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterQueryValidation.java @@ -31,10 +31,7 @@ import cz.jirutka.rsql.parser.RSQLParserException; * * Validates the target filter query. * - * - * */ - public final class FilterQueryValidation { private static final Logger LOGGER = LoggerFactory.getLogger(FilterQueryValidation.class); @@ -103,6 +100,9 @@ public final class FilterQueryValidation { * @param expectedTokens * @return */ + // Exception squid:S2095 - see + // https://jira.sonarsource.com/browse/SONARJAVA-1478 + @SuppressWarnings({ "squid:S2095" }) public static List processExpectedTokens(final List expectedTokens) { final List expectToken = new ArrayList<>(); if (expectedTokens.size() == 2 && expectedTokens.contains(9) && expectedTokens.contains(4)) { 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 210509623..4d63753fe 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 @@ -43,10 +43,6 @@ import com.vaadin.ui.themes.ValoTheme; @SpringComponent @VaadinSessionScope public class CreateUpdateDistributionTagLayoutWindow extends CreateUpdateTagLayout { - - /** - * - */ private static final long serialVersionUID = 444276149954167545L; @Autowired @@ -288,16 +284,22 @@ public class CreateUpdateDistributionTagLayoutWindow extends CreateUpdateTagLayo } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedBulkEvent event) { populateTagNameCombo(); } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEvent event) { populateTagNameCombo(); } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdateEvent event) { populateTagNameCombo(); } 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 57091b660..934d9c4c7 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 @@ -61,16 +61,22 @@ public class DistributionTagButtons extends AbstractFilterButtons { } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedBulkEvent event) { refreshTagTable(); } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEvent event) { refreshTagTable(); } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdateEvent event) { refreshTagTable(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java index 51ac77f10..e6e428ce3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java @@ -85,16 +85,22 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout { } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onEventTargetTagCreated(final TargetTagCreatedBulkEvent event) { populateTagNameCombo(); } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onEventTargetDeletedEvent(final TargetTagDeletedEvent event) { populateTagNameCombo(); } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onEventTargetTagUpdateEvent(final TargetTagUpdateEvent event) { populateTagNameCombo(); } 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 4e5246703..48447f112 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 @@ -267,16 +267,22 @@ public class TargetTagFilterButtons extends AbstractFilterButtons { } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onEvent(final TargetTagUpdateEvent event) { refreshContainer(); } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onEventTargetTagCreated(final TargetTagCreatedBulkEvent event) { refreshContainer(); } @EventBusListenerMethod(scope = EventScope.SESSION) + // Exception squid:S1172 - event not needed + @SuppressWarnings({ "squid:S1172" }) void onEventTargetDeletedEvent(final TargetTagDeletedEvent event) { refreshContainer(); } From d30eef7e6d4f9d4fb227851f7f04f274449b2b1b Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 4 May 2016 12:18:29 +0200 Subject: [PATCH 25/47] Sonar false positive added for hidden exception. Signed-off-by: Kai Zimmermann --- .../org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java index d4a733de3..8fb5a8b42 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/UserDetailsFormatter.java @@ -170,6 +170,8 @@ public final class UserDetailsFormatter { return trimmedDetail; } + // Exception squid:S1166 - exception has to be hidden + @SuppressWarnings({ "squid:S1166" }) private static UserDetails loadUserByUsername(final String username) { final UserDetailsService userDetailsService = SpringContextHelper.getBean(UserDetailsService.class); try { From 6df949bf2b050f0fc115e3c9cde1c87b99afedcf Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 4 May 2016 12:22:19 +0200 Subject: [PATCH 26/47] Set sw version also if modules empty. Signed-off-by: Kai Zimmermann --- .../org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3d33b61f8..43474b9a9 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 @@ -100,7 +100,7 @@ public class DeviceSimulatorUpdater { device.setProgress(0.0); - if (modules == null) { + if (modules == null || modules.isEmpty()) { device.setSwversion(swVersion); } else { device.setSwversion(modules.stream().map(sm -> sm.getModuleVersion()).collect(Collectors.joining(", "))); From 0014dc6302b00aae52f3abbe23d806ee648af10a Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 4 May 2016 12:22:49 +0200 Subject: [PATCH 27/47] Removed accidental addition of scala dependency. Signed-off-by: Kai Zimmermann --- examples/hawkbit-device-simulator/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/hawkbit-device-simulator/pom.xml b/examples/hawkbit-device-simulator/pom.xml index 33d165584..728fe0595 100644 --- a/examples/hawkbit-device-simulator/pom.xml +++ b/examples/hawkbit-device-simulator/pom.xml @@ -133,11 +133,6 @@ spring-boot-configuration-processor true - - org.scala-lang - scala-library - 2.10.4 - org.apache.httpcomponents httpclient From ebe24394d039cb07468f43d724b5f7b3b32e48b8 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 4 May 2016 12:24:23 +0200 Subject: [PATCH 28/47] Fixed comment --- .../eclipse/hawkbit/DistributedResourceBundleMessageSource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/DistributedResourceBundleMessageSource.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/DistributedResourceBundleMessageSource.java index 859bf28d6..0f5301c40 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/DistributedResourceBundleMessageSource.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/DistributedResourceBundleMessageSource.java @@ -24,7 +24,7 @@ import org.springframework.core.io.support.ResourcePatternResolver; * same name. All properties files will be merged. */ public class DistributedResourceBundleMessageSource extends ReloadableResourceBundleMessageSource { - // Follows our upper case convention + // Exception squid:S2387 - Follows our upper case convention @SuppressWarnings({ "squid:S2387" }) private static final Logger LOGGER = LoggerFactory.getLogger(DistributedResourceBundleMessageSource.class); private static final String PROPERTIES_SUFFIX = ".properties"; From c73e4a94a07a06060d13c2fce232b0adebbc880c Mon Sep 17 00:00:00 2001 From: Dennis Melzer Date: Wed, 4 May 2016 15:49:35 +0200 Subject: [PATCH 29/47] Update DashboardMenu.java float values - capital F Signed-off-by: SirWayne --- .../main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9d2c0d246..3cc0b6be5 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 @@ -115,7 +115,7 @@ public final class DashboardMenu extends CustomComponent { final VerticalLayout links = buildLinksAndVersion(); menus.addComponent(links); menus.setComponentAlignment(links, Alignment.BOTTOM_CENTER); - menus.setExpandRatio(links, 1.0f); + menus.setExpandRatio(links, 1.0F); menuContent.addComponent(menus); menuContent.setExpandRatio(menus, 1.0F); From 55c59824fc4d4a150ed6f875548c2c19f79b1bbe Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 4 May 2016 15:58:53 +0200 Subject: [PATCH 30/47] Correct a typo Signed-off-by: Melanie Retter --- .../ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 ecc0ad79d..341d619ea 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 @@ -553,7 +553,7 @@ public class CreateUpdateSoftwareTypeLayout extends CustomComponent implements C .findSoftwareModuleTypeByName(typeName.getValue()); if (createOptiongroup.getValue().equals(createTypeStr)) { if (!checkIsKeyDuplicate(typeKey.getValue()) && !checkIsDuplicate(existingType)) { - crateNewSWModuleType(); + createNewSWModuleType(); } } else { @@ -610,7 +610,7 @@ public class CreateUpdateSoftwareTypeLayout extends CustomComponent implements C /** * Create new tag. */ - private void crateNewSWModuleType() { + private void createNewSWModuleType() { int assignNumber = 0; final String colorPicked = getColorPickedString(); final String typeNameValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeName.getValue()); From dc0c845793a50d9754f26fdcb2480f7af908f05e Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 4 May 2016 18:59:42 +0200 Subject: [PATCH 31/47] Removed N+1 query that came in with the tooltip pull request. Signed-off-by: Kai Zimmermann --- .../targettable/TargetBeanQuery.java | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 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 e48004d7a..e96a9af8e 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 @@ -134,21 +134,17 @@ public class TargetBeanQuery extends AbstractBeanQuery { prxyTarget.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(targ)); prxyTarget.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(targ)); - final Target target = getTargetManagement().findTargetByControllerIDWithDetails(targ.getControllerId()); - final DistributionSet installedDistributionSet = target.getTargetInfo().getInstalledDistributionSet(); - final DistributionSet assignedDistributionSet = target.getAssignedDistributionSet(); - - prxyTarget.setInstalledDistributionSet(installedDistributionSet); - prxyTarget.setAssignedDistributionSet(assignedDistributionSet); - - if (installedDistributionSet != null) { - prxyTarget.setInstalledDistNameVersion(HawkbitCommonUtil.getFormattedNameVersion( - installedDistributionSet.getName(), installedDistributionSet.getVersion())); - } - if (assignedDistributionSet != null) { - prxyTarget.setAssignedDistNameVersion(HawkbitCommonUtil.getFormattedNameVersion( - assignedDistributionSet.getName(), assignedDistributionSet.getVersion())); + if (pinnedDistId == null) { + prxyTarget.setInstalledDistributionSet(null); + prxyTarget.setAssignedDistributionSet(null); + } else { + final Target target = getTargetManagement().findTargetByControllerIDWithDetails(targ.getControllerId()); + final DistributionSet installedDistributionSet = target.getTargetInfo().getInstalledDistributionSet(); + prxyTarget.setInstalledDistributionSet(installedDistributionSet); + final DistributionSet assignedDistributionSet = target.getAssignedDistributionSet(); + prxyTarget.setAssignedDistributionSet(assignedDistributionSet); } + prxyTarget.setUpdateStatus(targ.getTargetInfo().getUpdateStatus()); prxyTarget.setLastTargetQuery(targ.getTargetInfo().getLastTargetQuery()); prxyTarget.setTargetInfo(targ.getTargetInfo()); From e2d903382144facd80760d3876ceef7fc7f760ee Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 4 May 2016 19:37:58 +0200 Subject: [PATCH 32/47] remove singleton instance wihthin TenantConfigurationManagement Signed-off-by: Michael Hirsch --- .../RepositoryApplicationConfiguration.java | 5 ++- .../TenantConfigurationManagement.java | 14 +----- .../hawkbit/repository/model/TargetInfo.java | 13 +++--- .../TenantConfigurationManagementHolder.java | 44 +++++++++++++++++++ 4 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/TenantConfigurationManagementHolder.java diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java index 8ef427dcf..10100eda1 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java @@ -19,6 +19,7 @@ import org.eclipse.hawkbit.repository.model.helper.CacheManagerHolder; import org.eclipse.hawkbit.repository.model.helper.SecurityTokenGeneratorHolder; import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder; import org.eclipse.hawkbit.repository.model.helper.TenantAwareHolder; +import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder; import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -54,8 +55,8 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { * directly, e.g. JPA entities. */ @Bean - public TenantConfigurationManagement tenantConfigurationManagement() { - return TenantConfigurationManagement.getInstance(); + public TenantConfigurationManagementHolder tenantConfigurationManagementHolder() { + return TenantConfigurationManagementHolder.getInstance(); } /** diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index e311cf288..760942f06 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -24,6 +24,7 @@ import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -32,10 +33,9 @@ import org.springframework.validation.annotation.Validated; */ @Transactional(readOnly = true) @Validated +@Service public class TenantConfigurationManagement implements EnvironmentAware { - private static final TenantConfigurationManagement INSTANCE = new TenantConfigurationManagement(); - @Autowired private TenantConfigurationRepository tenantConfigurationRepository; @@ -46,16 +46,6 @@ public class TenantConfigurationManagement implements EnvironmentAware { private Environment environment; - /** - * Get Singleton instance, needed for classes which are not managed in - * Spring context - * - * @return singleton instance of TenantConfigurationManagement - */ - public static TenantConfigurationManagement getInstance() { - return INSTANCE; - } - /** * Retrieves a configuration value from the e.g. tenant overwritten * configuration values or in case the tenant does not a have a specific diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java index 47f52579a..e0ffa8f5f 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java @@ -38,7 +38,7 @@ import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.Transient; -import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder; import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.persistence.annotations.CascadeOnDelete; @@ -246,11 +246,12 @@ public class TargetInfo implements Persistable, Serializable { return null; } - final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagement.getInstance() - .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); - final Duration overdueTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagement - .getInstance().getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) - .getValue()); + 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()); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/TenantConfigurationManagementHolder.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/TenantConfigurationManagementHolder.java new file mode 100644 index 000000000..700511db6 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/TenantConfigurationManagementHolder.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.model.helper; + +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * A singleton bean which holds {@link TenantConfigurationManagement} service + * and makes it accessible to beans which are not managed by spring, e.g. JPA + * entities. + */ +public final class TenantConfigurationManagementHolder { + + private static final TenantConfigurationManagementHolder INSTANCE = new TenantConfigurationManagementHolder(); + + @Autowired + private TenantConfigurationManagement tenantConfiguration; + + private TenantConfigurationManagementHolder() { + } + + /** + * @return the singleton {@link TenantConfigurationManagementHolder} + * instance + */ + public static TenantConfigurationManagementHolder getInstance() { + return INSTANCE; + } + + /** + * @return the {@link TenantConfigurationManagement} service + */ + public TenantConfigurationManagement getTenantConfigurationManagement() { + return tenantConfiguration; + } + +} From bb0146fab65231e26191b138d2382f1b300b3a1b Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 4 May 2016 20:00:02 +0200 Subject: [PATCH 33/47] Disabled DS columns in target tables. An removed N+1 also from filter target table. Signed-off-by: Kai Zimmermann --- .../CreateOrUpdateFilterTable.java | 8 ++------ .../ui/filtermanagement/CustomTargetBeanQuery.java | 14 -------------- .../ui/management/targettable/TargetTable.java | 8 -------- 3 files changed, 2 insertions(+), 28 deletions(-) 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 6e4933d69..11121c1a5 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 @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.ui.filtermanagement; - import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -202,10 +201,7 @@ public class CreateOrUpdateFilterTable extends Table { new TableColumn(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, i18n.get("header.modifiedDate"), 0.1F)); columnList.add(new TableColumn(SPUILabelDefinitions.VAR_DESC, i18n.get("header.description"), 0.1F)); columnList.add(new TableColumn(SPUILabelDefinitions.STATUS_ICON, i18n.get("header.status"), 0.1F)); - columnList.add(new TableColumn(SPUILabelDefinitions.ASSIGNED_DISTRIBUTION_NAME_VER, - i18n.get("header.assigned.ds"), 0.125F)); - columnList.add(new TableColumn(SPUILabelDefinitions.INSTALLED_DISTRIBUTION_NAME_VER, - i18n.get("header.installed.ds"), 0.125F)); + return columnList; } @@ -258,5 +254,5 @@ public class CreateOrUpdateFilterTable extends Table { populateTableData(); eventBus.publish(this, CustomFilterUIEvent.UPDATE_TARGET_FILTER_SEARCH_ICON); } - + } 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 2cc572245..35f88f5a1 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 @@ -13,7 +13,6 @@ import java.util.List; import java.util.Map; import org.eclipse.hawkbit.repository.TargetManagement; -import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.ui.common.UserDetailsFormatter; import org.eclipse.hawkbit.ui.components.ProxyTarget; @@ -121,20 +120,7 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery { prxyTarget.setCreatedAt(targ.getCreatedAt()); prxyTarget.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(targ)); prxyTarget.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(targ)); - final Target target = getTargetManagement().findTargetByControllerIDWithDetails(targ.getControllerId()); - final DistributionSet installedDistributionSet = target.getTargetInfo().getInstalledDistributionSet(); - prxyTarget.setInstalledDistributionSet(installedDistributionSet); - final DistributionSet assignedDistributionSet = target.getAssignedDistributionSet(); - prxyTarget.setAssignedDistributionSet(assignedDistributionSet); - if (null != assignedDistributionSet) { - prxyTarget.setAssignedDistNameVersion(HawkbitCommonUtil.getFormattedNameVersion( - assignedDistributionSet.getName(), assignedDistributionSet.getVersion())); - } - if (null != installedDistributionSet) { - prxyTarget.setInstalledDistNameVersion(HawkbitCommonUtil.getFormattedNameVersion( - installedDistributionSet.getName(), installedDistributionSet.getVersion())); - } prxyTarget.setUpdateStatus(targ.getTargetInfo().getUpdateStatus()); prxyTarget.setLastTargetQuery(targ.getTargetInfo().getLastTargetQuery()); prxyTarget.setTargetInfo(targ.getTargetInfo()); 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 6232ebcf8..450895ef7 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 @@ -24,9 +24,7 @@ import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.repository.OffsetBasedPageRequest; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; -import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetIdName; -import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetIdName; @@ -113,7 +111,6 @@ public class TargetTable extends AbstractTable implements private static final int PROPERTY_DEPT = 3; private static final String ACTION_NOT_ALLOWED_MSG = "message.action.not.allowed"; - @Autowired private transient TargetManagement targetManagement; @@ -335,11 +332,6 @@ public class TargetTable extends AbstractTable implements if (!isMaximized()) { columnList.add(new TableColumn(SPUIDefinitions.TARGET_STATUS_POLL_TIME, "", 0.0F)); columnList.add(new TableColumn(SPUIDefinitions.TARGET_STATUS_PIN_TOGGLE_ICON, "", 0.0F)); - }else{ - columnList.add(new TableColumn(SPUILabelDefinitions.ASSIGNED_DISTRIBUTION_NAME_VER, - i18n.get("header.assigned.ds"), 0.1F)); - columnList.add(new TableColumn(SPUILabelDefinitions.INSTALLED_DISTRIBUTION_NAME_VER, - i18n.get("header.installed.ds"), 0.1F)); } return columnList; From d442a45b7a30fda7a55e814d2ddc86f62cf9db3c Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 6 May 2016 08:02:11 +0200 Subject: [PATCH 34/47] run getting polling configuration in system-code Signed-off-by: Michael Hirsch --- .../RepositoryApplicationConfiguration.java | 12 ++++++ .../hawkbit/repository/model/TargetInfo.java | 29 +++++++------ .../helper/SystemSecurityContextHolder.java | 41 +++++++++++++++++++ 3 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/SystemSecurityContextHolder.java diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java index 10100eda1..d5e8db96f 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java @@ -18,9 +18,11 @@ import org.eclipse.hawkbit.repository.model.helper.AfterTransactionCommitExecuto import org.eclipse.hawkbit.repository.model.helper.CacheManagerHolder; import org.eclipse.hawkbit.repository.model.helper.SecurityTokenGeneratorHolder; import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder; +import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.model.helper.TenantAwareHolder; import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder; import org.eclipse.hawkbit.security.SecurityTokenGenerator; +import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration; @@ -49,6 +51,16 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess @EnableAutoConfiguration public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { + /** + * @return the {@link SystemSecurityContext} singleton bean which make it + * accessible in beans which cannot access the service directly, + * e.g. JPA entities. + */ + @Bean + public SystemSecurityContextHolder systemSecurityContextHolder() { + return SystemSecurityContextHolder.getInstance(); + } + /** * @return the {@link TenantConfigurationManagement} singleton bean which * make it accessible in beans which cannot access the service diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java index e0ffa8f5f..00a501540 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java @@ -38,6 +38,7 @@ import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.Transient; +import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder; import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; @@ -245,19 +246,21 @@ public class TargetInfo implements Persistable, Serializable { if (lastTargetQuery == null) { return null; } - - 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); + 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); + }); } /** diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/SystemSecurityContextHolder.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/SystemSecurityContextHolder.java new file mode 100644 index 000000000..7d005e9bc --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/SystemSecurityContextHolder.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.model.helper; + +import org.eclipse.hawkbit.security.SystemSecurityContext; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * A singleton bean which holds {@link SystemSecurityContext} service and makes + * it accessible to beans which are not managed by spring, e.g. JPA entities. + */ +public final class SystemSecurityContextHolder { + + private static final SystemSecurityContextHolder INSTANCE = new SystemSecurityContextHolder(); + + @Autowired + private SystemSecurityContext systemSecurityContext; + + private SystemSecurityContextHolder() { + } + + /** + * @return the singleton {@link SystemSecurityContextHolder} instance + */ + public static SystemSecurityContextHolder getInstance() { + return INSTANCE; + } + + /** + * @return the {@link SystemSecurityContext} service + */ + public SystemSecurityContext getSystemSecurityContext() { + return systemSecurityContext; + } +} From 077e3c8d384a9c6ce56fd60b4d9efdaa34c7a69a Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 6 May 2016 08:16:12 +0200 Subject: [PATCH 35/47] add unit test for verification Signed-off-by: Michael Hirsch --- .../repository/TargetManagementTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java index 36fd2754b..a223c25b4 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementTest.java @@ -14,6 +14,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -29,6 +30,7 @@ import javax.validation.ConstraintViolationException; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; +import org.eclipse.hawkbit.WithSpringAuthorityRule; import org.eclipse.hawkbit.WithUser; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.TenantNotExistException; @@ -724,4 +726,20 @@ public class TargetManagementTest extends AbstractIntegrationTest { assertThat(25).as("Targets with no tag").isEqualTo(targetsListWithNoTag.size()); } + + @Test + @Description("Tests the a target can be read with only the read target permission") + public void targetCanBeReadWithOnlyReadTargetPermission() throws Exception { + final String knownTargetControllerId = "readTarget"; + controllerManagament.findOrRegisterTargetIfItDoesNotexist(knownTargetControllerId, new URI("http://127.0.0.1")); + + securityRule.runAs(WithSpringAuthorityRule.withUser("bumlux", "READ_TARGET"), () -> { + final Target findTargetByControllerID = targetManagement.findTargetByControllerID(knownTargetControllerId); + assertThat(findTargetByControllerID).isNotNull(); + assertThat(findTargetByControllerID.getTargetInfo()).isNotNull(); + assertThat(findTargetByControllerID.getTargetInfo().getPollStatus()).isNotNull(); + return null; + }); + + } } From 5220fa07ce5a06be41c1b1a211b3e5352016a2d5 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 6 May 2016 08:40:08 +0200 Subject: [PATCH 36/47] allow system code to read tenant configuration Signed-off-by: Michael Hirsch --- .../hawkbit/repository/TenantConfigurationManagement.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 760942f06..05d18908c 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -150,7 +150,8 @@ public class TenantConfigurationManagement implements EnvironmentAware { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.IS_SYSTEM_CODE) public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey) { return getConfigurationValue(configurationKey, configurationKey.getDataType()); } @@ -175,7 +176,8 @@ public class TenantConfigurationManagement implements EnvironmentAware { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.IS_SYSTEM_CODE) public T getGlobalConfigurationValue(final TenantConfigurationKey configurationKey, final Class propertyType) { From 5144f78c2b26c7df1032da54eae865827b4e9a3c Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 9 May 2016 10:50:14 +0200 Subject: [PATCH 37/47] Improved code readability. Signed-off-by: Kai Zimmermann --- .../simulator/DeviceSimulatorUpdater.java | 16 ++- .../hawkbit/simulator/UpdateStatus.java | 28 ++++- .../hawkbit/simulator/ui/SimulatorView.java | 105 +++++++++++------- .../hawkbit/controller/RootController.java | 6 +- 4 files changed, 104 insertions(+), 51 deletions(-) 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 43474b9a9..6f640ca53 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 @@ -138,7 +138,7 @@ public class DeviceSimulatorUpdater { public void run() { if (device.getProgress() <= 0 && modules != null) { device.setUpdateStatus(simulateDownloads(device.getTargetSecurityToken())); - if (device.getUpdateStatus().getResponseStatus().equals(ResponseStatus.ERROR)) { + if (isErrorResponse(device.getUpdateStatus())) { callback.updateFinished(device, actionId); eventbus.post(new ProgressUpdate(device)); return; @@ -169,7 +169,7 @@ public class DeviceSimulatorUpdater { result.getStatusMessages().add("Simulation complete!"); status.forEach(download -> { result.getStatusMessages().addAll(download.getStatusMessages()); - if (download.getResponseStatus().equals(ResponseStatus.ERROR)) { + if (isErrorResponse(download)) { result.setResponseStatus(ResponseStatus.ERROR); } }); @@ -179,6 +179,14 @@ public class DeviceSimulatorUpdater { return result; } + private boolean isErrorResponse(final UpdateStatus status) { + if (status == null) { + return false; + } + + return ResponseStatus.ERROR.equals(status.getResponseStatus()); + } + private static void handleArtifacts(final String targetToken, final List status, final Artifact artifact) { artifact.getUrls().entrySet().forEach(entry -> { @@ -195,7 +203,7 @@ public class DeviceSimulatorUpdater { } private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash) { - LOGGER.debug("Downloading " + url); + LOGGER.debug("Downloading {}", url); long overallread = 0; try { @@ -245,7 +253,7 @@ public class DeviceSimulatorUpdater { /** * Callback interface which is called when the simulated update process has * been finished and the caller of starting the simulated update process can - * send the result to the hawkBit update server back. * + * send the result back to the hawkBit update server. */ @FunctionalInterface public interface UpdaterCallback { diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/UpdateStatus.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/UpdateStatus.java index 49e9947d7..f4e1f75a7 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/UpdateStatus.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/UpdateStatus.java @@ -16,15 +16,30 @@ import java.util.List; * */ public class UpdateStatus { - private ResponseStatus responseStatus = ResponseStatus.SUCCESSFUL; - private final List statusMessages = new ArrayList<>(); + private ResponseStatus responseStatus; + private List statusMessages; + /** + * Constructor. + * + * @param responseStatus + * of the update + */ public UpdateStatus(final ResponseStatus responseStatus) { this.responseStatus = responseStatus; } + /** + * Constructor including status message. + * + * @param responseStatus + * of the update + * @param message + * of the update status + */ public UpdateStatus(final ResponseStatus responseStatus, final String message) { this(responseStatus); + statusMessages = new ArrayList<>(); statusMessages.add(message); } @@ -37,6 +52,10 @@ public class UpdateStatus { } public List getStatusMessages() { + if (statusMessages == null) { + statusMessages = new ArrayList<>(); + } + return statusMessages; } @@ -46,11 +65,12 @@ public class UpdateStatus { */ public enum ResponseStatus { /** - * updated has been successful and response the successful update. + * Update has been successful and response the successful update. */ SUCCESSFUL, + /** - * updated has been not successful and response the error update. + * Update has been not successful and response the error update. */ ERROR; } 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 455702501..bd6ecbe8b 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 @@ -55,6 +55,22 @@ import com.vaadin.ui.renderers.ProgressBarRenderer; @SpringView(name = "") public class SimulatorView extends VerticalLayout implements View { + private static final String NEXT_POLL_COUNTER_SEC_COL = "nextPollCounterSec"; + + private static final String RESPONSE_STATUS_COL = "responseStatus"; + + private static final String PROTOCOL_COL = "protocol"; + + private static final String TENANT_COL = "tenant"; + + private static final String PROGRESS_COL = "progress"; + + private static final String SWVERSION_COL = "swversion"; + + private static final String STATUS_COL = "status"; + + private static final String ID_COL = "id"; + private static final long serialVersionUID = 1L; @Autowired @@ -75,6 +91,7 @@ public class SimulatorView extends VerticalLayout implements View { private BeanContainer beanContainer; + @SuppressWarnings("unchecked") @Override public void enter(final ViewChangeEvent event) { eventbus.register(this); @@ -87,7 +104,7 @@ public class SimulatorView extends VerticalLayout implements View { createToolbar(); beanContainer = new BeanContainer<>(AbstractSimulatedDevice.class); - beanContainer.setBeanIdProperty("id"); + beanContainer.setBeanIdProperty(ID_COL); grid.setSizeFull(); grid.setCellStyleGenerator(new CellStyleGenerator() { @@ -96,28 +113,28 @@ public class SimulatorView extends VerticalLayout implements View { @Override public String getStyle(final CellReference cellReference) { - return cellReference.getPropertyId().equals("status") ? "centeralign" : null; + return cellReference.getPropertyId().equals(STATUS_COL) ? "centeralign" : null; } }); grid.setSelectionMode(SelectionMode.NONE); grid.setContainerDataSource(beanContainer); - grid.appendHeaderRow().getCell("responseStatus").setComponent(responseComboBox); - grid.setColumnOrder("id", "status", "swversion", "progress", "tenant", "protocol", "responseStatus", - "nextPollCounterSec"); + grid.appendHeaderRow().getCell(RESPONSE_STATUS_COL).setComponent(responseComboBox); + grid.setColumnOrder(ID_COL, STATUS_COL, SWVERSION_COL, PROGRESS_COL, TENANT_COL, PROTOCOL_COL, + RESPONSE_STATUS_COL, NEXT_POLL_COUNTER_SEC_COL); // header widths - grid.getColumn("status").setMaximumWidth(80); - grid.getColumn("protocol").setMaximumWidth(180); - grid.getColumn("responseStatus").setMaximumWidth(240); - grid.getColumn("nextPollCounterSec").setMaximumWidth(210); + grid.getColumn(STATUS_COL).setMaximumWidth(80); + grid.getColumn(PROTOCOL_COL).setMaximumWidth(180); + grid.getColumn(RESPONSE_STATUS_COL).setMaximumWidth(240); + grid.getColumn(NEXT_POLL_COUNTER_SEC_COL).setMaximumWidth(210); - grid.getColumn("nextPollCounterSec").setHeaderCaption("Next Poll in (sec)"); - grid.getColumn("swversion").setHeaderCaption("SW Version"); - grid.getColumn("responseStatus").setHeaderCaption("Response Update Status"); - grid.getColumn("progress").setRenderer(new ProgressBarRenderer()); - grid.getColumn("protocol").setConverter(createProtocolConverter()); - grid.getColumn("status").setRenderer(new HtmlRenderer(), createStatusConverter()); - grid.removeColumn("tenant"); + grid.getColumn(NEXT_POLL_COUNTER_SEC_COL).setHeaderCaption("Next Poll in (sec)"); + grid.getColumn(SWVERSION_COL).setHeaderCaption("SW Version"); + grid.getColumn(RESPONSE_STATUS_COL).setHeaderCaption("Response Update Status"); + grid.getColumn(PROGRESS_COL).setRenderer(new ProgressBarRenderer()); + grid.getColumn(PROTOCOL_COL).setConverter(createProtocolConverter()); + grid.getColumn(STATUS_COL).setRenderer(new HtmlRenderer(), createStatusConverter()); + grid.removeColumn(TENANT_COL); // grid combobox responseComboBox.setItemIcon(ResponseStatus.SUCCESSFUL, FontAwesome.CHECK_CIRCLE); @@ -125,8 +142,8 @@ public class SimulatorView extends VerticalLayout implements View { responseComboBox.setNullSelectionAllowed(false); responseComboBox.setValue(ResponseStatus.SUCCESSFUL); responseComboBox.addValueChangeListener(valueChangeEvent -> { - beanContainer.getItemIds().forEach(itemId -> beanContainer.getItem(itemId).getItemProperty("responseStatus") - .setValue(valueChangeEvent.getProperty().getValue())); + beanContainer.getItemIds().forEach(itemId -> beanContainer.getItem(itemId) + .getItemProperty(RESPONSE_STATUS_COL).setValue(valueChangeEvent.getProperty().getValue())); }); // add all components @@ -137,7 +154,7 @@ public class SimulatorView extends VerticalLayout implements View { setExpandRatio(grid, 1.0F); // load beans - repository.getAll().forEach(device -> beanContainer.addBean(device)); + repository.getAll().forEach(beanContainer::addBean); } @Override @@ -146,13 +163,14 @@ public class SimulatorView extends VerticalLayout implements View { eventbus.unregister(this); } + @SuppressWarnings("unchecked") @Subscribe public void pollCounterUpdate(final NextPollCounterUpdate update) { final List devices = update.getDevices(); this.getUI().access(() -> devices.forEach(device -> { final BeanItem item = beanContainer.getItem(device.getId()); if (item != null) { - item.getItemProperty("nextPollCounterSec").setValue(device.getNextPollCounterSec()); + item.getItemProperty(NEXT_POLL_COUNTER_SEC_COL).setValue(device.getNextPollCounterSec()); } })); } @@ -163,17 +181,19 @@ public class SimulatorView extends VerticalLayout implements View { * @param update * the update event posted on the event bus */ + @SuppressWarnings("unchecked") @Subscribe public void initUpdate(final InitUpdate update) { final AbstractSimulatedDevice device = update.getDevice(); this.getUI().access(() -> { final BeanItem item = beanContainer.getItem(device.getId()); - if (item != null) { - item.getItemProperty("progress").setValue(device.getProgress()); - item.getItemProperty("status").setValue(Status.PEDNING); - item.getItemProperty("swversion").setValue(device.getSwversion()); + if (item == null) { + return; } + item.getItemProperty(PROGRESS_COL).setValue(device.getProgress()); + item.getItemProperty(STATUS_COL).setValue(Status.PEDNING); + item.getItemProperty(SWVERSION_COL).setValue(device.getSwversion()); }); } @@ -183,32 +203,37 @@ public class SimulatorView extends VerticalLayout implements View { * @param update * the update event posted on the event bus */ + @SuppressWarnings("unchecked") @Subscribe public void progessUpdate(final ProgressUpdate update) { final AbstractSimulatedDevice device = update.getDevice(); this.getUI().access(() -> { final BeanItem item = beanContainer.getItem(device.getId()); if (item != null) { - item.getItemProperty("progress").setValue(device.getProgress()); - if (device.getProgress() >= 1) { - switch (device.getUpdateStatus().getResponseStatus()) { - case SUCCESSFUL: - item.getItemProperty("status").setValue(Status.FINISH); - break; - case ERROR: - item.getItemProperty("status").setValue(Status.ERROR); - break; - default: - item.getItemProperty("status").setValue(Status.UNKNWON); - } - } else { - item.getItemProperty("status").setValue(Status.PEDNING); - } + item.getItemProperty(PROGRESS_COL).setValue(device.getProgress()); + setStatusColumn(device, item); } - }); } + @SuppressWarnings("unchecked") + private void setStatusColumn(final AbstractSimulatedDevice device, final BeanItem item) { + if (device.getProgress() >= 1) { + switch (device.getUpdateStatus().getResponseStatus()) { + case SUCCESSFUL: + item.getItemProperty(STATUS_COL).setValue(Status.FINISH); + break; + case ERROR: + item.getItemProperty(STATUS_COL).setValue(Status.ERROR); + break; + default: + item.getItemProperty(STATUS_COL).setValue(Status.UNKNWON); + } + } else { + item.getItemProperty(STATUS_COL).setValue(Status.PEDNING); + } + } + private void createToolbar() { final Button createDevicesButton = new Button("generate..."); createDevicesButton.setIcon(FontAwesome.GEARS); diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java index 000e1e2e5..14383f30b 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java @@ -220,7 +220,7 @@ public class RootController { + " of: " + request.getRequestURI()); } else { statusMessage.addMessage( - ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI()); + ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads " + request.getRequestURI()); } controllerManagement.addActionStatusMessage(statusMessage); return action; @@ -390,7 +390,7 @@ public class RootController { LOG.debug("Controller confirmed cancel (actionid: {}, targetid: {}) as we got {} report.", actionid, targetid, feedback.getStatus().getExecution()); actionStatus.setStatus(Status.CANCELED); - actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target confirmed cancelation"); + actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target confirmed cancelation."); break; case REJECTED: LOG.info("Controller reported internal error (actionid: {}, targetid: {}) as we got {} report.", actionid, @@ -424,7 +424,7 @@ public class RootController { targetid, feedback.getStatus().getExecution()); actionStatus.setStatus(Status.RUNNING); actionStatus.addMessage( - ControllerManagement.SERVER_MESSAGE_PREFIX + "Target reported: " + feedback.getStatus().getExecution()); + ControllerManagement.SERVER_MESSAGE_PREFIX + "Target reported " + feedback.getStatus().getExecution()); } private static void handleClosedUpdateStatus(final ActionFeedback feedback, final String targetid, From c2413ebd61a2ddb9525bb7b1ca43b6b0c25c1ccf Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 9 May 2016 11:23:42 +0200 Subject: [PATCH 38/47] Added tests for md5 has gen in download messages. Signed-off-by: Kai Zimmermann --- .../amqp/AmqpMessageDispatcherServiceTest.java | 17 +++++++++++++++-- .../amqp/AmqpMessageHandlerServiceTest.java | 8 +++++--- .../hawkbit/amqp/BaseAmqpServiceTest.java | 2 ++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java index 4e0852ff3..c5cea9e05 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java @@ -8,8 +8,8 @@ */ package org.eclipse.hawkbit.amqp; +import static org.fest.assertions.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; @@ -23,6 +23,7 @@ import static org.mockito.Mockito.when; import java.net.URI; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB; import org.eclipse.hawkbit.TestDataUtil; @@ -159,7 +160,19 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit if (!softwareModule.getModuleId().equals(module.getId())) { continue; } - assertFalse("The software module artifacts should not be empty", softwareModule.getArtifacts().isEmpty()); + assertThat(softwareModule.getArtifacts().size()).isEqualTo(module.getArtifacts().size()).isGreaterThan(0); + + module.getArtifacts().forEach(dbArtifact -> { + final Optional found = softwareModule.getArtifacts() + .stream().filter(dmfartifact -> dmfartifact.getFilename() + .equals(((LocalArtifact) dbArtifact).getFilename())) + .findFirst(); + + assertTrue("The artifact should exist in message", found.isPresent()); + assertThat(found.get().getSize()).isEqualTo(dbArtifact.getSize()); + assertThat(found.get().getHashes().getMd5()).isEqualTo(dbArtifact.getMd5Hash()); + assertThat(found.get().getHashes().getSha1()).isEqualTo(dbArtifact.getSha1Hash()); + }); } } diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index 18ee0bde4..3051e4e22 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -333,6 +333,8 @@ public class AmqpMessageHandlerServiceTest { assertThat(downloadResponse.getResponseCode()).as("Message body response code is wrong") .isEqualTo(HttpStatus.OK.value()); assertThat(downloadResponse.getArtifact().getSize()).as("Wrong artifact size in message body").isEqualTo(1L); + assertThat(downloadResponse.getArtifact().getHashes().getSha1()).as("Wrong sha1 hash").isEqualTo("sha1"); + assertThat(downloadResponse.getArtifact().getHashes().getMd5()).as("Wrong md5 hash").isEqualTo("md5"); assertThat(downloadResponse.getDownloadUrl()).as("download url is wrong") .startsWith("http://localhost/api/v1/downloadserver/downloadId/"); } @@ -381,7 +383,7 @@ public class AmqpMessageHandlerServiceTest { } private ActionUpdateStatus createActionUpdateStatus(final ActionStatus status) { - return createActionUpdateStatus(status, 2l); + return createActionUpdateStatus(status, 2L); } private ActionUpdateStatus createActionUpdateStatus(final ActionStatus status, final Long id) { @@ -406,7 +408,7 @@ public class AmqpMessageHandlerServiceTest { } private List createSoftwareModuleList() { - final List softwareModuleList = new ArrayList(); + final List softwareModuleList = new ArrayList<>(); final SoftwareModule softwareModule = new SoftwareModule(); softwareModule.setId(777L); softwareModuleList.add(softwareModule); @@ -428,7 +430,7 @@ public class AmqpMessageHandlerServiceTest { return action; } - private void initalizeSecurityTokenGenerator() throws IllegalArgumentException, IllegalAccessException { + private void initalizeSecurityTokenGenerator() throws IllegalAccessException { final SecurityTokenGeneratorHolder instance = SecurityTokenGeneratorHolder.getInstance(); final Field[] fields = instance.getClass().getDeclaredFields(); for (final Field field : fields) { diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/BaseAmqpServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/BaseAmqpServiceTest.java index 0bd8c164b..20d03bdd6 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/BaseAmqpServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/BaseAmqpServiceTest.java @@ -52,6 +52,8 @@ public class BaseAmqpServiceTest { final ActionUpdateStatus actionUpdateStatus = new ActionUpdateStatus(); actionUpdateStatus.setActionId(1L); actionUpdateStatus.setSoftwareModuleId(2L); + actionUpdateStatus.getMessage().add("Message 1"); + actionUpdateStatus.getMessage().add("Message 2"); final Message message = rabbitTemplate.getMessageConverter().toMessage(actionUpdateStatus, new MessageProperties()); From cbcbe571ea164022341477ac2eab4853c50684e5 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 9 May 2016 17:02:12 +0200 Subject: [PATCH 39/47] Delete the eventbus call and add the used event to the hawkbitEventProvider Signed-off-by: Melanie Retter --- .../java/org/eclipse/hawkbit/ui/HawkbitEventProvider.java | 2 ++ .../ui/management/targettag/CreateUpdateTargetTagLayout.java | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) 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 12bcaacbc..4c1017fd4 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 @@ -21,6 +21,7 @@ import org.eclipse.hawkbit.eventbus.event.TargetCreatedEvent; import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.eventbus.event.TargetTagCreatedBulkEvent; +import org.eclipse.hawkbit.eventbus.event.TargetTagUpdateEvent; /** * The default hawkbit event provider. @@ -37,6 +38,7 @@ public class HawkbitEventProvider implements UIEventProvider { SINGLE_EVENTS.add(DistributionSetTagUpdateEvent.class); SINGLE_EVENTS.add(RolloutGroupChangeEvent.class); SINGLE_EVENTS.add(RolloutChangeEvent.class); + SINGLE_EVENTS.add(TargetTagUpdateEvent.class); BULK_EVENTS.add(TargetCreatedEvent.class); BULK_EVENTS.add(TargetInfoUpdateEvent.class); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java index aee07afc4..9a2805f19 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java @@ -144,7 +144,7 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout { final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue()); if (optiongroup.getValue().equals(createTagNw)) { if (!checkIsDuplicate(existingTag)) { - crateNewTag(); + createNewTag(); } } else { @@ -182,7 +182,7 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout { /** * Create new tag. */ - private void crateNewTag() { + private void createNewTag() { final String colorPicked = getColorPickedString(); final String tagNameValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagName.getValue()); final String tagDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue()); @@ -218,7 +218,6 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout { tagManagement.updateTargetTag(targetObj); uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { targetObj.getName() })); closeWindow(); - eventBus.publish(this, new TargetTagUpdateEvent(targetObj)); } else { uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); } From f89b7e4bebc32bcfbc65cc7d1f75c8ecd90f464f Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 10 May 2016 10:24:53 +0200 Subject: [PATCH 40/47] Update AbstractTableDetailsLayout.java use capital F for float value --- .../ui/common/detailslayout/AbstractTableDetailsLayout.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f471abf33..74c6b86ab 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 @@ -150,7 +150,7 @@ public abstract class AbstractTableDetailsLayout extends private void buildLayout() { final HorizontalLayout nameEditLayout = new HorizontalLayout(); - nameEditLayout.setWidth(100.0f, Unit.PERCENTAGE); + nameEditLayout.setWidth(100.0F, Unit.PERCENTAGE); nameEditLayout.addComponent(caption); nameEditLayout.setComponentAlignment(caption, Alignment.TOP_LEFT); if (hasEditPermission()) { From 5443f6e419bee6b634fa0d214ee0836ebcb0a52d Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 10 May 2016 12:01:55 +0200 Subject: [PATCH 41/47] Fixed auth problem in device simulator. Fixed equals ignore case in sha1 check. Signed-off-by: Kai Zimmermann --- .../simulator/DeviceSimulatorUpdater.java | 81 ++++++++++++++++--- .../artifact/repository/ArtifactStore.java | 3 +- 2 files changed, 73 insertions(+), 11 deletions(-) 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 6f640ca53..4545cf759 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 @@ -41,6 +41,7 @@ import org.eclipse.hawkbit.simulator.event.ProgressUpdate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import com.google.common.eventbus.EventBus; @@ -193,7 +194,8 @@ public class DeviceSimulatorUpdater { switch (entry.getKey()) { case HTTP: case HTTPS: - status.add(downloadUrl(entry.getValue(), targetToken, artifact.getHashes().getSha1())); + status.add(downloadUrl(entry.getValue(), targetToken, artifact.getHashes().getSha1(), + artifact.getSize())); break; default: // not supported yet @@ -202,37 +204,54 @@ public class DeviceSimulatorUpdater { }); } - private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash) { - LOGGER.debug("Downloading {}", url); + private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash, + final long size) { + LOGGER.debug("Downloading {} with token {}, expected sha1 hash {} and size {}", url, + hideTokenDetails(targetToken), sha1Hash, size); long overallread = 0; try { final CloseableHttpClient httpclient = createHttpClientThatAcceptsAllServerCerts(); final HttpGet request = new HttpGet(url); - request.addHeader("TargetToken", targetToken); + request.addHeader("Authorization", "TargetToken " + targetToken); final String sha1HashResult; try (final CloseableHttpResponse response = httpclient.execute(request)) { + + if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) { + final String message = wrongStatusCode(url, response); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + + if (response.getEntity().getContentLength() != size) { + final String message = wrongContentLength(url, size, response); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + final File tempFile = File.createTempFile("uploadFile", null); final MessageDigest md = MessageDigest.getInstance("SHA-1"); try (final DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(tempFile), md)) { overallread = ByteStreams.copy(response.getEntity().getContent(), dos); - sha1HashResult = BaseEncoding.base16().lowerCase().encode(md.digest()); } finally { tempFile.delete(); } + + if (overallread != size) { + final String message = incompleteRead(url, size, overallread); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + + sha1HashResult = BaseEncoding.base16().lowerCase().encode(md.digest()); } - if (!sha1Hash.equals(sha1HashResult)) { - final String message = "Download " + url + " failed with SHA1 hash missmatch (Expected: " + sha1Hash - + " but got: " + sha1HashResult + ")"; - LOGGER.debug(message); + if (!sha1Hash.equalsIgnoreCase(sha1HashResult)) { + final String message = wrongHash(url, sha1Hash, overallread, sha1HashResult); return new UpdateStatus(ResponseStatus.ERROR, message); } } catch (IOException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { - LOGGER.error("Failed to download {}", url, e); + LOGGER.error("Failed to download {} with {}", url, e.getMessage()); return new UpdateStatus(ResponseStatus.ERROR, "Failed to download " + url + ": " + e.getMessage()); } @@ -241,6 +260,48 @@ public class DeviceSimulatorUpdater { return new UpdateStatus(ResponseStatus.SUCCESSFUL, message); } + private static String hideTokenDetails(final String targetToken) { + if (targetToken.isEmpty()) { + return ""; + } + + if (targetToken.length() <= 3) { + return "***"; + } + + return targetToken.substring(0, 3) + "***" + + targetToken.substring(targetToken.length() - 3, targetToken.length()); + } + + private static String wrongHash(final String url, final String sha1Hash, final long overallread, + final String sha1HashResult) { + final String message = "Download " + url + " failed with SHA1 hash missmatch (Expected: " + sha1Hash + + " but got: " + sha1HashResult + ") (" + overallread + " bytes)"; + LOGGER.error(message); + return message; + } + + private static String incompleteRead(final String url, final long size, final long overallread) { + final String message = "Download " + url + " is incomplete (Expected: " + size + " but got: " + overallread + + ")"; + LOGGER.error(message); + return message; + } + + private static String wrongContentLength(final String url, final long size, + final CloseableHttpResponse response) { + final String message = "Download " + url + " has wrong content length (Expected: " + size + " but got: " + + response.getEntity().getContentLength() + ")"; + LOGGER.error(message); + return message; + } + + private static String wrongStatusCode(final String url, final CloseableHttpResponse response) { + final String message = "Download " + url + " failed (" + response.getStatusLine().getStatusCode() + ")"; + LOGGER.error(message); + return message; + } + private static CloseableHttpClient createHttpClientThatAcceptsAllServerCerts() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { final SSLContextBuilder builder = new SSLContextBuilder(); diff --git a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java index 94b093cb3..d863f60cf 100644 --- a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java +++ b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java @@ -185,7 +185,8 @@ public class ArtifactStore implements ArtifactRepository { throw new ArtifactStoreException(e.getMessage(), e); } - if (hash != null && hash.getMd5() != null && !storedArtifact.getHashes().getMd5().equals(hash.getMd5())) { + if (hash != null && hash.getMd5() != null + && !storedArtifact.getHashes().getMd5().equalsIgnoreCase(hash.getMd5())) { throw new HashNotMatchException("The given md5 hash " + hash.getMd5() + " not matching the calculated md5 hash " + storedArtifact.getHashes().getMd5(), HashNotMatchException.MD5); From bc37ea9b23313b941c97c6a4cfe0277440046ae3 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 10 May 2016 12:08:29 +0200 Subject: [PATCH 42/47] Improved hiding for small tokens. Signed-off-by: Kai Zimmermann --- .../eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 4545cf759..7e03c0f07 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 @@ -265,12 +265,12 @@ public class DeviceSimulatorUpdater { return ""; } - if (targetToken.length() <= 3) { + if (targetToken.length() <= 6) { return "***"; } - return targetToken.substring(0, 3) + "***" - + targetToken.substring(targetToken.length() - 3, targetToken.length()); + return targetToken.substring(0, 2) + "***" + + targetToken.substring(targetToken.length() - 2, targetToken.length()); } private static String wrongHash(final String url, final String sha1Hash, final long overallread, From 1236f65d9da85cbd8cacd99492c61622f26ce764 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 10 May 2016 13:12:19 +0200 Subject: [PATCH 43/47] Improved sha1 gen performance by using buffered streams. Signed-off-by: Kai Zimmermann --- .../hawkbit/simulator/DeviceSimulatorUpdater.java | 12 ++++++++++-- .../artifact/repository/ArtifactStore.java | 15 +++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) 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 7e03c0f07..197fcd7da 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,6 +8,8 @@ */ package org.eclipse.hawkbit.simulator; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -232,9 +234,15 @@ public class DeviceSimulatorUpdater { final MessageDigest md = MessageDigest.getInstance("SHA-1"); try (final DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(tempFile), md)) { - overallread = ByteStreams.copy(response.getEntity().getContent(), dos); + try (final BufferedOutputStream bdos = new BufferedOutputStream(dos)) { + try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) { + overallread = ByteStreams.copy(bis, bdos); + } + } } finally { - tempFile.delete(); + if (tempFile != null && !tempFile.delete()) { + LOGGER.error("Could not delete temporary file: {}", tempFile); + } } if (overallread != size) { diff --git a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java index d863f60cf..5f12498ff 100644 --- a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java +++ b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java @@ -8,11 +8,14 @@ */ package org.eclipse.hawkbit.artifact.repository; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.security.DigestOutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -122,7 +125,11 @@ public class ArtifactStore implements ArtifactRepository { LOGGER.debug("storing file {} of content {}", filename, contentType); tempFile = File.createTempFile("uploadFile", null); try (final FileOutputStream os = new FileOutputStream(tempFile)) { - return store(content, contentType, os, tempFile, hash); + try (BufferedOutputStream bos = new BufferedOutputStream(os)) { + try (BufferedInputStream bis = new BufferedInputStream(content)) { + return store(content, contentType, bos, tempFile, hash); + } + } } } catch (final IOException | MongoException e1) { throw new ArtifactStoreException(e1.getMessage(), e1); @@ -162,7 +169,7 @@ public class ArtifactStore implements ArtifactRepository { } - private DbArtifact store(final InputStream content, final String contentType, final FileOutputStream os, + private DbArtifact store(final InputStream content, final String contentType, final OutputStream os, final File tempFile, final DbArtifactHash hash) { final GridFsArtifact storedArtifact; try { @@ -196,8 +203,8 @@ public class ArtifactStore implements ArtifactRepository { } - private static String computeSHA1Hash(final InputStream stream, final FileOutputStream os, - final String providedSHA1Sum) throws NoSuchAlgorithmException, IOException { + private static String computeSHA1Hash(final InputStream stream, final OutputStream os, final String providedSHA1Sum) + throws NoSuchAlgorithmException, IOException { String sha1Hash; // compute digest final MessageDigest md = MessageDigest.getInstance("SHA-1"); From a9283b402ab020d4103da229a96dd8bfa6d488dd Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Tue, 10 May 2016 13:21:53 +0200 Subject: [PATCH 44/47] Improved code readability. Signed-off-by: Kai Zimmermann --- .../hawkbit/simulator/DeviceSimulatorUpdater.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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 197fcd7da..3704b9854 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 @@ -43,6 +43,7 @@ import org.eclipse.hawkbit.simulator.event.ProgressUpdate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @@ -117,6 +118,11 @@ public class DeviceSimulatorUpdater { } private static final class DeviceSimulatorUpdateThread implements Runnable { + /** + * + */ + private static final int MINIMUM_TOKENLENGTH_FOR_HINT = 6; + private static final Random rndSleep = new SecureRandom(); private final AbstractSimulatedDevice device; @@ -215,7 +221,7 @@ public class DeviceSimulatorUpdater { try { final CloseableHttpClient httpclient = createHttpClientThatAcceptsAllServerCerts(); final HttpGet request = new HttpGet(url); - request.addHeader("Authorization", "TargetToken " + targetToken); + request.addHeader(HttpHeaders.AUTHORIZATION, "TargetToken " + targetToken); final String sha1HashResult; try (final CloseableHttpResponse response = httpclient.execute(request)) { @@ -273,7 +279,7 @@ public class DeviceSimulatorUpdater { return ""; } - if (targetToken.length() <= 6) { + if (targetToken.length() <= MINIMUM_TOKENLENGTH_FOR_HINT) { return "***"; } From 2c49fc8f77a21dee74e36c4d1b75da21606c4164 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Thu, 12 May 2016 11:55:25 +0200 Subject: [PATCH 45/47] Fix action message. --- .../eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java | 3 --- .../src/main/java/org/eclipse/hawkbit/app/MyLoginUI.java | 6 +++--- .../src/main/java/org/eclipse/hawkbit/app/MyUI.java | 3 +++ .../org/eclipse/hawkbit/controller/RootController.java | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) 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 3704b9854..e7b81b017 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 @@ -118,9 +118,6 @@ public class DeviceSimulatorUpdater { } private static final class DeviceSimulatorUpdateThread implements Runnable { - /** - * - */ private static final int MINIMUM_TOKENLENGTH_FOR_HINT = 6; private static final Random rndSleep = new SecureRandom(); diff --git a/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyLoginUI.java b/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyLoginUI.java index 763e8447e..d8c5c8493 100644 --- a/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyLoginUI.java +++ b/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyLoginUI.java @@ -20,11 +20,11 @@ import com.vaadin.spring.annotation.SpringUI; * login path. The easiest way to get an hawkBit login UI running is to extend * the {@link HawkbitLoginUI} and to annotated it with {@link SpringUI} as in * this example to the defined {@link HawkbitTheme#LOGIN_UI_PATH}. - * - * - * */ @SpringUI(path = HawkbitTheme.LOGIN_UI_PATH) +// Exception squid:MaximumInheritanceDepth - Most of the inheritance comes from +// Vaadin. +@SuppressWarnings({ "squid:MaximumInheritanceDepth" }) public class MyLoginUI extends HawkbitLoginUI { private static final long serialVersionUID = 1L; diff --git a/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyUI.java b/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyUI.java index 68d3b2fd9..e5bc7535d 100644 --- a/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyUI.java +++ b/examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/MyUI.java @@ -29,6 +29,9 @@ import com.vaadin.spring.annotation.SpringUI; */ @SpringUI @Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET) +// Exception squid:MaximumInheritanceDepth - Most of the inheritance comes from +// Vaadin. +@SuppressWarnings({ "squid:MaximumInheritanceDepth" }) public class MyUI extends HawkbitUI { private static final long serialVersionUID = 1L; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java index 14383f30b..3969e1b83 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java @@ -318,8 +318,8 @@ public class RootController { LOG.debug("Found an active UpdateAction for target {}. returning deyploment: {}", targetid, base); - controllerManagement.registerRetrieved(action, - "Controller retrieved update action and should start now the download."); + controllerManagement.registerRetrieved(action, ControllerManagement.SERVER_MESSAGE_PREFIX + + "Target retrieved update action and should start now the download."); return new ResponseEntity<>(base, HttpStatus.OK); } @@ -497,8 +497,8 @@ public class RootController { LOG.debug("Found an active CancelAction for target {}. returning cancel: {}", targetid, cancel); - controllerManagement.registerRetrieved(action, - "Controller retrieved cancel action and should start now the cancelation."); + controllerManagement.registerRetrieved(action, ControllerManagement.SERVER_MESSAGE_PREFIX + + "Target retrieved cancel action and should start now the cancelation."); return new ResponseEntity<>(cancel, HttpStatus.OK); } From 8b7f24e202e151b5c1367f6c6ffeaedfc8698575 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Thu, 12 May 2016 11:58:16 +0200 Subject: [PATCH 46/47] Add mysql profile --- .../resources/application-mysql.properties | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 examples/hawkbit-example-app/src/main/resources/application-mysql.properties diff --git a/examples/hawkbit-example-app/src/main/resources/application-mysql.properties b/examples/hawkbit-example-app/src/main/resources/application-mysql.properties new file mode 100644 index 000000000..fbb0fcbad --- /dev/null +++ b/examples/hawkbit-example-app/src/main/resources/application-mysql.properties @@ -0,0 +1,32 @@ +# +# Copyright (c) 2015 Bosch Software Innovations GmbH and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# + +# This profile adds basic configurations for a MySQL DB usage. +# Keep in mind that you need the MaridDB driver in your classpath on compile. +# see https://github.com/eclipse/hawkbit/wiki/Run-hawkBit + +spring.jpa.database=MYSQL +spring.datasource.url=jdbc:mysql://localhost:3306/hawkbit +spring.datasource.username=root +spring.datasource.password= +spring.datasource.driverClassName=org.mariadb.jdbc.Driver + +spring.datasource.max-active=100 +spring.datasource.max-idle=10 +spring.datasource.min-idle=10 +spring.datasource.initial-size=10 +spring.datasource.validation-query=select 1 from dual +spring.datasource.validation-interval=30000 +spring.datasource.test-on-borrow=true +spring.datasource.test-on-return=false +spring.datasource.test-while-idle=true +spring.datasource.time-between-eviction-runs-millis=30000 +spring.datasource.min-evictable-idle-time-millis=60000 +spring.datasource.max-wait=10000 +spring.datasource.jmx-enabled=true \ No newline at end of file From 33a4ed117528c3789696974cf0004c3ab0071150 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 13 May 2016 09:30:22 +0200 Subject: [PATCH 47/47] fix typo of MariaDB --- .../src/main/resources/application-mysql.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/hawkbit-example-app/src/main/resources/application-mysql.properties b/examples/hawkbit-example-app/src/main/resources/application-mysql.properties index fbb0fcbad..202500245 100644 --- a/examples/hawkbit-example-app/src/main/resources/application-mysql.properties +++ b/examples/hawkbit-example-app/src/main/resources/application-mysql.properties @@ -8,7 +8,7 @@ # # This profile adds basic configurations for a MySQL DB usage. -# Keep in mind that you need the MaridDB driver in your classpath on compile. +# Keep in mind that you need the MariaDB driver in your classpath on compile. # see https://github.com/eclipse/hawkbit/wiki/Run-hawkBit spring.jpa.database=MYSQL @@ -29,4 +29,4 @@ spring.datasource.test-while-idle=true spring.datasource.time-between-eviction-runs-millis=30000 spring.datasource.min-evictable-idle-time-millis=60000 spring.datasource.max-wait=10000 -spring.datasource.jmx-enabled=true \ No newline at end of file +spring.datasource.jmx-enabled=true