From be348030b219437ceadc906747894c9181b5b98c Mon Sep 17 00:00:00 2001 From: Stefan Klotz <35995139+StefanKlt@users.noreply.github.com> Date: Mon, 26 Nov 2018 11:10:49 +0100 Subject: [PATCH] Feature target metadata ui (#765) * add metadata tab and popup to target UI Signed-off-by: Stefan Klotz * send event to update UI Signed-off-by: Stefan Klotz * send event on target meta data delete and update Signed-off-by: Stefan Klotz * display selected element name in details layout and metadata popup of UI Signed-off-by: Stefan Klotz * add comments to explain manual event publishing Signed-off-by: Stefan Klotz * remove option to hide metadata button in details layout Signed-off-by: Stefan Klotz * fix typos and refactor Signed-off-by: Stefan Klotz * fix typos Signed-off-by: Stefan Klotz * fix wrong method call Signed-off-by: Stefan Klotz --- .../hawkbit/repository/TargetManagement.java | 2 +- .../repository/jpa/JpaTargetManagement.java | 29 ++++-- .../repository/jpa/TargetManagementTest.java | 6 +- .../rest/resource/MgmtTargetResource.java | 2 +- .../common/AbstractMetadataPopupLayout.java | 15 ++-- .../AbstractMetadataPopupLayoutVersioned.java | 44 +++++++++ .../AbstractDistributionSetDetails.java | 5 -- .../AbstractSoftwareModuleDetails.java | 5 -- .../AbstractTableDetailsLayout.java | 14 ++- .../DistributionSetMetadataDetailsLayout.java | 3 +- .../TargetMetadataDetailsLayout.java | 87 ++++++++++++++++++ .../dstable/DsMetadataPopupLayout.java | 10 +-- .../smtable/SwMetadataPopupLayout.java | 4 +- .../management/targettable/TargetDetails.java | 44 +++++---- .../TargetMetadataPopupLayout.java | 90 +++++++++++++++++++ .../targettable/TargetTableLayout.java | 4 +- .../ui/utils/UIComponentIdProvider.java | 14 ++- 17 files changed, 313 insertions(+), 65 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayoutVersioned.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/TargetMetadataDetailsLayout.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetMetadataPopupLayout.java diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java index 73c5e121c..b8c77a18c 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java @@ -764,5 +764,5 @@ public interface TargetManagement { * updated */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - TargetMetadata updateMetaData(@NotEmpty String controllerId, @NotNull MetaData metadata); + TargetMetadata updateMetadata(@NotEmpty String controllerId, @NotNull MetaData metadata); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 1d16bf3c8..55374324b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -35,6 +35,7 @@ import org.eclipse.hawkbit.repository.builder.TargetCreate; import org.eclipse.hawkbit.repository.builder.TargetUpdate; import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent; +import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetCreate; @@ -182,10 +183,16 @@ public class JpaTargetManagement implements TargetManagement { final JpaTarget updatedTarget = touch(target); - return Collections.unmodifiableList(md.stream() + final List createdMetadata = Collections.unmodifiableList(md.stream() .map(meta -> targetMetadataRepository .save(new JpaTargetMetadata(meta.getKey(), meta.getValue(), updatedTarget))) .collect(Collectors.toList())); + + // TargetUpdatedEvent is not sent within the touch() method due to the + // "lastModifiedAt" field being ignored in JpaTarget + eventPublisher.publishEvent(new TargetUpdatedEvent(updatedTarget, applicationContext.getId())); + + return createdMetadata; } private void checkAndThrowIfTargetMetadataAlreadyExists(final TargetMetadataCompositeKey metadataId) { @@ -219,16 +226,21 @@ public class JpaTargetManagement implements TargetManagement { @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) - public TargetMetadata updateMetaData(final String controllerId, final MetaData md) { + public TargetMetadata updateMetadata(final String controllerId, final MetaData md) { // check if exists otherwise throw entity not found exception - final JpaTargetMetadata toUpdate = (JpaTargetMetadata) getMetaDataByControllerId(controllerId, md.getKey()) + final JpaTargetMetadata updatedMetadata = (JpaTargetMetadata) getMetaDataByControllerId(controllerId, + md.getKey()) .orElseThrow(() -> new EntityNotFoundException(TargetMetadata.class, controllerId, md.getKey())); - toUpdate.setValue(md.getValue()); + updatedMetadata.setValue(md.getValue()); // touch it to update the lock revision because we are modifying the // target indirectly - touch(controllerId); - return targetMetadataRepository.save(toUpdate); + final JpaTarget target = touch(controllerId); + final JpaTargetMetadata matadata = targetMetadataRepository.save(updatedMetadata); + // target update event is set to ignore "lastModifiedAt" field so it is + // not send automatically within the touch() method + eventPublisher.publishEvent(new TargetUpdatedEvent(target, applicationContext.getId())); + return matadata; } @Override @@ -239,8 +251,11 @@ public class JpaTargetManagement implements TargetManagement { final JpaTargetMetadata metadata = (JpaTargetMetadata) getMetaDataByControllerId(controllerId, key) .orElseThrow(() -> new EntityNotFoundException(TargetMetadata.class, controllerId, key)); - touch(controllerId); + final JpaTarget target = touch(controllerId); targetMetadataRepository.delete(metadata.getId()); + // target update event is set to ignore "lastModifiedAt" field so it is + // not send automatically within the touch() method + eventPublisher.publishEvent(new TargetUpdatedEvent(target, applicationContext.getId())); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/TargetManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/TargetManagementTest.java index c25e044ce..a30f979a6 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/TargetManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/TargetManagementTest.java @@ -152,9 +152,9 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest { verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerIdAndRsql(PAGE, NOT_EXIST_ID, "name==*"), "Target"); verifyThrownExceptionBy( - () -> targetManagement.updateMetaData(NOT_EXIST_ID, entityFactory.generateTargetMetadata("xxx", "xxx")), + () -> targetManagement.updateMetadata(NOT_EXIST_ID, entityFactory.generateTargetMetadata("xxx", "xxx")), "Target"); - verifyThrownExceptionBy(() -> targetManagement.updateMetaData(target.getControllerId(), + verifyThrownExceptionBy(() -> targetManagement.updateMetadata(target.getControllerId(), entityFactory.generateTargetMetadata(NOT_EXIST_ID, "xxx")), "TargetMetadata"); } @@ -1002,7 +1002,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest { Thread.sleep(100); // update the target metadata - final JpaTargetMetadata updated = (JpaTargetMetadata) targetManagement.updateMetaData(target.getControllerId(), + final JpaTargetMetadata updated = (JpaTargetMetadata) targetManagement.updateMetadata(target.getControllerId(), entityFactory.generateTargetMetadata(knownKey, knownUpdateValue)); // we are updating the target meta data so also modifying the base // software diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java index ec75e3657..ff8903745 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java @@ -388,7 +388,7 @@ public class MgmtTargetResource implements MgmtTargetRestApi { @Override public ResponseEntity updateMetadata(@PathVariable("targetId") final String targetId, @PathVariable("metadataKey") final String metadataKey, @RequestBody final MgmtMetadataBodyPut metadata) { - final TargetMetadata updated = targetManagement.updateMetaData(targetId, + final TargetMetadata updated = targetManagement.updateMetadata(targetId, entityFactory.generateTargetMetadata(metadataKey, metadata.getValue())); return ResponseEntity.ok(MgmtTargetMapper.toResponseTargetMetadata(updated)); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java index ca7ca1ce3..7aa454aaa 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java @@ -12,7 +12,7 @@ import java.util.List; import java.util.Set; import org.eclipse.hawkbit.repository.model.MetaData; -import org.eclipse.hawkbit.repository.model.NamedVersionedEntity; +import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.CommonDialogWindow.SaveDialogCloseListener; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; @@ -61,7 +61,7 @@ import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent; * M is the metadata * */ -public abstract class AbstractMetadataPopupLayout +public abstract class AbstractMetadataPopupLayout extends CustomComponent { private static final String DELETE_BUTTON = "DELETE_BUTTON"; @@ -140,10 +140,9 @@ public abstract class AbstractMetadataPopupLayout onCancel()) + .caption(getMetadataCaption()).content(this).cancelButtonClickListener(event -> onCancel()) .id(UIComponentIdProvider.METADATA_POPUP_ID).layout(mainLayout).i18n(i18n) .saveDialogCloseListener(new SaveOnDialogCloseListener()).buildCommonDialogWindow(); @@ -440,14 +439,18 @@ public abstract class AbstractMetadataPopupLayout + * E id the entity for which metadata is displayed + * @param + * M is the metadata + * + */ +public abstract class AbstractMetadataPopupLayoutVersioned + extends AbstractMetadataPopupLayout { + + private static final long serialVersionUID = 1L; + + protected AbstractMetadataPopupLayoutVersioned(final VaadinMessageSource i18n, final UINotification uiNotification, + final UIEventBus eventBus, final SpPermissionChecker permChecker) { + super(i18n, uiNotification, eventBus, permChecker); + } + + @Override + protected String getElementTitle() { + return HawkbitCommonUtil.getFormattedNameVersion(getSelectedEntity().getName(), + getSelectedEntity().getVersion()); + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractDistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractDistributionSetDetails.java index 9ba7f9bc1..d74164150 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractDistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractDistributionSetDetails.java @@ -128,11 +128,6 @@ public abstract class AbstractDistributionSetDetails return UIComponentIdProvider.DISTRIBUTION_DETAILS_HEADER_LABEL_ID; } - @Override - protected boolean isMetadataIconToBeDisplayed() { - return true; - } - @Override protected void showMetadata(final ClickEvent event) { final Optional ds = distributionSetManagement.get(getSelectedBaseEntityId()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractSoftwareModuleDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractSoftwareModuleDetails.java index 8c6933df9..cfff4a326 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractSoftwareModuleDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractSoftwareModuleDetails.java @@ -112,11 +112,6 @@ public abstract class AbstractSoftwareModuleDetails return UIComponentIdProvider.SOFTWARE_MODULE_DETAILS_HEADER_LABEL_ID; } - @Override - protected boolean isMetadataIconToBeDisplayed() { - return true; - } - @Override protected void showMetadata(final ClickEvent event) { softwareModuleManagement.get(getSelectedBaseEntityId()) 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 933ae44e0..0aa82ff99 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 @@ -248,10 +248,8 @@ public abstract class AbstractTableDetailsLayout extends if (hasEditPermission()) { nameEditLayout.addComponent(editButton); nameEditLayout.setComponentAlignment(editButton, Alignment.TOP_RIGHT); - if (isMetadataIconToBeDisplayed()) { - nameEditLayout.addComponent(manageMetadataBtn); - nameEditLayout.setComponentAlignment(manageMetadataBtn, Alignment.TOP_RIGHT); - } + nameEditLayout.addComponent(manageMetadataBtn); + nameEditLayout.setComponentAlignment(manageMetadataBtn, Alignment.TOP_RIGHT); } nameEditLayout.setExpandRatio(caption, 1.0F); nameEditLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE); @@ -300,6 +298,10 @@ public abstract class AbstractTableDetailsLayout extends return selectedBaseEntity == null ? null : selectedBaseEntity.getId(); } + protected String getName() { + return getSelectedBaseEntity().getName(); + } + protected abstract void populateDetailsWidget(); protected abstract void populateMetadataDetails(); @@ -331,10 +333,6 @@ public abstract class AbstractTableDetailsLayout extends protected abstract String getDetailsHeaderCaptionId(); - protected abstract String getName(); - - protected abstract boolean isMetadataIconToBeDisplayed(); - protected abstract void showMetadata(Button.ClickEvent event); public HorizontalLayout getNameEditLayout() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadataDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadataDetailsLayout.java index 769d2e0ee..da81a596f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadataDetailsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadataDetailsLayout.java @@ -54,7 +54,7 @@ public class DistributionSetMetadataDetailsLayout extends AbstractMetadataDetail } /** - * Populate software module metadata. + * Populate distribution set metadata. * * @param distributionSet */ @@ -70,7 +70,6 @@ public class DistributionSetMetadataDetailsLayout extends AbstractMetadataDetail if (null != dsMetadataList && !dsMetadataList.isEmpty()) { dsMetadataList.forEach(this::setMetadataProperties); } - } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/TargetMetadataDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/TargetMetadataDetailsLayout.java new file mode 100644 index 000000000..7196db02d --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/TargetMetadataDetailsLayout.java @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.common.detailslayout; + +import java.util.List; + +import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetMetadata; +import org.eclipse.hawkbit.ui.management.targettable.TargetMetadataPopupLayout; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.springframework.data.domain.PageRequest; + +import com.vaadin.ui.UI; + +/** + * Target Metadata details layout. + * + */ +public class TargetMetadataDetailsLayout extends AbstractMetadataDetailsLayout { + + private static final long serialVersionUID = 1L; + + private final transient TargetManagement targetManagement; + + private final TargetMetadataPopupLayout targetMetadataPopupLayout; + + private Long selectedTargetId; + + /** + * Initialize the layout. + * + * @param i18n + * the i18n service + * @param targetManagement + * the target management service + * @param targetMetadataPopupLayout + * the target metadata popup layout + */ + public TargetMetadataDetailsLayout(final VaadinMessageSource i18n, + final TargetManagement targetManagement, + final TargetMetadataPopupLayout targetMetadataPopupLayout) { + super(i18n); + this.targetManagement = targetManagement; + this.targetMetadataPopupLayout = targetMetadataPopupLayout; + + } + + /** + * Populate target metadata. + * + * @param target + */ + public void populateMetadata(final Target target) { + removeAllItems(); + if (target == null) { + return; + } + selectedTargetId = target.getId(); + final List targetMetadataList = targetManagement + .findMetaDataByControllerId(new PageRequest(0, MAX_METADATA_QUERY), target.getControllerId()) + .getContent(); + if (targetMetadataList != null && !targetMetadataList.isEmpty()) { + targetMetadataList.forEach(this::setMetadataProperties); + } + } + + @Override + protected String getDetailLinkId(final String name) { + return new StringBuilder(UIComponentIdProvider.TARGET_METADATA_DETAIL_LINK).append('.').append(name).toString(); + } + + @Override + protected void showMetadataDetails(final String metadataKey) { + targetManagement.get(selectedTargetId).ifPresent( + target -> UI.getCurrent().addWindow(targetMetadataPopupLayout.getWindow(target, metadataKey))); + + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java index 05213fee7..3c470a65d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.ui.distributions.dstable; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -18,7 +17,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.MetaData; import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.common.AbstractMetadataPopupLayout; +import org.eclipse.hawkbit.ui.common.AbstractMetadataPopupLayoutVersioned; import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.springframework.data.domain.PageRequest; @@ -27,9 +26,9 @@ import org.vaadin.spring.events.EventBus.UIEventBus; /** * Pop up layout to display distribution metadata. */ -public class DsMetadataPopupLayout extends AbstractMetadataPopupLayout { +public class DsMetadataPopupLayout extends AbstractMetadataPopupLayoutVersioned { - private static final long serialVersionUID = -7778944849012048106L; + private static final long serialVersionUID = 1L; private final transient DistributionSetManagement distributionSetManagement; @@ -52,7 +51,8 @@ public class DsMetadataPopupLayout extends AbstractMetadataPopupLayout { +public class SwMetadataPopupLayout extends AbstractMetadataPopupLayoutVersioned { private static final long serialVersionUID = 1L; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java index b5ea69de4..ed8158e20 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.management.targettable; import java.net.URI; import java.util.Map; +import java.util.Optional; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.EntityFactory; @@ -20,6 +21,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractTableDetailsLayout; +import org.eclipse.hawkbit.ui.common.detailslayout.TargetMetadataDetailsLayout; import org.eclipse.hawkbit.ui.common.tagdetails.TargetTagToken; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; @@ -55,11 +57,17 @@ public class TargetDetails extends AbstractTableDetailsLayout { private static final long serialVersionUID = 1L; private final TargetTagToken targetTagToken; + + private final TargetMetadataDetailsLayout targetMetadataTable; private final TargetAddUpdateWindowLayout targetAddUpdateWindowLayout; private final transient TargetManagement targetManagement; + private final TargetMetadataPopupLayout targetMetadataPopupLayout; + + private final UINotification uiNotification; + private final transient DeploymentManagement deploymentManagement; private VerticalLayout assignedDistLayout; @@ -69,15 +77,21 @@ public class TargetDetails extends AbstractTableDetailsLayout { TargetDetails(final VaadinMessageSource i18n, final UIEventBus eventBus, final SpPermissionChecker permissionChecker, final ManagementUIState managementUIState, final UINotification uiNotification, final TargetTagManagement tagManagement, - final TargetManagement targetManagement, final DeploymentManagement deploymentManagement, - final EntityFactory entityFactory, final TargetTable targetTable) { + final TargetManagement targetManagement, final TargetMetadataPopupLayout targetMetadataPopupLayout, + final DeploymentManagement deploymentManagement, final EntityFactory entityFactory, + final TargetTable targetTable) { super(i18n, eventBus, permissionChecker, managementUIState); this.targetTagToken = new TargetTagToken(permissionChecker, i18n, uiNotification, eventBus, managementUIState, tagManagement, targetManagement); - targetAddUpdateWindowLayout = new TargetAddUpdateWindowLayout(i18n, targetManagement, eventBus, uiNotification, + this.targetAddUpdateWindowLayout = new TargetAddUpdateWindowLayout(i18n, targetManagement, eventBus, + uiNotification, entityFactory, targetTable); + this.uiNotification = uiNotification; this.targetManagement = targetManagement; this.deploymentManagement = deploymentManagement; + this.targetMetadataPopupLayout = targetMetadataPopupLayout; + this.targetMetadataTable = new TargetMetadataDetailsLayout(i18n, targetManagement, + targetMetadataPopupLayout); addDetailsTab(); restoreState(); } @@ -95,6 +109,7 @@ public class TargetDetails extends AbstractTableDetailsLayout { getDetailsTab().addTab(createInstalledDistLayout(), getI18n().getMessage("header.target.installed"), null); getDetailsTab().addTab(getTagsLayout(), getI18n().getMessage("caption.tags.tab"), null); getDetailsTab().addTab(getLogLayout(), getI18n().getMessage("caption.logs.tab"), null); + getDetailsTab().addTab(targetMetadataTable, getI18n().getMessage("caption.metadata"), null); } private Component createInstalledDistLayout() { @@ -157,11 +172,7 @@ public class TargetDetails extends AbstractTableDetailsLayout { populateDistributionDtls(assignedDistLayout, null); } populateTags(targetTagToken); - } - - @Override - protected String getName() { - return getSelectedBaseEntity().getName(); + populateMetadataDetails(); } private void updateDetailsLayout(final String controllerId, final URI address, final String securityToken, @@ -324,25 +335,24 @@ public class TargetDetails extends AbstractTableDetailsLayout { return UIComponentIdProvider.TARGET_DETAILS_HEADER_LABEL_ID; } - @Override - protected boolean isMetadataIconToBeDisplayed() { - return false; - } - @Override protected void showMetadata(final ClickEvent event) { - // No implementation required + final Optional target = targetManagement.get(getSelectedBaseEntityId()); + if (!target.isPresent()) { + uiNotification.displayWarning(getI18n().getMessage("targets.not.exists")); + return; + } + UI.getCurrent().addWindow(targetMetadataPopupLayout.getWindow(target.get(), null)); } @Override protected void populateMetadataDetails() { - // No implementation required + targetMetadataTable.populateMetadata(getSelectedBaseEntity()); } @Override protected String getMetadataButtonId() { - // No implementation required - return null; + return UIComponentIdProvider.TARGET_METADATA_BUTTON; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetMetadataPopupLayout.java new file mode 100644 index 000000000..7e3a9d27d --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetMetadataPopupLayout.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.management.targettable; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.model.MetaData; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetMetadata; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.AbstractMetadataPopupLayout; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.springframework.data.domain.PageRequest; +import org.vaadin.spring.events.EventBus.UIEventBus; + +/** + * Pop up layout to display target metadata. + */ +public class TargetMetadataPopupLayout extends AbstractMetadataPopupLayout { + + private static final long serialVersionUID = 1L; + + private final transient TargetManagement targetManagement; + + private final transient EntityFactory entityFactory; + + public TargetMetadataPopupLayout(final VaadinMessageSource i18n, final UINotification uiNotification, + final UIEventBus eventBus, final TargetManagement targetManagement, final EntityFactory entityFactory, + final SpPermissionChecker permChecker) { + super(i18n, uiNotification, eventBus, permChecker); + this.targetManagement = targetManagement; + this.entityFactory = entityFactory; + } + + @Override + protected boolean checkForDuplicate(final Target entity, final String value) { + return targetManagement.getMetaDataByControllerId(entity.getControllerId(), value).isPresent(); + } + + @Override + protected MetaData createMetadata(final Target entity, final String key, final String value) { + final TargetMetadata metaData = targetManagement + .createMetaData(entity.getControllerId(), + Collections.singletonList(entityFactory.generateTargetMetadata(key, value))) + .get(0); + setSelectedEntity(metaData.getTarget()); + return metaData; + } + + @Override + protected MetaData updateMetadata(final Target entity, final String key, final String value) { + final TargetMetadata metaData = targetManagement.updateMetadata(entity.getControllerId(), + entityFactory.generateTargetMetadata(key, value)); + setSelectedEntity(metaData.getTarget()); + return metaData; + } + + @Override + protected List getMetadataList() { + return Collections.unmodifiableList(targetManagement + .findMetaDataByControllerId(new PageRequest(0, 500), getSelectedEntity().getControllerId()) + .getContent()); + } + + @Override + protected void deleteMetadata(final Target entity, final String key) { + targetManagement.deleteMetaData(entity.getControllerId(), key); + } + + @Override + protected boolean hasCreatePermission() { + return permChecker.hasCreateRepositoryPermission(); + } + + @Override + protected boolean hasUpdatePermission() { + return permChecker.hasUpdateRepositoryPermission(); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java index 44e81c8d9..996f93d42 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java @@ -47,9 +47,11 @@ public class TargetTableLayout extends AbstractTableLayout { final DeploymentManagement deploymentManagement, final UiProperties uiProperties, final SpPermissionChecker permissionChecker, final TargetTagManagement tagManagement, final DistributionSetManagement distributionSetManagement, final Executor uiExecutor) { + final TargetMetadataPopupLayout targetMetadataPopupLayout = new TargetMetadataPopupLayout(i18n, uiNotification, + eventBus, targetManagement, entityFactory, permissionChecker); this.eventBus = eventBus; this.targetDetails = new TargetDetails(i18n, eventBus, permissionChecker, managementUIState, uiNotification, - tagManagement, targetManagement, deploymentManagement, entityFactory, targetTable); + tagManagement, targetManagement, targetMetadataPopupLayout, deploymentManagement, entityFactory, targetTable); this.targetTableHeader = new TargetTableHeader(i18n, permissionChecker, eventBus, uiNotification, managementUIState, managementViewClientCriterion, targetManagement, deploymentManagement, uiProperties, entityFactory, uiNotification, tagManagement, distributionSetManagement, uiExecutor, targetTable); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java index 4dc8beaad..7cb73df05 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java @@ -470,6 +470,11 @@ public final class UIComponentIdProvider { */ public static final String SHOW_TARGET_TAGS = "show.target.tags.icon"; + /** + * Target metadata button id. + */ + public static final String TARGET_METADATA_BUTTON = "target.metadata.button"; + /** * ID-Target tag table. */ @@ -1131,7 +1136,7 @@ public final class UIComponentIdProvider { public static final String DS_TABLE_MANAGE_METADATA_ID = "dstable.manage.metadata.id"; /** - * DistributionSet - Metadata button id. + * DistributionSet - Metadata detail link. */ public static final String DS_METADATA_DETAIL_LINK = "distributionset.metadata.detail.link"; @@ -1151,10 +1156,15 @@ public final class UIComponentIdProvider { public static final String DIST_SW_MODULE_DETAILS_TABSHEET_ID = "dist.sw.module.details.tabsheet"; /** - * Software Module - Metadata button id. + * Software Module - Metadata detail link. */ public static final String SW_METADATA_DETAIL_LINK = "softwaremodule.metadata.detail.link"; + /** + * Target - Metadata detail link. + */ + public static final String TARGET_METADATA_DETAIL_LINK = "target.metadata.detail.link"; + /** * Table multiselect for selecting DistType */