Merge branch 'master' into feature_enable_push_in_deployment_view

This commit is contained in:
Gaurav
2016-08-01 17:25:19 +02:00
14 changed files with 174 additions and 205 deletions

View File

@@ -10,8 +10,12 @@ package org.eclipse.hawkbit.autoconfigure.amqp;
import org.eclipse.hawkbit.amqp.AmqpConfiguration; import org.eclipse.hawkbit.amqp.AmqpConfiguration;
import org.eclipse.hawkbit.amqp.annotation.EnableAmqp; 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.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.util.ErrorHandler;
/** /**
* The amqp autoconfiguration. * The amqp autoconfiguration.
@@ -24,4 +28,15 @@ import org.springframework.context.annotation.Configuration;
@EnableAmqp @EnableAmqp
public class AmqpAutoConfiguration { public class AmqpAutoConfiguration {
/**
* Create default error handler bean.
*
* @return the default error handler bean
*/
@Bean
@ConditionalOnMissingBean
public ErrorHandler errorHandler() {
return new ConditionalRejectingErrorHandler();
}
} }

View File

@@ -37,7 +37,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.retry.backoff.ExponentialBackOffPolicy; 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 * The spring AMQP configuration which is enabled by using the profile
@@ -263,13 +264,16 @@ public class AmqpConfiguration {
/** /**
* Returns the Listener factory. * Returns the Listener factory.
* *
* @param errorHandler
* the error hander
* @return the {@link SimpleMessageListenerContainer} that gets used receive * @return the {@link SimpleMessageListenerContainer} that gets used receive
* AMQP messages * AMQP messages
*/ */
@Bean(name = { "listenerContainerFactory" }) @Bean(name = { "listenerContainerFactory" })
public RabbitListenerContainerFactory<SimpleMessageListenerContainer> listenerContainerFactory() { public RabbitListenerContainerFactory<SimpleMessageListenerContainer> listenerContainerFactory(
return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory); final ErrorHandler errorHandler) {
return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory, errorHandler);
} }
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() { private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {

View File

@@ -12,6 +12,7 @@ import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFacto
import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory; import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.util.ErrorHandler;
/** /**
* {@link RabbitListenerContainerFactory} that can be configured through * {@link RabbitListenerContainerFactory} that can be configured through
@@ -28,10 +29,13 @@ public class ConfigurableRabbitListenerContainerFactory extends SimpleRabbitList
* for the container factory * for the container factory
* @param amqpProperties * @param amqpProperties
* to configure the container factory * to configure the container factory
* @param errorHandler
* the error handler which should be use
*/ */
public ConfigurableRabbitListenerContainerFactory(final AmqpProperties amqpProperties, public ConfigurableRabbitListenerContainerFactory(final AmqpProperties amqpProperties,
final ConnectionFactory rabbitConnectionFactory) { final ConnectionFactory rabbitConnectionFactory, final ErrorHandler errorHandler) {
this.amqpProperties = amqpProperties; this.amqpProperties = amqpProperties;
setErrorHandler(errorHandler);
setDefaultRequeueRejected(true); setDefaultRequeueRejected(true);
setConnectionFactory(rabbitConnectionFactory); setConnectionFactory(rabbitConnectionFactory);
setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal()); setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal());

View File

@@ -30,10 +30,7 @@ import com.vaadin.ui.VerticalLayout;
* View class that is instantiated when no other view matches the navigation * View class that is instantiated when no other view matches the navigation
* state. * state.
* *
*
*
* @see Navigator#setErrorView(Class) * @see Navigator#setErrorView(Class)
*
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
@SpringComponent @SpringComponent

View File

@@ -14,7 +14,7 @@ import java.util.Set;
import javax.servlet.http.Cookie; 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.DashboardEvent.PostViewChangeEvent;
import org.eclipse.hawkbit.ui.menu.DashboardMenu; import org.eclipse.hawkbit.ui.menu.DashboardMenu;
import org.eclipse.hawkbit.ui.menu.DashboardMenuItem; import org.eclipse.hawkbit.ui.menu.DashboardMenuItem;
@@ -180,7 +180,10 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener {
final String locale = getLocaleId(SPUIDefinitions.getAvailableLocales()); final String locale = getLocaleId(SPUIDefinitions.getAvailableLocales());
setLocale(new Locale(locale)); 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()); LOG.info("Current locale of the application is : {}", i18n.getLocale());
} }

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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());
}
}
}

View File

@@ -33,6 +33,7 @@ import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.ui.common.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
import org.eclipse.hawkbit.ui.common.tagdetails.AbstractTagToken.TagData; 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.BulkUploadValidationMessageEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent; 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.management.state.TargetBulkUpload;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N; 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.SpringContextHelper;
import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.UINotification;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventBus;
import com.vaadin.server.Page;
import com.vaadin.ui.Alignment; import com.vaadin.ui.Alignment;
import com.vaadin.ui.ComboBox; import com.vaadin.ui.ComboBox;
import com.vaadin.ui.CustomComponent; import com.vaadin.ui.CustomComponent;
@@ -445,7 +448,9 @@ public class BulkUploadHandler extends CustomComponent
@Override @Override
public void uploadStarted(final StartedEvent event) { public void uploadStarted(final StartedEvent event) {
if (!event.getFilename().endsWith(".csv")) { 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()); LOG.error("Wrong file format for file {}", event.getFilename());
upload.interruptUpload(); upload.interruptUpload();
} else { } else {

View File

@@ -590,24 +590,6 @@ public final class HawkbitCommonUtil {
return requiredExtraWidth + minTableWidth; 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. * Remove the prefix from text.
* *

View File

@@ -16,8 +16,6 @@ import com.vaadin.ui.Notification;
/** /**
* Show notification messages. * Show notification messages.
*
*
*/ */
@UIScope @UIScope
@SpringComponent @SpringComponent
@@ -27,8 +25,6 @@ public class NotificationMessage extends Notification {
/** /**
* Default constructor of notification message. * Default constructor of notification message.
*
* @param caption
*/ */
public NotificationMessage() { public NotificationMessage() {
super(""); super("");

View File

@@ -54,6 +54,7 @@ public final class SPUILabelDefinitions {
*/ */
public static final String SP_NOTIFICATION_ERROR_MESSAGE_STYLE = ValoTheme.NOTIFICATION_ERROR + " " public static final String SP_NOTIFICATION_ERROR_MESSAGE_STYLE = ValoTheme.NOTIFICATION_ERROR + " "
+ ValoTheme.NOTIFICATION_TRAY; + ValoTheme.NOTIFICATION_TRAY;
/** /**
* Style - Warning. * Style - Warning.
*/ */
@@ -539,13 +540,12 @@ public final class SPUILabelDefinitions {
* Total target coulmn property name. * Total target coulmn property name.
*/ */
public static final String VAR_TOTAL_TARGETS = "totalTargetsCount"; public static final String VAR_TOTAL_TARGETS = "totalTargetsCount";
/** /**
* Total target count status coulmn property name. * Total target count status coulmn property name.
*/ */
public static final String VAR_TOTAL_TARGETS_COUNT_STATUS = "totalTargetCountStatus"; public static final String VAR_TOTAL_TARGETS_COUNT_STATUS = "totalTargetCountStatus";
/** /**
* Rollout group started date column property. * Rollout group started date column property.
*/ */
@@ -560,7 +560,7 @@ public final class SPUILabelDefinitions {
* Rollout group installed percentage column property. * Rollout group installed percentage column property.
*/ */
public static final String ROLLOUT_GROUP_INSTALLED_PERCENTAGE = "finishedPercentage"; public static final String ROLLOUT_GROUP_INSTALLED_PERCENTAGE = "finishedPercentage";
/** /**
* Add metadata icon. * Add metadata icon.
*/ */

View File

@@ -18,8 +18,6 @@ import com.vaadin.spring.annotation.ViewScope;
/** /**
* Show success and error messages. * Show success and error messages.
*
*
*/ */
@ViewScope @ViewScope
@SpringComponent @SpringComponent
@@ -33,8 +31,6 @@ public class UINotification implements Serializable {
/** /**
* Display success type of notification message. * Display success type of notification message.
* *
* @param notificationMessage
* as reference
* @param message * @param message
* is the message to displayed as success. * is the message to displayed as success.
*/ */
@@ -46,8 +42,6 @@ public class UINotification implements Serializable {
/** /**
* Display error type of notification message. * Display error type of notification message.
* *
* @param notificationMessage
* as reference
* @param message * @param message
* as message. * as message.
*/ */
@@ -59,18 +53,4 @@ public class UINotification implements Serializable {
updatedMsg.toString(), true); 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);
}
} }