Merge remote-tracking branch 'eclipse/master' into
Feature_Improve_Code_Quality Conflicts: hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>
This commit is contained in:
@@ -10,8 +10,12 @@ package org.eclipse.hawkbit.autoconfigure.amqp;
|
||||
|
||||
import org.eclipse.hawkbit.amqp.AmqpConfiguration;
|
||||
import org.eclipse.hawkbit.amqp.annotation.EnableAmqp;
|
||||
import org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* The amqp autoconfiguration.
|
||||
@@ -24,4 +28,15 @@ import org.springframework.context.annotation.Configuration;
|
||||
@EnableAmqp
|
||||
public class AmqpAutoConfiguration {
|
||||
|
||||
/**
|
||||
* Create default error handler bean.
|
||||
*
|
||||
* @return the default error handler bean
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ErrorHandler errorHandler() {
|
||||
return new ConditionalRejectingErrorHandler();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
|
||||
import org.springframework.retry.support.RetryTemplate;;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* The spring AMQP configuration which is enabled by using the profile
|
||||
@@ -263,13 +264,16 @@ public class AmqpConfiguration {
|
||||
|
||||
/**
|
||||
* Returns the Listener factory.
|
||||
*
|
||||
*
|
||||
* @param errorHandler
|
||||
* the error hander
|
||||
* @return the {@link SimpleMessageListenerContainer} that gets used receive
|
||||
* AMQP messages
|
||||
*/
|
||||
@Bean(name = { "listenerContainerFactory" })
|
||||
public RabbitListenerContainerFactory<SimpleMessageListenerContainer> listenerContainerFactory() {
|
||||
return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory);
|
||||
public RabbitListenerContainerFactory<SimpleMessageListenerContainer> listenerContainerFactory(
|
||||
final ErrorHandler errorHandler) {
|
||||
return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory, errorHandler);
|
||||
}
|
||||
|
||||
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFacto
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
|
||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* {@link RabbitListenerContainerFactory} that can be configured through
|
||||
@@ -28,10 +29,13 @@ public class ConfigurableRabbitListenerContainerFactory extends SimpleRabbitList
|
||||
* for the container factory
|
||||
* @param amqpProperties
|
||||
* to configure the container factory
|
||||
* @param errorHandler
|
||||
* the error handler which should be use
|
||||
*/
|
||||
public ConfigurableRabbitListenerContainerFactory(final AmqpProperties amqpProperties,
|
||||
final ConnectionFactory rabbitConnectionFactory) {
|
||||
final ConnectionFactory rabbitConnectionFactory, final ErrorHandler errorHandler) {
|
||||
this.amqpProperties = amqpProperties;
|
||||
setErrorHandler(errorHandler);
|
||||
setDefaultRequeueRejected(true);
|
||||
setConnectionFactory(rabbitConnectionFactory);
|
||||
setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal());
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Interface for the entity interceptor lifecycle.
|
||||
*/
|
||||
public interface EntityInterceptor {
|
||||
|
||||
/**
|
||||
* Callback for the {@link @PrePersist} lifecycle event.
|
||||
*
|
||||
* @param entity
|
||||
* the model entity
|
||||
*/
|
||||
default void prePersist(final Object entity) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for the {@link @PostPersist} lifecycle event.
|
||||
*
|
||||
* @param entity
|
||||
* the model entity
|
||||
*/
|
||||
default void postPersist(final Object entity) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for the {@link @PostRemove} lifecycle event.
|
||||
*
|
||||
* @param entity
|
||||
* the model entity
|
||||
*/
|
||||
default void postRemove(final Object entity) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for the {@link @PreRemove} lifecycle event.
|
||||
*
|
||||
* @param entity
|
||||
* the model entity
|
||||
*/
|
||||
default void preRemove(final Object entity) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for the {@link @PostLoad} lifecycle event.
|
||||
*
|
||||
* @param entity
|
||||
* the model entity
|
||||
*/
|
||||
default void postLoad(final Object entity) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for the {@link @PreUpdate} lifecycle event.
|
||||
*
|
||||
* @param entity
|
||||
* the model entity
|
||||
*/
|
||||
default void preUpdate(final Object entity) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for the {@link @PostUpdate} lifecycle event.
|
||||
*
|
||||
* @param entity
|
||||
* the model entity
|
||||
*/
|
||||
default void postUpdate(final Object entity) {
|
||||
};
|
||||
|
||||
}
|
||||
@@ -46,6 +46,7 @@ import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.CacheManagerHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemManagementHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
|
||||
@@ -144,6 +145,14 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
return SecurityTokenGeneratorHolder.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the singleton instance of the {@link EntityInterceptorHolder}
|
||||
*/
|
||||
@Bean
|
||||
public EntityInterceptorHolder entityInterceptorHolder() {
|
||||
return EntityInterceptorHolder.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the singleton instance of the {@link CacheManagerHolder}
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,8 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
*/
|
||||
@MappedSuperclass
|
||||
@Access(AccessType.FIELD)
|
||||
@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class })
|
||||
@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class,
|
||||
EntityInterceptorListener.class })
|
||||
public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.persistence.PostLoad;
|
||||
import javax.persistence.PostPersist;
|
||||
import javax.persistence.PostRemove;
|
||||
import javax.persistence.PostUpdate;
|
||||
import javax.persistence.PrePersist;
|
||||
import javax.persistence.PreRemove;
|
||||
import javax.persistence.PreUpdate;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder;
|
||||
import org.eclipse.hawkbit.repository.model.EntityInterceptor;
|
||||
|
||||
/**
|
||||
* Entity listener which calls the callback's of all registered entity
|
||||
* interceptors.
|
||||
*/
|
||||
public class EntityInterceptorListener {
|
||||
|
||||
@PrePersist
|
||||
protected void prePersist(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.prePersist(entity));
|
||||
}
|
||||
|
||||
@PostPersist
|
||||
protected void postPersist(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.postPersist(entity));
|
||||
}
|
||||
|
||||
@PostRemove
|
||||
protected void postRemove(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.postRemove(entity));
|
||||
}
|
||||
|
||||
@PreRemove
|
||||
protected void preRemove(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.preRemove(entity));
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
protected void postLoad(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.postLoad(entity));
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
protected void preUpdate(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.preUpdate(entity));
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
protected void postUpdate(final Object entity) {
|
||||
notifyAll(interceptor -> interceptor.postUpdate(entity));
|
||||
}
|
||||
|
||||
private void notifyAll(final Consumer<? super EntityInterceptor> action) {
|
||||
EntityInterceptorHolder.getInstance().getEntityInterceptors().forEach(action);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model.helper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.EntityInterceptor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* A singleton bean which holds the {@link EntityInterceptor} to have all
|
||||
* interceptors in spring beans.
|
||||
*
|
||||
*/
|
||||
public final class EntityInterceptorHolder {
|
||||
|
||||
private static final EntityInterceptorHolder SINGLETON = new EntityInterceptorHolder();
|
||||
|
||||
@Autowired(required = false)
|
||||
private final List<EntityInterceptor> entityInterceptors = new ArrayList<>();
|
||||
|
||||
private EntityInterceptorHolder() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entity intreceptor holder singleton instance
|
||||
*/
|
||||
public static EntityInterceptorHolder getInstance() {
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
public List<EntityInterceptor> getEntityInterceptors() {
|
||||
return entityInterceptors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder;
|
||||
import org.eclipse.hawkbit.repository.model.EntityInterceptor;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test the entity listener interceptor.
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Entity Listener Interceptor")
|
||||
public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Override
|
||||
public void after() {
|
||||
EntityInterceptorHolder.getInstance().getEntityInterceptors().clear();
|
||||
super.after();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that the pre persist is called after a entity creation.")
|
||||
public void prePersistIsCalledWhenPersistingATarget() {
|
||||
executePersistAndAssertCallbackResult(new PrePersistEntityListener());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that the post persist is called after a entity creation.")
|
||||
public void postPersistIsCalledWhenPersistingATarget() {
|
||||
executePersistAndAssertCallbackResult(new PostPersistEntityListener());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that the post load is called after a entity is loaded.")
|
||||
public void postLoadIsCalledWhenLoadATarget() {
|
||||
final PostLoadEntityListener postLoadEntityListener = new PostLoadEntityListener();
|
||||
EntityInterceptorHolder.getInstance().getEntityInterceptors().add(postLoadEntityListener);
|
||||
|
||||
final Target targetToBeCreated = entityFactory.generateTarget("targetToBeCreated");
|
||||
|
||||
targetManagement.createTarget(targetToBeCreated);
|
||||
|
||||
final Target loadedTarget = targetManagement.findTargetByControllerID(targetToBeCreated.getControllerId());
|
||||
assertThat(postLoadEntityListener.getEntity()).isNotNull();
|
||||
assertThat(postLoadEntityListener.getEntity()).isEqualTo(loadedTarget);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that the pre update is called after a entity update.")
|
||||
public void preUpdateIsCalledWhenUpdateATarget() {
|
||||
executeUpdateAndAssertCallbackResult(new PreUpdateEntityListener());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that the post update is called after a entity update.")
|
||||
public void postUpdateIsCalledWhenUpdateATarget() {
|
||||
executeUpdateAndAssertCallbackResult(new PostUpdateEntityListener());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that the pre remove is called after a entity deletion.")
|
||||
public void preRemoveIsCalledWhenDeletingATarget() {
|
||||
executeDeleteAndAssertCallbackResult(new PreRemoveEntityListener());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that the post remove is called after a entity deletion.")
|
||||
public void postRemoveIsCalledWhenDeletingATarget() {
|
||||
executeDeleteAndAssertCallbackResult(new PostRemoveEntityListener());
|
||||
}
|
||||
|
||||
private void executePersistAndAssertCallbackResult(final AbstractEntityListener entityInterceptor) {
|
||||
final Target targetToBeCreated = entityFactory.generateTarget("targetToBeCreated");
|
||||
addListenerAndCreateTarget(entityInterceptor, targetToBeCreated);
|
||||
|
||||
assertThat(entityInterceptor.getEntity()).isNotNull();
|
||||
assertThat(entityInterceptor.getEntity()).isEqualTo(targetToBeCreated);
|
||||
}
|
||||
|
||||
private void executeUpdateAndAssertCallbackResult(final AbstractEntityListener entityInterceptor) {
|
||||
Target updateTarget = addListenerAndCreateTarget(entityInterceptor,
|
||||
entityFactory.generateTarget("targetToBeCreated"));
|
||||
updateTarget.setDescription("New");
|
||||
|
||||
updateTarget = targetManagement.updateTarget(updateTarget);
|
||||
|
||||
assertThat(entityInterceptor.getEntity()).isNotNull();
|
||||
assertThat(entityInterceptor.getEntity()).isEqualTo(updateTarget);
|
||||
}
|
||||
|
||||
private void executeDeleteAndAssertCallbackResult(final AbstractEntityListener entityInterceptor) {
|
||||
EntityInterceptorHolder.getInstance().getEntityInterceptors().add(entityInterceptor);
|
||||
final SoftwareModuleType type = softwareManagement
|
||||
.createSoftwareModuleType(entityFactory.generateSoftwareModuleType("test", "test", "test", 1));
|
||||
|
||||
softwareManagement.deleteSoftwareModuleType(type);
|
||||
assertThat(entityInterceptor.getEntity()).isNotNull();
|
||||
assertThat(entityInterceptor.getEntity()).isEqualTo(type);
|
||||
}
|
||||
|
||||
private Target addListenerAndCreateTarget(final AbstractEntityListener entityInterceptor,
|
||||
final Target targetToBeCreated) {
|
||||
EntityInterceptorHolder.getInstance().getEntityInterceptors().add(entityInterceptor);
|
||||
return targetManagement.createTarget(targetToBeCreated);
|
||||
}
|
||||
|
||||
private static abstract class AbstractEntityListener implements EntityInterceptor {
|
||||
|
||||
private Object entity;
|
||||
|
||||
public Object getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void setEntity(final Object entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PrePersistEntityListener extends AbstractEntityListener {
|
||||
@Override
|
||||
public void prePersist(final Object entity) {
|
||||
setEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PostPersistEntityListener extends AbstractEntityListener {
|
||||
@Override
|
||||
public void postPersist(final Object entity) {
|
||||
setEntity(entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class PostLoadEntityListener extends AbstractEntityListener {
|
||||
@Override
|
||||
public void postLoad(final Object entity) {
|
||||
setEntity(entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class PreUpdateEntityListener extends AbstractEntityListener {
|
||||
@Override
|
||||
public void preUpdate(final Object entity) {
|
||||
setEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PostUpdateEntityListener extends AbstractEntityListener {
|
||||
@Override
|
||||
public void postUpdate(final Object entity) {
|
||||
setEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PreRemoveEntityListener extends AbstractEntityListener {
|
||||
@Override
|
||||
public void preRemove(final Object entity) {
|
||||
setEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PostRemoveEntityListener extends AbstractEntityListener {
|
||||
@Override
|
||||
public void postRemove(final Object entity) {
|
||||
setEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,10 +30,7 @@ import com.vaadin.ui.VerticalLayout;
|
||||
* View class that is instantiated when no other view matches the navigation
|
||||
* state.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @see Navigator#setErrorView(Class)
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
@SpringComponent
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.Set;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.eclipse.hawkbit.ui.components.SPUIErrorHandler;
|
||||
import org.eclipse.hawkbit.ui.components.HawkbitUIErrorHandler;
|
||||
import org.eclipse.hawkbit.ui.menu.DashboardEvent.PostViewChangeEvent;
|
||||
import org.eclipse.hawkbit.ui.menu.DashboardMenu;
|
||||
import org.eclipse.hawkbit.ui.menu.DashboardMenuItem;
|
||||
@@ -180,7 +180,10 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener {
|
||||
final String locale = getLocaleId(SPUIDefinitions.getAvailableLocales());
|
||||
setLocale(new Locale(locale));
|
||||
|
||||
UI.getCurrent().setErrorHandler(new SPUIErrorHandler());
|
||||
if (UI.getCurrent().getErrorHandler() == null) {
|
||||
UI.getCurrent().setErrorHandler(new HawkbitUIErrorHandler());
|
||||
}
|
||||
|
||||
LOG.info("Current locale of the application is : {}", i18n.getLocale());
|
||||
}
|
||||
|
||||
|
||||
@@ -115,10 +115,10 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta
|
||||
protected void populateDetailsWidget() {
|
||||
String maxAssign = HawkbitCommonUtil.SP_STRING_EMPTY;
|
||||
if (getSelectedBaseEntity() != null) {
|
||||
if (getSelectedBaseEntity().getType().getMaxAssignments() == Integer.MAX_VALUE) {
|
||||
maxAssign = getI18n().get("label.multiAssign.type");
|
||||
} else {
|
||||
if (getSelectedBaseEntity().getType().getMaxAssignments() == 1) {
|
||||
maxAssign = getI18n().get("label.singleAssign.type");
|
||||
} else {
|
||||
maxAssign = getI18n().get("label.multiAssign.type");
|
||||
}
|
||||
updateSoftwareModuleDetailsLayout(getSelectedBaseEntity().getType().getName(),
|
||||
getSelectedBaseEntity().getVendor(), maxAssign);
|
||||
|
||||
@@ -185,6 +185,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout {
|
||||
assignOptiongroup.setStyleName(ValoTheme.OPTIONGROUP_SMALL);
|
||||
assignOptiongroup.addStyleName("custom-option-group");
|
||||
assignOptiongroup.setNullSelectionAllowed(false);
|
||||
assignOptiongroup.setId(SPUIDefinitions.ASSIGN_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID);
|
||||
assignOptiongroup.select(tagOptions.get(0));
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,10 @@ import com.vaadin.data.util.IndexedContainer;
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Button.ClickEvent;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Table;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
@@ -60,8 +62,6 @@ public class SoftwareModuleDetailsTable extends Table {
|
||||
|
||||
private static final String SOFT_TYPE_MANDATORY = "mandatory";
|
||||
|
||||
private static final String UNASSIGN_SOFT_MODULE = "unassignSoftModule";
|
||||
|
||||
private boolean isTargetAssigned;
|
||||
|
||||
private boolean isUnassignSoftModAllowed;
|
||||
@@ -109,7 +109,6 @@ public class SoftwareModuleDetailsTable extends Table {
|
||||
|
||||
private void createSwModuleTable() {
|
||||
addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES);
|
||||
addStyleName(ValoTheme.TABLE_NO_STRIPES);
|
||||
setSelectable(false);
|
||||
setImmediate(true);
|
||||
setContainerDataSource(getSwModuleContainer());
|
||||
@@ -123,22 +122,13 @@ public class SoftwareModuleDetailsTable extends Table {
|
||||
final IndexedContainer container = new IndexedContainer();
|
||||
container.addContainerProperty(SOFT_TYPE_MANDATORY, Label.class, "");
|
||||
container.addContainerProperty(SOFT_TYPE_NAME, Label.class, "");
|
||||
container.addContainerProperty(SOFT_MODULE, Label.class, "");
|
||||
if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission()) {
|
||||
container.addContainerProperty(UNASSIGN_SOFT_MODULE, Button.class, "");
|
||||
}
|
||||
container.addContainerProperty(SOFT_MODULE, VerticalLayout.class, "");
|
||||
setColumnExpandRatio(SOFT_TYPE_MANDATORY, 0.1f);
|
||||
setColumnExpandRatio(SOFT_TYPE_NAME, 0.4f);
|
||||
setColumnExpandRatio(SOFT_MODULE, 0.3f);
|
||||
if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission()) {
|
||||
setColumnExpandRatio(UNASSIGN_SOFT_MODULE, 0.2F);
|
||||
}
|
||||
setColumnAlignment(SOFT_TYPE_MANDATORY, Align.RIGHT);
|
||||
setColumnAlignment(SOFT_TYPE_NAME, Align.LEFT);
|
||||
setColumnAlignment(SOFT_MODULE, Align.LEFT);
|
||||
if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission()) {
|
||||
setColumnAlignment(UNASSIGN_SOFT_MODULE, Align.RIGHT);
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
@@ -146,10 +136,6 @@ public class SoftwareModuleDetailsTable extends Table {
|
||||
setColumnHeader(SOFT_TYPE_MANDATORY, "");
|
||||
setColumnHeader(SOFT_TYPE_NAME, i18n.get("header.caption.typename"));
|
||||
setColumnHeader(SOFT_MODULE, i18n.get("header.caption.softwaremodule"));
|
||||
if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission()) {
|
||||
setColumnHeader(UNASSIGN_SOFT_MODULE, i18n.get("header.caption.unassign"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,31 +174,18 @@ public class SoftwareModuleDetailsTable extends Table {
|
||||
final Item saveTblitem = getContainerDataSource().addItem(swModType.getName());
|
||||
final Label mandatoryLabel = createMandatoryLabel(isMandatory);
|
||||
final Label typeName = HawkbitCommonUtil.getFormatedLabel(swModType.getName());
|
||||
final VerticalLayout verticalLayout = createSoftModuleLayout(swModType, distributionSet,
|
||||
alreadyAssignedSwModules);
|
||||
|
||||
final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(HawkbitCommonUtil.SP_STRING_EMPTY);
|
||||
final Button reassignSoftModule = SPUIComponentProvider.getButton(swModType.getName(), "", "", "", true,
|
||||
FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class);
|
||||
|
||||
reassignSoftModule.addClickListener(event -> unassignSW(event, distributionSet, alreadyAssignedSwModules));
|
||||
if (null != alreadyAssignedSwModules && !alreadyAssignedSwModules.isEmpty()) {
|
||||
final String swModuleName = getSwModuleName(alreadyAssignedSwModules, swModType);
|
||||
softwareModule.setValue(swModuleName);
|
||||
softwareModule.setDescription(swModuleName);
|
||||
}
|
||||
saveTblitem.getItemProperty(SOFT_TYPE_MANDATORY).setValue(mandatoryLabel);
|
||||
saveTblitem.getItemProperty(SOFT_TYPE_NAME).setValue(typeName);
|
||||
saveTblitem.getItemProperty(SOFT_MODULE).setValue(softwareModule);
|
||||
if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission() && !isTargetAssigned
|
||||
&& (isSoftModAvaiableForSoftType(alreadyAssignedSwModules, swModType))) {
|
||||
saveTblitem.getItemProperty(UNASSIGN_SOFT_MODULE).setValue(reassignSoftModule);
|
||||
}
|
||||
saveTblitem.getItemProperty(SOFT_MODULE).setValue(verticalLayout);
|
||||
|
||||
}
|
||||
|
||||
private void unassignSW(final ClickEvent event, final DistributionSet distributionSet,
|
||||
final Set<SoftwareModule> alreadyAssignedSwModules) {
|
||||
final SoftwareModule unAssignedSw = getSoftwareModule((Label) getContainerDataSource()
|
||||
.getItem(event.getButton().getId()).getItemProperty(SOFT_MODULE).getValue(), alreadyAssignedSwModules);
|
||||
final SoftwareModule unAssignedSw = getSoftwareModule(event.getButton().getId(), alreadyAssignedSwModules);
|
||||
final DistributionSet newDistributionSet = distributionSetManagement.unassignSoftwareModule(distributionSet,
|
||||
unAssignedSw);
|
||||
manageDistUIState.setLastSelectedEntity(DistributionSetIdName.generate(newDistributionSet));
|
||||
@@ -233,15 +206,46 @@ public class SoftwareModuleDetailsTable extends Table {
|
||||
|
||||
}
|
||||
|
||||
private VerticalLayout createSoftModuleLayout(final SoftwareModuleType swModType,
|
||||
final DistributionSet distributionSet, final Set<SoftwareModule> alreadyAssignedSwModules) {
|
||||
final VerticalLayout verticalLayout = new VerticalLayout();
|
||||
for (final SoftwareModule sw : alreadyAssignedSwModules) {
|
||||
if (swModType.getKey().equals(sw.getType().getKey())) {
|
||||
final HorizontalLayout horizontalLayout = new HorizontalLayout();
|
||||
horizontalLayout.setSizeFull();
|
||||
final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(HawkbitCommonUtil.SP_STRING_EMPTY);
|
||||
final Button reassignSoftModule = SPUIComponentProvider.getButton(sw.getName(), "", "", "", true,
|
||||
FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class);
|
||||
reassignSoftModule
|
||||
.addClickListener(event -> unassignSW(event, distributionSet, alreadyAssignedSwModules));
|
||||
final String softwareModNameVersion = HawkbitCommonUtil.getFormattedNameVersion(sw.getName(),
|
||||
sw.getVersion());
|
||||
softwareModule.setValue(softwareModNameVersion);
|
||||
softwareModule.setDescription(softwareModNameVersion);
|
||||
softwareModule.setId(sw.getName() + "-label");
|
||||
horizontalLayout.addComponent(softwareModule);
|
||||
horizontalLayout.setExpandRatio(softwareModule, 1F);
|
||||
if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission() && !isTargetAssigned
|
||||
&& (isSoftModAvaiableForSoftType(alreadyAssignedSwModules, swModType))) {
|
||||
horizontalLayout.addComponent(reassignSoftModule);
|
||||
}
|
||||
verticalLayout.addComponent(horizontalLayout);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return verticalLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value
|
||||
* @param alreadyAssignedSwModules
|
||||
* @return
|
||||
*/
|
||||
protected SoftwareModule getSoftwareModule(final Label softwareModule,
|
||||
protected SoftwareModule getSoftwareModule(final String softwareModule,
|
||||
final Set<SoftwareModule> alreadyAssignedSwModules) {
|
||||
for (final SoftwareModule sw : alreadyAssignedSwModules) {
|
||||
if (softwareModule.getValue().contains(sw.getName())) {
|
||||
if (softwareModule.equals(sw.getName())) {
|
||||
return sw;
|
||||
}
|
||||
}
|
||||
@@ -256,15 +260,4 @@ public class SoftwareModuleDetailsTable extends Table {
|
||||
}
|
||||
return mandatoryLable;
|
||||
}
|
||||
|
||||
private String getSwModuleName(final Set<SoftwareModule> swModulesSet, final SoftwareModuleType swModType) {
|
||||
final StringBuilder assignedSWModules = new StringBuilder();
|
||||
for (final SoftwareModule sw : swModulesSet) {
|
||||
if (swModType.getKey().equals(sw.getType().getKey())) {
|
||||
assignedSWModules.append(HawkbitCommonUtil.getFormattedNameVersion(sw.getName(), sw.getVersion()))
|
||||
.append("</br>");
|
||||
}
|
||||
}
|
||||
return assignedSWModules.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.components;
|
||||
|
||||
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
||||
|
||||
import com.vaadin.shared.Position;
|
||||
import com.vaadin.ui.Notification;
|
||||
|
||||
/**
|
||||
* Notification message component for displaying errors in the UI.
|
||||
*/
|
||||
public class HawkbitErrorNotificationMessage extends Notification {
|
||||
|
||||
private static final long serialVersionUID = -6512576924243195753L;
|
||||
|
||||
/**
|
||||
* Constructor of HawkbitErrorNotificationMessage
|
||||
*
|
||||
* @param style
|
||||
* style of the notification message
|
||||
* @param caption
|
||||
* caption of the notification message
|
||||
* @param description
|
||||
* text which is displayed in the notification
|
||||
* @param autoClose
|
||||
* boolean if notification is closed after random click (true) or
|
||||
* closed by clicking on the notification (false)
|
||||
*/
|
||||
public HawkbitErrorNotificationMessage(final String style, final String caption, final String description,
|
||||
final boolean autoClose) {
|
||||
super(caption);
|
||||
setStyleName(style);
|
||||
if (autoClose) {
|
||||
setDelayMsec(SPUILabelDefinitions.SP_DELAY);
|
||||
} else {
|
||||
setDelayMsec(-1);
|
||||
}
|
||||
setHtmlContentAllowed(true);
|
||||
setPosition(Position.BOTTOM_RIGHT);
|
||||
setDescription(description);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.components;
|
||||
|
||||
import static com.vaadin.ui.themes.ValoTheme.NOTIFICATION_CLOSABLE;
|
||||
import static com.vaadin.ui.themes.ValoTheme.NOTIFICATION_FAILURE;
|
||||
import static com.vaadin.ui.themes.ValoTheme.NOTIFICATION_SMALL;
|
||||
|
||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||
import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.vaadin.server.DefaultErrorHandler;
|
||||
import com.vaadin.server.ErrorEvent;
|
||||
import com.vaadin.server.Page;
|
||||
import com.vaadin.ui.Component;
|
||||
|
||||
/**
|
||||
* Default handler for SP UI.
|
||||
*/
|
||||
public class HawkbitUIErrorHandler extends DefaultErrorHandler {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HawkbitUIErrorHandler.class);
|
||||
|
||||
private static final String STYLE = NOTIFICATION_FAILURE + " " + NOTIFICATION_SMALL + " " + NOTIFICATION_CLOSABLE;
|
||||
|
||||
@Override
|
||||
public void error(final ErrorEvent event) {
|
||||
|
||||
LOG.error("Error in UI: ", event.getThrowable());
|
||||
|
||||
final Optional<Page> originError = getPageOriginError(event);
|
||||
|
||||
if (originError.isPresent()) {
|
||||
final HawkbitErrorNotificationMessage message = buildNotification(getRootExceptionFrom(event));
|
||||
message.show(originError.get());
|
||||
}
|
||||
}
|
||||
|
||||
private static Throwable getRootExceptionFrom(final ErrorEvent event) {
|
||||
|
||||
return getRootCauseOf(event.getThrowable());
|
||||
}
|
||||
|
||||
private static Throwable getRootCauseOf(final Throwable exception) {
|
||||
|
||||
if (exception.getCause() != null) {
|
||||
return getRootCauseOf(exception.getCause());
|
||||
}
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
private static Optional<Page> getPageOriginError(final ErrorEvent event) {
|
||||
|
||||
final Component errorOrigin = findAbstractComponent(event);
|
||||
|
||||
if (errorOrigin != null && errorOrigin.getUI() != null) {
|
||||
return Optional.fromNullable(errorOrigin.getUI().getPage());
|
||||
}
|
||||
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
protected HawkbitErrorNotificationMessage buildNotification(final Throwable exception) {
|
||||
|
||||
final I18N i18n = SpringContextHelper.getBean(I18N.class);
|
||||
return new HawkbitErrorNotificationMessage(STYLE, i18n.get("caption.error"),
|
||||
i18n.get("message.error.temp", exception.getClass().getSimpleName()), false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.components;
|
||||
|
||||
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
||||
|
||||
import com.vaadin.server.Page;
|
||||
import com.vaadin.shared.Position;
|
||||
import com.vaadin.ui.Notification;
|
||||
|
||||
/**
|
||||
* Notification message component.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class SPNotificationMessage extends Notification {
|
||||
|
||||
/**
|
||||
* ID.
|
||||
*/
|
||||
private static final long serialVersionUID = -6512576924243195753L;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public SPNotificationMessage() {
|
||||
super("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification message component.
|
||||
*
|
||||
* @param styleName
|
||||
* style name of message
|
||||
* @param caption
|
||||
* message caption
|
||||
* @param description
|
||||
* message description
|
||||
* @param autoClose
|
||||
* flag to indicate enable close option
|
||||
* @param page
|
||||
* current {@link Page}
|
||||
*/
|
||||
public void showNotification(final String styleName, final String caption, final String description,
|
||||
final Boolean autoClose, final Page page) {
|
||||
decorate(styleName, caption, description, autoClose);
|
||||
this.show(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorate.
|
||||
*
|
||||
* @param styleName
|
||||
* style name of message
|
||||
* @param caption
|
||||
* message caption
|
||||
* @param description
|
||||
* message description
|
||||
* @param autoClose
|
||||
* flag to indicate enable close option
|
||||
*/
|
||||
private void decorate(final String styleName, final String caption, final String description,
|
||||
final Boolean autoClose) {
|
||||
setCaption(caption);
|
||||
setDescription(description);
|
||||
setStyleName(styleName);
|
||||
setHtmlContentAllowed(true);
|
||||
setPosition(Position.BOTTOM_RIGHT);
|
||||
if (autoClose) {
|
||||
setDelayMsec(SPUILabelDefinitions.SP_DELAY);
|
||||
} else {
|
||||
setDelayMsec(-1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.components;
|
||||
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||
import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.vaadin.server.DefaultErrorHandler;
|
||||
import com.vaadin.server.ErrorEvent;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
*
|
||||
* Default handler for SP UI.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class SPUIErrorHandler extends DefaultErrorHandler {
|
||||
|
||||
/**
|
||||
* Comment for <code>serialVersionUID</code>.
|
||||
*/
|
||||
private static final long serialVersionUID = 1877326479308824191L;
|
||||
/**
|
||||
* logger.
|
||||
*/
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SPUIErrorHandler.class);
|
||||
|
||||
@Override
|
||||
public void error(final ErrorEvent event) {
|
||||
final SPNotificationMessage notification = new SPNotificationMessage();
|
||||
// Build error style
|
||||
final StringBuilder style = new StringBuilder(ValoTheme.NOTIFICATION_FAILURE);
|
||||
style.append(' ');
|
||||
style.append(ValoTheme.NOTIFICATION_SMALL);
|
||||
style.append(' ');
|
||||
style.append(ValoTheme.NOTIFICATION_CLOSABLE);
|
||||
final I18N i18n = SpringContextHelper.getBean(I18N.class);
|
||||
String exceptionName = null;
|
||||
// From the exception trace we get the expected exception class name
|
||||
for (Throwable error = event.getThrowable(); error != null; error = error.getCause()) {
|
||||
exceptionName = HawkbitCommonUtil.getLastSequenceBySplitByDot(error.getClass().getName());
|
||||
LOG.error("Error in SP-UI:", error);
|
||||
}
|
||||
final Component errorOrgin = findAbstractComponent(event);
|
||||
if (null != errorOrgin && errorOrgin.getUI() != null) {
|
||||
notification.showNotification(style.toString(), i18n.get("caption.error"),
|
||||
i18n.get("message.error.temp", new Object[] { exceptionName }), false,
|
||||
errorOrgin.getUI().getPage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Button.ClickEvent;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.TabSheet;
|
||||
import com.vaadin.ui.UI;
|
||||
@@ -67,8 +68,6 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
|
||||
private static final String SOFT_MODULE = "softwareModule";
|
||||
|
||||
private static final String UNASSIGN_SOFT_MODULE = "unassignSoftModule";
|
||||
|
||||
@Autowired
|
||||
private ManageDistUIState manageDistUIState;
|
||||
|
||||
@@ -180,27 +179,25 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
for (final Map.Entry<String, StringBuilder> entry : assignedSWModule.entrySet()) {
|
||||
item = softwareModuleTable.getContainerDataSource().getItem(entry.getKey());
|
||||
if (item != null) {
|
||||
item.getItemProperty(SOFT_MODULE)
|
||||
.setValue(HawkbitCommonUtil.getFormatedLabel(entry.getValue().toString()));
|
||||
assignSoftModuleButton(item, entry);
|
||||
|
||||
item.getItemProperty(SOFT_MODULE).setValue(createSoftModuleLayout(entry.getValue().toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void assignSoftModuleButton(final Item item, final Map.Entry<String, StringBuilder> entry) {
|
||||
private Button assignSoftModuleButton(final String softwareModuleName) {
|
||||
if (getPermissionChecker().hasUpdateDistributionPermission() && distributionSetManagement
|
||||
.findDistributionSetById(manageDistUIState.getLastSelectedDistribution().get().getId())
|
||||
.getAssignedTargets().isEmpty()) {
|
||||
final Button reassignSoftModule = SPUIComponentProvider.getButton(entry.getKey(), "", "", "", true,
|
||||
final Button reassignSoftModule = SPUIComponentProvider.getButton(softwareModuleName, "", "", "", true,
|
||||
FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class);
|
||||
reassignSoftModule.setEnabled(false);
|
||||
item.getItemProperty(UNASSIGN_SOFT_MODULE).setValue(reassignSoftModule);
|
||||
return reassignSoftModule;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getUnsavedAssigedSwModule(final String name, final String version) {
|
||||
private static String getUnsavedAssigedSwModule(final String name, final String version) {
|
||||
return HawkbitCommonUtil.getFormattedNameVersion(name, version);
|
||||
}
|
||||
|
||||
@@ -215,7 +212,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
* type is drroped, then add to the list.
|
||||
*/
|
||||
|
||||
if (module.getType().getMaxAssignments() == Integer.MAX_VALUE) {
|
||||
if (module.getType().getMaxAssignments() > 1) {
|
||||
assignedSWModule.get(module.getType().getName()).append("</br>").append("<I>")
|
||||
.append(getUnsavedAssigedSwModule(module.getName(), module.getVersion())).append("</I>");
|
||||
}
|
||||
@@ -238,14 +235,27 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
||||
for (final Map.Entry<String, StringBuilder> entry : assignedSWModule.entrySet()) {
|
||||
final Item item = softwareModuleTable.getContainerDataSource().getItem(entry.getKey());
|
||||
if (item != null) {
|
||||
item.getItemProperty(SOFT_MODULE)
|
||||
.setValue(HawkbitCommonUtil.getFormatedLabel(entry.getValue().toString()));
|
||||
assignSoftModuleButton(item, entry);
|
||||
|
||||
item.getItemProperty(SOFT_MODULE).setValue(createSoftModuleLayout(entry.getValue().toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private VerticalLayout createSoftModuleLayout(final String softwareModuleName) {
|
||||
final VerticalLayout verticalLayout = new VerticalLayout();
|
||||
final HorizontalLayout horizontalLayout = new HorizontalLayout();
|
||||
horizontalLayout.setSizeFull();
|
||||
final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(HawkbitCommonUtil.SP_STRING_EMPTY);
|
||||
final Button reassignSoftModule = assignSoftModuleButton(softwareModuleName);
|
||||
softwareModule.setValue(softwareModuleName);
|
||||
softwareModule.setDescription(softwareModuleName);
|
||||
softwareModule.setId(softwareModuleName + "-label");
|
||||
horizontalLayout.addComponent(softwareModule);
|
||||
horizontalLayout.setExpandRatio(softwareModule, 1F);
|
||||
horizontalLayout.addComponent(reassignSoftModule);
|
||||
verticalLayout.addComponent(horizontalLayout);
|
||||
return verticalLayout;
|
||||
}
|
||||
|
||||
private VerticalLayout createSoftwareModuleTab() {
|
||||
final VerticalLayout softwareLayout = getTabLayout();
|
||||
softwareLayout.setSizeFull();
|
||||
|
||||
@@ -307,7 +307,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
|
||||
private void handleSoftwareCase(final Map<Long, HashSet<SoftwareModuleIdName>> map,
|
||||
final SoftwareModule softwareModule, final SoftwareModuleIdName softwareModuleIdName) {
|
||||
if (softwareModule.getType().getMaxAssignments() == Integer.MAX_VALUE) {
|
||||
if (softwareModule.getType().getMaxAssignments() > 1) {
|
||||
if (!map.containsKey(softwareModule.getType().getId())) {
|
||||
map.put(softwareModule.getType().getId(), new HashSet<SoftwareModuleIdName>());
|
||||
}
|
||||
|
||||
@@ -150,10 +150,10 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay
|
||||
private void populateDetails() {
|
||||
String maxAssign = HawkbitCommonUtil.SP_STRING_EMPTY;
|
||||
if (getSelectedBaseEntity() != null) {
|
||||
if (getSelectedBaseEntity().getType().getMaxAssignments() == Integer.MAX_VALUE) {
|
||||
maxAssign = getI18n().get("label.multiAssign.type");
|
||||
} else {
|
||||
if (getSelectedBaseEntity().getType().getMaxAssignments() == 1) {
|
||||
maxAssign = getI18n().get("label.singleAssign.type");
|
||||
} else {
|
||||
maxAssign = getI18n().get("label.multiAssign.type");
|
||||
}
|
||||
updateSwModuleDetailsLayout(getSelectedBaseEntity().getType().getName(),
|
||||
getSelectedBaseEntity().getVendor(), maxAssign);
|
||||
|
||||
@@ -210,18 +210,18 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private boolean isDistributionSetSelected(final DistributionSet ds) {
|
||||
final DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent()
|
||||
? managementUIState.getLastSelectedDistribution().get() : null;
|
||||
return ds != null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName())
|
||||
final DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState
|
||||
.getLastSelectedDistribution().get() : null;
|
||||
return ds!=null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName())
|
||||
&& lastselectedManageDS.getVersion().endsWith(ds.getVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void showMetadata(final ClickEvent event) {
|
||||
final DistributionSet ds = distributionSetManagement
|
||||
.findDistributionSetByIdWithDetails(getSelectedBaseEntityId());
|
||||
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null));
|
||||
final DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId());
|
||||
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
||||
import org.eclipse.hawkbit.ui.common.tagdetails.AbstractTagToken.TagData;
|
||||
import org.eclipse.hawkbit.ui.components.HawkbitErrorNotificationMessage;
|
||||
import org.eclipse.hawkbit.ui.management.event.BulkUploadValidationMessageEvent;
|
||||
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
|
||||
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent;
|
||||
@@ -40,12 +41,14 @@ import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
||||
import org.eclipse.hawkbit.ui.management.state.TargetBulkUpload;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
|
||||
import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.vaadin.spring.events.EventBus;
|
||||
|
||||
import com.vaadin.server.Page;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
@@ -445,7 +448,9 @@ public class BulkUploadHandler extends CustomComponent
|
||||
@Override
|
||||
public void uploadStarted(final StartedEvent event) {
|
||||
if (!event.getFilename().endsWith(".csv")) {
|
||||
uINotification.displayError(i18n.get("bulk.targets.upload"), null, true);
|
||||
|
||||
new HawkbitErrorNotificationMessage(SPUILabelDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE, null,
|
||||
i18n.get("bulk.targets.upload"), true).show(Page.getCurrent());
|
||||
LOG.error("Wrong file format for file {}", event.getFilename());
|
||||
upload.interruptUpload();
|
||||
} else {
|
||||
|
||||
@@ -590,24 +590,6 @@ public final class HawkbitCommonUtil {
|
||||
return requiredExtraWidth + minTableWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the Last sequence of string which is after last dot in String.
|
||||
*
|
||||
* @param name
|
||||
* dotted String name
|
||||
* @return String name
|
||||
*/
|
||||
public static String getLastSequenceBySplitByDot(final String name) {
|
||||
String lastSequence = null;
|
||||
if (null != name) {
|
||||
final String[] strArray = name.split("\\.");
|
||||
if (strArray.length > 0) {
|
||||
lastSequence = strArray[strArray.length - 1];
|
||||
}
|
||||
}
|
||||
return lastSequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the prefix from text.
|
||||
*
|
||||
|
||||
@@ -16,8 +16,6 @@ import com.vaadin.ui.Notification;
|
||||
|
||||
/**
|
||||
* Show notification messages.
|
||||
*
|
||||
*
|
||||
*/
|
||||
@UIScope
|
||||
@SpringComponent
|
||||
@@ -27,8 +25,6 @@ public class NotificationMessage extends Notification {
|
||||
|
||||
/**
|
||||
* Default constructor of notification message.
|
||||
*
|
||||
* @param caption
|
||||
*/
|
||||
public NotificationMessage() {
|
||||
super("");
|
||||
|
||||
@@ -309,6 +309,11 @@ public final class SPUIDefinitions {
|
||||
* New Create Update option group id.
|
||||
*/
|
||||
public static final String CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID = "create.option.group.dist.set.type.id";
|
||||
|
||||
/**
|
||||
* Assign option group id(Firmware/Software).
|
||||
*/
|
||||
public static final String ASSIGN_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID = "assign.option.group.soft.module.type.id";
|
||||
/**
|
||||
* SW Module Source Table ID.
|
||||
*/
|
||||
|
||||
@@ -54,6 +54,7 @@ public final class SPUILabelDefinitions {
|
||||
*/
|
||||
public static final String SP_NOTIFICATION_ERROR_MESSAGE_STYLE = ValoTheme.NOTIFICATION_ERROR + " "
|
||||
+ ValoTheme.NOTIFICATION_TRAY;
|
||||
|
||||
/**
|
||||
* Style - Warning.
|
||||
*/
|
||||
@@ -539,13 +540,12 @@ public final class SPUILabelDefinitions {
|
||||
* Total target coulmn property name.
|
||||
*/
|
||||
public static final String VAR_TOTAL_TARGETS = "totalTargetsCount";
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Total target count status coulmn property name.
|
||||
*/
|
||||
public static final String VAR_TOTAL_TARGETS_COUNT_STATUS = "totalTargetCountStatus";
|
||||
|
||||
|
||||
/**
|
||||
* Rollout group started date column property.
|
||||
*/
|
||||
@@ -560,7 +560,7 @@ public final class SPUILabelDefinitions {
|
||||
* Rollout group installed percentage column property.
|
||||
*/
|
||||
public static final String ROLLOUT_GROUP_INSTALLED_PERCENTAGE = "finishedPercentage";
|
||||
|
||||
|
||||
/**
|
||||
* Add metadata icon.
|
||||
*/
|
||||
|
||||
@@ -18,8 +18,6 @@ import com.vaadin.spring.annotation.ViewScope;
|
||||
|
||||
/**
|
||||
* Show success and error messages.
|
||||
*
|
||||
*
|
||||
*/
|
||||
@ViewScope
|
||||
@SpringComponent
|
||||
@@ -33,8 +31,6 @@ public class UINotification implements Serializable {
|
||||
/**
|
||||
* Display success type of notification message.
|
||||
*
|
||||
* @param notificationMessage
|
||||
* as reference
|
||||
* @param message
|
||||
* is the message to displayed as success.
|
||||
*/
|
||||
@@ -46,8 +42,6 @@ public class UINotification implements Serializable {
|
||||
/**
|
||||
* Display error type of notification message.
|
||||
*
|
||||
* @param notificationMessage
|
||||
* as reference
|
||||
* @param message
|
||||
* as message.
|
||||
*/
|
||||
@@ -59,18 +53,4 @@ public class UINotification implements Serializable {
|
||||
updatedMsg.toString(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display error type of notification message.
|
||||
*
|
||||
* @param message.
|
||||
* @param caption.
|
||||
* @param autoClose.
|
||||
*/
|
||||
public void displayError(final String message, final String caption, final Boolean autoClose) {
|
||||
final StringBuilder updatedMsg = new StringBuilder(FontAwesome.EXCLAMATION_TRIANGLE.getHtml());
|
||||
updatedMsg.append(' ');
|
||||
updatedMsg.append(message);
|
||||
notificationMessage.showNotification(SPUILabelDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE, caption,
|
||||
updatedMsg.toString(), autoClose);
|
||||
}
|
||||
}
|
||||
|
||||
39
pom.xml
39
pom.xml
@@ -100,7 +100,6 @@
|
||||
<org.powermock.version>1.5.4</org.powermock.version>
|
||||
<pl.pragmatists.version>1.0.2</pl.pragmatists.version>
|
||||
<json-path.version>0.9.1</json-path.version>
|
||||
<aspectj.version>1.8.5</aspectj.version>
|
||||
<guava.version>19.0</guava.version>
|
||||
<mariadb-java-client.version>1.4.3</mariadb-java-client.version>
|
||||
<embedded-mongo.version>1.50.2</embedded-mongo.version>
|
||||
@@ -124,33 +123,13 @@
|
||||
<!-- Sonar - START-->
|
||||
<sonar.host.url>https://sonar.eu-gb.mybluemix.net</sonar.host.url>
|
||||
<sonar.github.repository>eclipse/hawkbit</sonar.github.repository>
|
||||
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
|
||||
<sonar.links.homepage>https://projects.eclipse.org/projects/iot.hawkbit</sonar.links.homepage>
|
||||
<sonar.links.ci>https://circleci.com/gh/eclipse/hawkbit</sonar.links.ci>
|
||||
<!-- Jacoco version to use -->
|
||||
<jacoco.version>0.7.7.201606060606</jacoco.version>
|
||||
<!-- The Sonar Jacoco Listener for JUnit to extract coverage details
|
||||
per test -->
|
||||
<sonar-jacoco-listeners.version>1.4</sonar-jacoco-listeners.version>
|
||||
<!-- Don't let Sonar execute tests. We will ask it to Maven -->
|
||||
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
|
||||
<!-- The system property jacoco.outputDir needs to be override on the
|
||||
command line with an absolute path if you want to merge results from all
|
||||
modules. Example in a Jenkisn build where ${WORKSPACE} is defined and your
|
||||
project in the root directory of the workspace : mvn clean install -Prun-its,coverage
|
||||
-Djacoco.outputDir=${WORKSPACE}/target Note that unfortunately using the
|
||||
following does not work because of http://jira.codehaus.org/browse/SONAR-3427:
|
||||
<jacoco.outputDir>${session.executionRootDirectory}/target/</jacoco.outputDir> -->
|
||||
<jacoco.outputDir>${project.basedir}/../target/</jacoco.outputDir>
|
||||
<!-- Jacoco output file for UTs -->
|
||||
<jacoco.out.ut.file>jacoco-ut.exec</jacoco.out.ut.file>
|
||||
<!-- Tells Sonar where the Jacoco coverage result file is located for
|
||||
Unit Tests -->
|
||||
<sonar.jacoco.reportPath>${jacoco.outputDir}/${jacoco.out.ut.file}</sonar.jacoco.reportPath>
|
||||
<!-- Jacoco output file for ITs -->
|
||||
<jacoco.out.it.file>jacoco-it.exec</jacoco.out.it.file>
|
||||
<!-- Tells Sonar where the Jacoco coverage result file is located for
|
||||
Integration Tests -->
|
||||
<sonar.jacoco.itReportPath>${jacoco.outputDir}/${jacoco.out.it.file}</sonar.jacoco.itReportPath>
|
||||
<!-- Sonar - END-->
|
||||
</properties>
|
||||
@@ -295,7 +274,6 @@
|
||||
<forkCount>1</forkCount>
|
||||
<argLine>
|
||||
${jacoco.agent.ut.arg}
|
||||
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
|
||||
</argLine>
|
||||
<properties>
|
||||
<property>
|
||||
@@ -312,13 +290,6 @@
|
||||
<exclude>**/Abstract*.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -326,8 +297,7 @@
|
||||
<configuration>
|
||||
<reuseForks>true</reuseForks>
|
||||
<forkCount>3</forkCount>
|
||||
<argLine>-Xmx1024m ${jacoco.agent.ut.arg}
|
||||
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"</argLine>
|
||||
<argLine>-Xmx1024m ${jacoco.agent.ut.arg}</argLine>
|
||||
<properties>
|
||||
<property>
|
||||
<name>listener</name>
|
||||
@@ -335,13 +305,6 @@
|
||||
</property>
|
||||
</properties>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>integration-test</id>
|
||||
|
||||
Reference in New Issue
Block a user