diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java index 1c19b35d0..51a4f9ff1 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java @@ -21,7 +21,7 @@ public class ControllerPollProperties { private String pollingTime = "00:05:00"; private String pollingOverdueTime = "00:05:00"; private String maxPollingTime = "23:59:00"; - private String minPollingTime = "23:59:00"; + private String minPollingTime = "00:00:30"; public String getPollingTime() { return pollingTime; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java index 4e47f856d..a83004ead 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.repository.model; import java.io.Serializable; +import java.time.Duration; import javax.persistence.Access; import javax.persistence.AccessType; @@ -24,9 +25,11 @@ import javax.persistence.Index; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; +import javax.persistence.Transient; import javax.persistence.UniqueConstraint; import javax.persistence.Version; +import org.eclipse.hawkbit.repository.model.helper.DurationHelper; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; @@ -83,6 +86,9 @@ public class TenantMetaData implements Serializable { // "fk_tenant_md_default_ds_type" ) private DistributionSetType defaultDsType; + @Transient + private DurationHelper dh = new DurationHelper(); + public TenantMetaData() { } @@ -262,19 +268,19 @@ public class TenantMetaData implements Serializable { return true; } - public String getPollingTime() { - return pollingTime; + public Duration getPollingTime() { + return dh.formattedStringToDuration(pollingTime); } - public void setPollingTime(String pollingTime) { - this.pollingTime = pollingTime; + public void setPollingTime(Duration pollingTime) { + this.pollingTime = dh.durationToFormattedString(pollingTime); } - public String getPollingOverdueTime() { - return pollingOverdueTime; + public Duration getPollingOverdueTime() { + return dh.formattedStringToDuration(pollingOverdueTime); } - public void setPollingOverdueTime(String pollingOverdueTime) { - this.pollingOverdueTime = pollingOverdueTime; + public void setPollingOverdueTime(Duration pollingOverdueTime) { + this.pollingOverdueTime = dh.durationToFormattedString(pollingOverdueTime); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java new file mode 100644 index 000000000..d14752f8f --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java @@ -0,0 +1,70 @@ +package org.eclipse.hawkbit.repository.model.helper; + +import java.time.Duration; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.TemporalAccessor; + +/** + * This class is a helper for converting a duration into a string and for the + * other way. The string is in the format expected in configuration and database + * {@link #DURATION_FORMAT}. + * + */ +public class DurationHelper { + + /** + * Format of the String expected in configuration file and in the databse. + */ + public static final String DURATION_FORMAT = "HH:mm:ss"; + + /** + * Converts a Duration into a formatted String + * + * @param duration + * duration, which will be converted into a formatted String + * @return String in the duration format, specified at + * {@link #DURATION_FORMAT} + */ + public String durationToFormattedString(Duration duration) { + if (duration == null) { + return null; + } + + return LocalTime.ofNanoOfDay(duration.toNanos()).format(DateTimeFormatter.ofPattern(DURATION_FORMAT)); + } + + /** + * Converts a formatted Sting into a Duration object. + * + * @param formattedDuration + * String in {@link #DURATION_FORMAT} + * @return duration + * @throws DateTimeParseException + * when String is in wrong format + */ + public Duration formattedStringToDuration(String formattedDuration) throws DateTimeParseException { + if (formattedDuration == null) { + return null; + } + + final TemporalAccessor ta = DateTimeFormatter.ofPattern(DURATION_FORMAT).parse(formattedDuration.trim()); + return Duration.between(LocalTime.MIDNIGHT, LocalTime.from(ta)); + } + + /** + * converts values of time constants to a Duration object.. + * + * @param hours + * count of hours + * @param minutes + * count of minutes + * @param seconds + * count of seconds + * @return duration + */ + public Duration getDurationByTimeValues(long hours, long minutes, long seconds) { + return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds); + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java index 9b9d24de9..55f9395b0 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java @@ -9,10 +9,7 @@ package org.eclipse.hawkbit.repository.model.helper; import java.time.Duration; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; -import java.time.temporal.TemporalAccessor; import javax.annotation.PostConstruct; import javax.validation.constraints.NotNull; @@ -38,7 +35,6 @@ public final class PollConfigurationHelper { * Format of the expected Duration String. Pattern has to be in Valid Format * for SimpleDateFormat */ - public static final String DURATION_FORMAT = "HH:mm:ss"; private static final Logger LOG = LoggerFactory.getLogger(PollConfigurationHelper.class); private static final PollConfigurationHelper INSTANCE = new PollConfigurationHelper(); @@ -59,6 +55,8 @@ public final class PollConfigurationHelper { private static final int DEFAULT_MIN_MINUTE = 0; private static final int DEFAULT_MIN_SECOND = 30; + private static DurationHelper dh = new DurationHelper(); + @Autowired private ControllerPollProperties controllerPollProperties; @@ -91,32 +89,33 @@ public final class PollConfigurationHelper { private void readGlobalDurationsFromConfiguration() { try { - configurationMaximumPollTime = formattedStringToDuration(controllerPollProperties.getMaxPollingTime()); + configurationMaximumPollTime = dh.formattedStringToDuration(controllerPollProperties.getMaxPollingTime()); } catch (DateTimeParseException e) { // Set to default values - configurationMaximumPollTime = getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, + configurationMaximumPollTime = dh.getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, DEFAULT_MAX_SECOND); } try { - configurationMinimumPollTime = formattedStringToDuration(controllerPollProperties.getMinPollingTime()); + configurationMinimumPollTime = dh.formattedStringToDuration(controllerPollProperties.getMinPollingTime()); } catch (DateTimeParseException e) { // Set to default values - configurationMinimumPollTime = getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, + configurationMinimumPollTime = dh.getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, DEFAULT_MIN_SECOND); } try { - configurationPollTime = formattedStringToDuration(controllerPollProperties.getPollingTime()); + configurationPollTime = dh.formattedStringToDuration(controllerPollProperties.getPollingTime()); } catch (DateTimeParseException e) { - configurationPollTime = getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, + configurationPollTime = dh.getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, DEFAULT_POLL_SECOND); } try { - configurationOverduePollTime = formattedStringToDuration(controllerPollProperties.getPollingOverdueTime()); + configurationOverduePollTime = dh + .formattedStringToDuration(controllerPollProperties.getPollingOverdueTime()); } catch (DateTimeParseException e) { - configurationOverduePollTime = getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, + configurationOverduePollTime = dh.getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, DEFAULT_OVERDUE_SECOND); } @@ -129,27 +128,26 @@ public final class PollConfigurationHelper { LOG.warn("The configured maximum value of the polling time is smaller" + " than the configured minimum value. Both are replaced by default values."); - configurationMaximumPollTime = getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, + configurationMaximumPollTime = dh.getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, DEFAULT_MAX_SECOND); - configurationMinimumPollTime = getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, + configurationMinimumPollTime = dh.getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, DEFAULT_MIN_SECOND); } if (!isWithinRange(configurationPollTime)) { // poll time value not within allowed range ==> use default value - configurationPollTime = getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, + configurationPollTime = dh.getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, DEFAULT_POLL_SECOND); } if (!isWithinRange(configurationOverduePollTime)) { // overdue poll time value not within range => use default value - configurationOverduePollTime = getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, + configurationOverduePollTime = dh.getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, DEFAULT_OVERDUE_SECOND); } } private boolean isWithinRange(@NotNull Duration duration) { - return duration.compareTo(configurationMinimumPollTime) > 0 && duration.compareTo(configurationMaximumPollTime) < 0; } @@ -161,24 +159,19 @@ public final class PollConfigurationHelper { * the default value which is {@code 00:05:00} never {@code null}. */ public Duration getPollTimeInterval() { - Duration tenantPollTimeInterval = getTenantPollTimeIntervall(); + Duration tenantPollTimeInterval = systemManagement.getTenantMetadata().getPollingTime(); if (tenantPollTimeInterval != null) { - return tenantPollTimeInterval; + if (isWithinRange(tenantPollTimeInterval)) { + return tenantPollTimeInterval; + } + LOG.warn( + "Tenant {} has stored a pollign interval {} which is not in the allowed range. Configured default value is loaded.", + systemManagement.currentTenant(), tenantPollTimeInterval); } return configurationPollTime; } - /** - * @return the poll time interval stored in the tenant meta data. If there - * is no value stored this function returns {@code null} - */ - public Duration getTenantPollTimeIntervall() { - String tenantPollingTime = systemManagement.getTenantMetadata().getPollingTime(); - - return validateDurationStringAndGetDuration(tenantPollingTime, "polling time"); - } - /** * @return the poll time interval configured in the configuration * {@code hawkbit.server.controller.polling} or the default value @@ -189,23 +182,6 @@ public final class PollConfigurationHelper { return configurationPollTime; } - /** - * Stores the changed value in the tenant meta data configuration. The value - * {@code null} is clearly allowed. Setting the poll time to {@code null} - * means no specific tenant configuration and global configuration are used. - * - * @param pollingTime - * polling time interval as formatted string {@code HH:mm:ss} or - * {@code null} - */ - public void setTenantPollTimeIntervall(Duration pollingTime) { - if (pollingTime == null) { - systemManagement.getTenantMetadata().setPollingTime(null); - return; - } - systemManagement.getTenantMetadata().setPollingTime(durationToFormattedString(pollingTime)); - } - /** * @return the overdue poll time interval stored in the tenant meta data. If * there is no tenant specific configuration the global value, @@ -214,46 +190,19 @@ public final class PollConfigurationHelper { * which is {@code 00:05:00} never {@code null}. */ public Duration getOverduePollTimeInterval() { - Duration tenantOverduePollTimeInterval = getTenantOverduePollTimeIntervall(); + Duration tenantOverduePollTimeInterval = systemManagement.getTenantMetadata().getPollingOverdueTime(); if (tenantOverduePollTimeInterval != null) { - return tenantOverduePollTimeInterval; + if (isWithinRange(tenantOverduePollTimeInterval)) { + return tenantOverduePollTimeInterval; + } + LOG.warn( + "Tenant {} has stored an overdue polling interval {} which is not in the allowed range. Configured default value is loaded.", + systemManagement.currentTenant(), tenantOverduePollTimeInterval); } return configurationOverduePollTime; }; - /** - * @return the poll time interval stored in the tenant meta data. If there - * is no value stored this function returns {@code null} - */ - public Duration getTenantOverduePollTimeIntervall() { - String tenantOverduePollingTime = systemManagement.getTenantMetadata().getPollingOverdueTime(); - - return validateDurationStringAndGetDuration(tenantOverduePollingTime, "overdue polling time"); - } - - private Duration validateDurationStringAndGetDuration(String pollingTime, String paramNameForLog) { - if (pollingTime == null) { - return null; - } - - try { - Duration d = formattedStringToDuration(pollingTime); - - if (isWithinRange(d)) { - return d; - } - - LOG.warn("Tenant {} has stored a {} {} which is not in the allowed range.", - systemManagement.currentTenant(), paramNameForLog, pollingTime); - - } catch (DateTimeParseException ex) { - LOG.warn("Tenant {} has stored an invalid {} {} in its meta data.", systemManagement.currentTenant(), - paramNameForLog, pollingTime); - } - return null; - } - /** * @return the overdue poll time interval configured in the configuration * {@code hawkbit.server.controller.polling.overdue} or the default @@ -263,25 +212,6 @@ public final class PollConfigurationHelper { return configurationOverduePollTime; } - /** - * Stores the polling overtime interval value in the tenant meta data - * configuration. The value {@code null} is clearly allowed. Setting the - * overdue poll time to {@code null} means no specific tenant configuration - * and global configuration are used. - * - * @param pollingTime - * polling time interval as formatted string {@code HH:mm:ss} or - * {@code null} - */ - public void setTenantOverduePollTimeIntervall(Duration pollingTime) { - if (pollingTime == null) { - systemManagement.getTenantMetadata().setPollingOverdueTime(null); - return; - } - - systemManagement.getTenantMetadata().setPollingOverdueTime(durationToFormattedString(pollingTime)); - } - /** * @return the maximum poll time duration configured in the configuration * {@code hawkbit.server.controller.polling.overdue} or the default @@ -300,26 +230,13 @@ public final class PollConfigurationHelper { return configurationMinimumPollTime; } - private String durationToFormattedString(@NotNull Duration duration) { - return LocalTime.ofNanoOfDay(duration.toNanos()).format(DateTimeFormatter.ofPattern(DURATION_FORMAT)); - } - - private Duration formattedStringToDuration(String formattedDuration) throws DateTimeParseException { - final TemporalAccessor ta = DateTimeFormatter.ofPattern(DURATION_FORMAT).parse(formattedDuration.trim()); - return Duration.between(LocalTime.MIDNIGHT, LocalTime.from(ta)); - } - - private Duration getDurationByTimeValues(long hours, long minutes, long seconds) { - return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds); - } - /** * sets the ControllerPollProperties in a not spring handled context. Don't * forget to call {@code initializeConfigurationValues} afterwards to read * the values from the PollProperties. * * @param controllerPollProperties - * the controll properties + * the controller poll properties */ public void setControllerPollProperties(ControllerPollProperties controllerPollProperties) { this.controllerPollProperties = controllerPollProperties; diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java index 21bba6cf7..4ee6e92f9 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java @@ -1,14 +1,13 @@ package org.eclipse.hawkbit.repository; import static org.fest.assertions.api.Assertions.assertThat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.time.Duration; import org.eclipse.hawkbit.ControllerPollProperties; import org.eclipse.hawkbit.repository.model.TenantMetaData; +import org.eclipse.hawkbit.repository.model.helper.DurationHelper; import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; import org.junit.Before; import org.junit.Test; @@ -54,7 +53,7 @@ public class PollConfigurationHelperTest { pollConfigurationHelperUnderTest.initializeConfigurationValues(); } - private void setTenantConfiguration(String polling, String overdue) { + private void setTenantConfiguration(Duration polling, Duration overdue) { when(tenantMetaData.getPollingTime()).thenReturn(polling); when(tenantMetaData.getPollingOverdueTime()).thenReturn(overdue); @@ -113,17 +112,17 @@ public class PollConfigurationHelperTest { @Test public void getPollingValuesFromTenant() { - setTenantConfiguration("00:11:00", "00:13:00"); + setTenantConfiguration(Duration.ofMinutes(11), Duration.ofMinutes(17)); assertThat(pollConfigurationHelperUnderTest.getPollTimeInterval()).isEqualTo(Duration.ofMinutes(11)); - assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(Duration.ofMinutes(13)); + assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(Duration.ofMinutes(17)); } @Test public void getInvalidPollingValuesFromTenant() { - setTenantConfiguration("00:00:01", "00:130:00"); + setTenantConfiguration(Duration.ZERO, Duration.ofHours(30)); assertThat(pollConfigurationHelperUnderTest.getPollTimeInterval()).isEqualTo(DEFAULT_POLLING); assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(DEFAULT_OVERDUE); @@ -131,21 +130,18 @@ public class PollConfigurationHelperTest { } @Test - public void setTenantConfiguration() { - pollConfigurationHelperUnderTest.setTenantPollTimeIntervall(Duration.ofHours(3).plusSeconds(3)); - pollConfigurationHelperUnderTest.setTenantOverduePollTimeIntervall(Duration.ofMinutes(7).plusSeconds(7)); + public void basicTestingOfDurationHelper() { + DurationHelper dh = new DurationHelper(); + + assertThat(dh.durationToFormattedString(null)).isNull(); + assertThat(dh.durationToFormattedString(Duration.ofHours(1).plusMinutes(2).plusSeconds(1))) + .isEqualTo("01:02:01"); + + assertThat(dh.formattedStringToDuration(null)).isNull(); + assertThat(dh.formattedStringToDuration("01:02:01")) + .isEqualTo(Duration.ofHours(1).plusMinutes(2).plusSeconds(1)); + + assertThat(dh.getDurationByTimeValues(0, 0, 0)).isEqualTo(Duration.ZERO); - verify(tenantMetaData, times(1)).setPollingTime("03:00:03"); - verify(tenantMetaData, times(1)).setPollingOverdueTime("00:07:07"); } - - @Test - public void setTenantConfigurationToNull() { - pollConfigurationHelperUnderTest.setTenantPollTimeIntervall(null); - pollConfigurationHelperUnderTest.setTenantOverduePollTimeIntervall(null); - - verify(tenantMetaData, times(1)).setPollingTime(null); - verify(tenantMetaData, times(1)).setPollingOverdueTime(null); - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index 3363f1d23..537e839ba 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -4,6 +4,8 @@ import java.time.Duration; import javax.annotation.PostConstruct; +import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; import org.eclipse.hawkbit.ui.tenantconfiguration.polling.DurationConfigField; import org.eclipse.hawkbit.ui.utils.I18N; @@ -34,6 +36,9 @@ public class PollingConfigurationView extends BaseConfigurationView @Autowired PollConfigurationHelper pollConfigurationHelper; + @Autowired + private transient SystemManagement systemManagement; + @Autowired private DurationConfigField fieldPollingTime; @@ -61,7 +66,9 @@ public class PollingConfigurationView extends BaseConfigurationView headerDisSetType.addStyleName("config-panel-header"); vLayout.addComponent(headerDisSetType); - tenantPollingTime = pollConfigurationHelper.getTenantPollTimeIntervall(); + final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); + + tenantPollingTime = tenantMetaData.getPollingTime(); fieldPollingTime.setInitValues(i18n.get("configuration.polling.time"), tenantPollingTime, pollConfigurationHelper.getGlobalPollTimeInterval()); fieldPollingTime.setAllowedRange(pollConfigurationHelper.getMinimumPollingInterval(), @@ -70,7 +77,7 @@ public class PollingConfigurationView extends BaseConfigurationView vLayout.addComponent(fieldPollingTime); - tenantPollingOverdueTime = pollConfigurationHelper.getTenantOverduePollTimeIntervall(); + tenantPollingOverdueTime = tenantMetaData.getPollingOverdueTime(); fieldPollingOverdueTime.setInitValues(i18n.get("configuration.polling.overduetime"), tenantPollingOverdueTime, pollConfigurationHelper.getGlobalOverduePollTimeInterval()); @@ -88,16 +95,25 @@ public class PollingConfigurationView extends BaseConfigurationView public void save() { // make sure values are only saved, when the value has been changed + boolean hasChanged = false; + + final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); + if (!compareDurations(tenantPollingTime, fieldPollingTime.getValue())) { tenantPollingTime = fieldPollingTime.getValue(); - pollConfigurationHelper.setTenantPollTimeIntervall(fieldPollingTime.getValue()); + tenantMetaData.setPollingTime(fieldPollingTime.getValue()); + hasChanged = true; } if (!compareDurations(tenantPollingOverdueTime, fieldPollingOverdueTime.getValue())) { tenantPollingOverdueTime = fieldPollingOverdueTime.getValue(); - pollConfigurationHelper.setTenantOverduePollTimeIntervall(fieldPollingOverdueTime.getValue()); + tenantMetaData.setPollingOverdueTime(fieldPollingOverdueTime.getValue()); + hasChanged = true; } + if (hasChanged) { + systemManagement.updateTenantMetadata(tenantMetaData); + } } @Override