DB and RabbitMQ integration tests and PostgreSQL testing/bug fixing (#1047)

* Initial matrixSigned-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* License header

* MySQL DB testSigned-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Create matrix for DBsSigned-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* RabbitMQ and H2Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* MySQL 8.0Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Postgresql test supportSigned-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Postgresql test supportSigned-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Fix DB issues post and mssql

Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Wait MSSQL

Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Fix postgresql tests.

Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* MSSQL startup fix.Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Fix syntax error

Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Further fix postgres tests.Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Revert unnecessary changes.

Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Add SonarCloud Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>

* Simplify devcontainer. Test JDK 15Signed-off-by: Kai Zimmermann <kai.zimmermann@microsoft.com>
This commit is contained in:
Kai Zimmermann
2021-01-14 09:07:03 +01:00
committed by GitHub
parent 4ea5d7655b
commit e9f11d2a20
27 changed files with 557 additions and 114 deletions

View File

@@ -123,6 +123,9 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
QUERY_DELETE_ACTIONS_BY_STATE_AND_LAST_MODIFIED = new EnumMap<>(Database.class);
QUERY_DELETE_ACTIONS_BY_STATE_AND_LAST_MODIFIED.put(Database.SQL_SERVER, "DELETE TOP (" + ACTION_PAGE_LIMIT
+ ") FROM sp_action WHERE tenant=#tenant AND status IN (%s) AND last_modified_at<#last_modified_at ");
QUERY_DELETE_ACTIONS_BY_STATE_AND_LAST_MODIFIED.put(Database.POSTGRESQL,
"DELETE FROM sp_action WHERE id IN (SELECT id FROM sp_action WHERE tenant=#tenant AND status IN (%s) AND last_modified_at<#last_modified_at LIMIT "
+ ACTION_PAGE_LIMIT + ")");
}
private final EntityManager entityManager;
@@ -209,8 +212,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
final Map<Long, List<TargetWithActionType>> assignmentsByDsIds = convertRequest(validatedRequests);
final List<DistributionSetAssignmentResult> results = assignmentsByDsIds.entrySet().stream()
.map(entry -> assignDistributionSetToTargetsWithRetry(initiatedBy, entry.getKey(), entry.getValue(), actionMessage,
strategy))
.map(entry -> assignDistributionSetToTargetsWithRetry(initiatedBy, entry.getKey(), entry.getValue(),
actionMessage, strategy))
.collect(Collectors.toList());
strategy.sendDeploymentEvents(results);
return results;
@@ -239,8 +242,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
}
}
private DistributionSetAssignmentResult assignDistributionSetToTargetsWithRetry(final String initiatedBy, final Long dsID,
final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
private DistributionSetAssignmentResult assignDistributionSetToTargetsWithRetry(final String initiatedBy,
final Long dsID, final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
final AbstractDsAssignmentStrategy assignmentStrategy) {
final RetryCallback<DistributionSetAssignmentResult, ConcurrencyFailureException> retryCallback = retryContext -> assignDistributionSetToTargets(
initiatedBy, dsID, targetsWithActionType, actionMessage, assignmentStrategy);
@@ -427,9 +430,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
return targetsWithActionType.stream()
.map(twt -> assignmentStrategy.createTargetAction(initiatedBy, twt, targets, set))
.filter(Objects::nonNull)
.map(actionRepository::save)
.collect(Collectors.toList());
.filter(Objects::nonNull).map(actionRepository::save).collect(Collectors.toList());
}
private void createActionsStatus(final Collection<JpaAction> actions,

View File

@@ -38,6 +38,7 @@ import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.dao.ConcurrencyFailureException;
@@ -45,6 +46,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.transaction.PlatformTransactionManager;
@@ -123,11 +125,15 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
@Autowired
private ArtifactRepository artifactRepository;
@Autowired
private JpaProperties properties;
@Override
public SystemUsageReport getSystemUsageStatistics() {
final Number count = (Number) entityManager.createNativeQuery(
"select SUM(file_size) from sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = 0")
"select SUM(file_size) from sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = "
+ (isPostgreSql(properties) ? "false" : "0"))
.getSingleResult();
long sumOfArtifacts = 0;
@@ -141,7 +147,8 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
.getSingleResult()).longValue();
final long artifacts = ((Number) entityManager.createNativeQuery(
"SELECT COUNT(a.id) FROM sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = 0")
"SELECT COUNT(a.id) FROM sp_artifact a INNER JOIN sp_base_software_module sm ON a.software_module = sm.id WHERE sm.deleted = "
+ (isPostgreSql(properties) ? "false" : "0"))
.getSingleResult()).longValue();
final long actions = ((Number) entityManager.createNativeQuery("SELECT COUNT(id) FROM sp_action")
@@ -151,6 +158,10 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
tenantMetaDataRepository.count());
}
private static boolean isPostgreSql(final JpaProperties properties) {
return Database.POSTGRESQL.equals(properties.getDatabase());
}
@Override
public SystemUsageReportWithTenants getSystemUsageStatisticsWithTenants() {
final SystemUsageReportWithTenants result = (SystemUsageReportWithTenants) getSystemUsageStatistics();

View File

@@ -35,6 +35,7 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.text.StrLookup;
import org.eclipse.hawkbit.repository.FieldNameProvider;
import org.eclipse.hawkbit.repository.FieldValueConverter;
@@ -375,7 +376,8 @@ public final class RSQLUtility {
*/
private Path<Object> getFieldPath(final A enumField, final String finalProperty) {
return (Path<Object>) getFieldPath(root, getSubAttributesFrom(finalProperty), enumField.isMap(),
this::getJoinFieldPath).orElseThrow(() -> new RSQLParameterUnsupportedFieldException("RSQL field path cannot be empty", null));
this::getJoinFieldPath).orElseThrow(
() -> new RSQLParameterUnsupportedFieldException("RSQL field path cannot be empty", null));
}
private Path<?> getJoinFieldPath(final Path<?> fieldPath, final String fieldNameSplit) {
@@ -396,8 +398,8 @@ public final class RSQLUtility {
return fieldPath;
}
private static Optional<Path<?>> getFieldPath(final Root<?> root, final String[] split, final boolean isMapKeyField,
final BiFunction<Path<?>, String, Path<?>> joinFieldPathProvider) {
private static Optional<Path<?>> getFieldPath(final Root<?> root, final String[] split,
final boolean isMapKeyField, final BiFunction<Path<?>, String, Path<?>> joinFieldPathProvider) {
Path<?> fieldPath = null;
for (int i = 0; i < split.length; i++) {
if (!(isMapKeyField && i == (split.length - 1))) {
@@ -685,7 +687,11 @@ public final class RSQLUtility {
}
private Predicate getEqualToPredicate(final Object transformedValue, final Path<Object> fieldPath) {
if (transformedValue instanceof String) {
if (transformedValue == null) {
return cb.isNull(pathOfString(fieldPath));
}
if ((transformedValue instanceof String) && !NumberUtils.isCreatable((String) transformedValue)) {
if (StringUtils.isEmpty(transformedValue)) {
return cb.or(cb.isNull(pathOfString(fieldPath)), cb.equal(pathOfString(fieldPath), ""));
}
@@ -694,10 +700,6 @@ public final class RSQLUtility {
return cb.like(cb.upper(pathOfString(fieldPath)), sqlValue, ESCAPE_CHAR);
}
if (transformedValue == null) {
return cb.isNull(pathOfString(fieldPath));
}
return cb.equal(fieldPath, transformedValue);
}
@@ -708,7 +710,7 @@ public final class RSQLUtility {
return toNotNullPredicate(fieldPath);
}
if (transformedValue instanceof String) {
if ((transformedValue instanceof String) && !NumberUtils.isCreatable((String) transformedValue)) {
if (StringUtils.isEmpty(transformedValue)) {
return toNotNullAndNotEmptyPredicate(fieldPath);
}
@@ -725,7 +727,7 @@ public final class RSQLUtility {
return toNotEqualWithSubQueryPredicate(enumField, sqlValue, fieldNames);
}
return toNotEqualPredicate(fieldPath, transformedValue);
return toNullOrNotEqualPredicate(fieldPath, transformedValue);
}
private void clearOuterJoinsIfNotNeeded() {
@@ -738,15 +740,15 @@ public final class RSQLUtility {
return cb.isNotNull(pathOfString(fieldPath));
}
private Predicate toNotEqualPredicate(final Path<Object> fieldPath, final Object transformedValue) {
return cb.notEqual(fieldPath, transformedValue);
}
private Predicate toNullOrNotLikePredicate(final Path<Object> fieldPath, final String sqlValue) {
return cb.or(cb.isNull(pathOfString(fieldPath)),
cb.notLike(cb.upper(pathOfString(fieldPath)), sqlValue, ESCAPE_CHAR));
}
private Predicate toNullOrNotEqualPredicate(final Path<Object> fieldPath, final Object transformedValue) {
return cb.or(cb.isNull(pathOfString(fieldPath)), cb.notEqual(fieldPath, transformedValue));
}
private Predicate toNotNullAndNotEmptyPredicate(final Path<Object> fieldPath) {
return cb.and(cb.isNotNull(pathOfString(fieldPath)), cb.notEqual(pathOfString(fieldPath), ""));
}
@@ -797,9 +799,11 @@ public final class RSQLUtility {
}
private static Path<?> getInnerFieldPath(final Root<?> subqueryRoot, final String[] split,
final boolean isMapKeyField) {
final boolean isMapKeyField) {
return getFieldPath(subqueryRoot, split, isMapKeyField,
(fieldPath, fieldNameSplit) -> getInnerJoinFieldPath(subqueryRoot, fieldPath, fieldNameSplit)).orElseThrow(() -> new RSQLParameterUnsupportedFieldException("RSQL field path cannot be empty", null));
(fieldPath, fieldNameSplit) -> getInnerJoinFieldPath(subqueryRoot, fieldPath, fieldNameSplit))
.orElseThrow(() -> new RSQLParameterUnsupportedFieldException(
"RSQL field path cannot be empty", null));
}
private static Path<?> getInnerJoinFieldPath(final Root<?> subqueryRoot, final Path<?> fieldPath,