Feature/fix sonar warnings (#1226)
* Fixed sonar warnings - "Cognitive Complexity" - "Do not use replaceAll when not using a regex" - java:S5869 - Character classes in regular expressions should not contain the same character twice - Improved bad name - Typos - reduced code duplications - Replaced hand-made wait-utility with Awaitility - Log messages - Duplicate code - Typos - Removed Thread.sleep, instead relaxed check condition - Removed use of deprecated API - Removed use of deprecated API - Added supress-warnings as I do not see a better way to write the tests - Removed Thread.sleep / redundant functionality to Awaitility - Fixed other warnings (use isZero, isEmpty, hasToString) - Removed/Reduced duplicate code - Added generics - Fixed asserts - removed: field.setAccessible(true) actually should not be needed for public static fields! - Too long constructor passes arguments in wrong order - how surprisingly... - Clean-up use of varargs arguments - Fixed regex - Fixed typos and other minor stuff - Making public constructors protected in abstract classes - Swapped expected and asserted argument - volatile not enough for syncing threads - volatile not enough for syncing threads - out-commented code - Made regex not-greedy, added tests for verification - Avoid exposure of thread-local member var Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io> * Fixed Sonar warnings * License header fix Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io> * License header fix #2 Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io> * Fixing review findings Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io> * Fixing tests - Fixed '&' usage in javadoc and typos - Fixing some warnings Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>
This commit is contained in:
@@ -109,7 +109,7 @@ Please make sure newly created files contain a proper license header like this:
|
|||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* https://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*/
|
*/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Bosch.IO 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.artifact.repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown in case that the artifact could not be read.
|
||||||
|
*/
|
||||||
|
public class ArtifactFileNotFoundException extends RuntimeException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the Exception from it's cause
|
||||||
|
* @param cause the original exception
|
||||||
|
*/
|
||||||
|
public ArtifactFileNotFoundException(final Exception cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,12 +13,12 @@ import java.io.File;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
|
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
|
||||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
|
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link AbstractDbArtifact} implementation which dynamically creates a
|
* {@link AbstractDbArtifact} implementation which dynamically creates a
|
||||||
@@ -28,11 +28,11 @@ public class ArtifactFilesystem extends AbstractDbArtifact {
|
|||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
|
|
||||||
public ArtifactFilesystem(final File file, final String artifactId, final DbArtifactHash hashes, final Long size,
|
public ArtifactFilesystem(@NotNull final File file, @NotNull final String artifactId,
|
||||||
|
@NotNull final DbArtifactHash hashes, final Long size,
|
||||||
final String contentType) {
|
final String contentType) {
|
||||||
super(artifactId, hashes, size, contentType);
|
super(artifactId, hashes, size, contentType);
|
||||||
Assert.notNull(file, "File cannot be null");
|
this.file = Objects.requireNonNull(file, "Artifact file may not be null");
|
||||||
this.file = file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -43,7 +43,7 @@ public class ArtifactFilesystem extends AbstractDbArtifact {
|
|||||||
try {
|
try {
|
||||||
return new BufferedInputStream(new FileInputStream(file));
|
return new BufferedInputStream(new FileInputStream(file));
|
||||||
} catch (final FileNotFoundException e) {
|
} catch (final FileNotFoundException e) {
|
||||||
throw Throwables.propagate(e);
|
throw new ArtifactFileNotFoundException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.PropertySource;
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auto configuration for {@link HostnameResolver} and
|
* Auto configuration for {@link HostnameResolver} and
|
||||||
* {@link ArtifactUrlHandler} based on a properties.
|
* {@link ArtifactUrlHandler} based on a properties.
|
||||||
@@ -46,7 +44,7 @@ public class PropertyHostnameResolverAutoConfiguration {
|
|||||||
try {
|
try {
|
||||||
return new URL(serverProperties.getUrl());
|
return new URL(serverProperties.getUrl());
|
||||||
} catch (final MalformedURLException e) {
|
} catch (final MalformedURLException e) {
|
||||||
throw Throwables.propagate(e);
|
throw new IllegalArgumentException("URL not valid: " + serverProperties.getUrl(), e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.api;
|
package org.eclipse.hawkbit.api;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for variables available to the {@link ArtifactUrlHandler}.
|
* Container for variables available to the {@link ArtifactUrlHandler}.
|
||||||
*
|
*
|
||||||
@@ -107,59 +109,22 @@ public class URLPlaceholder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public boolean equals(final Object o) {
|
||||||
final int prime = 31;
|
if (this == o)
|
||||||
int result = 1;
|
return true;
|
||||||
result = prime * result + ((artifactId == null) ? 0 : artifactId.hashCode());
|
if (o == null || getClass() != o.getClass())
|
||||||
result = prime * result + ((filename == null) ? 0 : filename.hashCode());
|
return false;
|
||||||
result = prime * result + ((sha1Hash == null) ? 0 : sha1Hash.hashCode());
|
final SoftwareData that = (SoftwareData) o;
|
||||||
result = prime * result + ((softwareModuleId == null) ? 0 : softwareModuleId.hashCode());
|
return Objects.equals(softwareModuleId, that.softwareModuleId)
|
||||||
return result;
|
&& Objects.equals(filename, that.filename)
|
||||||
|
&& Objects.equals(artifactId, that.artifactId)
|
||||||
|
&& Objects.equals(sha1Hash, that.sha1Hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public int hashCode() {
|
||||||
if (this == obj) {
|
return Objects.hash(softwareModuleId, filename, artifactId, sha1Hash);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final SoftwareData other = (SoftwareData) obj;
|
|
||||||
if (artifactId == null) {
|
|
||||||
if (other.artifactId != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!artifactId.equals(other.artifactId)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (filename == null) {
|
|
||||||
if (other.filename != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!filename.equals(other.filename)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (sha1Hash == null) {
|
|
||||||
if (other.sha1Hash != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!sha1Hash.equals(other.sha1Hash)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (softwareModuleId == null) {
|
|
||||||
if (other.softwareModuleId != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!softwareModuleId.equals(other.softwareModuleId)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTenant() {
|
public String getTenant() {
|
||||||
@@ -183,65 +148,18 @@ public class URLPlaceholder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public boolean equals(final Object o) {
|
||||||
final int prime = 31;
|
if (this == o)
|
||||||
int result = 1;
|
return true;
|
||||||
result = prime * result + ((controllerId == null) ? 0 : controllerId.hashCode());
|
if (o == null || getClass() != o.getClass())
|
||||||
result = prime * result + ((softwareData == null) ? 0 : softwareData.hashCode());
|
return false;
|
||||||
result = prime * result + ((targetId == null) ? 0 : targetId.hashCode());
|
final URLPlaceholder that = (URLPlaceholder) o;
|
||||||
result = prime * result + ((tenant == null) ? 0 : tenant.hashCode());
|
return tenantId.equals(that.tenantId) && Objects.equals(controllerId, that.controllerId) && Objects.equals(
|
||||||
result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode());
|
targetId, that.targetId) && Objects.equals(softwareData, that.softwareData);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public int hashCode() {
|
||||||
if (this == obj) {
|
return Objects.hash(tenantId, controllerId, targetId, softwareData);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final URLPlaceholder other = (URLPlaceholder) obj;
|
|
||||||
if (controllerId == null) {
|
|
||||||
if (other.controllerId != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!controllerId.equals(other.controllerId)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (softwareData == null) {
|
|
||||||
if (other.softwareData != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!softwareData.equals(other.softwareData)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (targetId == null) {
|
|
||||||
if (other.targetId != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!targetId.equals(other.targetId)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (tenant == null) {
|
|
||||||
if (other.tenant != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!tenant.equals(other.tenant)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (tenantId == null) {
|
|
||||||
if (other.tenantId != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!tenantId.equals(other.tenantId)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.security.DigestInputStream;
|
import java.security.DigestInputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@@ -98,25 +99,23 @@ public abstract class AbstractArtifactRepository implements ArtifactRepository {
|
|||||||
|
|
||||||
protected void deleteTempFile(final String tempFile) {
|
protected void deleteTempFile(final String tempFile) {
|
||||||
final File file = new File(tempFile);
|
final File file = new File(tempFile);
|
||||||
|
try {
|
||||||
if (file.exists() && !file.delete()) {
|
Files.deleteIfExists(file.toPath());
|
||||||
LOG.error("Could not delete temp file {}", file);
|
} catch (IOException e) {
|
||||||
|
LOG.error("Could not delete temp file {} ({})", file, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String storeTempFile(final InputStream content) throws IOException {
|
protected String storeTempFile(final InputStream content) throws IOException {
|
||||||
final File file = createTempFile();
|
final File file = createTempFile();
|
||||||
|
|
||||||
try (final OutputStream outputstream = new BufferedOutputStream(new FileOutputStream(file))) {
|
try (final OutputStream outputstream = new BufferedOutputStream(new FileOutputStream(file))) {
|
||||||
ByteStreams.copy(content, outputstream);
|
ByteStreams.copy(content, outputstream);
|
||||||
outputstream.flush();
|
outputstream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
return file.getPath();
|
return file.getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File createTempFile() {
|
private static File createTempFile() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX);
|
return File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
@@ -160,5 +159,4 @@ public abstract class AbstractArtifactRepository implements ArtifactRepository {
|
|||||||
protected static String sanitizeTenant(final String tenant) {
|
protected static String sanitizeTenant(final String tenant) {
|
||||||
return tenant.trim().toUpperCase();
|
return tenant.trim().toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.cache;
|
package org.eclipse.hawkbit.cache;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.Cache.ValueWrapper;
|
import org.springframework.cache.Cache.ValueWrapper;
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
@@ -27,7 +28,6 @@ public class DefaultDownloadIdCache implements DownloadIdCache {
|
|||||||
* @param cacheManager
|
* @param cacheManager
|
||||||
* the underlying cache-manager to store the download-ids
|
* the underlying cache-manager to store the download-ids
|
||||||
*/
|
*/
|
||||||
@Autowired
|
|
||||||
public DefaultDownloadIdCache(final CacheManager cacheManager) {
|
public DefaultDownloadIdCache(final CacheManager cacheManager) {
|
||||||
this.cacheManager = cacheManager;
|
this.cacheManager = cacheManager;
|
||||||
}
|
}
|
||||||
@@ -49,9 +49,9 @@ public class DefaultDownloadIdCache implements DownloadIdCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Cache getCache() {
|
private Cache getCache() {
|
||||||
if (cacheManager instanceof TenancyCacheManager) {
|
final Cache cache = (cacheManager instanceof TenancyCacheManager)
|
||||||
return ((TenancyCacheManager) cacheManager).getDirectCache(DOWNLOAD_ID_CACHE);
|
? ((TenancyCacheManager) cacheManager).getDirectCache(DOWNLOAD_ID_CACHE)
|
||||||
}
|
: cacheManager.getCache(DOWNLOAD_ID_CACHE);
|
||||||
return cacheManager.getCache(DOWNLOAD_ID_CACHE);
|
return Objects.requireNonNull(cache, "Cache(s) returned by cache-manager must not be null!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public abstract class AbstractServerRtException extends RuntimeException {
|
|||||||
* @param error
|
* @param error
|
||||||
* detail
|
* detail
|
||||||
*/
|
*/
|
||||||
public AbstractServerRtException(final SpServerError error) {
|
protected AbstractServerRtException(final SpServerError error) {
|
||||||
super(error.getMessage());
|
super(error.getMessage());
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ public abstract class AbstractServerRtException extends RuntimeException {
|
|||||||
* @param error
|
* @param error
|
||||||
* detail
|
* detail
|
||||||
*/
|
*/
|
||||||
public AbstractServerRtException(final String message, final SpServerError error) {
|
protected AbstractServerRtException(final String message, final SpServerError error) {
|
||||||
super(message);
|
super(message);
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ public abstract class AbstractServerRtException extends RuntimeException {
|
|||||||
* @param cause
|
* @param cause
|
||||||
* of the exception
|
* of the exception
|
||||||
*/
|
*/
|
||||||
public AbstractServerRtException(final String message, final SpServerError error, final Throwable cause) {
|
protected AbstractServerRtException(final String message, final SpServerError error, final Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ public abstract class AbstractServerRtException extends RuntimeException {
|
|||||||
* @param cause
|
* @param cause
|
||||||
* of the exception
|
* of the exception
|
||||||
*/
|
*/
|
||||||
public AbstractServerRtException(final SpServerError error, final Throwable cause) {
|
protected AbstractServerRtException(final SpServerError error, final Throwable cause) {
|
||||||
super(error.getMessage(), cause);
|
super(error.getMessage(), cause);
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ import io.qameta.allure.Story;
|
|||||||
|
|
||||||
@Feature("Unit Tests - Artifact URL Handler")
|
@Feature("Unit Tests - Artifact URL Handler")
|
||||||
@Story("Base62 Utility tests")
|
@Story("Base62 Utility tests")
|
||||||
public class Base62UtilTest {
|
class Base62UtilTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Convert Base10 numbres to Base62 ASCII strings.")
|
@Description("Convert Base10 numbres to Base62 ASCII strings.")
|
||||||
public void fromBase10() {
|
void fromBase10() {
|
||||||
assertThat(Base62Util.fromBase10(0L)).isEqualTo("0");
|
assertThat(Base62Util.fromBase10(0L)).isEqualTo("0");
|
||||||
assertThat(Base62Util.fromBase10(11L)).isEqualTo("B");
|
assertThat(Base62Util.fromBase10(11L)).isEqualTo("B");
|
||||||
assertThat(Base62Util.fromBase10(36L)).isEqualTo("a");
|
assertThat(Base62Util.fromBase10(36L)).isEqualTo("a");
|
||||||
@@ -31,8 +31,8 @@ public class Base62UtilTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Convert Base62 ASCII strings to Base10 numbers.")
|
@Description("Convert Base62 ASCII strings to Base10 numbers.")
|
||||||
public void toBase10() {
|
void toBase10() {
|
||||||
assertThat(Base62Util.toBase10("0")).isEqualTo(0L);
|
assertThat(Base62Util.toBase10("0")).isZero();
|
||||||
assertThat(Base62Util.toBase10("B")).isEqualTo(11);
|
assertThat(Base62Util.toBase10("B")).isEqualTo(11);
|
||||||
assertThat(Base62Util.toBase10("a")).isEqualTo(36L);
|
assertThat(Base62Util.toBase10("a")).isEqualTo(36L);
|
||||||
assertThat(Base62Util.toBase10("G7")).isEqualTo(999L);
|
assertThat(Base62Util.toBase10("G7")).isEqualTo(999L);
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Bosch.IO 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.api;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import io.qameta.allure.Description;
|
||||||
|
import io.qameta.allure.Feature;
|
||||||
|
import io.qameta.allure.Story;
|
||||||
|
|
||||||
|
@Feature("Unit Tests - Artifact URL Handler")
|
||||||
|
@Story("URL placeholder tests")
|
||||||
|
class URLPlaceholderTest {
|
||||||
|
|
||||||
|
private final URLPlaceholder.SoftwareData softwareData;
|
||||||
|
private final URLPlaceholder placeholder;
|
||||||
|
|
||||||
|
public URLPlaceholderTest() {
|
||||||
|
this.softwareData = new URLPlaceholder.SoftwareData(1L, "file.txt", 123L, "someHash123");
|
||||||
|
this.placeholder = new URLPlaceholder("SuperCorp", 123L, "Super-1", 1L, softwareData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Same object should be equal")
|
||||||
|
// Exception squid:S5785 - JUnit assertTrue/assertFalse should be simplified to
|
||||||
|
// the corresponding dedicated assertion
|
||||||
|
// Need to test the equals method and need to bypass magic logic in utility
|
||||||
|
// classes
|
||||||
|
@SuppressWarnings({ "squid:S5838" })
|
||||||
|
void sameObjectShouldBeEqual() {
|
||||||
|
assertThat(softwareData.equals(softwareData)).isTrue();
|
||||||
|
assertThat(placeholder.equals(placeholder)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Different object should not be equal")
|
||||||
|
@SuppressWarnings({ "squid:S5838" })
|
||||||
|
void differentObjectShouldNotBeEqual() {
|
||||||
|
final URLPlaceholder.SoftwareData softwareData2 = new URLPlaceholder.SoftwareData(2L, "file.txt", 123L, "someHash123");
|
||||||
|
final URLPlaceholder placeholder2 = new URLPlaceholder("SuperCorp", 123L, "Super-2", 2L, softwareData2);
|
||||||
|
final URLPlaceholder placeholderWithOtherSoftwareData = new URLPlaceholder(placeholder.getTenant(),
|
||||||
|
placeholder.getTenantId(), placeholder.getControllerId(), placeholder.getTargetId(), softwareData2);
|
||||||
|
assertThat(placeholder.equals(placeholder2)).isFalse();
|
||||||
|
assertThat(placeholder2.equals(placeholder)).isFalse();
|
||||||
|
assertThat(softwareData.equals(softwareData2)).isFalse();
|
||||||
|
assertThat(softwareData2.equals(softwareData)).isFalse();
|
||||||
|
assertThat(placeholder.equals(placeholderWithOtherSoftwareData)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Different objects with same properties should be equal")
|
||||||
|
void differentObjectsWithSamePropertiesShouldBeEqual() {
|
||||||
|
final URLPlaceholder placeholderWithSameProperties = new URLPlaceholder(placeholder.getTenant(), placeholder.getTenantId(),
|
||||||
|
placeholder.getControllerId(), placeholder.getTargetId(), softwareData);
|
||||||
|
assertThat(placeholder).isEqualTo(placeholderWithSameProperties);
|
||||||
|
assertThat(placeholderWithSameProperties).isEqualTo(placeholder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Should not equal null")
|
||||||
|
// Exception squid:S5785 - JUnit assertTrue/assertFalse should be simplified to
|
||||||
|
// the corresponding dedicated assertion
|
||||||
|
// Need to test the equals method and need to bypass magic logic in utility
|
||||||
|
// classes
|
||||||
|
@SuppressWarnings({ "squid:S5838" })
|
||||||
|
void shouldNotEqualNull() {
|
||||||
|
assertThat(placeholder.equals(null)).isFalse();
|
||||||
|
assertThat(softwareData.equals(null)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("HashCode should not change")
|
||||||
|
void hashCodeShouldNotChange() {
|
||||||
|
final URLPlaceholder placeholderWithSameProperties = new URLPlaceholder(placeholder.getTenant(), placeholder.getTenantId(),
|
||||||
|
placeholder.getControllerId(), placeholder.getTargetId(), softwareData);
|
||||||
|
assertThat(placeholder).hasSameHashCodeAs(placeholder).hasSameHashCodeAs(placeholderWithSameProperties);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Captor;
|
import org.mockito.Captor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
@@ -32,7 +31,7 @@ import io.qameta.allure.Story;
|
|||||||
@Feature("Unit Tests - Cache")
|
@Feature("Unit Tests - Cache")
|
||||||
@Story("Download ID Cache")
|
@Story("Download ID Cache")
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class DefaultDownloadIdCacheTest {
|
class DefaultDownloadIdCacheTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private CacheManager cacheManagerMock;
|
private CacheManager cacheManagerMock;
|
||||||
@@ -61,7 +60,7 @@ public class DefaultDownloadIdCacheTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that putting key and value is delegated to the CacheManager implementation")
|
@Description("Verifies that putting key and value is delegated to the CacheManager implementation")
|
||||||
public void putKeyAndValueIsDelegatedToCacheManager() {
|
void putKeyAndValueIsDelegatedToCacheManager() {
|
||||||
final DownloadArtifactCache value = new DownloadArtifactCache(DownloadType.BY_SHA1, knownKey);
|
final DownloadArtifactCache value = new DownloadArtifactCache(DownloadType.BY_SHA1, knownKey);
|
||||||
|
|
||||||
underTest.put(knownKey, value);
|
underTest.put(knownKey, value);
|
||||||
@@ -74,7 +73,7 @@ public class DefaultDownloadIdCacheTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that evicting a key is delegated to the CacheManager implementation")
|
@Description("Verifies that evicting a key is delegated to the CacheManager implementation")
|
||||||
public void evictKeyIsDelegatedToCacheManager() {
|
void evictKeyIsDelegatedToCacheManager() {
|
||||||
|
|
||||||
underTest.evict(knownKey);
|
underTest.evict(knownKey);
|
||||||
|
|
||||||
@@ -85,7 +84,7 @@ public class DefaultDownloadIdCacheTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that retrieving a value for a specific key is delegated to the CacheManager implementation")
|
@Description("Verifies that retrieving a value for a specific key is delegated to the CacheManager implementation")
|
||||||
public void getValueReturnsTheAssociatedValueForKey() {
|
void getValueReturnsTheAssociatedValueForKey() {
|
||||||
final String knownKey = "12345";
|
final String knownKey = "12345";
|
||||||
final DownloadArtifactCache knownValue = new DownloadArtifactCache(DownloadType.BY_SHA1, knownKey);
|
final DownloadArtifactCache knownValue = new DownloadArtifactCache(DownloadType.BY_SHA1, knownKey);
|
||||||
|
|
||||||
@@ -98,7 +97,7 @@ public class DefaultDownloadIdCacheTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that retrieving a null value for a specific key is delegated to the CacheManager implementation")
|
@Description("Verifies that retrieving a null value for a specific key is delegated to the CacheManager implementation")
|
||||||
public void getValueReturnsNullIfNoKeyIsAssociated() {
|
void getValueReturnsNullIfNoKeyIsAssociated() {
|
||||||
|
|
||||||
when(cacheMock.get(knownKey)).thenReturn(new SimpleValueWrapper(null));
|
when(cacheMock.get(knownKey)).thenReturn(new SimpleValueWrapper(null));
|
||||||
|
|
||||||
@@ -109,7 +108,7 @@ public class DefaultDownloadIdCacheTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that TenancyCacheManager is using direct cache because download-ids are global unique and don't need to run as tenant aware")
|
@Description("Verifies that TenancyCacheManager is using direct cache because download-ids are global unique and don't need to run as tenant aware")
|
||||||
public void tenancyCacheManagerIsUsingDirectCache() {
|
void tenancyCacheManagerIsUsingDirectCache() {
|
||||||
|
|
||||||
when(tenancyCacheManagerMock.getDirectCache(DefaultDownloadIdCache.DOWNLOAD_ID_CACHE)).thenReturn(cacheMock);
|
when(tenancyCacheManagerMock.getDirectCache(DefaultDownloadIdCache.DOWNLOAD_ID_CACHE)).thenReturn(cacheMock);
|
||||||
underTest = new DefaultDownloadIdCache(tenancyCacheManagerMock);
|
underTest = new DefaultDownloadIdCache(tenancyCacheManagerMock);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class DefaultAmqpMessageSenderService extends BaseAmqpService implements
|
|||||||
LOGGER.debug("Sending message to exchange {} with correlationId {}", exchange, correlationId);
|
LOGGER.debug("Sending message to exchange {} with correlationId {}", exchange, correlationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRabbitTemplate().send(exchange, null, message, new CorrelationData(correlationId));
|
getRabbitTemplate().send(exchange, "", message, new CorrelationData(correlationId));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static boolean isCorrelationIdEmpty(final Message message) {
|
protected static boolean isCorrelationIdEmpty(final Message message) {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ import io.qameta.allure.Story;
|
|||||||
@Feature("Component Tests - Device Management Federation API")
|
@Feature("Component Tests - Device Management Federation API")
|
||||||
@Story("AmqpMessage Dispatcher Service Test")
|
@Story("AmqpMessage Dispatcher Service Test")
|
||||||
@SpringBootTest(classes = { RepositoryApplicationConfiguration.class })
|
@SpringBootTest(classes = { RepositoryApplicationConfiguration.class })
|
||||||
public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
private static final String TENANT = "default";
|
private static final String TENANT = "default";
|
||||||
private static final Long TENANT_ID = 4711L;
|
private static final Long TENANT_ID = 4711L;
|
||||||
@@ -127,7 +127,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that download and install event with 3 software modules and no artifacts works")
|
@Description("Verifies that download and install event with 3 software modules and no artifacts works")
|
||||||
public void testSendDownloadRequestWithSoftwareModulesAndNoArtifacts() {
|
void testSendDownloadRequestWithSoftwareModulesAndNoArtifacts() {
|
||||||
final DistributionSet createDistributionSet = testdataFactory
|
final DistributionSet createDistributionSet = testdataFactory
|
||||||
.createDistributionSet(UUID.randomUUID().toString());
|
.createDistributionSet(UUID.randomUUID().toString());
|
||||||
testdataFactory.addSoftwareModuleMetadata(createDistributionSet);
|
testdataFactory.addSoftwareModuleMetadata(createDistributionSet);
|
||||||
@@ -154,17 +154,19 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
if (!softwareModule.getModuleId().equals(softwareModule2.getId())) {
|
if (!softwareModule.getModuleId().equals(softwareModule2.getId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
assertThat(softwareModule.getModuleType()).isEqualTo(softwareModule2.getType().getKey()).as(
|
assertThat(softwareModule.getModuleType())
|
||||||
"Software module type in event should be the same as the softwaremodule in the distribution set");
|
.as("Software module type in event should be the same as the softwaremodule in the distribution set")
|
||||||
assertThat(softwareModule.getModuleVersion()).isEqualTo(softwareModule2.getVersion()).as(
|
.isEqualTo(softwareModule2.getType().getKey());
|
||||||
"Software module version in event should be the same as the softwaremodule in the distribution set");
|
assertThat(softwareModule.getModuleVersion())
|
||||||
|
.as("Software module version in event should be the same as the softwaremodule in the distribution set")
|
||||||
|
.isEqualTo(softwareModule2.getVersion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that download and install event with software modules and artifacts works")
|
@Description("Verifies that download and install event with software modules and artifacts works")
|
||||||
public void testSendDownloadRequest() {
|
void testSendDownloadRequest() {
|
||||||
DistributionSet dsA = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
DistributionSet dsA = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
||||||
SoftwareModule module = dsA.getModules().iterator().next();
|
SoftwareModule module = dsA.getModules().iterator().next();
|
||||||
final List<AbstractDbArtifact> receivedList = new ArrayList<>();
|
final List<AbstractDbArtifact> receivedList = new ArrayList<>();
|
||||||
@@ -186,15 +188,18 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
final DmfDownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage,
|
final DmfDownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage,
|
||||||
action.getId());
|
action.getId());
|
||||||
|
|
||||||
assertThat(downloadAndUpdateRequest.getSoftwareModules()).hasSize(3)
|
assertThat(downloadAndUpdateRequest.getSoftwareModules())
|
||||||
.as("DownloadAndUpdateRequest event should contains 3 software modules");
|
.as("DownloadAndUpdateRequest event should contains 3 software modules")
|
||||||
|
.hasSize(3);
|
||||||
assertThat(downloadAndUpdateRequest.getTargetSecurityToken()).isEqualTo(TEST_TOKEN);
|
assertThat(downloadAndUpdateRequest.getTargetSecurityToken()).isEqualTo(TEST_TOKEN);
|
||||||
|
|
||||||
for (final DmfSoftwareModule softwareModule : downloadAndUpdateRequest.getSoftwareModules()) {
|
for (final DmfSoftwareModule softwareModule : downloadAndUpdateRequest.getSoftwareModules()) {
|
||||||
if (!softwareModule.getModuleId().equals(module.getId())) {
|
if (!softwareModule.getModuleId().equals(module.getId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
assertThat(softwareModule.getArtifacts().size()).isEqualTo(module.getArtifacts().size()).isGreaterThan(0);
|
assertThat(softwareModule.getArtifacts().size())
|
||||||
|
.isEqualTo(module.getArtifacts().size())
|
||||||
|
.isNotZero();
|
||||||
|
|
||||||
module.getArtifacts().forEach(dbArtifact -> {
|
module.getArtifacts().forEach(dbArtifact -> {
|
||||||
final Optional<org.eclipse.hawkbit.dmf.json.model.DmfArtifact> found = softwareModule.getArtifacts()
|
final Optional<org.eclipse.hawkbit.dmf.json.model.DmfArtifact> found = softwareModule.getArtifacts()
|
||||||
@@ -211,7 +216,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that sending update controller attributes event works.")
|
@Description("Verifies that sending update controller attributes event works.")
|
||||||
public void sendUpdateAttributesRequest() {
|
void sendUpdateAttributesRequest() {
|
||||||
final String amqpUri = "amqp://anyhost";
|
final String amqpUri = "amqp://anyhost";
|
||||||
final TargetAttributesRequestedEvent targetAttributesRequestedEvent = new TargetAttributesRequestedEvent(TENANT,
|
final TargetAttributesRequestedEvent targetAttributesRequestedEvent = new TargetAttributesRequestedEvent(TENANT,
|
||||||
1L, CONTROLLER_ID, amqpUri, Target.class.getName(), serviceMatcher.getServiceId());
|
1L, CONTROLLER_ID, amqpUri, Target.class.getName(), serviceMatcher.getServiceId());
|
||||||
@@ -224,7 +229,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that send cancel event works")
|
@Description("Verifies that send cancel event works")
|
||||||
public void testSendCancelRequest() {
|
void testSendCancelRequest() {
|
||||||
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent(
|
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent(
|
||||||
testTarget, 1L, serviceMatcher.getServiceId());
|
testTarget, 1L, serviceMatcher.getServiceId());
|
||||||
amqpMessageDispatcherService
|
amqpMessageDispatcherService
|
||||||
@@ -237,7 +242,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that sending a delete message when receiving a delete event works.")
|
@Description("Verifies that sending a delete message when receiving a delete event works.")
|
||||||
public void sendDeleteRequest() {
|
void sendDeleteRequest() {
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
final String amqpUri = "amqp://anyhost";
|
final String amqpUri = "amqp://anyhost";
|
||||||
@@ -254,7 +259,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a delete message is not send if the address is not an amqp address.")
|
@Description("Verifies that a delete message is not send if the address is not an amqp address.")
|
||||||
public void sendDeleteRequestWithNoAmqpAddress() {
|
void sendDeleteRequestWithNoAmqpAddress() {
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
final String noAmqpUri = "http://anyhost";
|
final String noAmqpUri = "http://anyhost";
|
||||||
@@ -270,7 +275,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a delete message is not send if the address is null.")
|
@Description("Verifies that a delete message is not send if the address is null.")
|
||||||
public void sendDeleteRequestWithNullAddress() {
|
void sendDeleteRequestWithNullAddress() {
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
final String noAmqpUri = null;
|
final String noAmqpUri = null;
|
||||||
@@ -287,19 +292,22 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
private void assertCancelMessage(final Message sendMessage) {
|
private void assertCancelMessage(final Message sendMessage) {
|
||||||
assertEventMessage(sendMessage);
|
assertEventMessage(sendMessage);
|
||||||
final DmfActionRequest actionId = convertMessage(sendMessage, DmfActionRequest.class);
|
final DmfActionRequest actionId = convertMessage(sendMessage, DmfActionRequest.class);
|
||||||
assertThat(actionId.getActionId()).isEqualTo(Long.valueOf(1)).as("Action ID should be 1");
|
assertThat(actionId.getActionId())
|
||||||
assertThat(sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TOPIC))
|
.as("Action ID should be 1")
|
||||||
.isEqualTo(EventTopic.CANCEL_DOWNLOAD).as("The topc in the message should be a CANCEL_DOWNLOAD value");
|
.isOne();
|
||||||
|
assertThat(sendMessage.getMessageProperties().getHeaders())
|
||||||
|
.as("The topc in the message should be a CANCEL_DOWNLOAD value")
|
||||||
|
.containsEntry(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertDeleteMessage(final Message sendMessage) {
|
private void assertDeleteMessage(final Message sendMessage) {
|
||||||
|
|
||||||
assertThat(sendMessage).isNotNull();
|
assertThat(sendMessage).isNotNull();
|
||||||
assertThat(sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.THING_ID))
|
assertThat(sendMessage.getMessageProperties().getHeaders())
|
||||||
.isEqualTo(CONTROLLER_ID);
|
.containsEntry(MessageHeaderKey.THING_ID, CONTROLLER_ID);
|
||||||
assertThat(sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TENANT)).isEqualTo(TENANT);
|
assertThat(sendMessage.getMessageProperties().getHeaders())
|
||||||
assertThat(sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TYPE))
|
.containsEntry(MessageHeaderKey.TENANT, TENANT);
|
||||||
.isEqualTo(MessageType.THING_DELETED);
|
assertThat(sendMessage.getMessageProperties().getHeaders())
|
||||||
|
.containsEntry(MessageHeaderKey.TYPE,MessageType.THING_DELETED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DmfDownloadAndUpdateRequest assertDownloadAndInstallMessage(final Message sendMessage, final Long action) {
|
private DmfDownloadAndUpdateRequest assertDownloadAndInstallMessage(final Message sendMessage, final Long action) {
|
||||||
@@ -307,32 +315,35 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
|||||||
final DmfDownloadAndUpdateRequest downloadAndUpdateRequest = convertMessage(sendMessage,
|
final DmfDownloadAndUpdateRequest downloadAndUpdateRequest = convertMessage(sendMessage,
|
||||||
DmfDownloadAndUpdateRequest.class);
|
DmfDownloadAndUpdateRequest.class);
|
||||||
assertThat(downloadAndUpdateRequest.getActionId()).isEqualTo(action);
|
assertThat(downloadAndUpdateRequest.getActionId()).isEqualTo(action);
|
||||||
assertThat(sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TOPIC))
|
assertThat(sendMessage.getMessageProperties().getHeaders())
|
||||||
.isEqualTo(EventTopic.DOWNLOAD_AND_INSTALL)
|
.as("The topic of the event should contain DOWNLOAD_AND_INSTALL")
|
||||||
.as("The topic of the event should contain DOWNLOAD_AND_INSTALL");
|
.containsEntry(MessageHeaderKey.TOPIC,EventTopic.DOWNLOAD_AND_INSTALL);
|
||||||
assertThat(downloadAndUpdateRequest.getTargetSecurityToken()).isEqualTo(TEST_TOKEN)
|
assertThat(downloadAndUpdateRequest.getTargetSecurityToken())
|
||||||
.as("Security token of target");
|
.as("Security token of target")
|
||||||
|
.isEqualTo(TEST_TOKEN);
|
||||||
|
|
||||||
return downloadAndUpdateRequest;
|
return downloadAndUpdateRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertUpdateAttributesMessage(final Message sendMessage) {
|
private void assertUpdateAttributesMessage(final Message sendMessage) {
|
||||||
assertEventMessage(sendMessage);
|
assertEventMessage(sendMessage);
|
||||||
|
assertThat(sendMessage.getMessageProperties().getHeaders())
|
||||||
assertThat(sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TOPIC))
|
.as("The topic of the event should contain REQUEST_ATTRIBUTES_UPDATE")
|
||||||
.isEqualTo(EventTopic.REQUEST_ATTRIBUTES_UPDATE)
|
.containsEntry(MessageHeaderKey.TOPIC, EventTopic.REQUEST_ATTRIBUTES_UPDATE);
|
||||||
.as("The topic of the event should contain REQUEST_ATTRIBUTES_UPDATE");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertEventMessage(final Message sendMessage) {
|
private void assertEventMessage(final Message sendMessage) {
|
||||||
assertThat(sendMessage).isNotNull().as("The message should not be null");
|
assertThat(sendMessage).as("The message should not be null").isNotNull();
|
||||||
|
|
||||||
assertThat(sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.THING_ID))
|
assertThat(sendMessage.getMessageProperties().getHeaders())
|
||||||
.isEqualTo(CONTROLLER_ID).as("The value of the message header THING_ID should be " + CONTROLLER_ID);
|
.as("The value of the message header THING_ID should be " + CONTROLLER_ID)
|
||||||
assertThat(sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TYPE))
|
.containsEntry(MessageHeaderKey.THING_ID, CONTROLLER_ID);
|
||||||
.isEqualTo(MessageType.EVENT).as("The value of the message header TYPE should be EVENT");
|
assertThat(sendMessage.getMessageProperties().getHeaders())
|
||||||
assertThat(sendMessage.getMessageProperties().getContentType()).isEqualTo(MessageProperties.CONTENT_TYPE_JSON)
|
.as("The value of the message header TYPE should be EVENT")
|
||||||
.as("The content type message should be " + MessageProperties.CONTENT_TYPE_JSON);
|
.containsEntry(MessageHeaderKey.TYPE,MessageType.EVENT);
|
||||||
|
assertThat(sendMessage.getMessageProperties().getContentType())
|
||||||
|
.as("The content type message should be " + MessageProperties.CONTENT_TYPE_JSON)
|
||||||
|
.isEqualTo(MessageProperties.CONTENT_TYPE_JSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Message createArgumentCapture(final URI uri) {
|
protected Message createArgumentCapture(final URI uri) {
|
||||||
|
|||||||
@@ -153,9 +153,9 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
|||||||
final Message replyMessage = replyToListener.getDeleteMessages().get(target);
|
final Message replyMessage = replyToListener.getDeleteMessages().get(target);
|
||||||
assertAllTargetsCount(0);
|
assertAllTargetsCount(0);
|
||||||
final Map<String, Object> headers = replyMessage.getMessageProperties().getHeaders();
|
final Map<String, Object> headers = replyMessage.getMessageProperties().getHeaders();
|
||||||
assertThat(headers.get(MessageHeaderKey.THING_ID)).isEqualTo(target);
|
assertThat(headers).containsEntry(MessageHeaderKey.THING_ID, target)
|
||||||
assertThat(headers.get(MessageHeaderKey.TENANT)).isEqualTo(TENANT_EXIST);
|
.containsEntry(MessageHeaderKey.TENANT, TENANT_EXIST)
|
||||||
assertThat(headers.get(MessageHeaderKey.TYPE)).isEqualTo(MessageType.THING_DELETED.toString());
|
.containsEntry(MessageHeaderKey.TYPE, MessageType.THING_DELETED.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void assertRequestAttributesUpdateMessage(final String target) {
|
protected void assertRequestAttributesUpdateMessage(final String target) {
|
||||||
@@ -173,9 +173,9 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
|||||||
|
|
||||||
final Map<String, Object> headers = replyMessage.getMessageProperties().getHeaders();
|
final Map<String, Object> headers = replyMessage.getMessageProperties().getHeaders();
|
||||||
|
|
||||||
assertThat(headers.get(MessageHeaderKey.TENANT)).isEqualTo(TENANT_EXIST);
|
assertThat(headers).containsEntry(MessageHeaderKey.TENANT, TENANT_EXIST);
|
||||||
assertThat(correlationId).isEqualTo(replyMessage.getMessageProperties().getCorrelationId());
|
assertThat(correlationId).isEqualTo(replyMessage.getMessageProperties().getCorrelationId());
|
||||||
assertThat(headers.get(MessageHeaderKey.TYPE)).isEqualTo(MessageType.PING_RESPONSE.toString());
|
assertThat(headers).containsEntry(MessageHeaderKey.TYPE, MessageType.PING_RESPONSE.toString());
|
||||||
assertThat(Long.valueOf(new String(replyMessage.getBody(), StandardCharsets.UTF_8)))
|
assertThat(Long.valueOf(new String(replyMessage.getBody(), StandardCharsets.UTF_8)))
|
||||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||||
|
|
||||||
@@ -212,22 +212,17 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
|||||||
assertAssignmentMessage(dsModules, controllerId, EventTopic.DOWNLOAD);
|
assertAssignmentMessage(dsModules, controllerId, EventTopic.DOWNLOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void createAndSendThingCreated(final String controllerId, final String tenant) {
|
protected void createAndSendThingCreated(final String controllerId) {
|
||||||
createAndSendThingCreated(controllerId, null, null, tenant);
|
createAndSendThingCreated(controllerId, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void createAndSendThingCreated(final String controllerId, final String name,
|
protected void createAndSendThingCreated(final String controllerId, final String name,
|
||||||
final Map<String, String> attributes, final String tenant) {
|
final Map<String, String> attributes) {
|
||||||
final Message message = createTargetMessage(controllerId, name, attributes, tenant);
|
final Message message = createTargetMessage(controllerId, name, attributes,
|
||||||
|
AbstractAmqpServiceIntegrationTest.TENANT_EXIST);
|
||||||
getDmfClient().send(message);
|
getDmfClient().send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Message createAndSendPingMessage(final String correlationId, final String tenant) {
|
|
||||||
final Message message = createPingMessage(correlationId, tenant);
|
|
||||||
getDmfClient().send(message);
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void verifyReplyToListener() {
|
protected void verifyReplyToListener() {
|
||||||
createConditionFactory()
|
createConditionFactory()
|
||||||
.untilAsserted(() -> Mockito.verify(replyToListener, Mockito.atLeast(1)).handleMessage(Mockito.any()));
|
.untilAsserted(() -> Mockito.verify(replyToListener, Mockito.atLeast(1)).handleMessage(Mockito.any()));
|
||||||
@@ -254,10 +249,11 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
|||||||
final Message replyMessage = replyToListener.getLatestEventMessage(eventTopic);
|
final Message replyMessage = replyToListener.getLatestEventMessage(eventTopic);
|
||||||
assertAllTargetsCount(1);
|
assertAllTargetsCount(1);
|
||||||
final Map<String, Object> headers = replyMessage.getMessageProperties().getHeaders();
|
final Map<String, Object> headers = replyMessage.getMessageProperties().getHeaders();
|
||||||
assertThat(headers.get(MessageHeaderKey.TOPIC)).isEqualTo(eventTopic.toString());
|
|
||||||
assertThat(headers.get(MessageHeaderKey.THING_ID)).isEqualTo(controllerId);
|
assertThat(headers).containsEntry(MessageHeaderKey.TOPIC, eventTopic.toString())
|
||||||
assertThat(headers.get(MessageHeaderKey.TENANT)).isEqualTo(TENANT_EXIST);
|
.containsEntry(MessageHeaderKey.THING_ID, controllerId)
|
||||||
assertThat(headers.get(MessageHeaderKey.TYPE)).isEqualTo(MessageType.EVENT.toString());
|
.containsEntry(MessageHeaderKey.TENANT, TENANT_EXIST)
|
||||||
|
.containsEntry(MessageHeaderKey.TYPE, MessageType.EVENT.toString());
|
||||||
return replyMessage;
|
return replyMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +286,7 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
|||||||
final int existingTargetsAfterCreation, final TargetUpdateStatus expectedTargetStatus,
|
final int existingTargetsAfterCreation, final TargetUpdateStatus expectedTargetStatus,
|
||||||
final String createdBy, final Map<String, String> attributes,
|
final String createdBy, final Map<String, String> attributes,
|
||||||
final Callable<Optional<Target>> fetchTarget) {
|
final Callable<Optional<Target>> fetchTarget) {
|
||||||
createAndSendThingCreated(controllerId, name, attributes, TENANT_EXIST);
|
createAndSendThingCreated(controllerId, name, attributes);
|
||||||
final Target registeredTarget = waitUntilIsPresent(fetchTarget::call);
|
final Target registeredTarget = waitUntilIsPresent(fetchTarget::call);
|
||||||
assertAllTargetsCount(existingTargetsAfterCreation);
|
assertAllTargetsCount(existingTargetsAfterCreation);
|
||||||
assertThat(registeredTarget).isNotNull();
|
assertThat(registeredTarget).isNotNull();
|
||||||
@@ -372,14 +368,15 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
|||||||
final DmfActionStatus status) {
|
final DmfActionStatus status) {
|
||||||
final DmfActionUpdateStatus dmfActionUpdateStatus = new DmfActionUpdateStatus(actionId, status);
|
final DmfActionUpdateStatus dmfActionUpdateStatus = new DmfActionUpdateStatus(actionId, status);
|
||||||
|
|
||||||
final Message eventMessage = createUpdateActionEventMessage(TENANT_EXIST, dmfActionUpdateStatus);
|
final Message eventMessage = createUpdateActionEventMessage(dmfActionUpdateStatus);
|
||||||
eventMessage.getMessageProperties().getHeaders().put(MessageHeaderKey.THING_ID, target);
|
eventMessage.getMessageProperties().getHeaders().put(MessageHeaderKey.THING_ID, target);
|
||||||
|
|
||||||
getDmfClient().send(eventMessage);
|
getDmfClient().send(eventMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Message createUpdateActionEventMessage(final String tenant, final Object payload) {
|
protected Message createUpdateActionEventMessage(final Object payload) {
|
||||||
final MessageProperties messageProperties = createMessagePropertiesWithTenant(tenant);
|
final MessageProperties messageProperties = createMessagePropertiesWithTenant(
|
||||||
|
AbstractAmqpServiceIntegrationTest.TENANT_EXIST);
|
||||||
messageProperties.getHeaders().put(MessageHeaderKey.TYPE, MessageType.EVENT.toString());
|
messageProperties.getHeaders().put(MessageHeaderKey.TYPE, MessageType.EVENT.toString());
|
||||||
messageProperties.getHeaders().put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.toString());
|
messageProperties.getHeaders().put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.toString());
|
||||||
messageProperties.setCorrelationId(CORRELATION_ID);
|
messageProperties.setCorrelationId(CORRELATION_ID);
|
||||||
@@ -404,8 +401,9 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Message createUpdateAttributesMessageWrongBody(final String target, final String tenant) {
|
protected Message createUpdateAttributesMessageWrongBody(final String target) {
|
||||||
final MessageProperties messageProperties = createMessagePropertiesWithTenant(tenant);
|
final MessageProperties messageProperties = createMessagePropertiesWithTenant(
|
||||||
|
AbstractAmqpServiceIntegrationTest.TENANT_EXIST);
|
||||||
messageProperties.getHeaders().put(MessageHeaderKey.THING_ID, target);
|
messageProperties.getHeaders().put(MessageHeaderKey.THING_ID, target);
|
||||||
messageProperties.getHeaders().put(MessageHeaderKey.TYPE, MessageType.EVENT.toString());
|
messageProperties.getHeaders().put(MessageHeaderKey.TYPE, MessageType.EVENT.toString());
|
||||||
messageProperties.getHeaders().put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ATTRIBUTES.toString());
|
messageProperties.getHeaders().put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ATTRIBUTES.toString());
|
||||||
@@ -423,19 +421,13 @@ public abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpInt
|
|||||||
final Map<String, String> controllerAttributes = WithSpringAuthorityRule
|
final Map<String, String> controllerAttributes = WithSpringAuthorityRule
|
||||||
.runAsPrivileged(() -> targetManagement.getControllerAttributes(controllerId));
|
.runAsPrivileged(() -> targetManagement.getControllerAttributes(controllerId));
|
||||||
assertThat(controllerAttributes.size()).isEqualTo(attributes.size());
|
assertThat(controllerAttributes.size()).isEqualTo(attributes.size());
|
||||||
attributes.forEach((k, v) -> assertKeyValueInMap(k, v, controllerAttributes));
|
assertThat(controllerAttributes).containsAllEntriesOf(attributes);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertKeyValueInMap(final String key, final String value,
|
|
||||||
final Map<String, String> controllerAttributes) {
|
|
||||||
assertThat(controllerAttributes.containsKey(key)).isTrue();
|
|
||||||
assertThat(controllerAttributes.get(key)).isEqualTo(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getExchange() {
|
protected String getExchange() {
|
||||||
return AmqpSettings.DMF_EXCHANGE;
|
return AmqpSettings.DMF_EXCHANGE;
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
|
|||||||
assertCancelActionMessage(getFirstAssignedActionId(assignmentResult), controllerId);
|
assertCancelActionMessage(getFirstAssignedActionId(assignmentResult), controllerId);
|
||||||
|
|
||||||
// cancelation message is returned upon polling
|
// cancelation message is returned upon polling
|
||||||
createAndSendThingCreated(controllerId, TENANT_EXIST);
|
createAndSendThingCreated(controllerId);
|
||||||
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.CANCEL_DOWNLOAD);
|
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.CANCEL_DOWNLOAD);
|
||||||
assertCancelActionMessage(getFirstAssignedActionId(assignmentResult), controllerId);
|
assertCancelActionMessage(getFirstAssignedActionId(assignmentResult), controllerId);
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
|
|||||||
assertDownloadAndInstallMessage(distributionSet2.getModules(), controllerId);
|
assertDownloadAndInstallMessage(distributionSet2.getModules(), controllerId);
|
||||||
|
|
||||||
// latest action is returned upon polling
|
// latest action is returned upon polling
|
||||||
createAndSendThingCreated(controllerId, TENANT_EXIST);
|
createAndSendThingCreated(controllerId);
|
||||||
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.DOWNLOAD_AND_INSTALL);
|
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.DOWNLOAD_AND_INSTALL);
|
||||||
assertDownloadAndInstallMessage(distributionSet2.getModules(), controllerId);
|
assertDownloadAndInstallMessage(distributionSet2.getModules(), controllerId);
|
||||||
}
|
}
|
||||||
@@ -478,7 +478,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
|
|||||||
|
|
||||||
final Long actionId = registerTargetAndCancelActionId(controllerId);
|
final Long actionId = registerTargetAndCancelActionId(controllerId);
|
||||||
|
|
||||||
createAndSendThingCreated(controllerId, TENANT_EXIST);
|
createAndSendThingCreated(controllerId);
|
||||||
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING);
|
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING);
|
||||||
assertCancelActionMessage(actionId, controllerId);
|
assertCancelActionMessage(actionId, controllerId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,8 +58,12 @@ import org.eclipse.hawkbit.repository.model.Target;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||||
|
import org.eclipse.hawkbit.repository.test.util.TargetTestData;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.NullSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.springframework.amqp.core.Message;
|
import org.springframework.amqp.core.Message;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||||
@@ -75,8 +79,11 @@ import io.qameta.allure.Story;
|
|||||||
|
|
||||||
@Feature("Component Tests - Device Management Federation API")
|
@Feature("Component Tests - Device Management Federation API")
|
||||||
@Story("Amqp Message Handler Service")
|
@Story("Amqp Message Handler Service")
|
||||||
public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegrationTest {
|
class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegrationTest {
|
||||||
private static final String TARGET_PREFIX = "Dmf_hand_";
|
private static final String TARGET_PREFIX = "Dmf_hand_";
|
||||||
|
public static final String DMF_REGISTER_TEST_CONTROLLER_ID = "Dmf_hand_registerTargets_1";
|
||||||
|
public static final String DMF_ATTR_TEST_CONTROLLER_ID = "Dmf_hand_updateAttributes";
|
||||||
|
public static final String UPDATE_ATTR_TEST_CONTROLLER_ID = "ControllerAttributeTestTarget";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AmqpProperties amqpProperties;
|
private AmqpProperties amqpProperties;
|
||||||
@@ -86,7 +93,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests DMF PING request and expected response.")
|
@Description("Tests DMF PING request and expected response.")
|
||||||
public void pingDmfInterface() {
|
void pingDmfInterface() {
|
||||||
final Message pingMessage = createPingMessage(CORRELATION_ID, TENANT_EXIST);
|
final Message pingMessage = createPingMessage(CORRELATION_ID, TENANT_EXIST);
|
||||||
getDmfClient().send(pingMessage);
|
getDmfClient().send(pingMessage);
|
||||||
|
|
||||||
@@ -99,7 +106,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Description("Tests register target")
|
@Description("Tests register target")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 2),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetPollEvent.class, count = 3) })
|
@Expect(type = TargetPollEvent.class, count = 3) })
|
||||||
public void registerTargets() {
|
void registerTargets() {
|
||||||
final String controllerId = TARGET_PREFIX + "registerTargets";
|
final String controllerId = TARGET_PREFIX + "registerTargets";
|
||||||
registerAndAssertTargetWithExistingTenant(controllerId, 1);
|
registerAndAssertTargetWithExistingTenant(controllerId, 1);
|
||||||
|
|
||||||
@@ -114,7 +121,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Description("Tests register target with name")
|
@Description("Tests register target with name")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
||||||
public void registerTargetWithName() {
|
void registerTargetWithName() {
|
||||||
final String controllerId = TARGET_PREFIX + "registerTargetWithName";
|
final String controllerId = TARGET_PREFIX + "registerTargetWithName";
|
||||||
final String name = "NonDefaultTargetName";
|
final String name = "NonDefaultTargetName";
|
||||||
registerAndAssertTargetWithExistingTenant(controllerId, name, 1, TargetUpdateStatus.REGISTERED, CREATED_BY,
|
registerAndAssertTargetWithExistingTenant(controllerId, name, 1, TargetUpdateStatus.REGISTERED, CREATED_BY,
|
||||||
@@ -130,7 +137,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Description("Tests register target with attributes")
|
@Description("Tests register target with attributes")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 2) })
|
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 2) })
|
||||||
public void registerTargetWithAttributes() {
|
void registerTargetWithAttributes() {
|
||||||
final String controllerId = TARGET_PREFIX + "registerTargetWithAttributes";
|
final String controllerId = TARGET_PREFIX + "registerTargetWithAttributes";
|
||||||
final Map<String, String> attributes = new HashMap<>();
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
attributes.put("testKey1", "testValue1");
|
attributes.put("testKey1", "testValue1");
|
||||||
@@ -149,7 +156,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Description("Tests register target with name and attributes")
|
@Description("Tests register target with name and attributes")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 3), @Expect(type = TargetPollEvent.class, count = 2) })
|
@Expect(type = TargetUpdatedEvent.class, count = 3), @Expect(type = TargetPollEvent.class, count = 2) })
|
||||||
public void registerTargetWithNameAndAttributes() {
|
void registerTargetWithNameAndAttributes() {
|
||||||
final String controllerId = TARGET_PREFIX + "registerTargetWithAttributes";
|
final String controllerId = TARGET_PREFIX + "registerTargetWithAttributes";
|
||||||
final String name = "NonDefaultTargetName";
|
final String name = "NonDefaultTargetName";
|
||||||
final Map<String, String> attributes = new HashMap<>();
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
@@ -166,46 +173,30 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
Mockito.verifyNoInteractions(getDeadletterListener());
|
Mockito.verifyNoInteractions(getDeadletterListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {"", "Invalid Invalid"})
|
||||||
|
@NullSource
|
||||||
@Description("Tests register invalid target with empty controller id.")
|
@Description("Tests register invalid target with empty controller id.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void registerEmptyTarget() {
|
void shouldNotRegisterTargetsWithInvalidControllerIds(String controllerId) {
|
||||||
createAndSendThingCreated("", TENANT_EXIST);
|
createAndSendThingCreated(controllerId);
|
||||||
assertAllTargetsCount(0);
|
|
||||||
verifyOneDeadLetterMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests register invalid target with whitespace controller id.")
|
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
|
||||||
public void registerWhitespaceTarget() {
|
|
||||||
createAndSendThingCreated("Invalid Invalid", TENANT_EXIST);
|
|
||||||
assertAllTargetsCount(0);
|
|
||||||
verifyOneDeadLetterMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests register invalid target with null controller id.")
|
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
|
||||||
public void registerInvalidNullTarget() {
|
|
||||||
createAndSendThingCreated(null, TENANT_EXIST);
|
|
||||||
assertAllTargetsCount(0);
|
assertAllTargetsCount(0);
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests register invalid target with too long controller id")
|
@Description("Tests register invalid target with too long controller id")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void registerInvalidTargetWithTooLongControllerId() {
|
void registerInvalidTargetWithTooLongControllerId() {
|
||||||
createAndSendThingCreated(RandomStringUtils.randomAlphabetic(Target.CONTROLLER_ID_MAX_SIZE + 1), TENANT_EXIST);
|
createAndSendThingCreated(RandomStringUtils.randomAlphabetic(Target.CONTROLLER_ID_MAX_SIZE + 1));
|
||||||
assertAllTargetsCount(0);
|
assertAllTargetsCount(0);
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests null reply to property in message header. This message should forwarded to the deadletter queue")
|
@Description("Tests null reply to property in message header. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void missingReplyToProperty() {
|
void missingReplyToProperty() {
|
||||||
final String controllerId = TARGET_PREFIX + "missingReplyToProperty";
|
final String controllerId = TARGET_PREFIX + "missingReplyToProperty";
|
||||||
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
|
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
|
||||||
createTargetMessage.getMessageProperties().setReplyTo(null);
|
createTargetMessage.getMessageProperties().setReplyTo(null);
|
||||||
@@ -217,8 +208,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests missing reply to property in message header. This message should forwarded to the deadletter queue")
|
@Description("Tests missing reply to property in message header. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void emptyReplyToProperty() {
|
void emptyReplyToProperty() {
|
||||||
final String controllerId = TARGET_PREFIX + "emptyReplyToProperty";
|
final String controllerId = TARGET_PREFIX + "emptyReplyToProperty";
|
||||||
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
|
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
|
||||||
createTargetMessage.getMessageProperties().setReplyTo("");
|
createTargetMessage.getMessageProperties().setReplyTo("");
|
||||||
@@ -230,8 +221,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests missing thing id property in message. This message should forwarded to the deadletter queue")
|
@Description("Tests missing thing id property in message. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void missingThingIdProperty() {
|
void missingThingIdProperty() {
|
||||||
final Message createTargetMessage = createTargetMessage(null, TENANT_EXIST);
|
final Message createTargetMessage = createTargetMessage(null, TENANT_EXIST);
|
||||||
createTargetMessage.getMessageProperties().getHeaders().remove(MessageHeaderKey.THING_ID);
|
createTargetMessage.getMessageProperties().getHeaders().remove(MessageHeaderKey.THING_ID);
|
||||||
getDmfClient().send(createTargetMessage);
|
getDmfClient().send(createTargetMessage);
|
||||||
@@ -242,8 +233,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests null thing id property in message. This message should forwarded to the deadletter queue")
|
@Description("Tests null thing id property in message. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void nullThingIdProperty() {
|
void nullThingIdProperty() {
|
||||||
final Message createTargetMessage = createTargetMessage(null, TENANT_EXIST);
|
final Message createTargetMessage = createTargetMessage(null, TENANT_EXIST);
|
||||||
getDmfClient().send(createTargetMessage);
|
getDmfClient().send(createTargetMessage);
|
||||||
|
|
||||||
@@ -253,8 +244,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests missing tenant message header. This message should forwarded to the deadletter queue")
|
@Description("Tests missing tenant message header. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void missingTenantHeader() {
|
void missingTenantHeader() {
|
||||||
final String controllerId = TARGET_PREFIX + "missingTenantHeader";
|
final String controllerId = TARGET_PREFIX + "missingTenantHeader";
|
||||||
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
|
final Message createTargetMessage = createTargetMessage(controllerId, TENANT_EXIST);
|
||||||
createTargetMessage.getMessageProperties().getHeaders().remove(MessageHeaderKey.TENANT);
|
createTargetMessage.getMessageProperties().getHeaders().remove(MessageHeaderKey.TENANT);
|
||||||
@@ -266,8 +257,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests null tenant message header. This message should forwarded to the deadletter queue")
|
@Description("Tests null tenant message header. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void nullTenantHeader() {
|
void nullTenantHeader() {
|
||||||
final String controllerId = TARGET_PREFIX + "nullTenantHeader";
|
final String controllerId = TARGET_PREFIX + "nullTenantHeader";
|
||||||
final Message createTargetMessage = createTargetMessage(controllerId, null);
|
final Message createTargetMessage = createTargetMessage(controllerId, null);
|
||||||
getDmfClient().send(createTargetMessage);
|
getDmfClient().send(createTargetMessage);
|
||||||
@@ -278,8 +269,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests empty tenant message header. This message should forwarded to the deadletter queue")
|
@Description("Tests empty tenant message header. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void emptyTenantHeader() {
|
void emptyTenantHeader() {
|
||||||
final String controllerId = TARGET_PREFIX + "emptyTenantHeader";
|
final String controllerId = TARGET_PREFIX + "emptyTenantHeader";
|
||||||
final Message createTargetMessage = createTargetMessage(controllerId, "");
|
final Message createTargetMessage = createTargetMessage(controllerId, "");
|
||||||
getDmfClient().send(createTargetMessage);
|
getDmfClient().send(createTargetMessage);
|
||||||
@@ -290,8 +281,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests tenant not exist. This message should forwarded to the deadletter queue")
|
@Description("Tests tenant not exist. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void tenantNotExist() {
|
void tenantNotExist() {
|
||||||
final String controllerId = TARGET_PREFIX + "tenantNotExist";
|
final String controllerId = TARGET_PREFIX + "tenantNotExist";
|
||||||
final Message createTargetMessage = createTargetMessage(controllerId, "TenantNotExist");
|
final Message createTargetMessage = createTargetMessage(controllerId, "TenantNotExist");
|
||||||
getDmfClient().send(createTargetMessage);
|
getDmfClient().send(createTargetMessage);
|
||||||
@@ -302,8 +293,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests missing type message header. This message should forwarded to the deadletter queue")
|
@Description("Tests missing type message header. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void missingTypeHeader() {
|
void missingTypeHeader() {
|
||||||
final Message createTargetMessage = createTargetMessage(null, TENANT_EXIST);
|
final Message createTargetMessage = createTargetMessage(null, TENANT_EXIST);
|
||||||
createTargetMessage.getMessageProperties().getHeaders().remove(MessageHeaderKey.TYPE);
|
createTargetMessage.getMessageProperties().getHeaders().remove(MessageHeaderKey.TYPE);
|
||||||
getDmfClient().send(createTargetMessage);
|
getDmfClient().send(createTargetMessage);
|
||||||
@@ -312,70 +303,28 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
assertAllTargetsCount(0);
|
assertAllTargetsCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings={"", "NotExist"})
|
||||||
|
@NullSource
|
||||||
@Description("Tests null type message header. This message should forwarded to the deadletter queue")
|
@Description("Tests null type message header. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void nullTypeHeader() {
|
void shouldNotCreateTargetsWithInvalidTypeInHeader(String type) {
|
||||||
final Message createTargetMessage = createTargetMessage(null, TENANT_EXIST);
|
final Message createTargetMessage = createTargetMessage(null, TENANT_EXIST);
|
||||||
createTargetMessage.getMessageProperties().getHeaders().put(MessageHeaderKey.TYPE, null);
|
createTargetMessage.getMessageProperties().getHeaders().put(MessageHeaderKey.TYPE, type);
|
||||||
getDmfClient().send(createTargetMessage);
|
getDmfClient().send(createTargetMessage);
|
||||||
|
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
assertAllTargetsCount(0);
|
assertAllTargetsCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
@Description("Tests empty type message header. This message should forwarded to the deadletter queue")
|
@ValueSource(strings = {"", "NotExist"})
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@NullSource
|
||||||
public void emptyTypeHeader() {
|
|
||||||
final Message createTargetMessage = createTargetMessage(null, TENANT_EXIST);
|
|
||||||
createTargetMessage.getMessageProperties().getHeaders().put(MessageHeaderKey.TYPE, "");
|
|
||||||
getDmfClient().send(createTargetMessage);
|
|
||||||
|
|
||||||
verifyOneDeadLetterMessage();
|
|
||||||
assertAllTargetsCount(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests invalid type message header. This message should forwarded to the deadletter queue")
|
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
|
||||||
public void invalidTypeHeader() {
|
|
||||||
final Message createTargetMessage = createTargetMessage(null, TENANT_EXIST);
|
|
||||||
createTargetMessage.getMessageProperties().getHeaders().put(MessageHeaderKey.TYPE, "NotExist");
|
|
||||||
getDmfClient().send(createTargetMessage);
|
|
||||||
|
|
||||||
verifyOneDeadLetterMessage();
|
|
||||||
assertAllTargetsCount(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests null topic message header. This message should forwarded to the deadletter queue")
|
@Description("Tests null topic message header. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void nullTopicHeader() {
|
void shouldNotSendMessagesWithInvalidTopic(String topic) {
|
||||||
final Message eventMessage = createUpdateActionEventMessage(TENANT_EXIST, "");
|
final Message eventMessage = createUpdateActionEventMessage("");
|
||||||
eventMessage.getMessageProperties().getHeaders().put(MessageHeaderKey.TOPIC, null);
|
eventMessage.getMessageProperties().getHeaders().put(MessageHeaderKey.TOPIC, topic);
|
||||||
getDmfClient().send(eventMessage);
|
|
||||||
|
|
||||||
verifyOneDeadLetterMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests null topic message header. This message should forwarded to the deadletter queue")
|
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
|
||||||
public void emptyTopicHeader() {
|
|
||||||
final Message eventMessage = createUpdateActionEventMessage(TENANT_EXIST, "");
|
|
||||||
eventMessage.getMessageProperties().getHeaders().put(MessageHeaderKey.TOPIC, "");
|
|
||||||
getDmfClient().send(eventMessage);
|
|
||||||
|
|
||||||
verifyOneDeadLetterMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests null topic message header. This message should forwarded to the deadletter queue")
|
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
|
||||||
public void invalidTopicHeader() {
|
|
||||||
final Message eventMessage = createUpdateActionEventMessage(TENANT_EXIST, "");
|
|
||||||
eventMessage.getMessageProperties().getHeaders().put(MessageHeaderKey.TOPIC, "NotExist");
|
|
||||||
getDmfClient().send(eventMessage);
|
getDmfClient().send(eventMessage);
|
||||||
|
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
@@ -383,48 +332,32 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests missing topic message header. This message should forwarded to the deadletter queue")
|
@Description("Tests missing topic message header. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void missingTopicHeader() {
|
void missingTopicHeader() {
|
||||||
final Message eventMessage = createUpdateActionEventMessage(TENANT_EXIST, "");
|
final Message eventMessage = createUpdateActionEventMessage("");
|
||||||
eventMessage.getMessageProperties().getHeaders().remove(MessageHeaderKey.TOPIC);
|
eventMessage.getMessageProperties().getHeaders().remove(MessageHeaderKey.TOPIC);
|
||||||
getDmfClient().send(eventMessage);
|
getDmfClient().send(eventMessage);
|
||||||
|
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = { "", "Invalid Content"})
|
||||||
|
@NullSource
|
||||||
@Description("Tests invalid null message content. This message should forwarded to the deadletter queue")
|
@Description("Tests invalid null message content. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void updateActionStatusWithNullContent() {
|
void shouldMoveUpdateActionStatusWithInvalidPayloadIntoDeadLetter(String payload) {
|
||||||
final Message eventMessage = createUpdateActionEventMessage(TENANT_EXIST, null);
|
final Message eventMessage = createUpdateActionEventMessage(payload);
|
||||||
getDmfClient().send(eventMessage);
|
|
||||||
verifyOneDeadLetterMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests invalid empty message content. This message should forwarded to the deadletter queue")
|
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
|
||||||
public void updateActionStatusWithEmptyContent() {
|
|
||||||
final Message eventMessage = createUpdateActionEventMessage(TENANT_EXIST, "");
|
|
||||||
getDmfClient().send(eventMessage);
|
|
||||||
verifyOneDeadLetterMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests invalid json message content. This message should forwarded to the deadletter queue")
|
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
|
||||||
public void updateActionStatusWithInvalidJsonContent() {
|
|
||||||
final Message eventMessage = createUpdateActionEventMessage(TENANT_EXIST, "Invalid Content");
|
|
||||||
getDmfClient().send(eventMessage);
|
getDmfClient().send(eventMessage);
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests invalid topic message header. This message should forwarded to the deadletter queue")
|
@Description("Tests invalid topic message header. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void updateActionStatusWithInvalidActionId() {
|
void updateActionStatusWithInvalidActionId() {
|
||||||
final DmfActionUpdateStatus actionUpdateStatus = new DmfActionUpdateStatus(1L, DmfActionStatus.RUNNING);
|
final DmfActionUpdateStatus actionUpdateStatus = new DmfActionUpdateStatus(1L, DmfActionStatus.RUNNING);
|
||||||
final Message eventMessage = createUpdateActionEventMessage(TENANT_EXIST, actionUpdateStatus);
|
final Message eventMessage = createUpdateActionEventMessage(actionUpdateStatus);
|
||||||
getDmfClient().send(eventMessage);
|
getDmfClient().send(eventMessage);
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
}
|
}
|
||||||
@@ -439,7 +372,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void finishActionStatus() {
|
void finishActionStatus() {
|
||||||
final String controllerId = TARGET_PREFIX + "finishActionStatus";
|
final String controllerId = TARGET_PREFIX + "finishActionStatus";
|
||||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.FINISHED, Status.FINISHED, controllerId);
|
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.FINISHED, Status.FINISHED, controllerId);
|
||||||
}
|
}
|
||||||
@@ -448,12 +381,12 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Description("Register a target and send a update action status (running). Verify if the updated action status is correct.")
|
@Description("Register a target and send a update action status (running). Verify if the updated action status is correct.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 0), @Expect(type = ActionCreatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class), @Expect(type = ActionCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void runningActionStatus() {
|
void runningActionStatus() {
|
||||||
final String controllerId = TARGET_PREFIX + "runningActionStatus";
|
final String controllerId = TARGET_PREFIX + "runningActionStatus";
|
||||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.RUNNING, Status.RUNNING, controllerId);
|
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.RUNNING, Status.RUNNING, controllerId);
|
||||||
}
|
}
|
||||||
@@ -462,12 +395,12 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Description("Register a target and send an update action status (downloaded). Verify if the updated action status is correct.")
|
@Description("Register a target and send an update action status (downloaded). Verify if the updated action status is correct.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 0), @Expect(type = ActionCreatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class), @Expect(type = ActionCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void downloadedActionStatus() {
|
void downloadedActionStatus() {
|
||||||
final String controllerId = TARGET_PREFIX + "downloadedActionStatus";
|
final String controllerId = TARGET_PREFIX + "downloadedActionStatus";
|
||||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.DOWNLOADED, Status.DOWNLOADED, controllerId);
|
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.DOWNLOADED, Status.DOWNLOADED, controllerId);
|
||||||
}
|
}
|
||||||
@@ -481,7 +414,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void downloadActionStatus() {
|
void downloadActionStatus() {
|
||||||
final String controllerId = TARGET_PREFIX + "downloadActionStatus";
|
final String controllerId = TARGET_PREFIX + "downloadActionStatus";
|
||||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.DOWNLOAD, Status.DOWNLOAD, controllerId);
|
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.DOWNLOAD, Status.DOWNLOAD, controllerId);
|
||||||
}
|
}
|
||||||
@@ -495,7 +428,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void errorActionStatus() {
|
void errorActionStatus() {
|
||||||
final String controllerId = TARGET_PREFIX + "errorActionStatus";
|
final String controllerId = TARGET_PREFIX + "errorActionStatus";
|
||||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.ERROR, Status.ERROR, controllerId);
|
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.ERROR, Status.ERROR, controllerId);
|
||||||
}
|
}
|
||||||
@@ -509,7 +442,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void warningActionStatus() {
|
void warningActionStatus() {
|
||||||
final String controllerId = TARGET_PREFIX + "warningActionStatus";
|
final String controllerId = TARGET_PREFIX + "warningActionStatus";
|
||||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.WARNING, Status.WARNING, controllerId);
|
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.WARNING, Status.WARNING, controllerId);
|
||||||
}
|
}
|
||||||
@@ -523,7 +456,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void retrievedActionStatus() {
|
void retrievedActionStatus() {
|
||||||
final String controllerId = TARGET_PREFIX + "retrievedActionStatus";
|
final String controllerId = TARGET_PREFIX + "retrievedActionStatus";
|
||||||
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.RETRIEVED, Status.RETRIEVED, controllerId);
|
registerTargetAndSendAndAssertUpdateActionStatus(DmfActionStatus.RETRIEVED, Status.RETRIEVED, controllerId);
|
||||||
}
|
}
|
||||||
@@ -537,7 +470,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void cancelNotAllowActionStatus() {
|
void cancelNotAllowActionStatus() {
|
||||||
final String controllerId = TARGET_PREFIX + "cancelNotAllowActionStatus";
|
final String controllerId = TARGET_PREFIX + "cancelNotAllowActionStatus";
|
||||||
registerTargetAndSendActionStatus(DmfActionStatus.CANCELED, controllerId);
|
registerTargetAndSendActionStatus(DmfActionStatus.CANCELED, controllerId);
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
@@ -552,7 +485,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
||||||
public void receiveDownLoadAndInstallMessageAfterAssignment() {
|
void receiveDownLoadAndInstallMessageAfterAssignment() {
|
||||||
final String controllerId = TARGET_PREFIX + "receiveDownLoadAndInstallMessageAfterAssignment";
|
final String controllerId = TARGET_PREFIX + "receiveDownLoadAndInstallMessageAfterAssignment";
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
@@ -578,7 +511,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
||||||
public void receiveDownloadMessageBeforeMaintenanceWindowStartTime() {
|
void receiveDownloadMessageBeforeMaintenanceWindowStartTime() {
|
||||||
final String controllerId = TARGET_PREFIX + "receiveDownLoadMessageBeforeMaintenanceWindowStartTime";
|
final String controllerId = TARGET_PREFIX + "receiveDownLoadMessageBeforeMaintenanceWindowStartTime";
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
@@ -605,7 +538,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
|
||||||
public void receiveDownloadAndInstallMessageDuringMaintenanceWindow() {
|
void receiveDownloadAndInstallMessageDuringMaintenanceWindow() {
|
||||||
final String controllerId = TARGET_PREFIX + "receiveDownLoadAndInstallMessageDuringMaintenanceWindow";
|
final String controllerId = TARGET_PREFIX + "receiveDownLoadAndInstallMessageDuringMaintenanceWindow";
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
@@ -633,7 +566,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 2) })
|
@Expect(type = TargetPollEvent.class, count = 2) })
|
||||||
public void receiveCancelUpdateMessageAfterAssignmentWasCanceled() {
|
void receiveCancelUpdateMessageAfterAssignmentWasCanceled() {
|
||||||
final String controllerId = TARGET_PREFIX + "receiveCancelUpdateMessageAfterAssignmentWasCanceled";
|
final String controllerId = TARGET_PREFIX + "receiveCancelUpdateMessageAfterAssignmentWasCanceled";
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
@@ -661,11 +594,11 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void actionNotExists() {
|
void actionNotExists() {
|
||||||
final String controllerId = TARGET_PREFIX + "actionNotExists";
|
final String controllerId = TARGET_PREFIX + "actionNotExists";
|
||||||
|
|
||||||
final Long actionId = registerTargetAndCancelActionId(controllerId);
|
final Long actionId = registerTargetAndCancelActionId(controllerId);
|
||||||
final Long actionNotExist = actionId + 1;
|
final long actionNotExist = actionId + 1;
|
||||||
|
|
||||||
createAndSendActionStatusUpdateMessage(controllerId, actionNotExist, DmfActionStatus.CANCELED);
|
createAndSendActionStatusUpdateMessage(controllerId, actionNotExist, DmfActionStatus.CANCELED);
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
@@ -680,7 +613,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void canceledRejectedNotAllowActionStatus() {
|
void canceledRejectedNotAllowActionStatus() {
|
||||||
final String controllerId = TARGET_PREFIX + "canceledRejectedNotAllowActionStatus";
|
final String controllerId = TARGET_PREFIX + "canceledRejectedNotAllowActionStatus";
|
||||||
registerTargetAndSendActionStatus(DmfActionStatus.CANCEL_REJECTED, controllerId);
|
registerTargetAndSendActionStatus(DmfActionStatus.CANCEL_REJECTED, controllerId);
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
@@ -696,7 +629,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void canceledRejectedActionStatus() {
|
void canceledRejectedActionStatus() {
|
||||||
final String controllerId = TARGET_PREFIX + "canceledRejectedActionStatus";
|
final String controllerId = TARGET_PREFIX + "canceledRejectedActionStatus";
|
||||||
|
|
||||||
final Long actionId = registerTargetAndCancelActionId(controllerId);
|
final Long actionId = registerTargetAndCancelActionId(controllerId);
|
||||||
@@ -709,35 +642,36 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Description("Verify that sending an update controller attribute message to an existing target works. Verify that different update modes (merge, replace, remove) can be used.")
|
@Description("Verify that sending an update controller attribute message to an existing target works. Verify that different update modes (merge, replace, remove) can be used.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 4), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 4), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void updateAttributesWithDifferentUpdateModes() {
|
void updateAttributesWithDifferentUpdateModes() {
|
||||||
final String controllerId = TARGET_PREFIX + "updateAttributes";
|
final String controllerId = TARGET_PREFIX + "updateAttributes";
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
registerAndAssertTargetWithExistingTenant(controllerId);
|
registerAndAssertTargetWithExistingTenant(controllerId);
|
||||||
|
|
||||||
// no update mode specified
|
// no update mode specified
|
||||||
updateAttributesWithoutUpdateMode(controllerId);
|
updateAttributesWithoutUpdateMode();
|
||||||
|
|
||||||
// update mode REPLACE
|
// update mode REPLACE
|
||||||
updateAttributesWithUpdateModeReplace(controllerId);
|
updateAttributesWithUpdateModeReplace();
|
||||||
|
|
||||||
// update mode MERGE
|
// update mode MERGE
|
||||||
updateAttributesWithUpdateModeMerge(controllerId);
|
updateAttributesWithUpdateModeMerge();
|
||||||
|
|
||||||
// update mode REMOVE
|
// update mode REMOVE
|
||||||
updateAttributesWithUpdateModeRemove(controllerId);
|
updateAttributesWithUpdateModeRemove();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void updateAttributesWithUpdateModeRemove(final String controllerId) {
|
private void updateAttributesWithUpdateModeRemove() {
|
||||||
|
|
||||||
// assemble the expected attributes
|
// assemble the expected attributes
|
||||||
final Map<String, String> expectedAttributes = targetManagement.getControllerAttributes(controllerId);
|
final Map<String, String> expectedAttributes = targetManagement
|
||||||
|
.getControllerAttributes(DMF_ATTR_TEST_CONTROLLER_ID);
|
||||||
expectedAttributes.remove("k1");
|
expectedAttributes.remove("k1");
|
||||||
expectedAttributes.remove("k3");
|
expectedAttributes.remove("k3");
|
||||||
|
|
||||||
// send a update message with update mode
|
// send an update message with update mode
|
||||||
final Map<String, String> removeAttributes = new HashMap<>();
|
final Map<String, String> removeAttributes = new HashMap<>();
|
||||||
removeAttributes.put("k1", "foo");
|
removeAttributes.put("k1", "foo");
|
||||||
removeAttributes.put("k3", "bar");
|
removeAttributes.put("k3", "bar");
|
||||||
@@ -745,19 +679,19 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
final DmfAttributeUpdate remove = new DmfAttributeUpdate();
|
final DmfAttributeUpdate remove = new DmfAttributeUpdate();
|
||||||
remove.setMode(DmfUpdateMode.REMOVE);
|
remove.setMode(DmfUpdateMode.REMOVE);
|
||||||
remove.getAttributes().putAll(removeAttributes);
|
remove.getAttributes().putAll(removeAttributes);
|
||||||
sendUpdateAttributeMessage(controllerId, TENANT_EXIST, remove);
|
sendUpdateAttributeMessage(remove);
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
assertUpdateAttributes(controllerId, expectedAttributes);
|
assertUpdateAttributes(DMF_ATTR_TEST_CONTROLLER_ID, expectedAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void updateAttributesWithUpdateModeMerge(final String controllerId) {
|
private void updateAttributesWithUpdateModeMerge() {
|
||||||
|
|
||||||
// get the current attributes
|
// get the current attributes
|
||||||
final Map<String, String> attributes = new HashMap<>(targetManagement.getControllerAttributes(controllerId));
|
final Map<String, String> attributes = new HashMap<>(
|
||||||
|
targetManagement.getControllerAttributes(DMF_ATTR_TEST_CONTROLLER_ID));
|
||||||
|
|
||||||
// send a update message with update mode MERGE
|
// send an update message with update mode MERGE
|
||||||
final Map<String, String> mergeAttributes = new HashMap<>();
|
final Map<String, String> mergeAttributes = new HashMap<>();
|
||||||
mergeAttributes.put("k1", "v1_modified_again");
|
mergeAttributes.put("k1", "v1_modified_again");
|
||||||
mergeAttributes.put("k4", "v4");
|
mergeAttributes.put("k4", "v4");
|
||||||
@@ -765,19 +699,18 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
final DmfAttributeUpdate merge = new DmfAttributeUpdate();
|
final DmfAttributeUpdate merge = new DmfAttributeUpdate();
|
||||||
merge.setMode(DmfUpdateMode.MERGE);
|
merge.setMode(DmfUpdateMode.MERGE);
|
||||||
merge.getAttributes().putAll(mergeAttributes);
|
merge.getAttributes().putAll(mergeAttributes);
|
||||||
sendUpdateAttributeMessage(controllerId, TENANT_EXIST, merge);
|
sendUpdateAttributeMessage(merge);
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
final Map<String, String> expectedAttributes = new HashMap<>();
|
final Map<String, String> expectedAttributes = new HashMap<>();
|
||||||
expectedAttributes.putAll(attributes);
|
expectedAttributes.putAll(attributes);
|
||||||
expectedAttributes.putAll(mergeAttributes);
|
expectedAttributes.putAll(mergeAttributes);
|
||||||
assertUpdateAttributes(controllerId, expectedAttributes);
|
assertUpdateAttributes(DMF_ATTR_TEST_CONTROLLER_ID, expectedAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void updateAttributesWithUpdateModeReplace(final String controllerId) {
|
private void updateAttributesWithUpdateModeReplace() {
|
||||||
|
// send an update message with update mode REPLACE
|
||||||
// send a update message with update mode REPLACE
|
|
||||||
final Map<String, String> expectedAttributes = new HashMap<>();
|
final Map<String, String> expectedAttributes = new HashMap<>();
|
||||||
expectedAttributes.put("k1", "v1_modified");
|
expectedAttributes.put("k1", "v1_modified");
|
||||||
expectedAttributes.put("k2", "v2");
|
expectedAttributes.put("k2", "v2");
|
||||||
@@ -786,33 +719,32 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
final DmfAttributeUpdate replace = new DmfAttributeUpdate();
|
final DmfAttributeUpdate replace = new DmfAttributeUpdate();
|
||||||
replace.setMode(DmfUpdateMode.REPLACE);
|
replace.setMode(DmfUpdateMode.REPLACE);
|
||||||
replace.getAttributes().putAll(expectedAttributes);
|
replace.getAttributes().putAll(expectedAttributes);
|
||||||
sendUpdateAttributeMessage(controllerId, TENANT_EXIST, replace);
|
sendUpdateAttributeMessage(replace);
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
assertUpdateAttributes(controllerId, expectedAttributes);
|
assertUpdateAttributes(DMF_ATTR_TEST_CONTROLLER_ID, expectedAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void updateAttributesWithoutUpdateMode(final String controllerId) {
|
private void updateAttributesWithoutUpdateMode() {
|
||||||
|
// send an update message which does not specify an update mode
|
||||||
// send a update message which does not specify an update mode
|
|
||||||
final Map<String, String> expectedAttributes = new HashMap<>();
|
final Map<String, String> expectedAttributes = new HashMap<>();
|
||||||
expectedAttributes.put("k0", "v0");
|
expectedAttributes.put("k0", "v0");
|
||||||
expectedAttributes.put("k1", "v1");
|
expectedAttributes.put("k1", "v1");
|
||||||
|
|
||||||
final DmfAttributeUpdate defaultUpdate = new DmfAttributeUpdate();
|
final DmfAttributeUpdate defaultUpdate = new DmfAttributeUpdate();
|
||||||
defaultUpdate.getAttributes().putAll(expectedAttributes);
|
defaultUpdate.getAttributes().putAll(expectedAttributes);
|
||||||
sendUpdateAttributeMessage(controllerId, TENANT_EXIST, defaultUpdate);
|
sendUpdateAttributeMessage(defaultUpdate);
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
assertUpdateAttributes(controllerId, expectedAttributes);
|
assertUpdateAttributes(DMF_ATTR_TEST_CONTROLLER_ID, expectedAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that sending an update controller attribute message with no thingid header to an existing target does not work.")
|
@Description("Verify that sending an update controller attribute message with no thingid header to an existing target does not work.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 0), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void updateAttributesWithNoThingId() {
|
void updateAttributesWithNoThingId() {
|
||||||
final String controllerId = TARGET_PREFIX + "updateAttributesWithNoThingId";
|
final String controllerId = TARGET_PREFIX + "updateAttributesWithNoThingId";
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
@@ -836,17 +768,15 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that sending an update controller attribute message with invalid body to an existing target does not work.")
|
@Description("Verify that sending an update controller attribute message with invalid body to an existing target does not work.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 0), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void updateAttributesWithWrongBody() {
|
void updateAttributesWithWrongBody() {
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
final String target = "ControllerAttributeTestTarget";
|
registerAndAssertTargetWithExistingTenant(UPDATE_ATTR_TEST_CONTROLLER_ID);
|
||||||
registerAndAssertTargetWithExistingTenant(target);
|
|
||||||
final DmfAttributeUpdate controllerAttribute = new DmfAttributeUpdate();
|
final DmfAttributeUpdate controllerAttribute = new DmfAttributeUpdate();
|
||||||
controllerAttribute.getAttributes().put("test1", "testA");
|
controllerAttribute.getAttributes().put("test1", "testA");
|
||||||
controllerAttribute.getAttributes().put("test2", "testB");
|
controllerAttribute.getAttributes().put("test2", "testB");
|
||||||
final Message createUpdateAttributesMessageWrongBody = createUpdateAttributesMessageWrongBody(target,
|
final Message createUpdateAttributesMessageWrongBody = createUpdateAttributesMessageWrongBody(
|
||||||
TENANT_EXIST);
|
UPDATE_ATTR_TEST_CONTROLLER_ID);
|
||||||
|
|
||||||
// test
|
// test
|
||||||
getDmfClient().send(createUpdateAttributesMessageWrongBody);
|
getDmfClient().send(createUpdateAttributesMessageWrongBody);
|
||||||
@@ -857,20 +787,12 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that sending an UPDATE_ATTRIBUTES message with invalid attributes is handled correctly.")
|
@Description("Verifies that sending an UPDATE_ATTRIBUTES message with invalid attributes is handled correctly.")
|
||||||
public void updateAttributesWithInvalidValues() {
|
void updateAttributesWithInvalidValues() {
|
||||||
// setup
|
registerAndAssertTargetWithExistingTenant(UPDATE_ATTR_TEST_CONTROLLER_ID);
|
||||||
final String target = "ControllerAttributeTestTarget";
|
|
||||||
registerAndAssertTargetWithExistingTenant(target);
|
|
||||||
final String keyTooLong = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE + 1);
|
|
||||||
final String keyValid = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE);
|
|
||||||
final String valueTooLong = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE + 1);
|
|
||||||
final String valueValid = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE);
|
|
||||||
|
|
||||||
sendUpdateAttributesMessageWithGivenAttributes(target, keyTooLong, valueValid);
|
sendUpdateAttributesMessageWithGivenAttributes(TargetTestData.ATTRIBUTE_KEY_TOO_LONG, TargetTestData.ATTRIBUTE_VALUE_VALID);
|
||||||
|
sendUpdateAttributesMessageWithGivenAttributes(TargetTestData.ATTRIBUTE_KEY_TOO_LONG, TargetTestData.ATTRIBUTE_VALUE_TOO_LONG);
|
||||||
sendUpdateAttributesMessageWithGivenAttributes(target, keyTooLong, valueTooLong);
|
sendUpdateAttributesMessageWithGivenAttributes(TargetTestData.ATTRIBUTE_KEY_VALID, TargetTestData.ATTRIBUTE_VALUE_TOO_LONG);
|
||||||
|
|
||||||
sendUpdateAttributesMessageWithGivenAttributes(target, keyValid, valueTooLong);
|
|
||||||
|
|
||||||
verifyNumberOfDeadLetterMessages(3);
|
verifyNumberOfDeadLetterMessages(3);
|
||||||
}
|
}
|
||||||
@@ -885,7 +807,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void downloadOnlyAssignmentFinishesActionWhenTargetReportsDownloaded() throws IOException {
|
void downloadOnlyAssignmentFinishesActionWhenTargetReportsDownloaded() throws IOException {
|
||||||
// create target
|
// create target
|
||||||
final String controllerId = TARGET_PREFIX + "registerTargets_1";
|
final String controllerId = TARGET_PREFIX + "registerTargets_1";
|
||||||
final DistributionSet distributionSet = createTargetAndDistributionSetAndAssign(controllerId, DOWNLOAD_ONLY);
|
final DistributionSet distributionSet = createTargetAndDistributionSetAndAssign(controllerId, DOWNLOAD_ONLY);
|
||||||
@@ -895,14 +817,14 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
Mockito.verifyNoInteractions(getDeadletterListener());
|
Mockito.verifyNoInteractions(getDeadletterListener());
|
||||||
|
|
||||||
// get actionId from Message
|
// get actionId from Message
|
||||||
final Long actionId = Long.parseLong(getJsonFieldFromBody(message.getBody(), "actionId"));
|
final long actionId = Long.parseLong(getActionIdFromBody(message.getBody()));
|
||||||
|
|
||||||
// Send DOWNLOADED message
|
// Send DOWNLOADED message
|
||||||
createAndSendActionStatusUpdateMessage(controllerId, actionId, DmfActionStatus.DOWNLOADED);
|
createAndSendActionStatusUpdateMessage(controllerId, actionId, DmfActionStatus.DOWNLOADED);
|
||||||
assertAction(actionId, 1, Status.RUNNING, Status.DOWNLOADED);
|
assertAction(actionId, 1, Status.RUNNING, Status.DOWNLOADED);
|
||||||
Mockito.verifyNoInteractions(getDeadletterListener());
|
Mockito.verifyNoInteractions(getDeadletterListener());
|
||||||
|
|
||||||
verifyAssignedDsAndInstalledDs(controllerId, distributionSet.getId(), null);
|
verifyAssignedDsAndInstalledDs(distributionSet.getId(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -915,9 +837,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 2),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 2),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 3), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 3), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void downloadOnlyAssignmentAllowsActionStatusUpdatesWhenTargetReportsFinishedAndUpdatesInstalledDS()
|
void downloadOnlyAssignmentAllowsActionStatusUpdatesWhenTargetReportsFinishedAndUpdatesInstalledDS()
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
// create target
|
// create target
|
||||||
final String controllerId = TARGET_PREFIX + "registerTargets_1";
|
final String controllerId = TARGET_PREFIX + "registerTargets_1";
|
||||||
final DistributionSet distributionSet = createTargetAndDistributionSetAndAssign(controllerId, DOWNLOAD_ONLY);
|
final DistributionSet distributionSet = createTargetAndDistributionSetAndAssign(controllerId, DOWNLOAD_ONLY);
|
||||||
@@ -927,29 +848,28 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
Mockito.verifyNoInteractions(getDeadletterListener());
|
Mockito.verifyNoInteractions(getDeadletterListener());
|
||||||
|
|
||||||
// get actionId from Message
|
// get actionId from Message
|
||||||
final Long actionId = Long.parseLong(getJsonFieldFromBody(message.getBody(), "actionId"));
|
final long actionId = Long.parseLong(getActionIdFromBody(message.getBody()));
|
||||||
|
|
||||||
// Send DOWNLOADED message, should result in the action being closed
|
// Send DOWNLOADED message, should result in the action being closed
|
||||||
createAndSendActionStatusUpdateMessage(controllerId, actionId, DmfActionStatus.DOWNLOADED);
|
createAndSendActionStatusUpdateMessage(controllerId, actionId, DmfActionStatus.DOWNLOADED);
|
||||||
assertAction(actionId, 1, Status.RUNNING, Status.DOWNLOADED);
|
assertAction(actionId, 1, Status.RUNNING, Status.DOWNLOADED);
|
||||||
Mockito.verifyNoInteractions(getDeadletterListener());
|
Mockito.verifyNoInteractions(getDeadletterListener());
|
||||||
|
|
||||||
verifyAssignedDsAndInstalledDs(controllerId, distributionSet.getId(), null);
|
verifyAssignedDsAndInstalledDs(distributionSet.getId(), null);
|
||||||
|
|
||||||
// Send FINISHED message
|
// Send FINISHED message
|
||||||
createAndSendActionStatusUpdateMessage(controllerId, actionId, DmfActionStatus.FINISHED);
|
createAndSendActionStatusUpdateMessage(controllerId, actionId, DmfActionStatus.FINISHED);
|
||||||
assertAction(actionId, 2, Status.RUNNING, Status.DOWNLOADED, Status.FINISHED);
|
assertAction(actionId, 2, Status.RUNNING, Status.DOWNLOADED, Status.FINISHED);
|
||||||
Mockito.verifyNoInteractions(getDeadletterListener());
|
Mockito.verifyNoInteractions(getDeadletterListener());
|
||||||
|
|
||||||
verifyAssignedDsAndInstalledDs(controllerId, distributionSet.getId(), distributionSet.getId());
|
verifyAssignedDsAndInstalledDs(distributionSet.getId(), distributionSet.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Messages that result into certain exceptions being raised should not be requeued. This message should forwarded to the deadletter queue")
|
@Description("Messages that result into certain exceptions being raised should not be requeued. This message should forwarded to the deadletter queue")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void ignoredExceptionTypesShouldNotBeRequeued() {
|
void ignoredExceptionTypesShouldNotBeRequeued() {
|
||||||
final ControllerManagement mockedControllerManagement = Mockito.mock(ControllerManagement.class);
|
final ControllerManagement mockedControllerManagement = Mockito.mock(ControllerManagement.class);
|
||||||
|
|
||||||
final List<Class<? extends RuntimeException>> exceptionsThatShouldNotBeRequeued = Arrays
|
final List<Class<? extends RuntimeException>> exceptionsThatShouldNotBeRequeued = Arrays
|
||||||
.asList(IllegalArgumentException.class, EntityAlreadyExistsException.class);
|
.asList(IllegalArgumentException.class, EntityAlreadyExistsException.class);
|
||||||
final String controllerId = "dummy_target";
|
final String controllerId = "dummy_target";
|
||||||
@@ -960,7 +880,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
.findOrRegisterTargetIfItDoesNotExist(eq(controllerId), any());
|
.findOrRegisterTargetIfItDoesNotExist(eq(controllerId), any());
|
||||||
|
|
||||||
amqpMessageHandlerService.setControllerManagement(mockedControllerManagement);
|
amqpMessageHandlerService.setControllerManagement(mockedControllerManagement);
|
||||||
createAndSendThingCreated(controllerId, TENANT_EXIST);
|
createAndSendThingCreated(controllerId);
|
||||||
verifyOneDeadLetterMessage();
|
verifyOneDeadLetterMessage();
|
||||||
assertThat(targetManagement.getByControllerID(controllerId)).isEmpty();
|
assertThat(targetManagement.getByControllerID(controllerId)).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -970,9 +890,8 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void verifyAssignedDsAndInstalledDs(final String controllerId, final Long assignedDsId,
|
private void verifyAssignedDsAndInstalledDs(final Long assignedDsId, final Long installedDsId) {
|
||||||
final Long installedDsId) {
|
final Optional<Target> target = controllerManagement.getByControllerId(DMF_REGISTER_TEST_CONTROLLER_ID);
|
||||||
final Optional<Target> target = controllerManagement.getByControllerId(controllerId);
|
|
||||||
assertThat(target).isPresent();
|
assertThat(target).isPresent();
|
||||||
|
|
||||||
// verify the DS was assigned to the Target
|
// verify the DS was assigned to the Target
|
||||||
@@ -989,11 +908,11 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendUpdateAttributesMessageWithGivenAttributes(final String target, final String key,
|
private void sendUpdateAttributesMessageWithGivenAttributes(final String key, final String value) {
|
||||||
final String value) {
|
|
||||||
final DmfAttributeUpdate controllerAttribute = new DmfAttributeUpdate();
|
final DmfAttributeUpdate controllerAttribute = new DmfAttributeUpdate();
|
||||||
controllerAttribute.getAttributes().put(key, value);
|
controllerAttribute.getAttributes().put(key, value);
|
||||||
final Message message = createUpdateAttributesMessage(target, TENANT_EXIST, controllerAttribute);
|
final Message message = createUpdateAttributesMessage(UPDATE_ATTR_TEST_CONTROLLER_ID, TENANT_EXIST,
|
||||||
|
controllerAttribute);
|
||||||
getDmfClient().send(message);
|
getDmfClient().send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,9 +960,9 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendUpdateAttributeMessage(final String target, final String tenant,
|
private void sendUpdateAttributeMessage(final DmfAttributeUpdate attributeUpdate) {
|
||||||
final DmfAttributeUpdate attributeUpdate) {
|
final Message updateMessage = createUpdateAttributesMessage(DMF_ATTR_TEST_CONTROLLER_ID,
|
||||||
final Message updateMessage = createUpdateAttributesMessage(target, tenant, attributeUpdate);
|
AbstractAmqpServiceIntegrationTest.TENANT_EXIST, attributeUpdate);
|
||||||
getDmfClient().send(updateMessage);
|
getDmfClient().send(updateMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1068,10 +987,10 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServic
|
|||||||
Mockito.reset(getDeadletterListener());
|
Mockito.reset(getDeadletterListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getJsonFieldFromBody(final byte[] body, final String fieldName) throws IOException {
|
private static String getActionIdFromBody(final byte[] body) throws IOException {
|
||||||
final ObjectMapper objectMapper = new ObjectMapper();
|
final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
final ObjectNode node = objectMapper.readValue(new String(body, Charset.defaultCharset()), ObjectNode.class);
|
final ObjectNode node = objectMapper.readValue(new String(body, Charset.defaultCharset()), ObjectNode.class);
|
||||||
assertThat(node.has(fieldName)).isTrue();
|
assertThat(node.has("actionId")).isTrue();
|
||||||
return node.get(fieldName).asText();
|
return node.get("actionId").asText();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,11 +36,7 @@ import org.springframework.util.AntPathMatcher;
|
|||||||
/**
|
/**
|
||||||
* An abstraction for all controller based security to parse the e.g. the tenant
|
* An abstraction for all controller based security to parse the e.g. the tenant
|
||||||
* name from the URL and the controller ID from the URL to do security checks
|
* name from the URL and the controller ID from the URL to do security checks
|
||||||
* based on these information.
|
* based on this information.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractHttpControllerAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
|
public abstract class AbstractHttpControllerAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
|
||||||
|
|
||||||
@@ -77,8 +73,9 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
* @param systemSecurityContext
|
* @param systemSecurityContext
|
||||||
* the system secruity context
|
* the system secruity context
|
||||||
*/
|
*/
|
||||||
public AbstractHttpControllerAuthenticationFilter(final TenantConfigurationManagement tenantConfigurationManagement,
|
protected AbstractHttpControllerAuthenticationFilter(
|
||||||
final TenantAware tenantAware, final SystemSecurityContext systemSecurityContext) {
|
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
||||||
|
final SystemSecurityContext systemSecurityContext) {
|
||||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
||||||
this.tenantAware = tenantAware;
|
this.tenantAware = tenantAware;
|
||||||
this.systemSecurityContext = systemSecurityContext;
|
this.systemSecurityContext = systemSecurityContext;
|
||||||
@@ -127,7 +124,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
*
|
*
|
||||||
* @param request
|
* @param request
|
||||||
* the Http request to extract the path variables.
|
* the Http request to extract the path variables.
|
||||||
* @return the extracted {@link PathVariables} or {@code null} if the
|
* @return the extracted {@link DmfTenantSecurityToken} or {@code null} if the
|
||||||
* request does not match the pattern and no variables could be
|
* request does not match the pattern and no variables could be
|
||||||
* extracted
|
* extracted
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -8,15 +8,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.event.remote;
|
package org.eclipse.hawkbit.repository.event.remote;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.Identifiable;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.Identifiable;
|
||||||
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic deployment event for the Multi-Assignments feature. The event payload
|
* Generic deployment event for the Multi-Assignments feature. The event payload
|
||||||
* holds a list of controller IDs identifying the targets which are affected by
|
* holds a list of controller IDs identifying the targets which are affected by
|
||||||
@@ -33,7 +33,7 @@ public abstract class MultiActionEvent extends RemoteTenantAwareEvent implements
|
|||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
*/
|
*/
|
||||||
public MultiActionEvent() {
|
protected MultiActionEvent() {
|
||||||
// for serialization libs like jackson
|
// for serialization libs like jackson
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ public abstract class MultiActionEvent extends RemoteTenantAwareEvent implements
|
|||||||
* @param actions
|
* @param actions
|
||||||
* the actions involved
|
* the actions involved
|
||||||
*/
|
*/
|
||||||
public MultiActionEvent(String tenant, String applicationId, List<Action> actions) {
|
protected MultiActionEvent(String tenant, String applicationId, List<Action> actions) {
|
||||||
super(applicationId, tenant, applicationId);
|
super(applicationId, tenant, applicationId);
|
||||||
this.controllerIds.addAll(getControllerIdsFromActions(actions));
|
this.controllerIds.addAll(getControllerIdsFromActions(actions));
|
||||||
this.actionIds.addAll(getIdsFromActions(actions));
|
this.actionIds.addAll(getIdsFromActions(actions));
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,15 +18,18 @@ import org.eclipse.hawkbit.repository.model.Action;
|
|||||||
public abstract class AbstractActionEvent extends RemoteEntityEvent<Action> {
|
public abstract class AbstractActionEvent extends RemoteEntityEvent<Action> {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private Long targetId;
|
private final Long targetId;
|
||||||
private Long rolloutId;
|
private final Long rolloutId;
|
||||||
private Long rolloutGroupId;
|
private final Long rolloutGroupId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
*/
|
*/
|
||||||
public AbstractActionEvent() {
|
protected AbstractActionEvent() {
|
||||||
// for serialization libs like jackson
|
// for serialization libs like jackson
|
||||||
|
this.targetId = null;
|
||||||
|
this.rolloutId = null;
|
||||||
|
this.rolloutGroupId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +46,7 @@ public abstract class AbstractActionEvent extends RemoteEntityEvent<Action> {
|
|||||||
* @param applicationId
|
* @param applicationId
|
||||||
* the origin application id
|
* the origin application id
|
||||||
*/
|
*/
|
||||||
public AbstractActionEvent(final Action action, final Long targetId, final Long rolloutId,
|
protected AbstractActionEvent(final Action action, final Long targetId, final Long rolloutId,
|
||||||
final Long rolloutGroupId, final String applicationId) {
|
final Long rolloutGroupId, final String applicationId) {
|
||||||
super(action, applicationId);
|
super(action, applicationId);
|
||||||
this.targetId = targetId;
|
this.targetId = targetId;
|
||||||
@@ -61,4 +66,21 @@ public abstract class AbstractActionEvent extends RemoteEntityEvent<Action> {
|
|||||||
return rolloutGroupId;
|
return rolloutGroupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
if (!super.equals(o))
|
||||||
|
return false;
|
||||||
|
final AbstractActionEvent that = (AbstractActionEvent) o;
|
||||||
|
return Objects.equals(targetId, that.targetId) && Objects.equals(rolloutId, that.rolloutId)
|
||||||
|
&& Objects.equals(rolloutGroupId, that.rolloutGroupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), targetId, rolloutId, rolloutGroupId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,26 +8,28 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TenantAwareEvent definition which is been published in case a rollout group
|
* Event which is published in case a {@linkplain RolloutGroup} is created or
|
||||||
* has been created for a specific rollout or updated.
|
* updated
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractRolloutGroupEvent extends RemoteEntityEvent<RolloutGroup> {
|
public abstract class AbstractRolloutGroupEvent extends RemoteEntityEvent<RolloutGroup> {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private Long rolloutId;
|
private final Long rolloutId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
*/
|
*/
|
||||||
public AbstractRolloutGroupEvent() {
|
protected AbstractRolloutGroupEvent() {
|
||||||
// for serialization libs like jackson
|
// for serialization libs like jackson
|
||||||
|
this.rolloutId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractRolloutGroupEvent(final RolloutGroup rolloutGroup, final Long rolloutId,
|
protected AbstractRolloutGroupEvent(final RolloutGroup rolloutGroup, final Long rolloutId,
|
||||||
final String applicationId) {
|
final String applicationId) {
|
||||||
super(rolloutGroup, applicationId);
|
super(rolloutGroup, applicationId);
|
||||||
this.rolloutId = rolloutId;
|
this.rolloutId = rolloutId;
|
||||||
@@ -37,4 +39,20 @@ public abstract class AbstractRolloutGroupEvent extends RemoteEntityEvent<Rollou
|
|||||||
return rolloutId;
|
return rolloutId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
if (!super.equals(o))
|
||||||
|
return false;
|
||||||
|
final AbstractRolloutGroupEvent that = (AbstractRolloutGroupEvent) o;
|
||||||
|
return Objects.equals(rolloutId, that.rolloutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), rolloutId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public abstract class AbstractAssignmentResult<T extends BaseEntity> {
|
|||||||
* @param unassignedEntity
|
* @param unassignedEntity
|
||||||
* {@link List} of unassigned entity.
|
* {@link List} of unassigned entity.
|
||||||
*/
|
*/
|
||||||
public AbstractAssignmentResult(final int alreadyAssigned, final List<? extends T> assignedEntity,
|
protected AbstractAssignmentResult(final int alreadyAssigned, final List<? extends T> assignedEntity,
|
||||||
final List<? extends T> unassignedEntity) {
|
final List<? extends T> unassignedEntity) {
|
||||||
this.alreadyAssigned = alreadyAssigned;
|
this.alreadyAssigned = alreadyAssigned;
|
||||||
this.assignedEntity = assignedEntity;
|
this.assignedEntity = assignedEntity;
|
||||||
|
|||||||
@@ -156,12 +156,15 @@ public interface Action extends TenantAwareBaseEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Check if action type is either forced or time-forced <i>and</i> force-time is
|
||||||
|
* exceeded.
|
||||||
|
*
|
||||||
* @return {@code true} if either the {@link #getActionType()} is
|
* @return {@code true} if either the {@link #getActionType()} is
|
||||||
* {@link ActionType#FORCED} or {@link ActionType#TIMEFORCED} but
|
* {@link ActionType#FORCED} or {@link ActionType#TIMEFORCED} but then
|
||||||
* then if the {@link #getForcedTime()} has been exceeded otherwise
|
* if the {@link #getForcedTime()} has been exceeded otherwise always
|
||||||
* always {@code false}
|
* {@code false}
|
||||||
*/
|
*/
|
||||||
default boolean isForce() {
|
default boolean isForcedOrTimeForced() {
|
||||||
switch (getActionType()) {
|
switch (getActionType()) {
|
||||||
case FORCED:
|
case FORCED:
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.cache.TenancyCacheManager;
|
import org.eclipse.hawkbit.cache.TenancyCacheManager;
|
||||||
import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
|
import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.RolloutDeletedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.RolloutDeletedEvent;
|
||||||
@@ -74,9 +76,7 @@ public class RolloutStatusCache {
|
|||||||
* @return map of cached entries
|
* @return map of cached entries
|
||||||
*/
|
*/
|
||||||
public Map<Long, List<TotalTargetCountActionStatus>> getRolloutStatus(final List<Long> rollouts) {
|
public Map<Long, List<TotalTargetCountActionStatus>> getRolloutStatus(final List<Long> rollouts) {
|
||||||
final Cache cache = cacheManager.getCache(CACHE_RO_NAME);
|
return retrieveFromCache(rollouts, getRolloutStatusCache());
|
||||||
|
|
||||||
return retrieveFromCache(rollouts, cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,9 +88,7 @@ public class RolloutStatusCache {
|
|||||||
* @return map of cached entries
|
* @return map of cached entries
|
||||||
*/
|
*/
|
||||||
public List<TotalTargetCountActionStatus> getRolloutStatus(final Long rolloutId) {
|
public List<TotalTargetCountActionStatus> getRolloutStatus(final Long rolloutId) {
|
||||||
final Cache cache = cacheManager.getCache(CACHE_RO_NAME);
|
return retrieveFromCache(rolloutId, getRolloutStatusCache());
|
||||||
|
|
||||||
return retrieveFromCache(rolloutId, cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,9 +100,7 @@ public class RolloutStatusCache {
|
|||||||
* @return map of cached entries
|
* @return map of cached entries
|
||||||
*/
|
*/
|
||||||
public Map<Long, List<TotalTargetCountActionStatus>> getRolloutGroupStatus(final List<Long> rolloutGroups) {
|
public Map<Long, List<TotalTargetCountActionStatus>> getRolloutGroupStatus(final List<Long> rolloutGroups) {
|
||||||
final Cache cache = cacheManager.getCache(CACHE_GR_NAME);
|
return retrieveFromCache(rolloutGroups, getGroupStatusCache());
|
||||||
|
|
||||||
return retrieveFromCache(rolloutGroups, cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,9 +112,7 @@ public class RolloutStatusCache {
|
|||||||
* @return map of cached entries
|
* @return map of cached entries
|
||||||
*/
|
*/
|
||||||
public List<TotalTargetCountActionStatus> getRolloutGroupStatus(final Long groupId) {
|
public List<TotalTargetCountActionStatus> getRolloutGroupStatus(final Long groupId) {
|
||||||
final Cache cache = cacheManager.getCache(CACHE_GR_NAME);
|
return retrieveFromCache(groupId, getGroupStatusCache());
|
||||||
|
|
||||||
return retrieveFromCache(groupId, cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,8 +123,7 @@ public class RolloutStatusCache {
|
|||||||
* map of cached entries
|
* map of cached entries
|
||||||
*/
|
*/
|
||||||
public void putRolloutStatus(final Map<Long, List<TotalTargetCountActionStatus>> put) {
|
public void putRolloutStatus(final Map<Long, List<TotalTargetCountActionStatus>> put) {
|
||||||
final Cache cache = cacheManager.getCache(CACHE_RO_NAME);
|
putIntoCache(put, getRolloutStatusCache());
|
||||||
putIntoCache(put, cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,10 +137,10 @@ public class RolloutStatusCache {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void putRolloutStatus(final Long rolloutId, final List<TotalTargetCountActionStatus> status) {
|
public void putRolloutStatus(final Long rolloutId, final List<TotalTargetCountActionStatus> status) {
|
||||||
final Cache cache = cacheManager.getCache(CACHE_RO_NAME);
|
putIntoCache(rolloutId, status, getRolloutStatusCache());
|
||||||
putIntoCache(rolloutId, status, cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put {@link TotalTargetCountActionStatus} for multiple
|
* Put {@link TotalTargetCountActionStatus} for multiple
|
||||||
* {@link RolloutGroup}s into cache.
|
* {@link RolloutGroup}s into cache.
|
||||||
@@ -156,8 +149,7 @@ public class RolloutStatusCache {
|
|||||||
* map of cached entries
|
* map of cached entries
|
||||||
*/
|
*/
|
||||||
public void putRolloutGroupStatus(final Map<Long, List<TotalTargetCountActionStatus>> put) {
|
public void putRolloutGroupStatus(final Map<Long, List<TotalTargetCountActionStatus>> put) {
|
||||||
final Cache cache = cacheManager.getCache(CACHE_GR_NAME);
|
putIntoCache(put, getGroupStatusCache());
|
||||||
putIntoCache(put, cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -170,17 +162,17 @@ public class RolloutStatusCache {
|
|||||||
* list to cache
|
* list to cache
|
||||||
*/
|
*/
|
||||||
public void putRolloutGroupStatus(final Long groupId, final List<TotalTargetCountActionStatus> status) {
|
public void putRolloutGroupStatus(final Long groupId, final List<TotalTargetCountActionStatus> status) {
|
||||||
final Cache cache = cacheManager.getCache(CACHE_GR_NAME);
|
putIntoCache(groupId, status, getGroupStatusCache());
|
||||||
putIntoCache(groupId, status, cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Long, List<TotalTargetCountActionStatus>> retrieveFromCache(final List<Long> ids, final Cache cache) {
|
private Map<Long, List<TotalTargetCountActionStatus>> retrieveFromCache(final List<Long> ids,
|
||||||
|
@NotNull final Cache cache) {
|
||||||
return ids.stream().map(id -> cache.get(id, CachedTotalTargetCountActionStatus.class)).filter(Objects::nonNull)
|
return ids.stream().map(id -> cache.get(id, CachedTotalTargetCountActionStatus.class)).filter(Objects::nonNull)
|
||||||
.collect(Collectors.toMap(CachedTotalTargetCountActionStatus::getId,
|
.collect(Collectors.toMap(CachedTotalTargetCountActionStatus::getId,
|
||||||
CachedTotalTargetCountActionStatus::getStatus));
|
CachedTotalTargetCountActionStatus::getStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TotalTargetCountActionStatus> retrieveFromCache(final Long id, final Cache cache) {
|
private List<TotalTargetCountActionStatus> retrieveFromCache(final Long id, @NotNull final Cache cache) {
|
||||||
final CachedTotalTargetCountActionStatus cacheItem = cache.get(id, CachedTotalTargetCountActionStatus.class);
|
final CachedTotalTargetCountActionStatus cacheItem = cache.get(id, CachedTotalTargetCountActionStatus.class);
|
||||||
|
|
||||||
if (cacheItem == null) {
|
if (cacheItem == null) {
|
||||||
@@ -190,17 +182,17 @@ public class RolloutStatusCache {
|
|||||||
return cacheItem.getStatus();
|
return cacheItem.getStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putIntoCache(final Long id, final List<TotalTargetCountActionStatus> status, final Cache cache) {
|
private void putIntoCache(final Long id, final List<TotalTargetCountActionStatus> status,
|
||||||
|
@NotNull final Cache cache) {
|
||||||
cache.put(id, new CachedTotalTargetCountActionStatus(id, status));
|
cache.put(id, new CachedTotalTargetCountActionStatus(id, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putIntoCache(final Map<Long, List<TotalTargetCountActionStatus>> put, final Cache cache) {
|
private void putIntoCache(final Map<Long, List<TotalTargetCountActionStatus>> put, @NotNull final Cache cache) {
|
||||||
put.entrySet().forEach(entry -> cache.put(entry.getKey(),
|
put.forEach((k, v) -> cache.put(k, new CachedTotalTargetCountActionStatus(k, v)));
|
||||||
new CachedTotalTargetCountActionStatus(entry.getKey(), entry.getValue())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventListener(classes = AbstractActionEvent.class)
|
@EventListener(classes = AbstractActionEvent.class)
|
||||||
void invalidateCachedTotalTargetCountActionStatus(final AbstractActionEvent event) {
|
public void invalidateCachedTotalTargetCountActionStatus(final AbstractActionEvent event) {
|
||||||
if (event.getRolloutId() != null) {
|
if (event.getRolloutId() != null) {
|
||||||
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
|
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
|
||||||
cache.evict(event.getRolloutId());
|
cache.evict(event.getRolloutId());
|
||||||
@@ -213,19 +205,19 @@ public class RolloutStatusCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventListener(classes = RolloutDeletedEvent.class)
|
@EventListener(classes = RolloutDeletedEvent.class)
|
||||||
void invalidateCachedTotalTargetCountOnRolloutDelete(final RolloutDeletedEvent event) {
|
public void invalidateCachedTotalTargetCountOnRolloutDelete(final RolloutDeletedEvent event) {
|
||||||
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
|
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
|
||||||
cache.evict(event.getEntityId());
|
cache.evict(event.getEntityId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventListener(classes = RolloutGroupDeletedEvent.class)
|
@EventListener(classes = RolloutGroupDeletedEvent.class)
|
||||||
void invalidateCachedTotalTargetCountOnRolloutGroupDelete(final RolloutGroupDeletedEvent event) {
|
public void invalidateCachedTotalTargetCountOnRolloutGroupDelete(final RolloutGroupDeletedEvent event) {
|
||||||
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_GR_NAME));
|
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_GR_NAME));
|
||||||
cache.evict(event.getEntityId());
|
cache.evict(event.getEntityId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventListener(classes = RolloutStoppedEvent.class)
|
@EventListener(classes = RolloutStoppedEvent.class)
|
||||||
void invalidateCachedTotalTargetCountOnRolloutStopped(final RolloutStoppedEvent event) {
|
public void invalidateCachedTotalTargetCountOnRolloutStopped(final RolloutStoppedEvent event) {
|
||||||
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
|
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
|
||||||
cache.evict(event.getRolloutId());
|
cache.evict(event.getRolloutId());
|
||||||
|
|
||||||
@@ -247,6 +239,14 @@ public class RolloutStatusCache {
|
|||||||
cacheManager.evictCaches(tenant);
|
cacheManager.evictCaches(tenant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private @NotNull Cache getRolloutStatusCache() {
|
||||||
|
return Objects.requireNonNull(cacheManager.getCache(CACHE_RO_NAME), "Cache '" + CACHE_RO_NAME + "' is null!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NotNull Cache getGroupStatusCache() {
|
||||||
|
return Objects.requireNonNull(cacheManager.getCache(CACHE_GR_NAME), "Cache '" + CACHE_RO_NAME + "' is null!");
|
||||||
|
}
|
||||||
|
|
||||||
private static final class CachedTotalTargetCountActionStatus {
|
private static final class CachedTotalTargetCountActionStatus {
|
||||||
private final long id;
|
private final long id;
|
||||||
private final List<TotalTargetCountActionStatus> status;
|
private final List<TotalTargetCountActionStatus> status;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import javax.persistence.PersistenceException;
|
|||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
|
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
import org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect;
|
import org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect;
|
||||||
|
|
||||||
@@ -53,13 +54,12 @@ public class HawkBitEclipseLinkJpaDialect extends EclipseLinkJpaDialect {
|
|||||||
private static final SQLStateSQLExceptionTranslator SQLSTATE_EXCEPTION_TRANSLATOR = new SQLStateSQLExceptionTranslator();
|
private static final SQLStateSQLExceptionTranslator SQLSTATE_EXCEPTION_TRANSLATOR = new SQLStateSQLExceptionTranslator();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataAccessException translateExceptionIfPossible(final RuntimeException ex) {
|
public DataAccessException translateExceptionIfPossible(@NonNull final RuntimeException ex) {
|
||||||
final DataAccessException dataAccessException = super.translateExceptionIfPossible(ex);
|
final DataAccessException dataAccessException = super.translateExceptionIfPossible(ex);
|
||||||
|
|
||||||
if (dataAccessException == null) {
|
if (dataAccessException == null) {
|
||||||
return searchAndTranslateSqlException(ex);
|
return searchAndTranslateSqlException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return translateJpaSystemExceptionIfPossible(dataAccessException);
|
return translateJpaSystemExceptionIfPossible(dataAccessException);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,22 +69,19 @@ public class HawkBitEclipseLinkJpaDialect extends EclipseLinkJpaDialect {
|
|||||||
return accessException;
|
return accessException;
|
||||||
}
|
}
|
||||||
|
|
||||||
final DataAccessException sql = searchAndTranslateSqlException(accessException);
|
final DataAccessException sqlException = searchAndTranslateSqlException(accessException);
|
||||||
if (sql == null) {
|
if (sqlException == null) {
|
||||||
return accessException;
|
return accessException;
|
||||||
}
|
}
|
||||||
|
return sqlException;
|
||||||
return sql;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DataAccessException searchAndTranslateSqlException(final RuntimeException ex) {
|
private static DataAccessException searchAndTranslateSqlException(final RuntimeException ex) {
|
||||||
final SQLException sqlException = findSqlException(ex);
|
final SQLException sqlException = findSqlException(ex);
|
||||||
|
|
||||||
if (sqlException == null) {
|
if (sqlException == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return SQLSTATE_EXCEPTION_TRANSLATOR.translate("", null, sqlException);
|
||||||
return SQLSTATE_EXCEPTION_TRANSLATOR.translate(null, null, sqlException);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SQLException findSqlException(final RuntimeException jpaSystemException) {
|
private static SQLException findSqlException(final RuntimeException jpaSystemException) {
|
||||||
|
|||||||
@@ -767,7 +767,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
|||||||
final JpaAction action = actionRepository.findById(actionId)
|
final JpaAction action = actionRepository.findById(actionId)
|
||||||
.orElseThrow(() -> new EntityNotFoundException(Action.class, actionId));
|
.orElseThrow(() -> new EntityNotFoundException(Action.class, actionId));
|
||||||
|
|
||||||
if (!action.isForce()) {
|
if (!action.isForcedOrTimeForced()) {
|
||||||
action.setActionType(ActionType.FORCED);
|
action.setActionType(ActionType.FORCED);
|
||||||
return actionRepository.save(action);
|
return actionRepository.save(action);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
package org.eclipse.hawkbit.repository.jpa;
|
package org.eclipse.hawkbit.repository.jpa;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -25,7 +24,6 @@ import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
|
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData;
|
||||||
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
|
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||||
@@ -202,11 +200,11 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
// Create if it does not exist
|
// Create if it does not exist
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
try {
|
try {
|
||||||
currentTenantCacheKeyGenerator.getCreateInitialTenant().set(tenant);
|
currentTenantCacheKeyGenerator.setTenantInCreation(tenant);
|
||||||
return createInitialTenantMetaData(tenant);
|
return createInitialTenantMetaData(tenant);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
currentTenantCacheKeyGenerator.getCreateInitialTenant().remove();
|
currentTenantCacheKeyGenerator.removeTenantInCreation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -276,20 +274,17 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
if (tenantAware.getCurrentTenant() == null) {
|
if (tenantAware.getCurrentTenant() == null) {
|
||||||
throw new IllegalStateException("Tenant not set");
|
throw new IllegalStateException("Tenant not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
return getTenantMetadata(tenantAware.getCurrentTenant());
|
return getTenantMetadata(tenantAware.getCurrentTenant());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator", cacheManager = "directCacheManager", unless = "#result == null")
|
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator", cacheManager = "directCacheManager", unless = "#result == null")
|
||||||
public String currentTenant() {
|
public String currentTenant() {
|
||||||
final String initialTenantCreation = currentTenantCacheKeyGenerator.getCreateInitialTenant().get();
|
return currentTenantCacheKeyGenerator.getTenantInCreation().orElseGet(() -> {
|
||||||
if (initialTenantCreation == null) {
|
|
||||||
final TenantMetaData findByTenant = tenantMetaDataRepository
|
final TenantMetaData findByTenant = tenantMetaDataRepository
|
||||||
.findByTenantIgnoreCase(tenantAware.getCurrentTenant());
|
.findByTenantIgnoreCase(tenantAware.getCurrentTenant());
|
||||||
return findByTenant != null ? findByTenant.getTenant() : null;
|
return findByTenant != null ? findByTenant.getTenant() : null;
|
||||||
}
|
});
|
||||||
return initialTenantCreation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -312,7 +307,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
Integer.MAX_VALUE));
|
Integer.MAX_VALUE));
|
||||||
final SoftwareModuleType os = softwareModuleTypeRepository.save(new JpaSoftwareModuleType(
|
final SoftwareModuleType os = softwareModuleTypeRepository.save(new JpaSoftwareModuleType(
|
||||||
org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_OS_KEY,
|
org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_OS_KEY,
|
||||||
org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_OS_NAME, "Core firmware or operationg system", 1));
|
org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_OS_NAME, "Core firmware or operation system", 1));
|
||||||
|
|
||||||
// make sure the module types get their IDs
|
// make sure the module types get their IDs
|
||||||
entityManager.flush();
|
entityManager.flush();
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
package org.eclipse.hawkbit.repository.jpa;
|
package org.eclipse.hawkbit.repository.jpa;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -18,7 +22,6 @@ import org.springframework.context.annotation.Bean;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link CurrentTenantCacheKeyGenerator}.
|
* Implementation of {@link CurrentTenantCacheKeyGenerator}.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class SystemManagementCacheKeyGenerator implements CurrentTenantCacheKeyGenerator {
|
public class SystemManagementCacheKeyGenerator implements CurrentTenantCacheKeyGenerator {
|
||||||
|
|
||||||
@@ -28,25 +31,17 @@ public class SystemManagementCacheKeyGenerator implements CurrentTenantCacheKeyG
|
|||||||
private final ThreadLocal<String> createInitialTenant = new ThreadLocal<>();
|
private final ThreadLocal<String> createInitialTenant = new ThreadLocal<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A implementation of the {@link KeyGenerator} to generate a key based on
|
* An implementation of the {@link KeyGenerator} to generate a key based on
|
||||||
* either the {@code createInitialTenant} thread local and the
|
* either the {@code createInitialTenant} thread local and the
|
||||||
* {@link TenantAware}, but in case we are in a tenant creation with its
|
* {@link TenantAware}, but in case we are in a tenant creation with its default
|
||||||
* default types we need to use the tenant the current tenant which is
|
* types we need to use as the tenant the current tenant which is currently
|
||||||
* currently created and not the one currently in the {@link TenantAware}.
|
* created and not the one currently in the {@link TenantAware}.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class CurrentTenantKeyGenerator implements KeyGenerator {
|
public class CurrentTenantKeyGenerator implements KeyGenerator {
|
||||||
@Override
|
@Override
|
||||||
// Exception squid:S923 - override
|
|
||||||
@SuppressWarnings({ "squid:S923" })
|
|
||||||
public Object generate(final Object target, final Method method, final Object... params) {
|
public Object generate(final Object target, final Method method, final Object... params) {
|
||||||
final String initialTenantCreation = createInitialTenant.get();
|
String tenant = getTenantInCreation().orElseGet(() -> tenantAware.getCurrentTenant()).toUpperCase();
|
||||||
if (initialTenantCreation == null) {
|
return SimpleKeyGenerator.generateKey(tenant, tenant);
|
||||||
return SimpleKeyGenerator.generateKey(tenantAware.getCurrentTenant().toUpperCase(),
|
|
||||||
tenantAware.getCurrentTenant().toUpperCase());
|
|
||||||
}
|
|
||||||
return SimpleKeyGenerator.generateKey(initialTenantCreation.toUpperCase(),
|
|
||||||
initialTenantCreation.toUpperCase());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,8 +51,33 @@ public class SystemManagementCacheKeyGenerator implements CurrentTenantCacheKeyG
|
|||||||
return new CurrentTenantKeyGenerator();
|
return new CurrentTenantKeyGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadLocal<String> getCreateInitialTenant() {
|
/**
|
||||||
return createInitialTenant;
|
* Get the tenant which overwrites the actual tenant used by the
|
||||||
|
* {@linkplain #currentTenantKeyGenerator()}.
|
||||||
|
*
|
||||||
|
* @return A present optional in case that there is a tenant in the progress of
|
||||||
|
* creation.
|
||||||
|
*/
|
||||||
|
public Optional<String> getTenantInCreation() {
|
||||||
|
return Optional.ofNullable(createInitialTenant.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrite the tenant used by the key generator in case that the tenant is in
|
||||||
|
* the process of creation.
|
||||||
|
*
|
||||||
|
* @param tenant
|
||||||
|
* the tenant which should be used instead of the actual one.
|
||||||
|
*/
|
||||||
|
public void setTenantInCreation(@NotNull String tenant) {
|
||||||
|
createInitialTenant.set(Objects.requireNonNull(tenant));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the tenant overwriting the standard one used by the
|
||||||
|
* {@linkplain #currentTenantKeyGenerator()}.
|
||||||
|
*/
|
||||||
|
public void removeTenantInCreation() {
|
||||||
|
createInitialTenant.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.configuration;
|
package org.eclipse.hawkbit.repository.jpa.configuration;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
import javax.transaction.Transaction;
|
import javax.transaction.Transaction;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
@@ -37,8 +40,10 @@ public class MultiTenantJpaTransactionManager extends JpaTransactionManager {
|
|||||||
|
|
||||||
final String currentTenant = tenantAware.getCurrentTenant();
|
final String currentTenant = tenantAware.getCurrentTenant();
|
||||||
if (currentTenant != null) {
|
if (currentTenant != null) {
|
||||||
final EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager
|
final EntityManagerFactory emFactory = Objects.requireNonNull(getEntityManagerFactory());
|
||||||
.getResource(getEntityManagerFactory());
|
final EntityManagerHolder emHolder = Objects.requireNonNull(
|
||||||
|
(EntityManagerHolder) TransactionSynchronizationManager.getResource(emFactory),
|
||||||
|
"No EntityManagerHolder provided by TransactionSynchronizationManager");
|
||||||
final EntityManager em = emHolder.getEntityManager();
|
final EntityManager em = emHolder.getEntityManager();
|
||||||
em.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, currentTenant.toUpperCase());
|
em.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, currentTenant.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,34 +55,34 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
|||||||
/**
|
/**
|
||||||
* Default constructor needed for JPA entities.
|
* Default constructor needed for JPA entities.
|
||||||
*/
|
*/
|
||||||
public AbstractJpaBaseEntity() {
|
protected AbstractJpaBaseEntity() {
|
||||||
// Default constructor needed for JPA entities.
|
// Default constructor needed for JPA entities.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Access(AccessType.PROPERTY)
|
@Access(AccessType.PROPERTY)
|
||||||
@Column(name = "created_at", insertable = true, updatable = false, nullable = false)
|
@Column(name = "created_at", updatable = false, nullable = false)
|
||||||
public long getCreatedAt() {
|
public long getCreatedAt() {
|
||||||
return createdAt;
|
return createdAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Access(AccessType.PROPERTY)
|
@Access(AccessType.PROPERTY)
|
||||||
@Column(name = "created_by", insertable = true, updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH)
|
@Column(name = "created_by", updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH)
|
||||||
public String getCreatedBy() {
|
public String getCreatedBy() {
|
||||||
return createdBy;
|
return createdBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Access(AccessType.PROPERTY)
|
@Access(AccessType.PROPERTY)
|
||||||
@Column(name = "last_modified_at", insertable = true, updatable = true, nullable = false)
|
@Column(name = "last_modified_at", nullable = false)
|
||||||
public long getLastModifiedAt() {
|
public long getLastModifiedAt() {
|
||||||
return lastModifiedAt;
|
return lastModifiedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Access(AccessType.PROPERTY)
|
@Access(AccessType.PROPERTY)
|
||||||
@Column(name = "last_modified_by", insertable = true, updatable = true, nullable = false, length = USERNAME_FIELD_LENGTH)
|
@Column(name = "last_modified_by", nullable = false, length = USERNAME_FIELD_LENGTH)
|
||||||
public String getLastModifiedBy() {
|
public String getLastModifiedBy() {
|
||||||
return lastModifiedBy;
|
return lastModifiedBy;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.model;
|
package org.eclipse.hawkbit.repository.jpa.model;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import javax.persistence.Basic;
|
import javax.persistence.Basic;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
@@ -36,12 +38,12 @@ public abstract class AbstractJpaMetaData implements MetaData {
|
|||||||
@Basic
|
@Basic
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
public AbstractJpaMetaData(final String key, final String value) {
|
protected AbstractJpaMetaData(final String key, final String value) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractJpaMetaData() {
|
protected AbstractJpaMetaData() {
|
||||||
// Default constructor needed for JPA entities
|
// Default constructor needed for JPA entities
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,41 +66,17 @@ public abstract class AbstractJpaMetaData implements MetaData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public boolean equals(final Object o) {
|
||||||
final int prime = 31;
|
if (this == o)
|
||||||
int result = 1;
|
return true;
|
||||||
result = prime * result + ((key == null) ? 0 : key.hashCode());
|
if (o == null || getClass() != o.getClass())
|
||||||
result = prime * result + ((value == null) ? 0 : value.hashCode());
|
return false;
|
||||||
return result;
|
final AbstractJpaMetaData that = (AbstractJpaMetaData) o;
|
||||||
|
return Objects.equals(key, that.key) && Objects.equals(value, that.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public int hashCode() {
|
||||||
if (this == obj) {
|
return Objects.hash(key, value);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(this.getClass().isInstance(obj))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final AbstractJpaMetaData other = (AbstractJpaMetaData) obj;
|
|
||||||
if (key == null) {
|
|
||||||
if (other.key != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!key.equals(other.key)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (value == null) {
|
|
||||||
if (other.value != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!value.equals(other.value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ public abstract class AbstractJpaNamedEntity extends AbstractJpaTenantAwareBaseE
|
|||||||
@NotNull
|
@NotNull
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Column(name = "description", nullable = true, length = NamedEntity.DESCRIPTION_MAX_SIZE)
|
@Column(name = "description", length = NamedEntity.DESCRIPTION_MAX_SIZE)
|
||||||
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
|
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
*/
|
*/
|
||||||
public AbstractJpaNamedEntity() {
|
protected AbstractJpaNamedEntity() {
|
||||||
// Default constructor needed for JPA entities
|
// Default constructor needed for JPA entities
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn
|
|||||||
/**
|
/**
|
||||||
* Default constructor needed for JPA entities.
|
* Default constructor needed for JPA entities.
|
||||||
*/
|
*/
|
||||||
public AbstractJpaTenantAwareBaseEntity() {
|
protected AbstractJpaTenantAwareBaseEntity() {
|
||||||
// Default constructor needed for JPA entities.
|
// Default constructor needed for JPA entities.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -299,22 +299,10 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeModule(final SoftwareModule softwareModule) {
|
public void removeModule(final SoftwareModule softwareModule) {
|
||||||
if (modules == null) {
|
if (modules != null && modules.removeIf(m -> m.getId().equals(softwareModule.getId()))) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Optional<SoftwareModule> found = modules.stream()
|
|
||||||
.filter(module -> module.getId().equals(softwareModule.getId())).findAny();
|
|
||||||
|
|
||||||
if (found.isPresent()) {
|
|
||||||
modules.remove(found.get());
|
|
||||||
complete = type.checkComplete(this);
|
complete = type.checkComplete(this);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -371,11 +359,11 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
|
|||||||
private static boolean isSoftDeleted(final DescriptorEvent event) {
|
private static boolean isSoftDeleted(final DescriptorEvent event) {
|
||||||
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
|
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
|
||||||
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
|
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
|
||||||
.filter(record -> record instanceof DirectToFieldChangeRecord)
|
.filter(DirectToFieldChangeRecord.class::isInstance).map(DirectToFieldChangeRecord.class::cast)
|
||||||
.map(record -> (DirectToFieldChangeRecord) record).collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return changes.stream().filter(record -> DELETED_PROPERTY.equals(record.getAttribute())
|
return changes.stream().anyMatch(changeRecord -> DELETED_PROPERTY.equals(changeRecord.getAttribute())
|
||||||
&& Boolean.parseBoolean(record.getNewValue().toString())).count() > 0;
|
&& Boolean.parseBoolean(changeRecord.getNewValue().toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -278,11 +278,11 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
|
|||||||
private static boolean isSoftDeleted(final DescriptorEvent event) {
|
private static boolean isSoftDeleted(final DescriptorEvent event) {
|
||||||
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
|
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
|
||||||
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
|
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
|
||||||
.filter(record -> record instanceof DirectToFieldChangeRecord)
|
.filter(DirectToFieldChangeRecord.class::isInstance).map(DirectToFieldChangeRecord.class::cast)
|
||||||
.map(record -> (DirectToFieldChangeRecord) record).collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return changes.stream().filter(record -> DELETED_PROPERTY.equals(record.getAttribute())
|
return changes.stream().anyMatch(changeRecord -> DELETED_PROPERTY.equals(changeRecord.getAttribute())
|
||||||
&& Boolean.parseBoolean(record.getNewValue().toString())).count() > 0;
|
&& Boolean.parseBoolean(changeRecord.getNewValue().toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -258,11 +258,11 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
|
|||||||
private static boolean isSoftDeleted(final DescriptorEvent event) {
|
private static boolean isSoftDeleted(final DescriptorEvent event) {
|
||||||
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
|
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
|
||||||
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
|
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
|
||||||
.filter(record -> record instanceof DirectToFieldChangeRecord)
|
.filter(DirectToFieldChangeRecord.class::isInstance).map(DirectToFieldChangeRecord.class::cast)
|
||||||
.map(record -> (DirectToFieldChangeRecord) record).collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return changes.stream().filter(record -> DELETED_PROPERTY.equals(record.getAttribute())
|
return changes.stream().anyMatch(changeRecord -> DELETED_PROPERTY.equals(changeRecord.getAttribute())
|
||||||
&& Boolean.parseBoolean(record.getNewValue().toString())).count() > 0;
|
&& Boolean.parseBoolean(changeRecord.getNewValue().toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
|
|||||||
@Column(name = "controller_id", length = Target.CONTROLLER_ID_MAX_SIZE, updatable = false, nullable = false)
|
@Column(name = "controller_id", length = Target.CONTROLLER_ID_MAX_SIZE, updatable = false, nullable = false)
|
||||||
@Size(min = 1, max = Target.CONTROLLER_ID_MAX_SIZE)
|
@Size(min = 1, max = Target.CONTROLLER_ID_MAX_SIZE)
|
||||||
@NotNull
|
@NotNull
|
||||||
@Pattern(regexp = "[.\\S]*", message = "has whitespaces which are not allowed")
|
@Pattern(regexp = "[\\S]*", message = "has whitespaces which are not allowed")
|
||||||
private String controllerId;
|
private String controllerId;
|
||||||
|
|
||||||
@CascadeOnDelete
|
@CascadeOnDelete
|
||||||
@@ -243,34 +243,28 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
|
|||||||
if (rolloutTargetGroup == null) {
|
if (rolloutTargetGroup == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Collections.unmodifiableList(rolloutTargetGroup);
|
return Collections.unmodifiableList(rolloutTargetGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tag
|
* @param tag
|
||||||
* tag
|
* to be added
|
||||||
* @return boolean true or false
|
|
||||||
*/
|
*/
|
||||||
public boolean addTag(final TargetTag tag) {
|
public void addTag(final TargetTag tag) {
|
||||||
if (tags == null) {
|
if (tags == null) {
|
||||||
tags = new HashSet<>();
|
tags = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
tags.add(tag);
|
||||||
return tags.add(tag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tag
|
* @param tag
|
||||||
* tag
|
* the tag to be removed from the target
|
||||||
* @return boolean true or false
|
|
||||||
*/
|
*/
|
||||||
public boolean removeTag(final TargetTag tag) {
|
public void removeTag(final TargetTag tag) {
|
||||||
if (tags == null) {
|
if (tags != null) {
|
||||||
return false;
|
tags.remove(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tags.remove(tag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -303,14 +297,12 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
|
|||||||
/**
|
/**
|
||||||
* @param action
|
* @param action
|
||||||
* Action
|
* Action
|
||||||
* @return boolean true or false
|
|
||||||
*/
|
*/
|
||||||
public boolean addAction(final Action action) {
|
public void addAction(final Action action) {
|
||||||
if (actions == null) {
|
if (actions == null) {
|
||||||
actions = new ArrayList<>();
|
actions = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
actions.add((JpaAction) action);
|
||||||
return actions.add((JpaAction) action);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -25,7 +27,7 @@ public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldName
|
|||||||
|
|
||||||
private final Class<A> fieldNameProvider;
|
private final Class<A> fieldNameProvider;
|
||||||
|
|
||||||
public AbstractFieldNameRSQLVisitor(final Class<A> fieldNameProvider) {
|
protected AbstractFieldNameRSQLVisitor(final Class<A> fieldNameProvider) {
|
||||||
this.fieldNameProvider = fieldNameProvider;
|
this.fieldNameProvider = fieldNameProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +53,7 @@ public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldName
|
|||||||
|
|
||||||
// sub entity need minimum 1 dot
|
// sub entity need minimum 1 dot
|
||||||
if (!propertyEnum.getSubEntityAttributes().isEmpty() && graph.length < 2) {
|
if (!propertyEnum.getSubEntityAttributes().isEmpty() && graph.length < 2) {
|
||||||
throw createRSQLParameterUnsupportedException(node);
|
throw createRSQLParameterUnsupportedException(node, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
final StringBuilder fieldNameBuilder = new StringBuilder(propertyEnum.getFieldName());
|
final StringBuilder fieldNameBuilder = new StringBuilder(propertyEnum.getFieldName());
|
||||||
@@ -67,7 +69,7 @@ public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldName
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!propertyEnum.containsSubEntityAttribute(propertyField)) {
|
if (!propertyEnum.containsSubEntityAttribute(propertyField)) {
|
||||||
throw createRSQLParameterUnsupportedException(node);
|
throw createRSQLParameterUnsupportedException(node, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,30 +95,21 @@ public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldName
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param node
|
||||||
|
* current processing node
|
||||||
|
* @param rootException
|
||||||
|
* in case there is a cause otherwise {@code null}
|
||||||
|
* @return Exception with prepared message extracted from the comparison node.
|
||||||
|
*/
|
||||||
protected RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException(
|
protected RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException(
|
||||||
final ComparisonNode node) {
|
@NotNull final ComparisonNode node,
|
||||||
return createRSQLParameterUnsupportedException(node, new Exception());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException(final ComparisonNode node,
|
|
||||||
final Exception rootException) {
|
final Exception rootException) {
|
||||||
return createRSQLParameterUnsupportedException(String.format(
|
return new RSQLParameterUnsupportedFieldException(String.format(
|
||||||
"The given search parameter field {%s} does not exist, must be one of the following fields %s",
|
"The given search parameter field {%s} does not exist, must be one of the following fields %s",
|
||||||
node.getSelector(), getExpectedFieldList()), rootException);
|
node.getSelector(), getExpectedFieldList()), rootException);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException(final String message) {
|
|
||||||
return createRSQLParameterUnsupportedException(message, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException(final String message,
|
|
||||||
final Exception rootException) {
|
|
||||||
return new RSQLParameterUnsupportedFieldException(message, rootException);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exception squid:S2095 - see
|
|
||||||
// https://jira.sonarsource.com/browse/SONARJAVA-1478
|
|
||||||
@SuppressWarnings({ "squid:S2095" })
|
|
||||||
private List<String> getExpectedFieldList() {
|
private List<String> getExpectedFieldList() {
|
||||||
final List<String> expectedFieldList = Arrays.stream(fieldNameProvider.getEnumConstants())
|
final List<String> expectedFieldList = Arrays.stream(fieldNameProvider.getEnumConstants())
|
||||||
.filter(enumField -> enumField.getSubEntityAttributes().isEmpty()).map(enumField -> {
|
.filter(enumField -> enumField.getSubEntityAttributes().isEmpty()).map(enumField -> {
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ public class JpaQueryRsqlVisitor<A extends Enum<A> & FieldNameProvider, T> exten
|
|||||||
private Path<Object> getFieldPath(final A enumField, final String finalProperty) {
|
private Path<Object> getFieldPath(final A enumField, final String finalProperty) {
|
||||||
return (Path<Object>) getFieldPath(root, enumField.getSubAttributes(finalProperty), enumField.isMap(),
|
return (Path<Object>) getFieldPath(root, enumField.getSubAttributes(finalProperty), enumField.isMap(),
|
||||||
this::getJoinFieldPath).orElseThrow(
|
this::getJoinFieldPath).orElseThrow(
|
||||||
() -> createRSQLParameterUnsupportedException("RSQL field path cannot be empty", null));
|
() -> new RSQLParameterUnsupportedFieldException("RSQL field path cannot be empty", null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -279,7 +279,7 @@ public class JpaQueryRsqlVisitor<A extends Enum<A> & FieldNameProvider, T> exten
|
|||||||
private Object convertFieldConverterValue(final ComparisonNode node, final A fieldName, final String value) {
|
private Object convertFieldConverterValue(final ComparisonNode node, final A fieldName, final String value) {
|
||||||
final Object convertedValue = ((FieldValueConverter) fieldName).convertValue(fieldName, value);
|
final Object convertedValue = ((FieldValueConverter) fieldName).convertValue(fieldName, value);
|
||||||
if (convertedValue == null) {
|
if (convertedValue == null) {
|
||||||
throw createRSQLParameterUnsupportedException(
|
throw new RSQLParameterUnsupportedFieldException(
|
||||||
"field {" + node.getSelector() + "} must be one of the following values {"
|
"field {" + node.getSelector() + "} must be one of the following values {"
|
||||||
+ Arrays.toString(((FieldValueConverter) fieldName).possibleValues(fieldName)) + "}",
|
+ Arrays.toString(((FieldValueConverter) fieldName).possibleValues(fieldName)) + "}",
|
||||||
null);
|
null);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ package org.eclipse.hawkbit.repository.jpa.rsql;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
import cz.jirutka.rsql.parser.ParseException;
|
import cz.jirutka.rsql.parser.ParseException;
|
||||||
|
|
||||||
@@ -24,13 +24,7 @@ import cz.jirutka.rsql.parser.ParseException;
|
|||||||
*/
|
*/
|
||||||
public class ParseExceptionWrapper {
|
public class ParseExceptionWrapper {
|
||||||
|
|
||||||
private static final String FIELD_EXPECTED_TOKEN_SEQ = "expectedTokenSequences";
|
|
||||||
private static final String FIELD_CURRENT_TOKEN = "currentToken";
|
|
||||||
|
|
||||||
private final ParseException parseException;
|
private final ParseException parseException;
|
||||||
private final Class<? extends ParseException> parseExceptionClass;
|
|
||||||
private Field expectedTokenSequenceField;
|
|
||||||
private Field currentTokenField;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@@ -41,33 +35,24 @@ public class ParseExceptionWrapper {
|
|||||||
*/
|
*/
|
||||||
public ParseExceptionWrapper(final ParseException parseException) {
|
public ParseExceptionWrapper(final ParseException parseException) {
|
||||||
this.parseException = parseException;
|
this.parseException = parseException;
|
||||||
parseExceptionClass = parseException.getClass();
|
|
||||||
|
|
||||||
try {
|
|
||||||
expectedTokenSequenceField = getAccessibleField(parseExceptionClass, FIELD_EXPECTED_TOKEN_SEQ);
|
|
||||||
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
|
||||||
expectedTokenSequenceField = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
currentTokenField = getAccessibleField(parseExceptionClass, FIELD_CURRENT_TOKEN);
|
|
||||||
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
|
||||||
currentTokenField = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[][] getExpectedTokenSequence() {
|
public int[][] getExpectedTokenSequence() {
|
||||||
if (expectedTokenSequenceField == null) {
|
return (parseException.expectedTokenSequences != null) // unclear if this can happen
|
||||||
return new int[0][0];
|
? parseException.expectedTokenSequences
|
||||||
}
|
: new int[0][0];
|
||||||
return (int[][]) getValue(expectedTokenSequenceField, parseException);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current token
|
||||||
|
*
|
||||||
|
* @return the current token or {@code null} if there is non.
|
||||||
|
*/
|
||||||
public TokenWrapper getCurrentToken() {
|
public TokenWrapper getCurrentToken() {
|
||||||
if (currentTokenField == null) {
|
return (parseException.currentToken != null) // unclear if this can happen
|
||||||
return null;
|
? new TokenWrapper(parseException.currentToken)
|
||||||
}
|
: null;
|
||||||
return new TokenWrapper(getValue(currentTokenField, parseException));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -76,19 +61,6 @@ public class ParseExceptionWrapper {
|
|||||||
+ ", getCurrentToken()=" + getCurrentToken() + "]";
|
+ ", getCurrentToken()=" + getCurrentToken() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Field getAccessibleField(final Class<?> clazz, final String field) throws NoSuchFieldException {
|
|
||||||
final Field declaredField = clazz.getDeclaredField(field);
|
|
||||||
declaredField.setAccessible(true);
|
|
||||||
return declaredField;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object getValue(final Field field, final Object instance) {
|
|
||||||
try {
|
|
||||||
return field.get(instance);
|
|
||||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
|
||||||
throw Throwables.propagate(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link TokenWrapper} which wraps the
|
* A {@link TokenWrapper} which wraps the
|
||||||
@@ -115,37 +87,37 @@ public class ParseExceptionWrapper {
|
|||||||
this.tokenInstance = tokenField;
|
this.tokenInstance = tokenField;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
nextTokenField = getAccessibleField(tokenField.getClass(), FIELD_NEXT);
|
nextTokenField = getAccessibleField(FIELD_NEXT);
|
||||||
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
||||||
nextTokenField = null;
|
nextTokenField = null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
kindTokenField = getAccessibleField(tokenField.getClass(), FIELD_KIND);
|
kindTokenField = getAccessibleField(FIELD_KIND);
|
||||||
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
||||||
kindTokenField = null;
|
kindTokenField = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
imageTokenField = getAccessibleField(tokenField.getClass(), FIELD_IMAGE);
|
imageTokenField = getAccessibleField(FIELD_IMAGE);
|
||||||
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
||||||
imageTokenField = null;
|
imageTokenField = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
beginColumnTokenField = getAccessibleField(tokenField.getClass(), FIELD_BEGIN_COL);
|
beginColumnTokenField = getAccessibleField(FIELD_BEGIN_COL);
|
||||||
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
||||||
beginColumnTokenField = null;
|
beginColumnTokenField = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
endColumnTokenField = getAccessibleField(tokenField.getClass(), FIELD_END_COL);
|
endColumnTokenField = getAccessibleField(FIELD_END_COL);
|
||||||
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
|
||||||
endColumnTokenField = null;
|
endColumnTokenField = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TokenWrapper getNext() {
|
public TokenWrapper getNext() {
|
||||||
final Object nextToken = getValue(nextTokenField, tokenInstance);
|
final Object nextToken = getValue(nextTokenField);
|
||||||
return nextToken != null ? new TokenWrapper(nextToken) : null;
|
return nextToken != null ? new TokenWrapper(nextToken) : null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -154,28 +126,42 @@ public class ParseExceptionWrapper {
|
|||||||
if (kindTokenField == null) {
|
if (kindTokenField == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return (int) getValue(kindTokenField, tokenInstance);
|
return (int) getValue(kindTokenField);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getImage() {
|
public String getImage() {
|
||||||
if (imageTokenField == null) {
|
if (imageTokenField == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (String) getValue(imageTokenField, tokenInstance);
|
return (String) getValue(imageTokenField);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBeginColumn() {
|
public int getBeginColumn() {
|
||||||
if (beginColumnTokenField == null) {
|
if (beginColumnTokenField == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return (int) getValue(beginColumnTokenField, tokenInstance);
|
return (int) getValue(beginColumnTokenField);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getEndColumn() {
|
public int getEndColumn() {
|
||||||
if (endColumnTokenField == null) {
|
if (endColumnTokenField == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return (int) getValue(endColumnTokenField, tokenInstance);
|
return (int) getValue(endColumnTokenField);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Field getAccessibleField(final String field) throws NoSuchFieldException {
|
||||||
|
final Field declaredField = tokenInstance.getClass().getDeclaredField(field);
|
||||||
|
ReflectionUtils.makeAccessible(declaredField);
|
||||||
|
return declaredField;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getValue(final Field field) {
|
||||||
|
try {
|
||||||
|
return field.get(tokenInstance);
|
||||||
|
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||||
|
throw new IllegalFieldAccessExeption(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -185,4 +171,11 @@ public class ParseExceptionWrapper {
|
|||||||
+ ", getEndColumn()=" + getEndColumn() + "]";
|
+ ", getEndColumn()=" + getEndColumn() + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class IllegalFieldAccessExeption extends RuntimeException {
|
||||||
|
public IllegalFieldAccessExeption(Throwable e) {
|
||||||
|
super(e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
|
|||||||
private static List<SuggestToken> getNextTokens(final ParseException parseException) {
|
private static List<SuggestToken> getNextTokens(final ParseException parseException) {
|
||||||
final List<SuggestToken> listTokens = new ArrayList<>();
|
final List<SuggestToken> listTokens = new ArrayList<>();
|
||||||
final ParseExceptionWrapper parseExceptionWrapper = new ParseExceptionWrapper(parseException);
|
final ParseExceptionWrapper parseExceptionWrapper = new ParseExceptionWrapper(parseException);
|
||||||
final int[][] expectedTokenSequence = parseExceptionWrapper.getExpectedTokenSequence();
|
final int[][] expectedTokenSequence = parseException.expectedTokenSequences;
|
||||||
final TokenWrapper currentToken = parseExceptionWrapper.getCurrentToken();
|
final TokenWrapper currentToken = parseExceptionWrapper.getCurrentToken();
|
||||||
if (currentToken == null) {
|
if (currentToken == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@@ -243,8 +243,8 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
|
|||||||
}
|
}
|
||||||
builder = builder.replace('\r', ' ');
|
builder = builder.replace('\r', ' ');
|
||||||
builder = builder.replace('\n', ' ');
|
builder = builder.replace('\n', ' ');
|
||||||
builder = builder.replaceAll(">", " ");
|
builder = builder.replace(">", " ");
|
||||||
builder = builder.replaceAll("<", " ");
|
builder = builder.replace("<", " ");
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ package org.eclipse.hawkbit.repository.jpa;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.awaitility.Awaitility;
|
||||||
|
import org.awaitility.Duration;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -24,7 +26,7 @@ public class ActionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that timeforced moded switch from soft to forces after defined timeframe.")
|
@Description("Ensures that timeforced moded switch from soft to forces after defined timeframe.")
|
||||||
public void timeforcedHitNewHasCodeIsGenerated() throws InterruptedException {
|
public void timeforcedHitNewHasCodeIsGenerated() {
|
||||||
|
|
||||||
// current time + 1 seconds
|
// current time + 1 seconds
|
||||||
final long sleepTime = 1000;
|
final long sleepTime = 1000;
|
||||||
@@ -32,10 +34,10 @@ public class ActionTest {
|
|||||||
final JpaAction timeforcedAction = new JpaAction();
|
final JpaAction timeforcedAction = new JpaAction();
|
||||||
timeforcedAction.setActionType(ActionType.TIMEFORCED);
|
timeforcedAction.setActionType(ActionType.TIMEFORCED);
|
||||||
timeforcedAction.setForcedTime(timeForceTimeAt);
|
timeforcedAction.setForcedTime(timeForceTimeAt);
|
||||||
assertThat(timeforcedAction.isForce()).isFalse();
|
assertThat(timeforcedAction.isForcedOrTimeForced()).isFalse();
|
||||||
|
|
||||||
// wait until timeforce time is hit
|
// wait until timeforce time is hit
|
||||||
Thread.sleep(sleepTime + 100);
|
Awaitility.await().atMost(Duration.TWO_SECONDS).pollInterval(Duration.ONE_HUNDRED_MILLISECONDS)
|
||||||
assertThat(timeforcedAction.isForce()).isTrue();
|
.until(timeforcedAction::isForcedOrTimeForced);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,11 +50,11 @@ import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedE
|
|||||||
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleUpdatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleUpdatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
||||||
|
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
||||||
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
import org.eclipse.hawkbit.repository.exception.InvalidTargetAttributeException;
|
import org.eclipse.hawkbit.repository.exception.InvalidTargetAttributeException;
|
||||||
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||||
@@ -69,6 +69,7 @@ import org.eclipse.hawkbit.repository.model.Target;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||||
|
import org.eclipse.hawkbit.repository.test.util.TargetTestData;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
@@ -85,7 +86,7 @@ import io.qameta.allure.Story;
|
|||||||
|
|
||||||
@Feature("Component Tests - Repository")
|
@Feature("Component Tests - Repository")
|
||||||
@Story("Controller Management")
|
@Story("Controller Management")
|
||||||
public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RepositoryProperties repositoryProperties;
|
private RepositoryProperties repositoryProperties;
|
||||||
@@ -95,7 +96,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
+ "of Optional not present.")
|
+ "of Optional not present.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
|
||||||
public void nonExistingEntityAccessReturnsNotPresent() {
|
void nonExistingEntityAccessReturnsNotPresent() {
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
final SoftwareModule module = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule module = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
@@ -116,7 +117,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
+ " by means of throwing EntityNotFoundException.")
|
+ " by means of throwing EntityNotFoundException.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
|
||||||
public void entityQueriesReferringToNotExistingEntitiesThrowsException() throws URISyntaxException {
|
void entityQueriesReferringToNotExistingEntitiesThrowsException() throws URISyntaxException {
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
final SoftwareModule module = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule module = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
@@ -157,7 +158,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerConfirmsUpdateWithFinished() {
|
void controllerConfirmsUpdateWithFinished() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
simulateIntermediateStatusOnUpdate(actionId);
|
simulateIntermediateStatusOnUpdate(actionId);
|
||||||
@@ -178,7 +179,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerConfirmationFailsWithInvalidMessages() {
|
void controllerConfirmationFailsWithInvalidMessages() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
simulateIntermediateStatusOnUpdate(actionId);
|
simulateIntermediateStatusOnUpdate(actionId);
|
||||||
@@ -209,7 +210,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerConfirmsUpdateWithFinishedAndIgnoresCancellationWithThat() {
|
void controllerConfirmsUpdateWithFinishedAndIgnoresCancellationWithThat() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
deploymentManagement.cancelAction(actionId);
|
deploymentManagement.cancelAction(actionId);
|
||||||
|
|
||||||
@@ -229,7 +230,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void cancellationFeedbackRejectedIfActionIsNotInCanceling() {
|
void cancellationFeedbackRejectedIfActionIsNotInCanceling() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
assertThatExceptionOfType(CancelActionNotAllowedException.class)
|
assertThatExceptionOfType(CancelActionNotAllowedException.class)
|
||||||
@@ -253,7 +254,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerConfirmsActionCancellationWithFinished() {
|
void controllerConfirmsActionCancellationWithFinished() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
deploymentManagement.cancelAction(actionId);
|
deploymentManagement.cancelAction(actionId);
|
||||||
@@ -280,7 +281,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerConfirmsActionCancellationWithCanceled() {
|
void controllerConfirmsActionCancellationWithCanceled() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
deploymentManagement.cancelAction(actionId);
|
deploymentManagement.cancelAction(actionId);
|
||||||
@@ -308,7 +309,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerRejectsActionCancellationWithReject() {
|
void controllerRejectsActionCancellationWithReject() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
deploymentManagement.cancelAction(actionId);
|
deploymentManagement.cancelAction(actionId);
|
||||||
@@ -336,7 +337,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerRejectsActionCancellationWithError() {
|
void controllerRejectsActionCancellationWithError() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
deploymentManagement.cancelAction(actionId);
|
deploymentManagement.cancelAction(actionId);
|
||||||
@@ -472,7 +473,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
|
||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 2) })
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 2) })
|
||||||
public void hasTargetArtifactAssignedIsTrueWithMultipleArtifacts() {
|
void hasTargetArtifactAssignedIsTrueWithMultipleArtifacts() {
|
||||||
final int artifactSize = 5 * 1024;
|
final int artifactSize = 5 * 1024;
|
||||||
final byte[] random = RandomUtils.nextBytes(artifactSize);
|
final byte[] random = RandomUtils.nextBytes(artifactSize);
|
||||||
|
|
||||||
@@ -503,7 +504,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Register a controller which does not exist")
|
@Description("Register a controller which does not exist")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 2) })
|
@Expect(type = TargetPollEvent.class, count = 2) })
|
||||||
public void findOrRegisterTargetIfItDoesNotExist() {
|
void findOrRegisterTargetIfItDoesNotExist() {
|
||||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
||||||
assertThat(target).as("target should not be null").isNotNull();
|
assertThat(target).as("target should not be null").isNotNull();
|
||||||
|
|
||||||
@@ -516,7 +517,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Register a controller with name which does not exist and update its name")
|
@Description("Register a controller with name which does not exist and update its name")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 1) })
|
@Expect(type = TargetPollEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 1) })
|
||||||
public void findOrRegisterTargetIfItDoesNotExistWithName() {
|
void findOrRegisterTargetIfItDoesNotExistWithName() {
|
||||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST, "TestName");
|
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST, "TestName");
|
||||||
final Target sameTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST,
|
final Target sameTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST,
|
||||||
"ChangedTestName");
|
"ChangedTestName");
|
||||||
@@ -528,7 +529,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tries to register a target with an invalid controller id")
|
@Description("Tries to register a target with an invalid controller id")
|
||||||
public void findOrRegisterTargetIfItDoesNotExistThrowsExceptionForInvalidControllerIdParam() {
|
void findOrRegisterTargetIfItDoesNotExistThrowsExceptionForInvalidControllerIdParam() {
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.as("register target with null as controllerId should fail")
|
.as("register target with null as controllerId should fail")
|
||||||
.isThrownBy(() -> controllerManagement.findOrRegisterTargetIfItDoesNotExist(null, LOCALHOST));
|
.isThrownBy(() -> controllerManagement.findOrRegisterTargetIfItDoesNotExist(null, LOCALHOST));
|
||||||
@@ -550,7 +551,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Register a controller which does not exist, when a ConcurrencyFailureException is raised, the "
|
@Description("Register a controller which does not exist, when a ConcurrencyFailureException is raised, the "
|
||||||
+ "exception is rethrown after max retries")
|
+ "exception is rethrown after max retries")
|
||||||
public void findOrRegisterTargetIfItDoesNotExistThrowsExceptionAfterMaxRetries() {
|
void findOrRegisterTargetIfItDoesNotExistThrowsExceptionAfterMaxRetries() {
|
||||||
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
|
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
|
||||||
when(mockTargetRepository.findOne(any())).thenThrow(ConcurrencyFailureException.class);
|
when(mockTargetRepository.findOne(any())).thenThrow(ConcurrencyFailureException.class);
|
||||||
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
|
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
|
||||||
@@ -572,7 +573,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
+ "exception is not rethrown when the max retries are not yet reached")
|
+ "exception is not rethrown when the max retries are not yet reached")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void findOrRegisterTargetIfItDoesNotExistDoesNotThrowExceptionBeforeMaxRetries() {
|
void findOrRegisterTargetIfItDoesNotExistDoesNotThrowExceptionBeforeMaxRetries() {
|
||||||
|
|
||||||
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
|
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
|
||||||
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
|
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
|
||||||
@@ -598,7 +599,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Register a controller which does not exist, then update the controller twice, first time by providing a name property and second time without a new name")
|
@Description("Register a controller which does not exist, then update the controller twice, first time by providing a name property and second time without a new name")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 3), @Expect(type = TargetUpdatedEvent.class, count = 1) })
|
@Expect(type = TargetPollEvent.class, count = 3), @Expect(type = TargetUpdatedEvent.class, count = 1) })
|
||||||
public void findOrRegisterTargetIfItDoesNotExistDoesUpdateNameOnExistingTargetProperly() {
|
void findOrRegisterTargetIfItDoesNotExistDoesUpdateNameOnExistingTargetProperly() {
|
||||||
|
|
||||||
final String controllerId = "12345";
|
final String controllerId = "12345";
|
||||||
final String targetName = "UpdatedName";
|
final String targetName = "UpdatedName";
|
||||||
@@ -620,7 +621,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Register a controller which does not exist, if a EntityAlreadyExistsException is raised, the "
|
@Description("Register a controller which does not exist, if a EntityAlreadyExistsException is raised, the "
|
||||||
+ "exception is rethrown and no further retries will be attempted")
|
+ "exception is rethrown and no further retries will be attempted")
|
||||||
public void findOrRegisterTargetIfItDoesNotExistDoesntRetryWhenEntityAlreadyExistsException() {
|
void findOrRegisterTargetIfItDoesNotExistDoesntRetryWhenEntityAlreadyExistsException() {
|
||||||
|
|
||||||
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
|
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
|
||||||
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
|
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
|
||||||
@@ -643,7 +644,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Retry is aborted when an unchecked exception is thrown and the exception should also be "
|
@Description("Retry is aborted when an unchecked exception is thrown and the exception should also be "
|
||||||
+ "rethrown")
|
+ "rethrown")
|
||||||
public void recoverFindOrRegisterTargetIfItDoesNotExistIsNotInvokedForOtherExceptions() {
|
void recoverFindOrRegisterTargetIfItDoesNotExistIsNotInvokedForOtherExceptions() {
|
||||||
|
|
||||||
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
|
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
|
||||||
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
|
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
|
||||||
@@ -666,7 +667,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6) })
|
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6) })
|
||||||
public void findTargetVisibleMetaDataBySoftwareModuleId() {
|
void findTargetVisibleMetaDataBySoftwareModuleId() {
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet();
|
final DistributionSet set = testdataFactory.createDistributionSet();
|
||||||
testdataFactory.addSoftwareModuleMetadata(set);
|
testdataFactory.addSoftwareModuleMetadata(set);
|
||||||
|
|
||||||
@@ -682,7 +683,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Verify that controller registration does not result in a TargetPollEvent if feature is disabled")
|
@Description("Verify that controller registration does not result in a TargetPollEvent if feature is disabled")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 0) })
|
@Expect(type = TargetPollEvent.class, count = 0) })
|
||||||
public void targetPollEventNotSendIfDisabled() {
|
void targetPollEventNotSendIfDisabled() {
|
||||||
repositoryProperties.setPublishTargetPollEvent(false);
|
repositoryProperties.setPublishTargetPollEvent(false);
|
||||||
controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
||||||
repositoryProperties.setPublishTargetPollEvent(true);
|
repositoryProperties.setPublishTargetPollEvent(true);
|
||||||
@@ -696,7 +697,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void tryToFinishWithErrorUpdateProcessMoreThanOnce() {
|
void tryToFinishWithErrorUpdateProcessMoreThanOnce() {
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
|
|
||||||
// test and verify
|
// test and verify
|
||||||
@@ -743,7 +744,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void tryToFinishUpdateProcessMoreThanOnce() {
|
void tryToFinishUpdateProcessMoreThanOnce() {
|
||||||
final Long actionId = prepareFinishedUpdate().getId();
|
final Long actionId = prepareFinishedUpdate().getId();
|
||||||
|
|
||||||
// try with disabled late feedback
|
// try with disabled late feedback
|
||||||
@@ -780,7 +781,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void sendUpdatesForFinishUpdateProcessDroppedIfDisabled() {
|
void sendUpdatesForFinishUpdateProcessDroppedIfDisabled() {
|
||||||
repositoryProperties.setRejectActionStatusForClosedAction(true);
|
repositoryProperties.setRejectActionStatusForClosedAction(true);
|
||||||
|
|
||||||
final Action action = prepareFinishedUpdate();
|
final Action action = prepareFinishedUpdate();
|
||||||
@@ -807,7 +808,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void sendUpdatesForFinishUpdateProcessAcceptedIfEnabled() {
|
void sendUpdatesForFinishUpdateProcessAcceptedIfEnabled() {
|
||||||
repositoryProperties.setRejectActionStatusForClosedAction(false);
|
repositoryProperties.setRejectActionStatusForClosedAction(false);
|
||||||
|
|
||||||
Action action = prepareFinishedUpdate();
|
Action action = prepareFinishedUpdate();
|
||||||
@@ -828,7 +829,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Ensures that target attribute update is reflected by the repository.")
|
@Description("Ensures that target attribute update is reflected by the repository.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 3) })
|
@Expect(type = TargetUpdatedEvent.class, count = 3) })
|
||||||
public void updateTargetAttributes() throws Exception {
|
void updateTargetAttributes() throws Exception {
|
||||||
final String controllerId = "test123";
|
final String controllerId = "test123";
|
||||||
final Target target = testdataFactory.createTarget(controllerId);
|
final Target target = testdataFactory.createTarget(controllerId);
|
||||||
|
|
||||||
@@ -884,7 +885,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Ensures that target attributes can be updated using different update modes.")
|
@Description("Ensures that target attributes can be updated using different update modes.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 4) })
|
@Expect(type = TargetUpdatedEvent.class, count = 4) })
|
||||||
public void updateTargetAttributesWithDifferentUpdateModes() {
|
void updateTargetAttributesWithDifferentUpdateModes() {
|
||||||
|
|
||||||
final String controllerId = "testCtrl";
|
final String controllerId = "testCtrl";
|
||||||
testdataFactory.createTarget(controllerId);
|
testdataFactory.createTarget(controllerId);
|
||||||
@@ -1027,33 +1028,28 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Checks if invalid values of attribute-key and attribute-value are handled correctly")
|
@Description("Checks if invalid values of attribute-key and attribute-value are handled correctly")
|
||||||
public void updateTargetAttributesFailsForInvalidAttributes() {
|
public void updateTargetAttributesFailsForInvalidAttributes() {
|
||||||
final String keyTooLong = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE + 1);
|
|
||||||
final String keyValid = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE);
|
|
||||||
final String valueTooLong = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE + 1);
|
|
||||||
final String valueValid = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE);
|
|
||||||
final String keyNull = null;
|
|
||||||
|
|
||||||
final String controllerId = "targetId123";
|
final String controllerId = "targetId123";
|
||||||
testdataFactory.createTarget(controllerId);
|
testdataFactory.createTarget(controllerId);
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidTargetAttributeException.class)
|
assertThatExceptionOfType(InvalidTargetAttributeException.class)
|
||||||
.as("Attribute with key too long should not be created")
|
.as("Attribute with key too long should not be created")
|
||||||
.isThrownBy(() -> controllerManagement.updateControllerAttributes(controllerId,
|
.isThrownBy(() -> controllerManagement.updateControllerAttributes(controllerId,
|
||||||
Collections.singletonMap(keyTooLong, valueValid), null));
|
Collections.singletonMap(TargetTestData.ATTRIBUTE_KEY_TOO_LONG, TargetTestData.ATTRIBUTE_VALUE_VALID), null));
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidTargetAttributeException.class)
|
assertThatExceptionOfType(InvalidTargetAttributeException.class)
|
||||||
.as("Attribute with key too long and value too long should not be created")
|
.as("Attribute with key too long and value too long should not be created")
|
||||||
.isThrownBy(() -> controllerManagement.updateControllerAttributes(controllerId,
|
.isThrownBy(() -> controllerManagement.updateControllerAttributes(controllerId,
|
||||||
Collections.singletonMap(keyTooLong, valueTooLong), null));
|
Collections.singletonMap(TargetTestData.ATTRIBUTE_KEY_TOO_LONG, TargetTestData.ATTRIBUTE_VALUE_TOO_LONG), null));
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidTargetAttributeException.class)
|
assertThatExceptionOfType(InvalidTargetAttributeException.class)
|
||||||
.as("Attribute with value too long should not be created")
|
.as("Attribute with value too long should not be created")
|
||||||
.isThrownBy(() -> controllerManagement.updateControllerAttributes(controllerId,
|
.isThrownBy(() -> controllerManagement.updateControllerAttributes(controllerId,
|
||||||
Collections.singletonMap(keyValid, valueTooLong), null));
|
Collections.singletonMap(TargetTestData.ATTRIBUTE_KEY_VALID, TargetTestData.ATTRIBUTE_VALUE_TOO_LONG), null));
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidTargetAttributeException.class)
|
assertThatExceptionOfType(InvalidTargetAttributeException.class)
|
||||||
.as("Attribute with key NULL should not be created").isThrownBy(() -> controllerManagement
|
.as("Attribute with key NULL should not be created").isThrownBy(() -> controllerManagement
|
||||||
.updateControllerAttributes(controllerId, Collections.singletonMap(keyNull, valueValid), null));
|
.updateControllerAttributes(controllerId,
|
||||||
|
Collections.singletonMap(null, TargetTestData.ATTRIBUTE_VALUE_VALID), null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1198,7 +1194,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerReportsDownloadedForDownloadOnlyAction() {
|
void controllerReportsDownloadedForDownloadOnlyAction() {
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
||||||
assertThat(actionId).isNotNull();
|
assertThat(actionId).isNotNull();
|
||||||
@@ -1221,7 +1217,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = ActionUpdatedEvent.class, count = 2),
|
@Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerReportsActionFinishedForDownloadOnlyActionThatIsNotActive() {
|
void controllerReportsActionFinishedForDownloadOnlyActionThatIsNotActive() {
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
||||||
assertThat(actionId).isNotNull();
|
assertThat(actionId).isNotNull();
|
||||||
@@ -1244,7 +1240,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void controllerReportsMultipleDownloadedForDownloadOnlyAction() {
|
void controllerReportsMultipleDownloadedForDownloadOnlyAction() {
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
||||||
assertThat(actionId).isNotNull();
|
assertThat(actionId).isNotNull();
|
||||||
@@ -1269,7 +1265,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 9),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 9),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void quotaExceptionWhencontrollerReportsTooManyDownloadedMessagesForDownloadOnlyAction() {
|
void quotaExceptionWhencontrollerReportsTooManyDownloadedMessagesForDownloadOnlyAction() {
|
||||||
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
||||||
@@ -1289,7 +1285,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForDownloadOnlyAction() {
|
void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForDownloadOnlyAction() {
|
||||||
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
|
||||||
@@ -1318,7 +1314,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForForced() {
|
void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForForced() {
|
||||||
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
|
||||||
final Long actionId = createTargetAndAssignDs();
|
final Long actionId = createTargetAndAssignDs();
|
||||||
assertThat(actionId).isNotNull();
|
assertThat(actionId).isNotNull();
|
||||||
@@ -1341,7 +1337,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that the attaching externalRef to an action is properly stored")
|
@Description("Verify that the attaching externalRef to an action is properly stored")
|
||||||
public void updatedExternalRefOnActionIsReallyUpdated() {
|
void updatedExternalRefOnActionIsReallyUpdated() {
|
||||||
final List<String> allExternalRef = new ArrayList<>();
|
final List<String> allExternalRef = new ArrayList<>();
|
||||||
final List<Long> allActionId = new ArrayList<>();
|
final List<Long> allActionId = new ArrayList<>();
|
||||||
final int numberOfActions = 3;
|
final int numberOfActions = 3;
|
||||||
@@ -1369,7 +1365,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that getting a single action using externalRef works")
|
@Description("Verify that getting a single action using externalRef works")
|
||||||
public void getActionUsingSingleExternalRef() {
|
void getActionUsingSingleExternalRef() {
|
||||||
|
|
||||||
final String knownControllerId = "controllerId";
|
final String knownControllerId = "controllerId";
|
||||||
final String knownExternalRef = "externalRefId";
|
final String knownExternalRef = "externalRefId";
|
||||||
@@ -1392,7 +1388,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that a null externalRef cannot be assigned to an action")
|
@Description("Verify that a null externalRef cannot be assigned to an action")
|
||||||
public void externalRefCannotBeNull() {
|
void externalRefCannotBeNull() {
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.as("No ConstraintViolationException thrown when a null externalRef was set on an action")
|
.as("No ConstraintViolationException thrown when a null externalRef was set on an action")
|
||||||
.isThrownBy(() -> controllerManagement.updateActionExternalRef(1L, null));
|
.isThrownBy(() -> controllerManagement.updateActionExternalRef(1L, null));
|
||||||
@@ -1408,7 +1404,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 6),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 6),
|
||||||
@Expect(type = ActionUpdatedEvent.class, count = 8),
|
@Expect(type = ActionUpdatedEvent.class, count = 8),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 12) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 12) })
|
||||||
public void targetCanAlwaysReportFinishedOrErrorAfterActionIsClosedForDownloadOnlyAssignments() {
|
void targetCanAlwaysReportFinishedOrErrorAfterActionIsClosedForDownloadOnlyAssignments() {
|
||||||
|
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
|
|
||||||
@@ -1459,7 +1455,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = ActionUpdatedEvent.class, count = 3),
|
@Expect(type = ActionUpdatedEvent.class, count = 3),
|
||||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
|
||||||
public void controllerReportsFinishedForOldDownloadOnlyActionAfterSuccessfulForcedAssignment() {
|
void controllerReportsFinishedForOldDownloadOnlyActionAfterSuccessfulForcedAssignment() {
|
||||||
|
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final DistributionSet downloadOnlyDs = testdataFactory.createDistributionSet("downloadOnlyDs1");
|
final DistributionSet downloadOnlyDs = testdataFactory.createDistributionSet("downloadOnlyDs1");
|
||||||
@@ -1495,7 +1491,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Actions are exposed according to thier weight in multi assignment mode.")
|
@Description("Actions are exposed according to thier weight in multi assignment mode.")
|
||||||
public void actionsAreExposedAccordingToTheirWeight() {
|
void actionsAreExposedAccordingToTheirWeight() {
|
||||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet();
|
final DistributionSet ds = testdataFactory.createDistributionSet();
|
||||||
final Long actionWeightNull = assignDistributionSet(ds.getId(), targetId).getAssignedEntity().get(0).getId();
|
final Long actionWeightNull = assignDistributionSet(ds.getId(), targetId).getAssignedEntity().get(0).getId();
|
||||||
@@ -1552,7 +1548,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Delete a target on requested target deletion from client side")
|
@Description("Delete a target on requested target deletion from client side")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TargetDeletedEvent.class, count = 1) })
|
@Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TargetDeletedEvent.class, count = 1) })
|
||||||
public void deleteTargetWithValidThingId() {
|
void deleteTargetWithValidThingId() {
|
||||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
||||||
assertThat(target).as("target should not be null").isNotNull();
|
assertThat(target).as("target should not be null").isNotNull();
|
||||||
assertThat(targetRepository.count()).as("target exists and is ready for deletion").isEqualTo(1L);
|
assertThat(targetRepository.count()).as("target exists and is ready for deletion").isEqualTo(1L);
|
||||||
@@ -1565,7 +1561,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Delete a target with a non existing thingId")
|
@Description("Delete a target with a non existing thingId")
|
||||||
@ExpectEvents({ @Expect(type = TargetDeletedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetDeletedEvent.class, count = 0) })
|
||||||
public void deleteTargetWithInvalidThingId() {
|
void deleteTargetWithInvalidThingId() {
|
||||||
assertThatExceptionOfType(EntityNotFoundException.class)
|
assertThatExceptionOfType(EntityNotFoundException.class)
|
||||||
.as("No EntityNotFoundException thrown when deleting a non-existing target")
|
.as("No EntityNotFoundException thrown when deleting a non-existing target")
|
||||||
.isThrownBy(() -> controllerManagement.deleteExistingTarget("BB"));
|
.isThrownBy(() -> controllerManagement.deleteExistingTarget("BB"));
|
||||||
@@ -1576,7 +1572,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Delete a target after it has been deleted already")
|
@Description("Delete a target after it has been deleted already")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TargetDeletedEvent.class, count = 1) })
|
@Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TargetDeletedEvent.class, count = 1) })
|
||||||
public void deleteTargetAfterItWasDeleted() {
|
void deleteTargetAfterItWasDeleted() {
|
||||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
|
||||||
assertThat(target).as("target should not be null").isNotNull();
|
assertThat(target).as("target should not be null").isNotNull();
|
||||||
assertThat(targetRepository.count()).as("target exists and is ready for deletion").isEqualTo(1L);
|
assertThat(targetRepository.count()).as("target exists and is ready for deletion").isEqualTo(1L);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa;
|
package org.eclipse.hawkbit.repository.jpa;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
@@ -18,6 +19,8 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -74,14 +77,16 @@ import io.qameta.allure.Story;
|
|||||||
*/
|
*/
|
||||||
@Feature("Component Tests - Repository")
|
@Feature("Component Tests - Repository")
|
||||||
@Story("DistributionSet Management")
|
@Story("DistributionSet Management")
|
||||||
public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||||
|
|
||||||
|
public static final String TAG1_NAME = "Tag1";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that management get access react as specfied on calls for non existing entities by means "
|
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
|
||||||
+ "of Optional not present.")
|
+ "of Optional not present.")
|
||||||
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void nonExistingEntityAccessReturnsNotPresent() {
|
void nonExistingEntityAccessReturnsNotPresent() {
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet();
|
final DistributionSet set = testdataFactory.createDistributionSet();
|
||||||
assertThat(distributionSetManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
assertThat(distributionSetManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
||||||
assertThat(distributionSetManagement.getWithDetails(NOT_EXIST_IDL)).isNotPresent();
|
assertThat(distributionSetManagement.getWithDetails(NOT_EXIST_IDL)).isNotPresent();
|
||||||
@@ -95,16 +100,16 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetTagCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetTagCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 4) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 4) })
|
||||||
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet();
|
final DistributionSet set = testdataFactory.createDistributionSet();
|
||||||
final DistributionSetTag dsTag = testdataFactory.createDistributionSetTags(1).get(0);
|
final DistributionSetTag dsTag = testdataFactory.createDistributionSetTags(1).get(0);
|
||||||
final SoftwareModule module = testdataFactory.createSoftwareModuleApp();
|
final SoftwareModule module = testdataFactory.createSoftwareModuleApp();
|
||||||
|
|
||||||
verifyThrownExceptionBy(
|
verifyThrownExceptionBy(
|
||||||
() -> distributionSetManagement.assignSoftwareModules(NOT_EXIST_IDL, Arrays.asList(module.getId())),
|
() -> distributionSetManagement.assignSoftwareModules(NOT_EXIST_IDL, singletonList(module.getId())),
|
||||||
"DistributionSet");
|
"DistributionSet");
|
||||||
verifyThrownExceptionBy(
|
verifyThrownExceptionBy(
|
||||||
() -> distributionSetManagement.assignSoftwareModules(set.getId(), Arrays.asList(NOT_EXIST_IDL)),
|
() -> distributionSetManagement.assignSoftwareModules(set.getId(), singletonList(NOT_EXIST_IDL)),
|
||||||
"SoftwareModule");
|
"SoftwareModule");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> distributionSetManagement.countByTypeId(NOT_EXIST_IDL), "DistributionSet");
|
verifyThrownExceptionBy(() -> distributionSetManagement.countByTypeId(NOT_EXIST_IDL), "DistributionSet");
|
||||||
@@ -114,10 +119,10 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
verifyThrownExceptionBy(() -> distributionSetManagement.unassignSoftwareModule(set.getId(), NOT_EXIST_IDL),
|
verifyThrownExceptionBy(() -> distributionSetManagement.unassignSoftwareModule(set.getId(), NOT_EXIST_IDL),
|
||||||
"SoftwareModule");
|
"SoftwareModule");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(Arrays.asList(set.getId()), NOT_EXIST_IDL),
|
verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(singletonList(set.getId()), NOT_EXIST_IDL),
|
||||||
"DistributionSetTag");
|
"DistributionSetTag");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(Arrays.asList(NOT_EXIST_IDL), dsTag.getId()),
|
verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(singletonList(NOT_EXIST_IDL), dsTag.getId()),
|
||||||
"DistributionSet");
|
"DistributionSet");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> distributionSetManagement.findByTag(PAGE, NOT_EXIST_IDL), "DistributionSetTag");
|
verifyThrownExceptionBy(() -> distributionSetManagement.findByTag(PAGE, NOT_EXIST_IDL), "DistributionSetTag");
|
||||||
@@ -125,10 +130,10 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
"DistributionSetTag");
|
"DistributionSetTag");
|
||||||
|
|
||||||
verifyThrownExceptionBy(
|
verifyThrownExceptionBy(
|
||||||
() -> distributionSetManagement.toggleTagAssignment(Arrays.asList(NOT_EXIST_IDL), dsTag.getName()),
|
() -> distributionSetManagement.toggleTagAssignment(singletonList(NOT_EXIST_IDL), dsTag.getName()),
|
||||||
"DistributionSet");
|
"DistributionSet");
|
||||||
verifyThrownExceptionBy(
|
verifyThrownExceptionBy(
|
||||||
() -> distributionSetManagement.toggleTagAssignment(Arrays.asList(set.getId()), NOT_EXIST_ID),
|
() -> distributionSetManagement.toggleTagAssignment(singletonList(set.getId()), NOT_EXIST_ID),
|
||||||
"DistributionSetTag");
|
"DistributionSetTag");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> distributionSetManagement.unAssignTag(set.getId(), NOT_EXIST_IDL),
|
verifyThrownExceptionBy(() -> distributionSetManagement.unAssignTag(set.getId(), NOT_EXIST_IDL),
|
||||||
@@ -143,9 +148,9 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
"DistributionSetType");
|
"DistributionSetType");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> distributionSetManagement.createMetaData(NOT_EXIST_IDL,
|
verifyThrownExceptionBy(() -> distributionSetManagement.createMetaData(NOT_EXIST_IDL,
|
||||||
Arrays.asList(entityFactory.generateDsMetadata("123", "123"))), "DistributionSet");
|
singletonList(entityFactory.generateDsMetadata("123", "123"))), "DistributionSet");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> distributionSetManagement.delete(Arrays.asList(NOT_EXIST_IDL)),
|
verifyThrownExceptionBy(() -> distributionSetManagement.delete(singletonList(NOT_EXIST_IDL)),
|
||||||
"DistributionSet");
|
"DistributionSet");
|
||||||
verifyThrownExceptionBy(() -> distributionSetManagement.delete(NOT_EXIST_IDL), "DistributionSet");
|
verifyThrownExceptionBy(() -> distributionSetManagement.delete(NOT_EXIST_IDL), "DistributionSet");
|
||||||
verifyThrownExceptionBy(() -> distributionSetManagement.deleteMetaData(NOT_EXIST_IDL, "xxx"),
|
verifyThrownExceptionBy(() -> distributionSetManagement.deleteMetaData(NOT_EXIST_IDL, "xxx"),
|
||||||
@@ -191,8 +196,8 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Verify that a DistributionSet with invalid properties cannot be created or updated")
|
@Description("Verify that a DistributionSet with invalid properties cannot be created or updated")
|
||||||
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||||
@Expect(type = DistributionSetUpdatedEvent.class, count = 0) })
|
@Expect(type = DistributionSetUpdatedEvent.class) })
|
||||||
public void createAndUpdateDistributionSetWithInvalidFields() {
|
void createAndUpdateDistributionSetWithInvalidFields() {
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet();
|
final DistributionSet set = testdataFactory.createDistributionSet();
|
||||||
|
|
||||||
createAndUpdateDistributionSetWithInvalidDescription(set);
|
createAndUpdateDistributionSetWithInvalidDescription(set);
|
||||||
@@ -204,57 +209,57 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
private void createAndUpdateDistributionSetWithInvalidDescription(final DistributionSet set) {
|
private void createAndUpdateDistributionSetWithInvalidDescription(final DistributionSet set) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with too long description should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||||
.version("a").description(RandomStringUtils.randomAlphanumeric(513))))
|
.version("a").description(RandomStringUtils.randomAlphanumeric(513))));
|
||||||
.as("entity with too long description should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with invalid description should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement.create(
|
.isThrownBy(() -> distributionSetManagement.create(
|
||||||
entityFactory.distributionSet().create().name("a").version("a").description(INVALID_TEXT_HTML)))
|
entityFactory.distributionSet().create().name("a").version("a")
|
||||||
.as("entity with invalid description should not be created");
|
.description(INVALID_TEXT_HTML)));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with too long description should not be updated")
|
||||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||||
.description(RandomStringUtils.randomAlphanumeric(513))))
|
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||||
.as("entity with too long description should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with invalid characters should not be updated")
|
||||||
.isThrownBy(() -> distributionSetManagement
|
.isThrownBy(() -> distributionSetManagement
|
||||||
.update(entityFactory.distributionSet().update(set.getId()).description(INVALID_TEXT_HTML)))
|
.update(entityFactory.distributionSet().update(set.getId()).description(INVALID_TEXT_HTML)));
|
||||||
.as("entity with invalid characters should not be updated");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createAndUpdateDistributionSetWithInvalidName(final DistributionSet set) {
|
private void createAndUpdateDistributionSetWithInvalidName(final DistributionSet set) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with too long name should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a")
|
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a")
|
||||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))))
|
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||||
.as("entity with too long name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
|
||||||
() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a").name("")))
|
|
||||||
.as("entity with too short name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with too short name should not be created").isThrownBy(() -> distributionSetManagement
|
||||||
|
.create(entityFactory.distributionSet().create().version("a").name("")));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with invalid characters in name should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement
|
.isThrownBy(() -> distributionSetManagement
|
||||||
.create(entityFactory.distributionSet().create().version("a").name(INVALID_TEXT_HTML)))
|
.create(entityFactory.distributionSet().create().version("a").name(INVALID_TEXT_HTML)));
|
||||||
.as("entity with invalid characters in name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with too long name should not be updated")
|
||||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))))
|
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||||
.as("entity with too long name should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with invalid characters should not be updated")
|
||||||
.isThrownBy(() -> distributionSetManagement
|
.isThrownBy(() -> distributionSetManagement
|
||||||
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)))
|
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)));
|
||||||
.as("entity with invalid characters should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId()).name("")))
|
.as("entity with too short name should not be updated").isThrownBy(() -> distributionSetManagement
|
||||||
.as("entity with too short name should not be updated");
|
.update(entityFactory.distributionSet().update(set.getId()).name("")));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,28 +267,28 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
private void createAndUpdateDistributionSetWithInvalidVersion(final DistributionSet set) {
|
private void createAndUpdateDistributionSetWithInvalidVersion(final DistributionSet set) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with too long version should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))))
|
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||||
.as("entity with too long version should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
|
||||||
() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a").version("")))
|
|
||||||
.as("entity with too short version should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
.as("entity with too short version should not be created").isThrownBy(() -> distributionSetManagement
|
||||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))))
|
.create(entityFactory.distributionSet().create().name("a").version("")));
|
||||||
.as("entity with too long version should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId()).version("")))
|
.as("entity with too long version should not be updated")
|
||||||
.as("entity with too short version should not be updated");
|
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||||
|
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("entity with too short version should not be updated").isThrownBy(() -> distributionSetManagement
|
||||||
|
.update(entityFactory.distributionSet().update(set.getId()).version("")));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that it is not possible to create a DS that already exists (unique constraint is on name,version for DS).")
|
@Description("Ensures that it is not possible to create a DS that already exists (unique constraint is on name,version for DS).")
|
||||||
public void createDuplicateDistributionSetsFailsWithException() {
|
void createDuplicateDistributionSetsFailsWithException() {
|
||||||
testdataFactory.createDistributionSet("a");
|
testdataFactory.createDistributionSet("a");
|
||||||
|
|
||||||
assertThatThrownBy(() -> testdataFactory.createDistributionSet("a"))
|
assertThatThrownBy(() -> testdataFactory.createDistributionSet("a"))
|
||||||
@@ -292,7 +297,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a DS is of default type if not specified explicitly at creation time.")
|
@Description("Verifies that a DS is of default type if not specified explicitly at creation time.")
|
||||||
public void createDistributionSetWithImplicitType() {
|
void createDistributionSetWithImplicitType() {
|
||||||
final DistributionSet set = distributionSetManagement
|
final DistributionSet set = distributionSetManagement
|
||||||
.create(entityFactory.distributionSet().create().name("newtypesoft").version("1"));
|
.create(entityFactory.distributionSet().create().name("newtypesoft").version("1"));
|
||||||
|
|
||||||
@@ -303,7 +308,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a DS cannot be created if another DS with same name and version exists.")
|
@Description("Verifies that a DS cannot be created if another DS with same name and version exists.")
|
||||||
public void createDistributionSetWithDuplicateNameAndVersionFails() {
|
void createDistributionSetWithDuplicateNameAndVersionFails() {
|
||||||
distributionSetManagement.create(entityFactory.distributionSet().create().name("newtypesoft").version("1"));
|
distributionSetManagement.create(entityFactory.distributionSet().create().name("newtypesoft").version("1"));
|
||||||
|
|
||||||
assertThatExceptionOfType(EntityAlreadyExistsException.class).isThrownBy(() -> distributionSetManagement
|
assertThatExceptionOfType(EntityAlreadyExistsException.class).isThrownBy(() -> distributionSetManagement
|
||||||
@@ -313,7 +318,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that multiple DS are of default type if not specified explicitly at creation time.")
|
@Description("Verifies that multiple DS are of default type if not specified explicitly at creation time.")
|
||||||
public void createMultipleDistributionSetsWithImplicitType() {
|
void createMultipleDistributionSetsWithImplicitType() {
|
||||||
|
|
||||||
final List<DistributionSetCreate> creates = Lists.newArrayListWithExpectedSize(10);
|
final List<DistributionSetCreate> creates = Lists.newArrayListWithExpectedSize(10);
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
@@ -333,7 +338,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Checks that metadata for a distribution set can be created.")
|
@Description("Checks that metadata for a distribution set can be created.")
|
||||||
public void createDistributionSetMetadata() {
|
void createDistributionSetMetadata() {
|
||||||
final String knownKey = "dsMetaKnownKey";
|
final String knownKey = "dsMetaKnownKey";
|
||||||
final String knownValue = "dsMetaKnownValue";
|
final String knownValue = "dsMetaKnownValue";
|
||||||
|
|
||||||
@@ -351,7 +356,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies the enforcement of the metadata quota per distribution set.")
|
@Description("Verifies the enforcement of the metadata quota per distribution set.")
|
||||||
public void createDistributionSetMetadataUntilQuotaIsExceeded() {
|
void createDistributionSetMetadataUntilQuotaIsExceeded() {
|
||||||
|
|
||||||
// add meta data one by one
|
// add meta data one by one
|
||||||
final DistributionSet ds1 = testdataFactory.createDistributionSet("ds1");
|
final DistributionSet ds1 = testdataFactory.createDistributionSet("ds1");
|
||||||
@@ -378,7 +383,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// add some meta data entries
|
// add some meta data entries
|
||||||
final DistributionSet ds3 = testdataFactory.createDistributionSet("ds3");
|
final DistributionSet ds3 = testdataFactory.createDistributionSet("ds3");
|
||||||
final int firstHalf = Math.round(maxMetaData / 2);
|
final int firstHalf = Math.round(((float) maxMetaData) / 2.f);
|
||||||
for (int i = 0; i < firstHalf; ++i) {
|
for (int i = 0; i < firstHalf; ++i) {
|
||||||
createDistributionSetMetadata(ds3.getId(), new JpaDistributionSetMetadata("k" + i, ds3, "v" + i));
|
createDistributionSetMetadata(ds3.getId(), new JpaDistributionSetMetadata("k" + i, ds3, "v" + i));
|
||||||
}
|
}
|
||||||
@@ -396,20 +401,21 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that distribution sets can assigned and unassigned to a distribution set tag.")
|
@Description("Ensures that distribution sets can assigned and unassigned to a distribution set tag.")
|
||||||
public void assignAndUnassignDistributionSetToTag() {
|
void assignAndUnassignDistributionSetToTag() {
|
||||||
final List<Long> assignDS = Lists.newArrayListWithExpectedSize(4);
|
final List<Long> assignDS = Lists.newArrayListWithExpectedSize(4);
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
assignDS.add(testdataFactory.createDistributionSet("DS" + i, "1.0", Collections.emptyList()).getId());
|
assignDS.add(testdataFactory.createDistributionSet("DS" + i, "1.0", Collections.emptyList()).getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
final DistributionSetTag tag = distributionSetTagManagement.create(entityFactory.tag().create().name("Tag1"));
|
final DistributionSetTag tag = distributionSetTagManagement
|
||||||
|
.create(entityFactory.tag().create().name(TAG1_NAME));
|
||||||
|
|
||||||
final List<DistributionSet> assignedDS = distributionSetManagement.assignTag(assignDS, tag.getId());
|
final List<DistributionSet> assignedDS = distributionSetManagement.assignTag(assignDS, tag.getId());
|
||||||
assertThat(assignedDS.size()).as("assigned ds has wrong size").isEqualTo(4);
|
assertThat(assignedDS.size()).as("assigned ds has wrong size").isEqualTo(4);
|
||||||
assignedDS.stream().map(c -> (JpaDistributionSet) c)
|
assignedDS.stream().map(c -> (JpaDistributionSet) c)
|
||||||
.forEach(ds -> assertThat(ds.getTags().size()).as("ds has wrong tag size").isEqualTo(1));
|
.forEach(ds -> assertThat(ds.getTags().size()).as("ds has wrong tag size").isEqualTo(1));
|
||||||
|
|
||||||
DistributionSetTag findDistributionSetTag = distributionSetTagManagement.getByName("Tag1").get();
|
DistributionSetTag findDistributionSetTag = getOrThrow(distributionSetTagManagement.getByName(TAG1_NAME));
|
||||||
|
|
||||||
assertThat(assignedDS.size()).as("assigned ds has wrong size")
|
assertThat(assignedDS.size()).as("assigned ds has wrong size")
|
||||||
.isEqualTo(distributionSetManagement.findByTag(PAGE, tag.getId()).getNumberOfElements());
|
.isEqualTo(distributionSetManagement.findByTag(PAGE, tag.getId()).getNumberOfElements());
|
||||||
@@ -417,20 +423,20 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
final JpaDistributionSet unAssignDS = (JpaDistributionSet) distributionSetManagement
|
final JpaDistributionSet unAssignDS = (JpaDistributionSet) distributionSetManagement
|
||||||
.unAssignTag(assignDS.get(0), findDistributionSetTag.getId());
|
.unAssignTag(assignDS.get(0), findDistributionSetTag.getId());
|
||||||
assertThat(unAssignDS.getId()).as("unassigned ds is wrong").isEqualTo(assignDS.get(0));
|
assertThat(unAssignDS.getId()).as("unassigned ds is wrong").isEqualTo(assignDS.get(0));
|
||||||
assertThat(unAssignDS.getTags().size()).as("unassigned ds has wrong tag size").isEqualTo(0);
|
assertThat(unAssignDS.getTags().size()).as("unassigned ds has wrong tag size").isZero();
|
||||||
findDistributionSetTag = distributionSetTagManagement.getByName("Tag1").get();
|
assertThat(distributionSetTagManagement.getByName(TAG1_NAME)).isPresent();
|
||||||
assertThat(distributionSetManagement.findByTag(PAGE, tag.getId()).getNumberOfElements())
|
assertThat(distributionSetManagement.findByTag(PAGE, tag.getId()).getNumberOfElements())
|
||||||
.as("ds tag ds has wrong ds size").isEqualTo(3);
|
.as("ds tag ds has wrong ds size").isEqualTo(3);
|
||||||
|
|
||||||
assertThat(distributionSetManagement.findByRsqlAndTag(PAGE, "name==" + unAssignDS.getName(), tag.getId())
|
assertThat(distributionSetManagement.findByRsqlAndTag(PAGE, "name==" + unAssignDS.getName(), tag.getId())
|
||||||
.getNumberOfElements()).as("ds tag ds has wrong ds size").isEqualTo(0);
|
.getNumberOfElements()).as("ds tag ds has wrong ds size").isZero();
|
||||||
assertThat(distributionSetManagement.findByRsqlAndTag(PAGE, "name!=" + unAssignDS.getName(), tag.getId())
|
assertThat(distributionSetManagement.findByRsqlAndTag(PAGE, "name!=" + unAssignDS.getName(), tag.getId())
|
||||||
.getNumberOfElements()).as("ds tag ds has wrong ds size").isEqualTo(3);
|
.getNumberOfElements()).as("ds tag ds has wrong ds size").isEqualTo(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that updates concerning the internal software structure of a DS are not possible if the DS is already assigned.")
|
@Description("Ensures that updates concerning the internal software structure of a DS are not possible if the DS is already assigned.")
|
||||||
public void updateDistributionSetForbiddedWithIllegalUpdate() {
|
void updateDistributionSetForbiddenWithIllegalUpdate() {
|
||||||
// prepare data
|
// prepare data
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
|
|
||||||
@@ -444,7 +450,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// assign target
|
// assign target
|
||||||
assignDistributionSet(ds.getId(), target.getControllerId());
|
assignDistributionSet(ds.getId(), target.getControllerId());
|
||||||
ds = distributionSetManagement.getWithDetails(ds.getId()).get();
|
ds = getOrThrow(distributionSetManagement.getWithDetails(ds.getId()));
|
||||||
|
|
||||||
final Long dsId = ds.getId();
|
final Long dsId = ds.getId();
|
||||||
// not allowed as it is assigned now
|
// not allowed as it is assigned now
|
||||||
@@ -452,20 +458,20 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
.isInstanceOf(EntityReadOnlyException.class);
|
.isInstanceOf(EntityReadOnlyException.class);
|
||||||
|
|
||||||
// not allowed as it is assigned now
|
// not allowed as it is assigned now
|
||||||
final Long appId = ds.findFirstModuleByType(appType).get().getId();
|
final Long appId = getOrThrow(ds.findFirstModuleByType(appType)).getId();
|
||||||
assertThatThrownBy(() -> distributionSetManagement.unassignSoftwareModule(dsId, appId))
|
assertThatThrownBy(() -> distributionSetManagement.unassignSoftwareModule(dsId, appId))
|
||||||
.isInstanceOf(EntityReadOnlyException.class);
|
.isInstanceOf(EntityReadOnlyException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that it is not possible to add a software module that is not defined of the DS's type.")
|
@Description("Ensures that it is not possible to add a software module that is not defined of the DS's type.")
|
||||||
public void updateDistributionSetUnsupportedModuleFails() {
|
void updateDistributionSetUnsupportedModuleFails() {
|
||||||
final DistributionSet set = distributionSetManagement
|
final DistributionSet set = distributionSetManagement
|
||||||
.create(entityFactory
|
.create(entityFactory
|
||||||
.distributionSet().create().name("agent-hub2").version(
|
.distributionSet().create().name("agent-hub2").version(
|
||||||
"1.0.5")
|
"1.0.5")
|
||||||
.type(distributionSetTypeManagement.create(entityFactory.distributionSetType().create()
|
.type(distributionSetTypeManagement.create(entityFactory.distributionSetType().create()
|
||||||
.key("test").name("test").mandatory(Arrays.asList(osType.getId()))).getKey()));
|
.key("test").name("test").mandatory(singletonList(osType.getId()))).getKey()));
|
||||||
|
|
||||||
final SoftwareModule module = softwareModuleManagement.create(
|
final SoftwareModule module = softwareModuleManagement.create(
|
||||||
entityFactory.softwareModule().create().name("agent-hub2").version("1.0.5").type(appType.getKey()));
|
entityFactory.softwareModule().create().name("agent-hub2").version("1.0.5").type(appType.getKey()));
|
||||||
@@ -478,7 +484,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Legal updates of a DS, e.g. name or description and module addition, removal while still unassigned.")
|
@Description("Legal updates of a DS, e.g. name or description and module addition, removal while still unassigned.")
|
||||||
public void updateDistributionSet() {
|
void updateDistributionSet() {
|
||||||
// prepare data
|
// prepare data
|
||||||
DistributionSet ds = testdataFactory.createDistributionSet("");
|
DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
final SoftwareModule os = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule os = testdataFactory.createSoftwareModuleOs();
|
||||||
@@ -486,18 +492,19 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// update data
|
// update data
|
||||||
// legal update of module addition
|
// legal update of module addition
|
||||||
distributionSetManagement.assignSoftwareModules(ds.getId(), Sets.newHashSet(os.getId()));
|
distributionSetManagement.assignSoftwareModules(ds.getId(), Sets.newHashSet(os.getId()));
|
||||||
ds = distributionSetManagement.getWithDetails(ds.getId()).get();
|
ds = getOrThrow(distributionSetManagement.getWithDetails(ds.getId()));
|
||||||
assertThat(ds.findFirstModuleByType(osType).get()).isEqualTo(os);
|
assertThat(getOrThrow(ds.findFirstModuleByType(osType))).isEqualTo(os);
|
||||||
|
|
||||||
// legal update of module removal
|
// legal update of module removal
|
||||||
distributionSetManagement.unassignSoftwareModule(ds.getId(), ds.findFirstModuleByType(appType).get().getId());
|
distributionSetManagement.unassignSoftwareModule(ds.getId(),
|
||||||
ds = distributionSetManagement.getWithDetails(ds.getId()).get();
|
getOrThrow(ds.findFirstModuleByType(appType)).getId());
|
||||||
assertThat(ds.findFirstModuleByType(appType).isPresent()).isFalse();
|
ds = getOrThrow(distributionSetManagement.getWithDetails(ds.getId()));
|
||||||
|
assertThat(ds.findFirstModuleByType(appType)).isNotPresent();
|
||||||
|
|
||||||
// Update description
|
// Update description
|
||||||
distributionSetManagement.update(entityFactory.distributionSet().update(ds.getId()).name("a new name")
|
distributionSetManagement.update(entityFactory.distributionSet().update(ds.getId()).name("a new name")
|
||||||
.description("a new description").version("a new version").requiredMigrationStep(true));
|
.description("a new description").version("a new version").requiredMigrationStep(true));
|
||||||
ds = distributionSetManagement.getWithDetails(ds.getId()).get();
|
ds = getOrThrow(distributionSetManagement.getWithDetails(ds.getId()));
|
||||||
assertThat(ds.getDescription()).isEqualTo("a new description");
|
assertThat(ds.getDescription()).isEqualTo("a new description");
|
||||||
assertThat(ds.getName()).isEqualTo("a new name");
|
assertThat(ds.getName()).isEqualTo("a new name");
|
||||||
assertThat(ds.getVersion()).isEqualTo("a new version");
|
assertThat(ds.getVersion()).isEqualTo("a new version");
|
||||||
@@ -506,7 +513,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that an exception is thrown when trying to update an invalid distribution set")
|
@Description("Verifies that an exception is thrown when trying to update an invalid distribution set")
|
||||||
public void updateInvalidDistributionSet() {
|
void updateInvalidDistributionSet() {
|
||||||
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
||||||
@@ -516,7 +523,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies the enforcement of the software module quota per distribution set.")
|
@Description("Verifies the enforcement of the software module quota per distribution set.")
|
||||||
public void assignSoftwareModulesUntilQuotaIsExceeded() {
|
void assignSoftwareModulesUntilQuotaIsExceeded() {
|
||||||
|
|
||||||
// create some software modules
|
// create some software modules
|
||||||
final int maxModules = quotaManagement.getMaxSoftwareModulesPerDistributionSet();
|
final int maxModules = quotaManagement.getMaxSoftwareModulesPerDistributionSet();
|
||||||
@@ -528,13 +535,11 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// assign software modules one by one
|
// assign software modules one by one
|
||||||
final DistributionSet ds1 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds1", "1.0");
|
final DistributionSet ds1 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds1", "1.0");
|
||||||
for (int i = 0; i < maxModules; ++i) {
|
for (int i = 0; i < maxModules; ++i) {
|
||||||
distributionSetManagement.assignSoftwareModules(ds1.getId(), Collections.singletonList(modules.get(i)));
|
distributionSetManagement.assignSoftwareModules(ds1.getId(), singletonList(modules.get(i)));
|
||||||
}
|
}
|
||||||
// add one more to cause the quota to be exceeded
|
// add one more to cause the quota to be exceeded
|
||||||
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> {
|
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> distributionSetManagement
|
||||||
distributionSetManagement.assignSoftwareModules(ds1.getId(),
|
.assignSoftwareModules(ds1.getId(), singletonList(modules.get(maxModules))));
|
||||||
Collections.singletonList(modules.get(maxModules)));
|
|
||||||
});
|
|
||||||
|
|
||||||
// assign all software modules at once
|
// assign all software modules at once
|
||||||
final DistributionSet ds2 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds2", "1.0");
|
final DistributionSet ds2 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds2", "1.0");
|
||||||
@@ -544,9 +549,9 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// assign some software modules
|
// assign some software modules
|
||||||
final DistributionSet ds3 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds3", "1.0");
|
final DistributionSet ds3 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds3", "1.0");
|
||||||
final int firstHalf = Math.round(maxModules / 2);
|
final int firstHalf = Math.round(((float) maxModules) / 2.f);
|
||||||
for (int i = 0; i < firstHalf; ++i) {
|
for (int i = 0; i < firstHalf; ++i) {
|
||||||
distributionSetManagement.assignSoftwareModules(ds3.getId(), Collections.singletonList(modules.get(i)));
|
distributionSetManagement.assignSoftwareModules(ds3.getId(), singletonList(modules.get(i)));
|
||||||
}
|
}
|
||||||
// assign the remaining modules to cause the quota to be exceeded
|
// assign the remaining modules to cause the quota to be exceeded
|
||||||
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> distributionSetManagement
|
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> distributionSetManagement
|
||||||
@@ -556,25 +561,25 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that an exception is thrown when trying to assign software modules to an invalidated distribution set.")
|
@Description("Verifies that an exception is thrown when trying to assign software modules to an invalidated distribution set.")
|
||||||
public void verifyAssignSoftwareModulesToInvalidDistributionSet() {
|
void verifyAssignSoftwareModulesToInvalidDistributionSet() {
|
||||||
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
||||||
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
||||||
.as("Invalid distributionSet should throw an exception")
|
.as("Invalid distributionSet should throw an exception")
|
||||||
.isThrownBy(() -> distributionSetManagement.assignSoftwareModules(distributionSet.getId(),
|
.isThrownBy(() -> distributionSetManagement.assignSoftwareModules(distributionSet.getId(),
|
||||||
Collections.singletonList(softwareModule.getId())));
|
singletonList(softwareModule.getId())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that an exception is thrown when trying to unassign a software module from an invalidated distribution set.")
|
@Description("Verifies that an exception is thrown when trying to unassign a software module from an invalidated distribution set.")
|
||||||
public void verifyUnassignSoftwareModulesToInvalidDistributionSet() {
|
void verifyUnassignSoftwareModulesToInvalidDistributionSet() {
|
||||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||||
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleOs();
|
||||||
distributionSetManagement.assignSoftwareModules(distributionSet.getId(),
|
distributionSetManagement.assignSoftwareModules(distributionSet.getId(),
|
||||||
Collections.singletonList(softwareModule.getId()));
|
singletonList(softwareModule.getId()));
|
||||||
distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation(
|
distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation(
|
||||||
Collections.singletonList(distributionSet.getId()), CancelationType.NONE, false));
|
singletonList(distributionSet.getId()), CancelationType.NONE, false));
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
||||||
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> distributionSetManagement
|
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> distributionSetManagement
|
||||||
@@ -584,7 +589,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithUser(allSpPermissions = true)
|
@WithUser(allSpPermissions = true)
|
||||||
@Description("Checks that metadata for a distribution set can be updated.")
|
@Description("Checks that metadata for a distribution set can be updated.")
|
||||||
public void updateDistributionSetMetadata() throws InterruptedException {
|
void updateDistributionSetMetadata() {
|
||||||
final String knownKey = "myKnownKey";
|
final String knownKey = "myKnownKey";
|
||||||
final String knownValue = "myKnownValue";
|
final String knownValue = "myKnownValue";
|
||||||
final String knownUpdateValue = "myNewUpdatedValue";
|
final String knownUpdateValue = "myNewUpdatedValue";
|
||||||
@@ -597,20 +602,17 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// create an DS meta data entry
|
// create an DS meta data entry
|
||||||
createDistributionSetMetadata(ds.getId(), new JpaDistributionSetMetadata(knownKey, ds, knownValue));
|
createDistributionSetMetadata(ds.getId(), new JpaDistributionSetMetadata(knownKey, ds, knownValue));
|
||||||
|
|
||||||
DistributionSet changedLockRevisionDS = distributionSetManagement.get(ds.getId()).get();
|
final DistributionSet changedLockRevisionDS = getOrThrow(distributionSetManagement.get(ds.getId()));
|
||||||
assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(2);
|
assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(2);
|
||||||
|
|
||||||
Thread.sleep(100);
|
|
||||||
|
|
||||||
// update the DS metadata
|
// update the DS metadata
|
||||||
final JpaDistributionSetMetadata updated = (JpaDistributionSetMetadata) distributionSetManagement
|
final JpaDistributionSetMetadata updated = (JpaDistributionSetMetadata) distributionSetManagement
|
||||||
.updateMetaData(ds.getId(), entityFactory.generateDsMetadata(knownKey, knownUpdateValue));
|
.updateMetaData(ds.getId(), entityFactory.generateDsMetadata(knownKey, knownUpdateValue));
|
||||||
// we are updating the sw metadata so also modifying the base software
|
// we are updating the sw metadata so also modifying the base software
|
||||||
// module so opt lock
|
// module so opt lock revision must be three
|
||||||
// revision must be three
|
final DistributionSet reloadedDS = getOrThrow(distributionSetManagement.get(ds.getId()));
|
||||||
changedLockRevisionDS = distributionSetManagement.get(ds.getId()).get();
|
assertThat(reloadedDS.getOptLockRevision()).isEqualTo(3);
|
||||||
assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(3);
|
assertThat(reloadedDS.getLastModifiedAt()).isPositive();
|
||||||
assertThat(changedLockRevisionDS.getLastModifiedAt()).isGreaterThan(0L);
|
|
||||||
|
|
||||||
// verify updated meta data contains the updated value
|
// verify updated meta data contains the updated value
|
||||||
assertThat(updated).isNotNull();
|
assertThat(updated).isNotNull();
|
||||||
@@ -621,7 +623,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests that a DS queue is possible where the result is ordered by the target assignment, i.e. assigned first in the list.")
|
@Description("Tests that a DS queue is possible where the result is ordered by the target assignment, i.e. assigned first in the list.")
|
||||||
public void findDistributionSetsAllOrderedByLinkTarget() {
|
void findDistributionSetsAllOrderedByLinkTarget() {
|
||||||
|
|
||||||
final List<DistributionSet> buildDistributionSets = testdataFactory.createDistributionSets("dsOrder", 10);
|
final List<DistributionSet> buildDistributionSets = testdataFactory.createDistributionSets("dsOrder", 10);
|
||||||
|
|
||||||
@@ -641,7 +643,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assignDistributionSet(dsThree.getId(), tFirst.getControllerId());
|
assignDistributionSet(dsThree.getId(), tFirst.getControllerId());
|
||||||
// set installed
|
// set installed
|
||||||
testdataFactory.sendUpdateActionStatusToTargets(Collections.singleton(tSecond), Status.FINISHED,
|
testdataFactory.sendUpdateActionStatusToTargets(Collections.singleton(tSecond), Status.FINISHED,
|
||||||
Arrays.asList("some message"));
|
singletonList("some message"));
|
||||||
|
|
||||||
assignDistributionSet(dsFour.getId(), tSecond.getControllerId());
|
assignDistributionSet(dsFour.getId(), tSecond.getControllerId());
|
||||||
|
|
||||||
@@ -669,7 +671,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("searches for distribution sets based on the various filter options, e.g. name, version, desc., tags.")
|
@Description("searches for distribution sets based on the various filter options, e.g. name, version, desc., tags.")
|
||||||
public void searchDistributionSetsOnFilters() {
|
void searchDistributionSetsOnFilters() {
|
||||||
DistributionSetTag dsTagA = distributionSetTagManagement
|
DistributionSetTag dsTagA = distributionSetTagManagement
|
||||||
.create(entityFactory.tag().create().name("DistributionSetTag-A"));
|
.create(entityFactory.tag().create().name("DistributionSetTag-A"));
|
||||||
final DistributionSetTag dsTagB = distributionSetTagManagement
|
final DistributionSetTag dsTagB = distributionSetTagManagement
|
||||||
@@ -689,7 +691,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
.create(entityFactory.distributionSetType().create().key("foo").name("bar").description("test"));
|
.create(entityFactory.distributionSetType().create().key("foo").name("bar").description("test"));
|
||||||
|
|
||||||
distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(newType.getId(),
|
distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(newType.getId(),
|
||||||
Arrays.asList(osType.getId()));
|
singletonList(osType.getId()));
|
||||||
newType = distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(newType.getId(),
|
newType = distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(newType.getId(),
|
||||||
Arrays.asList(appType.getId(), runtimeType.getId()));
|
Arrays.asList(appType.getId(), runtimeType.getId()));
|
||||||
|
|
||||||
@@ -699,14 +701,14 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
assignDistributionSet(dsDeleted, testdataFactory.createTargets(5));
|
assignDistributionSet(dsDeleted, testdataFactory.createTargets(5));
|
||||||
distributionSetManagement.delete(dsDeleted.getId());
|
distributionSetManagement.delete(dsDeleted.getId());
|
||||||
dsDeleted = distributionSetManagement.get(dsDeleted.getId()).get();
|
dsDeleted = getOrThrow(distributionSetManagement.get(dsDeleted.getId()));
|
||||||
|
|
||||||
dsGroup1 = toggleTagAssignment(dsGroup1, dsTagA).getAssignedEntity();
|
dsGroup1 = toggleTagAssignment(dsGroup1, dsTagA).getAssignedEntity();
|
||||||
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName()).get();
|
dsTagA = getOrThrow(distributionSetTagRepository.findByNameEquals(dsTagA.getName()));
|
||||||
dsGroup1 = toggleTagAssignment(dsGroup1, dsTagB).getAssignedEntity();
|
dsGroup1 = toggleTagAssignment(dsGroup1, dsTagB).getAssignedEntity();
|
||||||
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName()).get();
|
dsTagA = getOrThrow(distributionSetTagRepository.findByNameEquals(dsTagA.getName()));
|
||||||
dsGroup2 = toggleTagAssignment(dsGroup2, dsTagA).getAssignedEntity();
|
dsGroup2 = toggleTagAssignment(dsGroup2, dsTagA).getAssignedEntity();
|
||||||
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName()).get();
|
dsTagA = getOrThrow(distributionSetTagRepository.findByNameEquals(dsTagA.getName()));
|
||||||
|
|
||||||
final List<DistributionSet> allDistributionSets = Stream
|
final List<DistributionSet> allDistributionSets = Stream
|
||||||
.of(dsGroup1, dsGroup2, Arrays.asList(dsDeleted, dsInComplete, dsNewType)).flatMap(Collection::stream)
|
.of(dsGroup1, dsGroup2, Arrays.asList(dsDeleted, dsInComplete, dsNewType)).flatMap(Collection::stream)
|
||||||
@@ -743,7 +745,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
private void validateDeleted(final DistributionSet deletedDistributionSet, final int notDeletedSize) {
|
private void validateDeleted(final DistributionSet deletedDistributionSet, final int notDeletedSize) {
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE),
|
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE),
|
||||||
Arrays.asList(deletedDistributionSet));
|
singletonList(deletedDistributionSet));
|
||||||
|
|
||||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||||
getDistributionSetFilterBuilder().setIsDeleted(Boolean.FALSE), notDeletedSize, deletedDistributionSet);
|
getDistributionSetFilterBuilder().setIsDeleted(Boolean.FALSE), notDeletedSize, deletedDistributionSet);
|
||||||
@@ -756,7 +758,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE), completedSize, dsIncomplete);
|
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE), completedSize, dsIncomplete);
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE), Arrays.asList(dsIncomplete));
|
getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE), singletonList(dsIncomplete));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
@@ -764,7 +766,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
final int standardDsTypeSize) {
|
final int standardDsTypeSize) {
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(newType),
|
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(newType),
|
||||||
Arrays.asList(dsNewType));
|
singletonList(dsNewType));
|
||||||
|
|
||||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||||
getDistributionSetFilterBuilder().setType(standardDsType), standardDsTypeSize, dsNewType);
|
getDistributionSetFilterBuilder().setType(standardDsType), standardDsTypeSize, dsNewType);
|
||||||
@@ -772,7 +774,6 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void validateSearchText(final List<DistributionSet> withText, final String text) {
|
private void validateSearchText(final List<DistributionSet> withText, final String text) {
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setSearchText(text),
|
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setSearchText(text),
|
||||||
withText);
|
withText);
|
||||||
}
|
}
|
||||||
@@ -825,10 +826,10 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
final List<DistributionSet> dsWithTagB) {
|
final List<DistributionSet> dsWithTagB) {
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||||
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagA.getName())), dsWithTagA);
|
getDistributionSetFilterBuilder().setTagNames(singletonList(dsTagA.getName())), dsWithTagA);
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||||
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagB.getName())), dsWithTagB);
|
getDistributionSetFilterBuilder().setTagNames(singletonList(dsTagB.getName())), dsWithTagB);
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||||
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagA.getName(), dsTagB.getName())),
|
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagA.getName(), dsTagB.getName())),
|
||||||
@@ -839,7 +840,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
dsWithTagB);
|
dsWithTagB);
|
||||||
|
|
||||||
assertThatFilterDoesNotContainAnyDistributionSet(
|
assertThatFilterDoesNotContainAnyDistributionSet(
|
||||||
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagC.getName())));
|
getDistributionSetFilterBuilder().setTagNames(singletonList(dsTagC.getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
@@ -854,7 +855,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.TRUE),
|
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.TRUE),
|
||||||
Arrays.asList(dsDeleted));
|
singletonList(dsDeleted));
|
||||||
|
|
||||||
assertThatFilterDoesNotContainAnyDistributionSet(
|
assertThatFilterDoesNotContainAnyDistributionSet(
|
||||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.TRUE));
|
getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.TRUE));
|
||||||
@@ -868,14 +869,14 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
.setIsComplete(Boolean.TRUE).setType(standardDsType), deletedAndCompletedAndStandardType);
|
.setIsComplete(Boolean.TRUE).setType(standardDsType), deletedAndCompletedAndStandardType);
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||||
.setType(standardDsType).setIsDeleted(Boolean.TRUE), Arrays.asList(dsDeleted));
|
.setType(standardDsType).setIsDeleted(Boolean.TRUE), singletonList(dsDeleted));
|
||||||
|
|
||||||
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE)
|
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE)
|
||||||
.setIsComplete(Boolean.FALSE).setType(standardDsType));
|
.setIsComplete(Boolean.FALSE).setType(standardDsType));
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(newType),
|
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(newType),
|
||||||
Arrays.asList(dsNewType));
|
singletonList(dsNewType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
@@ -915,15 +916,15 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||||
.setIsDeleted(Boolean.TRUE).setType(standardDsType).setFilterString(filterString),
|
.setIsDeleted(Boolean.TRUE).setType(standardDsType).setFilterString(filterString),
|
||||||
Arrays.asList(dsDeleted));
|
singletonList(dsDeleted));
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(standardDsType)
|
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(standardDsType)
|
||||||
.setFilterString(filterString).setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE),
|
.setFilterString(filterString).setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE),
|
||||||
Arrays.asList(dsInComplete));
|
singletonList(dsInComplete));
|
||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(newType)
|
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(newType)
|
||||||
.setFilterString(filterString).setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE),
|
.setFilterString(filterString).setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE),
|
||||||
Arrays.asList(dsNewType));
|
singletonList(dsNewType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
@@ -933,11 +934,11 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(standardDsType)
|
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(standardDsType)
|
||||||
.setSearchText(text).setTagNames(Arrays.asList(dsTagA.getName())),
|
.setSearchText(text).setTagNames(singletonList(dsTagA.getName())),
|
||||||
completedAndStandartTypeAndSearchTextAndTagA);
|
completedAndStandartTypeAndSearchTextAndTagA);
|
||||||
|
|
||||||
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setType(standardDsType)
|
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setType(standardDsType)
|
||||||
.setSearchText(text).setTagNames(Arrays.asList(dsTagA.getName())).setIsComplete(Boolean.FALSE)
|
.setSearchText(text).setTagNames(singletonList(dsTagA.getName())).setIsComplete(Boolean.FALSE)
|
||||||
.setIsDeleted(Boolean.FALSE));
|
.setIsDeleted(Boolean.FALSE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -954,7 +955,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
private void assertThatFilterDoesNotContainAnyDistributionSet(final DistributionSetFilterBuilder filterBuilder) {
|
private void assertThatFilterDoesNotContainAnyDistributionSet(final DistributionSetFilterBuilder filterBuilder) {
|
||||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
||||||
.hasSize(0);
|
.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
private void assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||||
@@ -965,7 +966,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Simple DS load without the related data that should be loaded lazy.")
|
@Description("Simple DS load without the related data that should be loaded lazy.")
|
||||||
public void findDistributionSetsWithoutLazy() {
|
void findDistributionSetsWithoutLazy() {
|
||||||
testdataFactory.createDistributionSets(20);
|
testdataFactory.createDistributionSets(20);
|
||||||
|
|
||||||
assertThat(distributionSetManagement.findByCompleted(PAGE, true)).hasSize(20);
|
assertThat(distributionSetManagement.findByCompleted(PAGE, true)).hasSize(20);
|
||||||
@@ -973,7 +974,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Deltes a DS that is no in use. Expected behaviour is a hard delete on the database.")
|
@Description("Deltes a DS that is no in use. Expected behaviour is a hard delete on the database.")
|
||||||
public void deleteUnassignedDistributionSet() {
|
void deleteUnassignedDistributionSet() {
|
||||||
final DistributionSet ds1 = testdataFactory.createDistributionSet("ds-1");
|
final DistributionSet ds1 = testdataFactory.createDistributionSet("ds-1");
|
||||||
testdataFactory.createDistributionSet("ds-2");
|
testdataFactory.createDistributionSet("ds-2");
|
||||||
|
|
||||||
@@ -987,7 +988,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Deletes an invalid distribution set")
|
@Description("Deletes an invalid distribution set")
|
||||||
public void deleteInvalidDistributionSet() {
|
void deleteInvalidDistributionSet() {
|
||||||
final DistributionSet set = testdataFactory.createAndInvalidateDistributionSet();
|
final DistributionSet set = testdataFactory.createAndInvalidateDistributionSet();
|
||||||
assertThat(distributionSetRepository.findById(set.getId())).isNotEmpty();
|
assertThat(distributionSetRepository.findById(set.getId())).isNotEmpty();
|
||||||
distributionSetManagement.delete(set.getId());
|
distributionSetManagement.delete(set.getId());
|
||||||
@@ -996,7 +997,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Deletes an incomplete distribution set")
|
@Description("Deletes an incomplete distribution set")
|
||||||
public void deleteIncompleteDistributionSet() {
|
void deleteIncompleteDistributionSet() {
|
||||||
final DistributionSet set = testdataFactory.createIncompleteDistributionSet();
|
final DistributionSet set = testdataFactory.createIncompleteDistributionSet();
|
||||||
assertThat(distributionSetRepository.findById(set.getId())).isNotEmpty();
|
assertThat(distributionSetRepository.findById(set.getId())).isNotEmpty();
|
||||||
distributionSetManagement.delete(set.getId());
|
distributionSetManagement.delete(set.getId());
|
||||||
@@ -1005,7 +1006,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Queries and loads the metadata related to a given software module.")
|
@Description("Queries and loads the metadata related to a given software module.")
|
||||||
public void findAllDistributionSetMetadataByDsId() {
|
void findAllDistributionSetMetadataByDsId() {
|
||||||
// create a DS
|
// create a DS
|
||||||
final DistributionSet ds1 = testdataFactory.createDistributionSet("testDs1");
|
final DistributionSet ds1 = testdataFactory.createDistributionSet("testDs1");
|
||||||
final DistributionSet ds2 = testdataFactory.createDistributionSet("testDs2");
|
final DistributionSet ds2 = testdataFactory.createDistributionSet("testDs2");
|
||||||
@@ -1036,7 +1037,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Deletes a DS that is in use by either target assignment or rollout. Expected behaviour is a soft delete on the database, i.e. only marked as "
|
@Description("Deletes a DS that is in use by either target assignment or rollout. Expected behaviour is a soft delete on the database, i.e. only marked as "
|
||||||
+ "deleted, kept as reference but unavailable for future use..")
|
+ "deleted, kept as reference but unavailable for future use..")
|
||||||
public void deleteAssignedDistributionSet() {
|
void deleteAssignedDistributionSet() {
|
||||||
testdataFactory.createDistributionSet("ds-1");
|
testdataFactory.createDistributionSet("ds-1");
|
||||||
testdataFactory.createDistributionSet("ds-2");
|
testdataFactory.createDistributionSet("ds-2");
|
||||||
final DistributionSet dsToTargetAssigned = testdataFactory.createDistributionSet("ds-3");
|
final DistributionSet dsToTargetAssigned = testdataFactory.createDistributionSet("ds-3");
|
||||||
@@ -1062,7 +1063,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Verify that the find all by ids contains the entities which are looking for")
|
@Description("Verify that the find all by ids contains the entities which are looking for")
|
||||||
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 12),
|
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 12),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 36) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 36) })
|
||||||
public void verifyFindDistributionSetAllById() {
|
void verifyFindDistributionSetAllById() {
|
||||||
final List<Long> searchIds = new ArrayList<>();
|
final List<Long> searchIds = new ArrayList<>();
|
||||||
searchIds.add(testdataFactory.createDistributionSet("ds-4").getId());
|
searchIds.add(testdataFactory.createDistributionSet("ds-4").getId());
|
||||||
searchIds.add(testdataFactory.createDistributionSet("ds-5").getId());
|
searchIds.add(testdataFactory.createDistributionSet("ds-5").getId());
|
||||||
@@ -1081,7 +1082,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that an exception is thrown when trying to get an invalid distribution set")
|
@Description("Verify that an exception is thrown when trying to get an invalid distribution set")
|
||||||
public void verifyGetValid() {
|
void verifyGetValid() {
|
||||||
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
||||||
@@ -1094,7 +1095,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that an exception is thrown when trying to get an incomplete distribution set")
|
@Description("Verify that an exception is thrown when trying to get an incomplete distribution set")
|
||||||
public void verifyGetValidAndComplete() {
|
void verifyGetValidAndComplete() {
|
||||||
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
|
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
|
||||||
|
|
||||||
assertThatExceptionOfType(IncompleteDistributionSetException.class)
|
assertThatExceptionOfType(IncompleteDistributionSetException.class)
|
||||||
@@ -1104,7 +1105,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that an exception is thrown when trying to create or update metadata for an invalid distribution set.")
|
@Description("Verify that an exception is thrown when trying to create or update metadata for an invalid distribution set.")
|
||||||
public void createMetadataForInvalidDistributionSet() {
|
void createMetadataForInvalidDistributionSet() {
|
||||||
final String knownKey1 = "myKnownKey1";
|
final String knownKey1 = "myKnownKey1";
|
||||||
final String knownKey2 = "myKnownKey2";
|
final String knownKey2 = "myKnownKey2";
|
||||||
final String knownValue = "myKnownValue";
|
final String knownValue = "myKnownValue";
|
||||||
@@ -1112,16 +1113,16 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet();
|
final DistributionSet ds = testdataFactory.createDistributionSet();
|
||||||
distributionSetManagement.createMetaData(ds.getId(),
|
distributionSetManagement.createMetaData(ds.getId(),
|
||||||
Collections.singletonList(entityFactory.generateDsMetadata(knownKey1, knownValue)));
|
singletonList(entityFactory.generateDsMetadata(knownKey1, knownValue)));
|
||||||
|
|
||||||
distributionSetInvalidationManagement.invalidateDistributionSet(
|
distributionSetInvalidationManagement.invalidateDistributionSet(
|
||||||
new DistributionSetInvalidation(Arrays.asList(ds.getId()), CancelationType.NONE, false));
|
new DistributionSetInvalidation(singletonList(ds.getId()), CancelationType.NONE, false));
|
||||||
|
|
||||||
// assert that no new metadata can be created
|
// assert that no new metadata can be created
|
||||||
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
||||||
.as("Invalid distributionSet should throw an exception")
|
.as("Invalid distributionSet should throw an exception")
|
||||||
.isThrownBy(() -> distributionSetManagement.createMetaData(ds.getId(),
|
.isThrownBy(() -> distributionSetManagement.createMetaData(ds.getId(),
|
||||||
Collections.singletonList(entityFactory.generateDsMetadata(knownKey2, knownValue))));
|
singletonList(entityFactory.generateDsMetadata(knownKey2, knownValue))));
|
||||||
|
|
||||||
// assert that an existing metadata can not be updated
|
// assert that an existing metadata can not be updated
|
||||||
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
||||||
@@ -1129,4 +1130,8 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
.updateMetaData(ds.getId(), entityFactory.generateDsMetadata(knownKey1, knownUpdateValue)));
|
.updateMetaData(ds.getId(), entityFactory.generateDsMetadata(knownKey1, knownUpdateValue)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// can be removed with java-11
|
||||||
|
private <T> T getOrThrow(Optional<T> opt) {
|
||||||
|
return opt.orElseThrow(NoSuchElementException::new);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.validation.ConstraintViolationException;
|
import javax.validation.ConstraintViolationException;
|
||||||
|
|
||||||
@@ -27,8 +27,8 @@ import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreated
|
|||||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTypeCreatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTypeCreatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
|
|
||||||
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
||||||
|
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||||
@@ -70,16 +70,19 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
|
|||||||
@Expect(type = DistributionSetTypeCreatedEvent.class, count = 1) })
|
@Expect(type = DistributionSetTypeCreatedEvent.class, count = 1) })
|
||||||
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
||||||
|
|
||||||
|
final List<Long> softwareModuleTypes = Collections.singletonList(osType.getId());
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(NOT_EXIST_IDL,
|
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(NOT_EXIST_IDL,
|
||||||
Arrays.asList(osType.getId())), "DistributionSetType");
|
softwareModuleTypes), "DistributionSetType");
|
||||||
|
final List<Long> notExistingSwModuleTypeIds = Collections.singletonList(NOT_EXIST_IDL);
|
||||||
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(
|
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(
|
||||||
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), Arrays.asList(NOT_EXIST_IDL)),
|
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), notExistingSwModuleTypeIds),
|
||||||
"SoftwareModuleType");
|
"SoftwareModuleType");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(NOT_EXIST_IDL,
|
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(NOT_EXIST_IDL,
|
||||||
Arrays.asList(osType.getId())), "DistributionSetType");
|
softwareModuleTypes), "DistributionSetType");
|
||||||
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(
|
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(
|
||||||
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), Arrays.asList(NOT_EXIST_IDL)),
|
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), notExistingSwModuleTypeIds),
|
||||||
"SoftwareModuleType");
|
"SoftwareModuleType");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> distributionSetTypeManagement.delete(NOT_EXIST_IDL), "DistributionSetType");
|
verifyThrownExceptionBy(() -> distributionSetTypeManagement.delete(NOT_EXIST_IDL), "DistributionSetType");
|
||||||
@@ -106,99 +109,91 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
|
|||||||
private void createAndUpdateDistributionSetWithInvalidDescription(final DistributionSet set) {
|
private void createAndUpdateDistributionSetWithInvalidDescription(final DistributionSet set) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("set with too long description should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||||
.version("a").description(RandomStringUtils.randomAlphanumeric(513))))
|
.version("a").description(RandomStringUtils.randomAlphanumeric(513))));
|
||||||
.as("set with too long description should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("set invalid description text should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement.create(
|
.isThrownBy(() -> distributionSetManagement.create(
|
||||||
entityFactory.distributionSet().create().name("a").version("a").description(INVALID_TEXT_HTML)))
|
entityFactory.distributionSet().create().name("a").version("a")
|
||||||
.as("set invalid description text should not be created");
|
.description(INVALID_TEXT_HTML)));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("set with too long description should not be updated")
|
||||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||||
.description(RandomStringUtils.randomAlphanumeric(513))))
|
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||||
.as("set with too long description should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> distributionSetManagement
|
.as("set with invalid description should not be updated").isThrownBy(() -> distributionSetManagement
|
||||||
.update(entityFactory.distributionSet().update(set.getId()).description(INVALID_TEXT_HTML)))
|
.update(entityFactory.distributionSet().update(set.getId()).description(INVALID_TEXT_HTML)));
|
||||||
.as("set with invalid description should not be updated");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createAndUpdateDistributionSetWithInvalidName(final DistributionSet set) {
|
private void createAndUpdateDistributionSetWithInvalidName(final DistributionSet set) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class).as("set with too long name should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a")
|
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a")
|
||||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))))
|
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||||
.as("set with too long name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class).as("set with invalid name should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement
|
.isThrownBy(() -> distributionSetManagement
|
||||||
.create(entityFactory.distributionSet().create().version("a").name(INVALID_TEXT_HTML)))
|
.create(entityFactory.distributionSet().create().version("a").name(INVALID_TEXT_HTML)));
|
||||||
.as("set with invalid name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
|
||||||
() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a").name("")))
|
|
||||||
.as("set with too short name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("set with too short name should not be created").isThrownBy(() -> distributionSetManagement
|
||||||
|
.create(entityFactory.distributionSet().create().version("a").name("")));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class).as("set with null name should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement
|
.isThrownBy(() -> distributionSetManagement
|
||||||
.create(entityFactory.distributionSet().create().version("a").name(null)))
|
.create(entityFactory.distributionSet().create().version("a").name(null)));
|
||||||
.as("set with null name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class).as("set with too long name should not be updated")
|
||||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))))
|
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||||
.as("set with too long name should not be updated");
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class).as("set with invalid name should not be updated")
|
||||||
|
.isThrownBy(() -> distributionSetManagement
|
||||||
|
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> distributionSetManagement
|
.as("set with too short name should not be updated").isThrownBy(() -> distributionSetManagement
|
||||||
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)))
|
.update(entityFactory.distributionSet().update(set.getId()).name("")));
|
||||||
.as("set with invalid name should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
|
||||||
() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId()).name("")))
|
|
||||||
.as("set with too short name should not be updated");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createAndUpdateDistributionSetWithInvalidVersion(final DistributionSet set) {
|
private void createAndUpdateDistributionSetWithInvalidVersion(final DistributionSet set) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("set with too long version should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))))
|
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||||
.as("set with too long version should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("set with invalid version should not be created").isThrownBy(() -> distributionSetManagement
|
||||||
|
.create(entityFactory.distributionSet().create().name("a").version(INVALID_TEXT_HTML)));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("set with too short version should not be created").isThrownBy(() -> distributionSetManagement
|
||||||
|
.create(entityFactory.distributionSet().create().name("a").version("")));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class).as("set with null version should not be created")
|
||||||
.isThrownBy(() -> distributionSetManagement
|
.isThrownBy(() -> distributionSetManagement
|
||||||
.create(entityFactory.distributionSet().create().name("a").version(INVALID_TEXT_HTML)))
|
.create(entityFactory.distributionSet().create().name("a").version(null)));
|
||||||
.as("set with invalid version should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
|
||||||
() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a").version("")))
|
|
||||||
.as("set with too short version should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
|
||||||
.isThrownBy(() -> distributionSetManagement
|
|
||||||
.create(entityFactory.distributionSet().create().name("a").version(null)))
|
|
||||||
.as("set with null version should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("set with too long version should not be updated")
|
||||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))))
|
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||||
.as("set with too long version should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> distributionSetManagement
|
.as("set with invalid version should not be updated").isThrownBy(() -> distributionSetManagement
|
||||||
.update(entityFactory.distributionSet().update(set.getId()).version(INVALID_TEXT_HTML)))
|
.update(entityFactory.distributionSet().update(set.getId()).version(INVALID_TEXT_HTML)));
|
||||||
.as("set with invalid version should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId()).version("")))
|
.as("set with too short version should not be updated").isThrownBy(() -> distributionSetManagement
|
||||||
.as("set with too short version should not be updated");
|
.update(entityFactory.distributionSet().update(set.getId()).version("")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -278,11 +273,7 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
|
|||||||
@Test
|
@Test
|
||||||
@Description("Tests the successfull update of used distribution set type meta data which is in fact allowed.")
|
@Description("Tests the successfull update of used distribution set type meta data which is in fact allowed.")
|
||||||
public void updateAssignedDistributionSetTypeMetaData() {
|
public void updateAssignedDistributionSetTypeMetaData() {
|
||||||
final DistributionSetType nonUpdatableType = distributionSetTypeManagement.create(entityFactory
|
final DistributionSetType nonUpdatableType = createDistributionSetTypeUsedByDs();
|
||||||
.distributionSetType().create().key("updatableType").name("to be deleted").colour("test123"));
|
|
||||||
assertThat(distributionSetTypeManagement.getByKey("updatableType").get().getMandatoryModuleTypes()).isEmpty();
|
|
||||||
distributionSetManagement.create(entityFactory.distributionSet().create().name("newtypesoft").version("1")
|
|
||||||
.type(nonUpdatableType.getKey()));
|
|
||||||
|
|
||||||
distributionSetTypeManagement.update(
|
distributionSetTypeManagement.update(
|
||||||
entityFactory.distributionSetType().update(nonUpdatableType.getId()).description("a new description"));
|
entityFactory.distributionSetType().update(nonUpdatableType.getId()).description("a new description"));
|
||||||
@@ -295,17 +286,22 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
|
|||||||
@Test
|
@Test
|
||||||
@Description("Tests the unsuccessfull update of used distribution set type (module addition).")
|
@Description("Tests the unsuccessfull update of used distribution set type (module addition).")
|
||||||
public void addModuleToAssignedDistributionSetTypeFails() {
|
public void addModuleToAssignedDistributionSetTypeFails() {
|
||||||
final DistributionSetType nonUpdatableType = distributionSetTypeManagement
|
final DistributionSetType nonUpdatableType = createDistributionSetTypeUsedByDs();
|
||||||
.create(entityFactory.distributionSetType().create().key("updatableType").name("to be deleted"));
|
|
||||||
assertThat(distributionSetTypeManagement.getByKey("updatableType").get().getMandatoryModuleTypes()).isEmpty();
|
|
||||||
distributionSetManagement.create(entityFactory.distributionSet().create().name("newtypesoft").version("1")
|
|
||||||
.type(nonUpdatableType.getKey()));
|
|
||||||
|
|
||||||
assertThatThrownBy(() -> distributionSetTypeManagement
|
assertThatThrownBy(() -> distributionSetTypeManagement
|
||||||
.assignMandatorySoftwareModuleTypes(nonUpdatableType.getId(), Sets.newHashSet(osType.getId())))
|
.assignMandatorySoftwareModuleTypes(nonUpdatableType.getId(), Sets.newHashSet(osType.getId())))
|
||||||
.isInstanceOf(EntityReadOnlyException.class);
|
.isInstanceOf(EntityReadOnlyException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DistributionSetType createDistributionSetTypeUsedByDs() {
|
||||||
|
final DistributionSetType nonUpdatableType = distributionSetTypeManagement.create(entityFactory
|
||||||
|
.distributionSetType().create().key("updatableType").name("to be deleted").colour("test123"));
|
||||||
|
assertThat(distributionSetTypeManagement.getByKey("updatableType").get().getMandatoryModuleTypes()).isEmpty();
|
||||||
|
distributionSetManagement.create(entityFactory.distributionSet().create().name("newtypesoft").version("1")
|
||||||
|
.type(nonUpdatableType.getKey()));
|
||||||
|
return nonUpdatableType;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the unsuccessfull update of used distribution set type (module removal).")
|
@Description("Tests the unsuccessfull update of used distribution set type (module removal).")
|
||||||
public void removeModuleToAssignedDistributionSetTypeFails() {
|
public void removeModuleToAssignedDistributionSetTypeFails() {
|
||||||
@@ -338,15 +334,17 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
|
|||||||
@Test
|
@Test
|
||||||
@Description("Tests the successfull deletion of used (soft delete) distribution set types.")
|
@Description("Tests the successfull deletion of used (soft delete) distribution set types.")
|
||||||
public void deleteAssignedDistributionSetType() {
|
public void deleteAssignedDistributionSetType() {
|
||||||
final JpaDistributionSetType softDelete = (JpaDistributionSetType) distributionSetTypeManagement
|
final JpaDistributionSetType toBeDeleted = (JpaDistributionSetType) distributionSetTypeManagement
|
||||||
.create(entityFactory.distributionSetType().create().key("softdeleted").name("to be deleted"));
|
.create(entityFactory.distributionSetType().create().key("softdeleted").name("to be deleted"));
|
||||||
|
|
||||||
assertThat(distributionSetTypeRepository.findAll()).contains(softDelete);
|
assertThat(distributionSetTypeRepository.findAll()).contains(toBeDeleted);
|
||||||
distributionSetManagement.create(
|
distributionSetManagement.create(
|
||||||
entityFactory.distributionSet().create().name("softdeleted").version("1").type(softDelete.getKey()));
|
entityFactory.distributionSet().create().name("softdeleted").version("1").type(toBeDeleted.getKey()));
|
||||||
|
|
||||||
distributionSetTypeManagement.delete(softDelete.getId());
|
distributionSetTypeManagement.delete(toBeDeleted.getId());
|
||||||
assertThat(distributionSetTypeManagement.getByKey("softdeleted").get().isDeleted()).isEqualTo(true);
|
final Optional<DistributionSetType> softdeleted = distributionSetTypeManagement.getByKey("softdeleted");
|
||||||
|
assertThat(softdeleted).isPresent();
|
||||||
|
assertThat(softdeleted.get().isDeleted()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -17,17 +17,18 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.validation.ConstraintViolationException;
|
import javax.validation.ConstraintViolationException;
|
||||||
import javax.validation.ValidationException;
|
import javax.validation.ValidationException;
|
||||||
|
|
||||||
import org.assertj.core.api.Assertions;
|
import org.assertj.core.api.Assertions;
|
||||||
import org.assertj.core.api.Condition;
|
import org.assertj.core.api.Condition;
|
||||||
|
import org.awaitility.Awaitility;
|
||||||
|
import org.awaitility.Duration;
|
||||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
||||||
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
|
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
|
||||||
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
|
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
|
||||||
@@ -54,8 +55,6 @@ import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledExcep
|
|||||||
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
|
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
|
||||||
import org.eclipse.hawkbit.repository.jpa.utils.MultipleInvokeHelper;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.utils.SuccessCondition;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||||
@@ -76,6 +75,7 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
|||||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||||
|
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -138,9 +138,9 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a running action is auto canceled by a rollout which assigns another distribution-set.")
|
@Description("Verifies that a running action is auto canceled by a rollout which assigns another distribution-set.")
|
||||||
void rolloutAssignesNewDistributionSetAndAutoCloseActiveActions() {
|
void rolloutAssignsNewDistributionSetAndAutoCloseActiveActions() {
|
||||||
tenantConfigurationManagement
|
tenantConfigurationManagement.addOrUpdateConfiguration(
|
||||||
.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
|
TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// manually assign distribution set to target
|
// manually assign distribution set to target
|
||||||
@@ -182,7 +182,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verifies that management get access reacts as specified on calls for non existing entities by means "
|
@Description("Verifies that management get access reacts as specified on calls for non existing entities by means "
|
||||||
+ "of Optional not present.")
|
+ "of Optional not present.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
void nonExistingEntityAccessReturnsNotPresent() {
|
void nonExistingEntityAccessReturnsNotPresent() {
|
||||||
assertThat(rolloutManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
assertThat(rolloutManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
||||||
assertThat(rolloutManagement.getByName(NOT_EXIST_ID)).isNotPresent();
|
assertThat(rolloutManagement.getByName(NOT_EXIST_ID)).isNotPresent();
|
||||||
@@ -192,7 +192,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verifies that management queries react as specified on calls for non existing entities "
|
@Description("Verifies that management queries react as specified on calls for non existing entities "
|
||||||
+ " by means of throwing EntityNotFoundException.")
|
+ " by means of throwing EntityNotFoundException.")
|
||||||
@ExpectEvents({ @Expect(type = RolloutDeletedEvent.class, count = 0),
|
@ExpectEvents({ @Expect(type = RolloutDeletedEvent.class),
|
||||||
@Expect(type = RolloutGroupCreatedEvent.class, count = 10),
|
@Expect(type = RolloutGroupCreatedEvent.class, count = 10),
|
||||||
@Expect(type = RolloutGroupUpdatedEvent.class, count = 10),
|
@Expect(type = RolloutGroupUpdatedEvent.class, count = 10),
|
||||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||||
@@ -225,7 +225,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// verify the split of the target and targetGroup
|
// verify the split of the target and targetGroup
|
||||||
final Page<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId());
|
final Page<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId());
|
||||||
// we have total of #amountTargetsForRollout in rollouts splitted in
|
// we have total of #amountTargetsForRollout in rollouts split in
|
||||||
// group size #groupSize
|
// group size #groupSize
|
||||||
assertThat(rolloutGroups).hasSize(amountGroups);
|
assertThat(rolloutGroups).hasSize(amountGroups);
|
||||||
}
|
}
|
||||||
@@ -254,11 +254,10 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
scheduledGroups.forEach(group -> assertThat(group.getStatus())
|
scheduledGroups.forEach(group -> assertThat(group.getStatus())
|
||||||
.as("group which should be in scheduled state is in " + group.getStatus() + " state")
|
.as("group which should be in scheduled state is in " + group.getStatus() + " state")
|
||||||
.isEqualTo(RolloutGroupStatus.SCHEDULED));
|
.isEqualTo(RolloutGroupStatus.SCHEDULED));
|
||||||
// verify that the first group actions has been started and are in state
|
// verify that the first group actions has been started and are in state running
|
||||||
// running
|
|
||||||
final List<Action> runningActions = findActionsByRolloutAndStatus(createdRollout, Status.RUNNING);
|
final List<Action> runningActions = findActionsByRolloutAndStatus(createdRollout, Status.RUNNING);
|
||||||
assertThat(runningActions).hasSize(amountTargetsForRollout / amountGroups);
|
assertThat(runningActions).hasSize(amountTargetsForRollout / amountGroups)
|
||||||
assertThat(runningActions).as("Created actions are initiated by rollout creator")
|
.as("Created actions are initiated by rollout creator")
|
||||||
.allMatch(a -> a.getInitiatedBy().equals(createdRollout.getCreatedBy()));
|
.allMatch(a -> a.getInitiatedBy().equals(createdRollout.getCreatedBy()));
|
||||||
// the rest targets are only scheduled
|
// the rest targets are only scheduled
|
||||||
assertThat(findActionsByRolloutAndStatus(createdRollout, Status.SCHEDULED))
|
assertThat(findActionsByRolloutAndStatus(createdRollout, Status.SCHEDULED))
|
||||||
@@ -308,7 +307,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
// @Title("Deleting targets of a rollout")
|
// @Title("Deleting targets of a rollout")
|
||||||
@Description("Verfiying that next group is started when targets of the group have been deleted.")
|
@Description("Verifying that next group is started when targets of the group have been deleted.")
|
||||||
void checkRunningRolloutsStartsNextGroupIfTargetsDeleted() {
|
void checkRunningRolloutsStartsNextGroupIfTargetsDeleted() {
|
||||||
|
|
||||||
final int amountTargetsForRollout = 15;
|
final int amountTargetsForRollout = 15;
|
||||||
@@ -342,7 +341,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// Run here, because scheduler is disabled during tests
|
// Run here, because scheduler is disabled during tests
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
return rolloutManagement.get(createdRollout.getId()).get();
|
return reloadRollout(createdRollout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step("Finish three actions of the rollout group and delete two targets")
|
@Step("Finish three actions of the rollout group and delete two targets")
|
||||||
@@ -399,7 +398,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||||
assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||||
assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||||
assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()).isEqualTo(RolloutStatus.FINISHED);
|
assertThat(reloadRollout(createdRollout).getStatus()).isEqualTo(RolloutStatus.FINISHED);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,7 +408,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfiying that the error handling action of a group is executed to pause the current rollout")
|
@Description("Verifying that the error handling action of a group is executed to pause the current rollout")
|
||||||
void checkErrorHitOfGroupCallsErrorActionToPauseTheRollout() {
|
void checkErrorHitOfGroupCallsErrorActionToPauseTheRollout() {
|
||||||
final int amountTargetsForRollout = 10;
|
final int amountTargetsForRollout = 10;
|
||||||
final int amountOtherTargets = 15;
|
final int amountOtherTargets = 15;
|
||||||
@@ -433,7 +432,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// and should execute the error action
|
// and should execute the error action
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
final Rollout rollout = rolloutManagement.get(createdRollout.getId()).get();
|
final Rollout rollout = reloadRollout(createdRollout);
|
||||||
// the rollout itself should be in paused based on the error action
|
// the rollout itself should be in paused based on the error action
|
||||||
assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.PAUSED);
|
assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.PAUSED);
|
||||||
|
|
||||||
@@ -452,7 +451,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfiying a paused rollout in case of error action hit can be resumed again")
|
@Description("Verifying a paused rollout in case of error action hit can be resumed again")
|
||||||
void errorActionPausesRolloutAndRolloutGetsResumedStartsNextScheduledGroup() {
|
void errorActionPausesRolloutAndRolloutGetsResumedStartsNextScheduledGroup() {
|
||||||
final int amountTargetsForRollout = 10;
|
final int amountTargetsForRollout = 10;
|
||||||
final int amountOtherTargets = 15;
|
final int amountOtherTargets = 15;
|
||||||
@@ -475,7 +474,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// and should execute the error action
|
// and should execute the error action
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
final Rollout rollout = rolloutManagement.get(createdRollout.getId()).get();
|
final Rollout rollout = reloadRollout(createdRollout);
|
||||||
// the rollout itself should be in paused based on the error action
|
// the rollout itself should be in paused based on the error action
|
||||||
assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.PAUSED);
|
assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.PAUSED);
|
||||||
|
|
||||||
@@ -489,7 +488,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
rolloutManagement.resumeRollout(createdRollout.getId());
|
rolloutManagement.resumeRollout(createdRollout.getId());
|
||||||
|
|
||||||
// the rollout should be running again
|
// the rollout should be running again
|
||||||
assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()).isEqualTo(RolloutStatus.RUNNING);
|
assertThat(reloadRollout(createdRollout).getStatus()).isEqualTo(RolloutStatus.RUNNING);
|
||||||
|
|
||||||
// checking rollouts again
|
// checking rollouts again
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
@@ -503,7 +502,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfiying that the rollout is starting group after group and gets finished at the end")
|
@Description("Verifying that the rollout is starting group after group and gets finished at the end")
|
||||||
void rolloutStartsGroupAfterGroupAndGetsFinished() {
|
void rolloutStartsGroupAfterGroupAndGetsFinished() {
|
||||||
final int amountTargetsForRollout = 10;
|
final int amountTargetsForRollout = 10;
|
||||||
final int amountOtherTargets = 15;
|
final int amountOtherTargets = 15;
|
||||||
@@ -522,7 +521,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
// finish running actions, 2 actions should be finished
|
// finish running actions, 2 actions should be finished
|
||||||
assertThat(changeStatusForAllRunningActions(createdRollout, Status.FINISHED)).isEqualTo(2);
|
assertThat(changeStatusForAllRunningActions(createdRollout, Status.FINISHED)).isEqualTo(2);
|
||||||
assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus())
|
assertThat(getRollout(createdRollout.getId()).getStatus())
|
||||||
.isEqualTo(RolloutStatus.RUNNING);
|
.isEqualTo(RolloutStatus.RUNNING);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -536,7 +535,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.FINISHED));
|
.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.FINISHED));
|
||||||
|
|
||||||
// verify that rollout itself is in finished state
|
// verify that rollout itself is in finished state
|
||||||
final Rollout findRolloutById = rolloutManagement.get(createdRollout.getId()).get();
|
final Rollout findRolloutById = reloadRollout(createdRollout);
|
||||||
assertThat(findRolloutById.getStatus()).isEqualTo(RolloutStatus.FINISHED);
|
assertThat(findRolloutById.getStatus()).isEqualTo(RolloutStatus.FINISHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,7 +725,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// round(7/3)=2 targets running (Group 3)
|
// round(7/3)=2 targets running (Group 3)
|
||||||
// round(5/2)=3 targets SCHEDULED (Group 3)
|
// round(5/2)=3 targets SCHEDULED (Group 3)
|
||||||
// round(2/1)=2 targets SCHEDULED (Group 4)
|
// round(2/1)=2 targets SCHEDULED (Group 4)
|
||||||
createdRollout = rolloutManagement.get(createdRollout.getId()).get();
|
createdRollout = reloadRollout(createdRollout);
|
||||||
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId())
|
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId())
|
||||||
.getContent();
|
.getContent();
|
||||||
|
|
||||||
@@ -761,7 +760,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
successCondition, errorCondition);
|
successCondition, errorCondition);
|
||||||
final DistributionSet ds = createdRollout.getDistributionSet();
|
final DistributionSet ds = createdRollout.getDistributionSet();
|
||||||
|
|
||||||
createdRollout = rolloutManagement.get(createdRollout.getId()).get();
|
createdRollout = reloadRollout(createdRollout);
|
||||||
// 5 targets are running
|
// 5 targets are running
|
||||||
final List<Action> runningActions = findActionsByRolloutAndStatus(createdRollout, Status.RUNNING);
|
final List<Action> runningActions = findActionsByRolloutAndStatus(createdRollout, Status.RUNNING);
|
||||||
assertThat(runningActions.size()).isEqualTo(5);
|
assertThat(runningActions.size()).isEqualTo(5);
|
||||||
@@ -803,7 +802,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
|
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
|
||||||
successCondition, errorCondition);
|
successCondition, errorCondition);
|
||||||
|
|
||||||
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
|
rolloutOne = reloadRollout(rolloutOne);
|
||||||
|
|
||||||
final DistributionSet dsForRolloutTwo = testdataFactory.createDistributionSet("dsForRolloutTwo");
|
final DistributionSet dsForRolloutTwo = testdataFactory.createDistributionSet("dsForRolloutTwo");
|
||||||
|
|
||||||
@@ -834,7 +833,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that error status of DistributionSet installation during rollout can get rerun with second rollout so that all targets have some DistributionSet installed at the end.")
|
@Description("Verify that error status of DistributionSet installation during rollout can get rerun with second rollout so that all targets have some DistributionSet installed at the end.")
|
||||||
void startSecondRolloutAfterFristRolloutEndenWithErrors() {
|
void startSecondRolloutAfterFirstRolloutEndsWithErrors() {
|
||||||
|
|
||||||
final int amountTargetsForRollout = 15;
|
final int amountTargetsForRollout = 15;
|
||||||
final int amountOtherTargets = 0;
|
final int amountOtherTargets = 0;
|
||||||
@@ -845,7 +844,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
successCondition, errorCondition);
|
successCondition, errorCondition);
|
||||||
final DistributionSet distributionSet = rolloutOne.getDistributionSet();
|
final DistributionSet distributionSet = rolloutOne.getDistributionSet();
|
||||||
|
|
||||||
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
|
rolloutOne = reloadRollout(rolloutOne);
|
||||||
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
||||||
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
@@ -862,7 +861,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.ERROR, 6L);
|
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.ERROR, 6L);
|
||||||
validateRolloutActionStatus(rolloutOne.getId(), expectedTargetCountStatus);
|
validateRolloutActionStatus(rolloutOne.getId(), expectedTargetCountStatus);
|
||||||
// rollout is finished
|
// rollout is finished
|
||||||
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
|
rolloutOne = reloadRollout(rolloutOne);
|
||||||
assertThat(rolloutOne.getStatus()).isEqualTo(RolloutStatus.FINISHED);
|
assertThat(rolloutOne.getStatus()).isEqualTo(RolloutStatus.FINISHED);
|
||||||
|
|
||||||
final int amountGroupsForRolloutTwo = 1;
|
final int amountGroupsForRolloutTwo = 1;
|
||||||
@@ -875,7 +874,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// Run here, because scheduler is disabled during tests
|
// Run here, because scheduler is disabled during tests
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
rolloutTwo = rolloutManagement.get(rolloutTwo.getId()).get();
|
rolloutTwo = reloadRollout(rolloutTwo);
|
||||||
// 6 error targets are now running
|
// 6 error targets are now running
|
||||||
expectedTargetCountStatus = createInitStatusMap();
|
expectedTargetCountStatus = createInitStatusMap();
|
||||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 6L);
|
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 6L);
|
||||||
@@ -902,21 +901,21 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
|
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
|
||||||
successCondition, errorCondition);
|
successCondition, errorCondition);
|
||||||
|
|
||||||
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
|
rolloutOne = reloadRollout(rolloutOne);
|
||||||
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
||||||
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
// verify: 40% error but 60% finished -> should move to next group
|
// verify: 40% error but 60% finished -> should move to next group
|
||||||
final List<RolloutGroup> rolloutGruops = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId())
|
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId())
|
||||||
.getContent();
|
.getContent();
|
||||||
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
||||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 5L);
|
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 5L);
|
||||||
validateRolloutGroupActionStatus(rolloutGruops.get(1), expectedTargetCountStatus);
|
validateRolloutGroupActionStatus(rolloutGroups.get(1), expectedTargetCountStatus);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that the rollout does not move to the next group when the sucess condition was not achieved.")
|
@Description("Verify that the rollout does not move to the next group when the success condition was not achieved.")
|
||||||
void successConditionNotAchieved() {
|
void successConditionNotAchieved() {
|
||||||
|
|
||||||
final int amountTargetsForRollout = 10;
|
final int amountTargetsForRollout = 10;
|
||||||
@@ -927,7 +926,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
|
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
|
||||||
successCondition, errorCondition);
|
successCondition, errorCondition);
|
||||||
|
|
||||||
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
|
rolloutOne = reloadRollout(rolloutOne);
|
||||||
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
||||||
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
@@ -952,12 +951,12 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
|
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
|
||||||
successCondition, errorCondition);
|
successCondition, errorCondition);
|
||||||
|
|
||||||
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
|
rolloutOne = reloadRollout(rolloutOne);
|
||||||
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
||||||
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
// verify: 40% error -> should pause because errorCondition is 20%
|
// verify: 40% error -> should pause because errorCondition is 20%
|
||||||
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
|
rolloutOne = reloadRollout(rolloutOne);
|
||||||
assertThat(rolloutOne.getStatus()).isEqualTo(RolloutStatus.PAUSED);
|
assertThat(rolloutOne.getStatus()).isEqualTo(RolloutStatus.PAUSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1138,7 +1137,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
changeStatusForRunningActions(myRollout, Status.FINISHED, 2);
|
changeStatusForRunningActions(myRollout, Status.FINISHED, 2);
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
myRollout = reloadRollout(myRollout);
|
||||||
|
|
||||||
float percent = rolloutGroupManagement
|
float percent = rolloutGroupManagement
|
||||||
.getWithDetailedStatus(
|
.getWithDetailedStatus(
|
||||||
@@ -1191,7 +1190,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
final Condition<String> targetBelongsInRollout = new Condition<>(s -> s.startsWith(rolloutName),
|
final Condition<String> targetBelongsInRollout = new Condition<>(s -> s.startsWith(rolloutName),
|
||||||
"Target belongs into rollout");
|
"Target belongs into rollout");
|
||||||
|
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
myRollout = reloadRollout(myRollout);
|
||||||
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId())
|
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId())
|
||||||
.getContent();
|
.getContent();
|
||||||
|
|
||||||
@@ -1258,22 +1257,22 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify the creation and the start of a Rollout with more groups than targets.")
|
@Description("Verify the creation and the start of a Rollout with more groups than targets.")
|
||||||
void createAndStartRolloutWithEmptyGroups() throws Exception {
|
void createAndStartRolloutWithEmptyGroups() {
|
||||||
final int amountTargetsForRollout = 3;
|
final int amountTargetsForRollout = 3;
|
||||||
final int amountGroups = 5;
|
final int amountGroups = 5;
|
||||||
final String successCondition = "50";
|
final String successCondition = "50";
|
||||||
final String errorCondition = "80";
|
final String errorCondition = "80";
|
||||||
final String rolloutName = "rolloutTestG";
|
final String rolloutName = "rolloutTestG";
|
||||||
final String targetPrefixName = rolloutName;
|
|
||||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
||||||
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
|
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
|
||||||
|
|
||||||
Rollout myRollout = testdataFactory.createRolloutByVariables(rolloutName, "desc", amountGroups,
|
Rollout myRollout = testdataFactory.createRolloutByVariables(rolloutName, "desc", amountGroups,
|
||||||
"controllerId==" + targetPrefixName + "-*", distributionSet, successCondition, errorCondition);
|
"controllerId==" + rolloutName + "-*", distributionSet, successCondition, errorCondition);
|
||||||
|
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||||
|
|
||||||
final List<RolloutGroup> groups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent();
|
final Long myRolloutId = myRollout.getId();
|
||||||
|
final List<RolloutGroup> groups = rolloutGroupManagement.findByRollout(PAGE, myRolloutId).getContent();
|
||||||
|
|
||||||
assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY);
|
assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY);
|
||||||
assertThat(groups.get(0).getTotalTargets()).isEqualTo(1);
|
assertThat(groups.get(0).getTotalTargets()).isEqualTo(1);
|
||||||
@@ -1286,69 +1285,62 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assertThat(groups.get(4).getStatus()).isEqualTo(RolloutGroupStatus.READY);
|
assertThat(groups.get(4).getStatus()).isEqualTo(RolloutGroupStatus.READY);
|
||||||
assertThat(groups.get(4).getTotalTargets()).isZero();
|
assertThat(groups.get(4).getTotalTargets()).isZero();
|
||||||
|
|
||||||
rolloutManagement.start(myRollout.getId());
|
rolloutManagement.start(myRolloutId);
|
||||||
|
|
||||||
// Run here, because scheduler is disabled during tests
|
// Run here, because scheduler is disabled during tests
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
final SuccessConditionRolloutStatus conditionRolloutStatus = new SuccessConditionRolloutStatus(
|
awaitRunningState(myRolloutId);
|
||||||
RolloutStatus.RUNNING);
|
|
||||||
assertThat(MultipleInvokeHelper.doWithTimeout(new RolloutStatusCallable(myRollout.getId()),
|
|
||||||
conditionRolloutStatus, 15000, 500)).as("Rollout status").isNotNull();
|
|
||||||
|
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
myRollout = getRollout(myRolloutId);
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING);
|
||||||
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
||||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 1L);
|
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 1L);
|
||||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 2L);
|
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 2L);
|
||||||
validateRolloutActionStatus(myRollout.getId(), expectedTargetCountStatus);
|
validateRolloutActionStatus(myRolloutId, expectedTargetCountStatus);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify the creation and the start of a rollout.")
|
@Description("Verify the creation and the start of a rollout.")
|
||||||
void createAndStartRollout() throws Exception {
|
void createAndStartRollout() {
|
||||||
|
|
||||||
final int amountTargetsForRollout = 50;
|
final int amountTargetsForRollout = 50;
|
||||||
final int amountGroups = 5;
|
final int amountGroups = 5;
|
||||||
final String successCondition = "50";
|
final String successCondition = "50";
|
||||||
final String errorCondition = "80";
|
final String errorCondition = "80";
|
||||||
final String rolloutName = "rolloutTest";
|
final String rolloutName = "rolloutTest";
|
||||||
final String targetPrefixName = rolloutName;
|
|
||||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
||||||
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
|
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
|
||||||
|
|
||||||
Rollout myRollout = testdataFactory.createRolloutByVariables(rolloutName, "desc", amountGroups,
|
Rollout myRollout = testdataFactory.createRolloutByVariables(rolloutName, "desc", amountGroups,
|
||||||
"controllerId==" + targetPrefixName + "-*", distributionSet, successCondition, errorCondition);
|
"controllerId==" + rolloutName + "-*", distributionSet, successCondition, errorCondition);
|
||||||
|
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||||
|
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
final Long myRolloutId = myRollout.getId();
|
||||||
|
myRollout = getRollout(myRolloutId);
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||||
|
|
||||||
rolloutManagement.start(myRollout.getId());
|
rolloutManagement.start(myRolloutId);
|
||||||
|
|
||||||
// Run here, because scheduler is disabled during tests
|
// Run here, because scheduler is disabled during tests
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
final SuccessConditionRolloutStatus conditionRolloutTargetCount = new SuccessConditionRolloutStatus(
|
awaitRunningState(myRolloutId);
|
||||||
RolloutStatus.RUNNING);
|
|
||||||
assertThat(MultipleInvokeHelper.doWithTimeout(new RolloutStatusCallable(myRollout.getId()),
|
|
||||||
conditionRolloutTargetCount, 15000, 500)).as("Rollout status").isNotNull();
|
|
||||||
|
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
myRollout = reloadRollout(myRollout);
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING);
|
||||||
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
||||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 10L);
|
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 10L);
|
||||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 40L);
|
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 40L);
|
||||||
validateRolloutActionStatus(myRollout.getId(), expectedTargetCountStatus);
|
validateRolloutActionStatus(myRolloutId, expectedTargetCountStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that a rollout cannot be created if the 'max targets per rollout group' quota is violated.")
|
@Description("Verify that a rollout cannot be created if the 'max targets per rollout group' quota is violated.")
|
||||||
void createRolloutFailsIfQuotaGroupQuotaIsViolated() throws Exception {
|
void createRolloutFailsIfQuotaGroupQuotaIsViolated() {
|
||||||
|
|
||||||
final int maxTargets = quotaManagement.getMaxTargetsPerRolloutGroup();
|
final int maxTargets = quotaManagement.getMaxTargetsPerRolloutGroup();
|
||||||
|
|
||||||
@@ -1375,15 +1367,14 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that a rollout cannot be created based on group definitions if the 'max targets per rollout group' quota is violated for one of the groups.")
|
@Description("Verify that a rollout cannot be created based on group definitions if the 'max targets per rollout group' quota is violated for one of the groups.")
|
||||||
void createRolloutWithGroupDefinitionsFailsIfQuotaGroupQuotaIsViolated() throws Exception {
|
void createRolloutWithGroupDefinitionsFailsIfQuotaGroupQuotaIsViolated() {
|
||||||
|
|
||||||
final int maxTargets = quotaManagement.getMaxTargetsPerRolloutGroup();
|
final int maxTargets = quotaManagement.getMaxTargetsPerRolloutGroup();
|
||||||
|
|
||||||
final int amountTargetsForRollout = maxTargets * 2 + 2;
|
final int amountTargetsForRollout = maxTargets * 2 + 2;
|
||||||
final String rolloutName = "rolloutTest";
|
final String rolloutName = "rolloutTest";
|
||||||
final String targetPrefixName = rolloutName;
|
|
||||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
||||||
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
|
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
|
||||||
|
|
||||||
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
||||||
|
|
||||||
@@ -1395,9 +1386,12 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// group1 exceeds the quota
|
// group1 exceeds the quota
|
||||||
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
|
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
|
||||||
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
|
entityFactory.rollout()
|
||||||
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").set(distributionSet),
|
.create()
|
||||||
Arrays.asList(group1, group2), conditions));
|
.name(rolloutName)
|
||||||
|
.description(rolloutName)
|
||||||
|
.targetFilterQuery("controllerId==" + rolloutName + "-*")
|
||||||
|
.set(distributionSet), Arrays.asList(group1, group2), conditions));
|
||||||
|
|
||||||
// create group definitions
|
// create group definitions
|
||||||
final RolloutGroupCreate group3 = entityFactory.rolloutGroup().create().conditions(conditions).name("group3")
|
final RolloutGroupCreate group3 = entityFactory.rolloutGroup().create().conditions(conditions).name("group3")
|
||||||
@@ -1407,74 +1401,93 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// group4 exceeds the quota
|
// group4 exceeds the quota
|
||||||
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
|
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
|
||||||
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
|
entityFactory.rollout()
|
||||||
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").set(distributionSet),
|
.create()
|
||||||
Arrays.asList(group3, group4), conditions));
|
.name(rolloutName)
|
||||||
|
.description(rolloutName)
|
||||||
|
.targetFilterQuery("controllerId==" + rolloutName + "-*")
|
||||||
|
.set(distributionSet), Arrays.asList(group3, group4), conditions));
|
||||||
|
|
||||||
// create group definitions
|
// create group definitions
|
||||||
final RolloutGroupCreate group5 = entityFactory.rolloutGroup().create().conditions(conditions).name("group5")
|
final RolloutGroupCreate group5 = entityFactory.rolloutGroup()
|
||||||
|
.create()
|
||||||
|
.conditions(conditions)
|
||||||
|
.name("group5")
|
||||||
.targetPercentage(33.3F);
|
.targetPercentage(33.3F);
|
||||||
final RolloutGroupCreate group6 = entityFactory.rolloutGroup().create().conditions(conditions).name("group6")
|
final RolloutGroupCreate group6 = entityFactory.rolloutGroup()
|
||||||
|
.create()
|
||||||
|
.conditions(conditions)
|
||||||
|
.name("group6")
|
||||||
.targetPercentage(66.6F);
|
.targetPercentage(66.6F);
|
||||||
final RolloutGroupCreate group7 = entityFactory.rolloutGroup().create().conditions(conditions).name("group7")
|
final RolloutGroupCreate group7 = entityFactory.rolloutGroup()
|
||||||
|
.create()
|
||||||
|
.conditions(conditions)
|
||||||
|
.name("group7")
|
||||||
.targetPercentage(100.0F);
|
.targetPercentage(100.0F);
|
||||||
|
|
||||||
// should work fine
|
// should work fine
|
||||||
assertThat(rolloutManagement.create(
|
assertThat(rolloutManagement.create(entityFactory.rollout()
|
||||||
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
|
.create()
|
||||||
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").set(distributionSet),
|
.name(rolloutName)
|
||||||
Arrays.asList(group5, group6, group7), conditions)).isNotNull();
|
.description(rolloutName)
|
||||||
|
.targetFilterQuery("controllerId==" + rolloutName + "-*")
|
||||||
|
.set(distributionSet), Arrays.asList(group5, group6, group7), conditions)).isNotNull();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify the creation and the automatic start of a rollout.")
|
@Description("Verify the creation and the automatic start of a rollout.")
|
||||||
void createAndAutoStartRollout() throws Exception {
|
void createAndAutoStartRollout() {
|
||||||
|
|
||||||
final int amountTargetsForRollout = 50;
|
final int amountTargetsForRollout = 50;
|
||||||
final int amountGroups = 5;
|
final int amountGroups = 5;
|
||||||
final String successCondition = "50";
|
final String successCondition = "50";
|
||||||
final String errorCondition = "80";
|
final String errorCondition = "80";
|
||||||
final String rolloutName = "rolloutTest8";
|
final String rolloutName = "rolloutTest8";
|
||||||
final String targetPrefixName = rolloutName;
|
|
||||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
||||||
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
|
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
|
||||||
|
|
||||||
Rollout myRollout = testdataFactory.createRolloutByVariables(rolloutName, "desc", amountGroups,
|
Rollout myRollout = testdataFactory.createRolloutByVariables(rolloutName, "desc", amountGroups,
|
||||||
"controllerId==" + targetPrefixName + "-*", distributionSet, successCondition, errorCondition);
|
"controllerId==" + rolloutName + "-*", distributionSet, successCondition, errorCondition);
|
||||||
|
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||||
|
|
||||||
// schedule rollout auto start into the future
|
// schedule rollout auto start into the future
|
||||||
|
final Long myRolloutId = myRollout.getId();
|
||||||
rolloutManagement
|
rolloutManagement
|
||||||
.update(entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis() + 60000));
|
.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis() + 60000));
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
// rollout should not have been started
|
// rollout should not have been started
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
myRollout = getRollout(myRolloutId);
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||||
|
|
||||||
// schedule to now
|
// schedule to now
|
||||||
rolloutManagement.update(entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis()));
|
rolloutManagement.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis()));
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
myRollout = getRollout(myRolloutId);
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.STARTING);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.STARTING);
|
||||||
|
|
||||||
// Run here, because scheduler is disabled during tests
|
// Run here, because scheduler is disabled during tests
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
final SuccessConditionRolloutStatus conditionRolloutTargetCount = new SuccessConditionRolloutStatus(
|
awaitRunningState(myRolloutId);
|
||||||
RolloutStatus.RUNNING);
|
|
||||||
assertThat(MultipleInvokeHelper.doWithTimeout(new RolloutStatusCallable(myRollout.getId()),
|
|
||||||
conditionRolloutTargetCount, 15000, 500)).as("Rollout status").isNotNull();
|
|
||||||
|
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
myRollout = getRollout(myRolloutId);
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING);
|
||||||
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
||||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 10L);
|
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 10L);
|
||||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 40L);
|
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 40L);
|
||||||
validateRolloutActionStatus(myRollout.getId(), expectedTargetCountStatus);
|
validateRolloutActionStatus(myRolloutId, expectedTargetCountStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rollout reloadRollout(final Rollout r) {
|
||||||
|
return getRollout(r.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rollout getRollout(final Long myRolloutId) {
|
||||||
|
return rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1506,7 +1519,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
rolloutGroups.add(generateRolloutGroup(2, percentTargetsInGroup3, null));
|
rolloutGroups.add(generateRolloutGroup(2, percentTargetsInGroup3, null));
|
||||||
|
|
||||||
Rollout myRollout = rolloutManagement.create(rolloutcreate, rolloutGroups, conditions);
|
Rollout myRollout = rolloutManagement.create(rolloutcreate, rolloutGroups, conditions);
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
myRollout = getRollout(myRollout.getId());
|
||||||
|
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.CREATING);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.CREATING);
|
||||||
for (final RolloutGroup group : rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent()) {
|
for (final RolloutGroup group : rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent()) {
|
||||||
@@ -1520,7 +1533,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
myRollout = getRollout(myRollout.getId());
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||||
assertThat(myRollout.getTotalTargets()).isEqualTo(amountTargetsInGroup1and2 + amountTargetsInGroup1);
|
assertThat(myRollout.getTotalTargets()).isEqualTo(amountTargetsInGroup1and2 + amountTargetsInGroup1);
|
||||||
|
|
||||||
@@ -1539,7 +1552,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify rollout creation fails if group definition does not address all targets")
|
@Description("Verify rollout creation fails if group definition does not address all targets")
|
||||||
void createRolloutWithGroupsNotMatchingTargets() throws Exception {
|
void createRolloutWithGroupsNotMatchingTargets() {
|
||||||
final String rolloutName = "rolloutTest4";
|
final String rolloutName = "rolloutTest4";
|
||||||
final int amountTargetsForRollout = 500;
|
final int amountTargetsForRollout = 500;
|
||||||
final int percentTargetsInGroup1 = 20;
|
final int percentTargetsInGroup1 = 20;
|
||||||
@@ -1560,7 +1573,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify rollout creation fails if group definition specifies illegal target percentage")
|
@Description("Verify rollout creation fails if group definition specifies illegal target percentage")
|
||||||
void createRolloutWithIllegalPercentage() throws Exception {
|
void createRolloutWithIllegalPercentage() {
|
||||||
final String rolloutName = "rolloutTest6";
|
final String rolloutName = "rolloutTest6";
|
||||||
final int amountTargetsForRollout = 10;
|
final int amountTargetsForRollout = 10;
|
||||||
final int percentTargetsInGroup1 = 101;
|
final int percentTargetsInGroup1 = 101;
|
||||||
@@ -1581,7 +1594,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify rollout creation fails if the 'max rollout groups per rollout' quota is violated.")
|
@Description("Verify rollout creation fails if the 'max rollout groups per rollout' quota is violated.")
|
||||||
void createRolloutWithIllegalAmountOfGroups() throws Exception {
|
void createRolloutWithIllegalAmountOfGroups() {
|
||||||
final String rolloutName = "rolloutTest5";
|
final String rolloutName = "rolloutTest5";
|
||||||
final int targets = 10;
|
final int targets = 10;
|
||||||
final int maxGroups = quotaManagement.getMaxRolloutGroupsPerRollout();
|
final int maxGroups = quotaManagement.getMaxRolloutGroupsPerRollout();
|
||||||
@@ -1589,34 +1602,33 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
||||||
final RolloutCreate rollout = generateTargetsAndRollout(rolloutName, targets);
|
final RolloutCreate rollout = generateTargetsAndRollout(rolloutName, targets);
|
||||||
|
|
||||||
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
|
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(
|
||||||
.isThrownBy(() -> rolloutManagement.create(rollout, maxGroups + 1, conditions))
|
() -> rolloutManagement.create(rollout, maxGroups + 1, conditions))
|
||||||
.withMessageContaining("not be greater than " + maxGroups);
|
.withMessageContaining("not be greater than " + maxGroups);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify the start of a Rollout does not work during creation phase.")
|
@Description("Verify the start of a Rollout does not work during creation phase.")
|
||||||
void createAndStartRolloutDuringCreationFails() throws Exception {
|
void createAndStartRolloutDuringCreationFails() {
|
||||||
final int amountTargetsForRollout = 3;
|
final int amountTargetsForRollout = 3;
|
||||||
final int amountGroups = 5;
|
final int amountGroups = 5;
|
||||||
final String successCondition = "50";
|
final String successCondition = "50";
|
||||||
final String errorCondition = "80";
|
final String errorCondition = "80";
|
||||||
final String rolloutName = "rolloutTestGC";
|
final String rolloutName = "rolloutTestGC";
|
||||||
final String targetPrefixName = rolloutName;
|
|
||||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
||||||
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
|
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
|
||||||
|
|
||||||
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults()
|
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults()
|
||||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, successCondition)
|
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, successCondition)
|
||||||
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition)
|
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition)
|
||||||
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
|
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
|
||||||
final RolloutCreate rolloutToCreate = entityFactory.rollout().create().name(rolloutName)
|
final RolloutCreate rolloutToCreate = entityFactory.rollout().create().name(rolloutName)
|
||||||
.description("some description").targetFilterQuery("id==" + targetPrefixName + "-*")
|
.description("some description").targetFilterQuery("id==" + rolloutName + "-*")
|
||||||
.set(distributionSet);
|
.set(distributionSet);
|
||||||
|
|
||||||
Rollout myRollout = rolloutManagement.create(rolloutToCreate, amountGroups, conditions);
|
Rollout myRollout = rolloutManagement.create(rolloutToCreate, amountGroups, conditions);
|
||||||
myRollout = rolloutManagement.get(myRollout.getId()).get();
|
myRollout = getRollout(myRollout.getId());
|
||||||
|
|
||||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.CREATING);
|
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.CREATING);
|
||||||
|
|
||||||
@@ -1640,7 +1652,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Creating a rollout without approver role and approval enabled leads to transition to "
|
@Description("Creating a rollout without approve role and approval enabled leads to transition to "
|
||||||
+ "WAITING_FOR_APPROVAL state.")
|
+ "WAITING_FOR_APPROVAL state.")
|
||||||
void createdRolloutWithoutApprovalRoleTransitionsToWaitingForApprovalState() {
|
void createdRolloutWithoutApprovalRoleTransitionsToWaitingForApprovalState() {
|
||||||
approvalStrategy.setApprovalNeeded(true);
|
approvalStrategy.setApprovalNeeded(true);
|
||||||
@@ -1770,7 +1782,9 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Creating a rollout without weight value when multi assignment in enabled.")
|
@Description("Creating a rollout without weight value when multi assignment in enabled.")
|
||||||
void weightNotRequiredInMultiAssignmentMode() {
|
void weightNotRequiredInMultiAssignmentMode() {
|
||||||
enableMultiAssignments();
|
enableMultiAssignments();
|
||||||
createSimpleTestRolloutWithTargetsAndDistributionSet(10, 10, 2, "50", "80", ActionType.FORCED, null);
|
final Rollout rollout = createSimpleTestRolloutWithTargetsAndDistributionSet(
|
||||||
|
10, 10, 2, "50", "80", ActionType.FORCED, null);
|
||||||
|
assertThat(rollout).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1805,7 +1819,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("A Rollout with weight creats actions with weights")
|
@Description("A Rollout with weight creates actions with weights")
|
||||||
void actionsWithWeightAreCreated() {
|
void actionsWithWeightAreCreated() {
|
||||||
final int amountOfTargets = 5;
|
final int amountOfTargets = 5;
|
||||||
final int weight = 99;
|
final int weight = 99;
|
||||||
@@ -1815,8 +1829,9 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
rolloutManagement.start(rolloutId);
|
rolloutManagement.start(rolloutId);
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
|
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
|
||||||
assertThat(actions).hasSize(amountOfTargets);
|
assertThat(actions) //
|
||||||
assertThat(actions).allMatch(action -> action.getWeight().get() == weight);
|
.hasSize(amountOfTargets) //
|
||||||
|
.allMatch(action -> action.getWeight().get() == weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1830,57 +1845,58 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
rolloutManagement.start(rolloutId);
|
rolloutManagement.start(rolloutId);
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
|
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
|
||||||
assertThat(actions).hasSize(amountOfTargets);
|
assertThat(actions).hasSize(amountOfTargets).allMatch(action -> !action.getWeight().isPresent());
|
||||||
assertThat(actions).allMatch(action -> !action.getWeight().isPresent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that an exception is thrown when trying to create a rollout with an invalidated distribution set.")
|
@Description("Verifies that an exception is thrown when trying to create a rollout with an invalidated distribution set.")
|
||||||
public void createRolloutWithInvalidDistributionSet() {
|
void createRolloutWithInvalidDistributionSet() {
|
||||||
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
assertThatExceptionOfType(InvalidDistributionSetException.class).as(
|
||||||
.as("Invalid distributionSet should throw an exception")
|
"Invalid distributionSet should throw an exception")
|
||||||
.isThrownBy(() -> testdataFactory.createRolloutByVariables("createRolloutWithInvalidDistributionSet",
|
.isThrownBy(() -> testdataFactory.createRolloutByVariables("createRolloutWithInvalidDistributionSet",
|
||||||
"desc", 2, "name==*", distributionSet, "50", "80"));
|
"desc", 2, "name==*", distributionSet, "50", "80"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that an exception is thrown when trying to create a rollout with an incomplete distribution set.")
|
@Description("Verifies that an exception is thrown when trying to create a rollout with an incomplete distribution set.")
|
||||||
public void createRolloutWithIncompleteDistributionSet() {
|
void createRolloutWithIncompleteDistributionSet() {
|
||||||
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
|
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
|
||||||
|
|
||||||
assertThatExceptionOfType(IncompleteDistributionSetException.class)
|
assertThatExceptionOfType(IncompleteDistributionSetException.class).as(
|
||||||
.as("Incomplete distributionSet should throw an exception")
|
"Incomplete distributionSet should throw an exception")
|
||||||
.isThrownBy(() -> testdataFactory.createRolloutByVariables("createRolloutWithIncompleteDistributionSet",
|
.isThrownBy(() -> testdataFactory.createRolloutByVariables("createRolloutWithIncompleteDistributionSet",
|
||||||
"desc", 2, "name==*", distributionSet, "50", "80"));
|
"desc", 2, "name==*", distributionSet, "50", "80"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that an exception is thrown when trying to update a rollout with an invalidated distribution set.")
|
@Description("Verifies that an exception is thrown when trying to update a rollout with an invalidated distribution set.")
|
||||||
public void updateRolloutWithInvalidDistributionSet() {
|
void updateRolloutWithInvalidDistributionSet() {
|
||||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Rollout rollout = testdataFactory.createRolloutByVariables("updateRolloutWithInvalidDistributionSet",
|
final Rollout rollout = testdataFactory.createRolloutByVariables("updateRolloutWithInvalidDistributionSet",
|
||||||
"desc", 2, "name==*", distributionSet, "50", "80");
|
"desc", 2, "name==*", distributionSet, "50", "80");
|
||||||
final DistributionSet invalidDistributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
final DistributionSet invalidDistributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
assertThatExceptionOfType(InvalidDistributionSetException.class).as(
|
||||||
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> rolloutManagement
|
"Invalid distributionSet should throw an exception")
|
||||||
.update(entityFactory.rollout().update(rollout.getId()).set(invalidDistributionSet.getId())));
|
.isThrownBy(() -> rolloutManagement.update(
|
||||||
|
entityFactory.rollout().update(rollout.getId()).set(invalidDistributionSet.getId())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that an exception is thrown when trying to update a rollout with an incomplete distribution set.")
|
@Description("Verifies that an exception is thrown when trying to update a rollout with an incomplete distribution set.")
|
||||||
public void updateRolloutWithIncompleteDistributionSet() {
|
void updateRolloutWithIncompleteDistributionSet() {
|
||||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Rollout rollout = testdataFactory.createRolloutByVariables("updateRolloutWithIncompleteDistributionSet",
|
final Rollout rollout = testdataFactory.createRolloutByVariables("updateRolloutWithIncompleteDistributionSet",
|
||||||
"desc", 2, "name==*", distributionSet, "50", "80");
|
"desc", 2, "name==*", distributionSet, "50", "80");
|
||||||
final DistributionSet incompleteDistributionSet = testdataFactory.createIncompleteDistributionSet();
|
final DistributionSet incompleteDistributionSet = testdataFactory.createIncompleteDistributionSet();
|
||||||
|
|
||||||
assertThatExceptionOfType(IncompleteDistributionSetException.class)
|
assertThatExceptionOfType(IncompleteDistributionSetException.class).as(
|
||||||
.as("Incomplete distributionSet should throw an exception").isThrownBy(() -> rolloutManagement.update(
|
"Incomplete distributionSet should throw an exception")
|
||||||
|
.isThrownBy(() -> rolloutManagement.update(
|
||||||
entityFactory.rollout().update(rollout.getId()).set(incompleteDistributionSet.getId())));
|
entityFactory.rollout().update(rollout.getId()).set(incompleteDistributionSet.getId())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1903,27 +1919,31 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
targets.addAll(targetsWithoutType);
|
targets.addAll(targetsWithoutType);
|
||||||
|
|
||||||
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
||||||
final RolloutCreate rolloutToCreate = entityFactory.rollout().create().name(rolloutName)
|
final RolloutCreate rolloutToCreate = entityFactory.rollout()
|
||||||
.targetFilterQuery("name==*").set(testDs);
|
.create()
|
||||||
|
.name(rolloutName)
|
||||||
|
.targetFilterQuery("name==*")
|
||||||
|
.set(testDs);
|
||||||
|
|
||||||
final Rollout createdRollout = rolloutManagement.create(rolloutToCreate, 1, conditions);
|
final Rollout createdRollout = rolloutManagement.create(rolloutToCreate, 1, conditions);
|
||||||
|
|
||||||
// Let the executor handle created Rollout
|
// Let the executor handle created Rollout
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
final Rollout testRollout = rolloutManagement.get(createdRollout.getId()).get();
|
final Rollout testRollout = reloadRollout(createdRollout);
|
||||||
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement
|
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(Pageable.unpaged(),
|
||||||
.findByRollout(Pageable.unpaged(), testRollout.getId()).getContent();
|
testRollout.getId()).getContent();
|
||||||
|
|
||||||
assertThat(testRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
assertThat(testRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||||
assertThat(testRollout.getTotalTargets()).isEqualTo(targets.size());
|
assertThat(testRollout.getTotalTargets()).isEqualTo(targets.size());
|
||||||
assertThat(rolloutGroups).hasSize(1);
|
assertThat(rolloutGroups).hasSize(1);
|
||||||
assertThat(rolloutGroups.get(0).getTotalTargets()).isEqualTo(targets.size());
|
assertThat(rolloutGroups.get(0).getTotalTargets()).isEqualTo(targets.size());
|
||||||
|
|
||||||
final List<Target> rolloutGroupTargets = rolloutGroupManagement
|
final List<Target> rolloutGroupTargets = rolloutGroupManagement.findTargetsOfRolloutGroup(Pageable.unpaged(),
|
||||||
.findTargetsOfRolloutGroup(Pageable.unpaged(), rolloutGroups.get(0).getId()).getContent();
|
rolloutGroups.get(0).getId()).getContent();
|
||||||
|
|
||||||
assertThat(rolloutGroupTargets).hasSize(targets.size()).containsExactlyInAnyOrderElementsOf(targets)
|
assertThat(rolloutGroupTargets).hasSize(targets.size())
|
||||||
|
.containsExactlyInAnyOrderElementsOf(targets)
|
||||||
.doesNotContainAnyElementsOf(incompatibleTargets);
|
.doesNotContainAnyElementsOf(incompatibleTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2027,35 +2047,14 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SuccessConditionRolloutStatus implements SuccessCondition<RolloutStatus> {
|
private void awaitRunningState(final Long myRolloutId) {
|
||||||
|
Awaitility.await()
|
||||||
private final RolloutStatus rolloutStatus;
|
.atMost(Duration.TEN_SECONDS)
|
||||||
|
.pollInterval(Duration.FIVE_HUNDRED_MILLISECONDS)
|
||||||
public SuccessConditionRolloutStatus(final RolloutStatus rolloutStatus) {
|
.with()
|
||||||
this.rolloutStatus = rolloutStatus;
|
.until(() -> WithSpringAuthorityRule.runAsPrivileged(
|
||||||
}
|
() -> rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new))
|
||||||
|
.getStatus()
|
||||||
@Override
|
.equals(RolloutStatus.RUNNING));
|
||||||
public boolean success(final RolloutStatus result) {
|
|
||||||
return result.equals(rolloutStatus);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RolloutStatusCallable implements Callable<RolloutStatus> {
|
|
||||||
|
|
||||||
final Long rolloutId;
|
|
||||||
|
|
||||||
RolloutStatusCallable(final Long rolloutId) {
|
|
||||||
this.rolloutId = rolloutId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RolloutStatus call() throws Exception {
|
|
||||||
|
|
||||||
final Rollout myRollout = rolloutManagement.get(rolloutId).get();
|
|
||||||
return myRollout.getStatus();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.apache.commons.lang3.RandomUtils;
|
import org.apache.commons.lang3.RandomUtils;
|
||||||
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
|
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
|
||||||
@@ -57,7 +59,7 @@ import io.qameta.allure.Story;
|
|||||||
public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that management get access reacts as specfied on calls for non existing entities by means "
|
@Description("Verifies that management get access reacts as specified on calls for non existing entities by means "
|
||||||
+ "of Optional not present.")
|
+ "of Optional not present.")
|
||||||
@ExpectEvents({ @Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
|
@ExpectEvents({ @Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
|
||||||
public void nonExistingEntityAccessReturnsNotPresent() {
|
public void nonExistingEntityAccessReturnsNotPresent() {
|
||||||
@@ -80,7 +82,8 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
verifyThrownExceptionBy(
|
verifyThrownExceptionBy(
|
||||||
() -> softwareModuleManagement
|
() -> softwareModuleManagement
|
||||||
.create(Arrays.asList(entityFactory.softwareModule().create().name("xxx").type(NOT_EXIST_ID))),
|
.create(Collections
|
||||||
|
.singletonList(entityFactory.softwareModule().create().name("xxx").type(NOT_EXIST_ID))),
|
||||||
"SoftwareModuleType");
|
"SoftwareModuleType");
|
||||||
verifyThrownExceptionBy(
|
verifyThrownExceptionBy(
|
||||||
() -> softwareModuleManagement
|
() -> softwareModuleManagement
|
||||||
@@ -92,12 +95,13 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx")),
|
entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx")),
|
||||||
"SoftwareModule");
|
"SoftwareModule");
|
||||||
verifyThrownExceptionBy(
|
verifyThrownExceptionBy(
|
||||||
() -> softwareModuleManagement.createMetaData(Arrays
|
() -> softwareModuleManagement.createMetaData(Collections.singletonList(
|
||||||
.asList(entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx"))),
|
entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx"))),
|
||||||
"SoftwareModule");
|
"SoftwareModule");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> softwareModuleManagement.delete(NOT_EXIST_IDL), "SoftwareModule");
|
verifyThrownExceptionBy(() -> softwareModuleManagement.delete(NOT_EXIST_IDL), "SoftwareModule");
|
||||||
verifyThrownExceptionBy(() -> softwareModuleManagement.delete(Arrays.asList(NOT_EXIST_IDL)), "SoftwareModule");
|
verifyThrownExceptionBy(() -> softwareModuleManagement.delete(Collections.singletonList(NOT_EXIST_IDL)),
|
||||||
|
"SoftwareModule");
|
||||||
verifyThrownExceptionBy(() -> softwareModuleManagement.deleteMetaData(NOT_EXIST_IDL, "xxx"), "SoftwareModule");
|
verifyThrownExceptionBy(() -> softwareModuleManagement.deleteMetaData(NOT_EXIST_IDL, "xxx"), "SoftwareModule");
|
||||||
verifyThrownExceptionBy(() -> softwareModuleManagement.deleteMetaData(module.getId(), NOT_EXIST_ID),
|
verifyThrownExceptionBy(() -> softwareModuleManagement.deleteMetaData(module.getId(), NOT_EXIST_ID),
|
||||||
"SoftwareModuleMetadata");
|
"SoftwareModuleMetadata");
|
||||||
@@ -141,13 +145,13 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
.update(entityFactory.softwareModule().update(ah.getId()));
|
.update(entityFactory.softwareModule().update(ah.getId()));
|
||||||
|
|
||||||
assertThat(updated.getOptLockRevision())
|
assertThat(updated.getOptLockRevision())
|
||||||
.as("Expected version number of updated entitity to be equal to created version")
|
.as("Expected version number of updated entity to be equal to created version")
|
||||||
.isEqualTo(ah.getOptLockRevision());
|
.isEqualTo(ah.getOptLockRevision());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Calling update for changed fields results in change in the repository.")
|
@Description("Calling update for changed fields results in change in the repository.")
|
||||||
public void updateSoftareModuleFieldsToNewValue() {
|
public void updateSoftwareModuleFieldsToNewValue() {
|
||||||
final SoftwareModule ah = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule ah = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
final SoftwareModule updated = softwareModuleManagement
|
final SoftwareModule updated = softwareModuleManagement
|
||||||
@@ -213,7 +217,9 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assignDistributionSet(ds.getId(), target.getControllerId());
|
assignDistributionSet(ds.getId(), target.getControllerId());
|
||||||
assertThat(targetManagement.getByControllerID(target.getControllerId()).get().getUpdateStatus())
|
assertThat(targetManagement.getByControllerID(target.getControllerId()).get().getUpdateStatus())
|
||||||
.isEqualTo(TargetUpdateStatus.PENDING);
|
.isEqualTo(TargetUpdateStatus.PENDING);
|
||||||
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get()).isEqualTo(ds);
|
final Optional<DistributionSet> assignedDistributionSet = deploymentManagement
|
||||||
|
.getAssignedDistributionSet(target.getControllerId());
|
||||||
|
assertThat(assignedDistributionSet).contains(ds);
|
||||||
final Action action = actionRepository.findByTargetAndDistributionSet(PAGE, target, ds).getContent().get(0);
|
final Action action = actionRepository.findByTargetAndDistributionSet(PAGE, target, ds).getContent().get(0);
|
||||||
assertThat(action).isNotNull();
|
assertThat(action).isNotNull();
|
||||||
return action;
|
return action;
|
||||||
@@ -273,7 +279,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// [VERIFY EXPECTED RESULT]:
|
// [VERIFY EXPECTED RESULT]:
|
||||||
// verify: SoftwareModule is deleted
|
// verify: SoftwareModule is deleted
|
||||||
assertThat(softwareModuleRepository.findAll()).hasSize(0);
|
assertThat(softwareModuleRepository.findAll()).isEmpty();
|
||||||
assertThat(softwareModuleManagement.get(unassignedModule.getId())).isNotPresent();
|
assertThat(softwareModuleManagement.get(unassignedModule.getId())).isNotPresent();
|
||||||
|
|
||||||
// verify: binary data of artifact is deleted
|
// verify: binary data of artifact is deleted
|
||||||
@@ -301,7 +307,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// verify: assignedModule is marked as deleted
|
// verify: assignedModule is marked as deleted
|
||||||
assignedModule = softwareModuleManagement.get(assignedModule.getId()).get();
|
assignedModule = softwareModuleManagement.get(assignedModule.getId()).get();
|
||||||
assertTrue(assignedModule.isDeleted(), "The module should be flagged as deleted");
|
assertTrue(assignedModule.isDeleted(), "The module should be flagged as deleted");
|
||||||
assertThat(softwareModuleManagement.findAll(PAGE)).hasSize(0);
|
assertThat(softwareModuleManagement.findAll(PAGE)).isEmpty();
|
||||||
assertThat(softwareModuleRepository.findAll()).hasSize(1);
|
assertThat(softwareModuleRepository.findAll()).hasSize(1);
|
||||||
|
|
||||||
// verify: binary data is deleted
|
// verify: binary data is deleted
|
||||||
@@ -329,7 +335,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
final DistributionSet disSet = testdataFactory.createDistributionSet(Sets.newHashSet(assignedModule));
|
final DistributionSet disSet = testdataFactory.createDistributionSet(Sets.newHashSet(assignedModule));
|
||||||
|
|
||||||
// [STEP3]: Assign DistributionSet to a Device
|
// [STEP3]: Assign DistributionSet to a Device
|
||||||
assignDistributionSet(disSet, Arrays.asList(target));
|
assignDistributionSet(disSet, Collections.singletonList(target));
|
||||||
|
|
||||||
// [STEP4]: Delete the DistributionSet
|
// [STEP4]: Delete the DistributionSet
|
||||||
distributionSetManagement.delete(disSet.getId());
|
distributionSetManagement.delete(disSet.getId());
|
||||||
@@ -341,7 +347,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// verify: assignedModule is marked as deleted
|
// verify: assignedModule is marked as deleted
|
||||||
assignedModule = softwareModuleManagement.get(assignedModule.getId()).get();
|
assignedModule = softwareModuleManagement.get(assignedModule.getId()).get();
|
||||||
assertTrue(assignedModule.isDeleted(), "The found module should be flagged deleted");
|
assertTrue(assignedModule.isDeleted(), "The found module should be flagged deleted");
|
||||||
assertThat(softwareModuleManagement.findAll(PAGE)).hasSize(0);
|
assertThat(softwareModuleManagement.findAll(PAGE)).isEmpty();
|
||||||
assertThat(softwareModuleRepository.findAll()).hasSize(1);
|
assertThat(softwareModuleRepository.findAll()).hasSize(1);
|
||||||
|
|
||||||
// verify: binary data is deleted
|
// verify: binary data is deleted
|
||||||
@@ -357,7 +363,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Delete an software module with an artifact, which is also used by another software module.")
|
@Description("Delete an software module with an artifact, which is also used by another software module.")
|
||||||
public void deleteSoftwareModulesWithSharedArtifact() throws IOException {
|
public void deleteSoftwareModulesWithSharedArtifact() {
|
||||||
|
|
||||||
// Init artifact binary data, target and DistributionSets
|
// Init artifact binary data, target and DistributionSets
|
||||||
final int artifactSize = 1024;
|
final int artifactSize = 1024;
|
||||||
@@ -428,11 +434,11 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// [STEP3]: Assign SoftwareModuleX to DistributionSetX and to target
|
// [STEP3]: Assign SoftwareModuleX to DistributionSetX and to target
|
||||||
final DistributionSet disSetX = testdataFactory.createDistributionSet(Sets.newHashSet(moduleX), "X");
|
final DistributionSet disSetX = testdataFactory.createDistributionSet(Sets.newHashSet(moduleX), "X");
|
||||||
assignDistributionSet(disSetX, Arrays.asList(target));
|
assignDistributionSet(disSetX, Collections.singletonList(target));
|
||||||
|
|
||||||
// [STEP4]: Assign SoftwareModuleY to DistributionSet and to target
|
// [STEP4]: Assign SoftwareModuleY to DistributionSet and to target
|
||||||
final DistributionSet disSetY = testdataFactory.createDistributionSet(Sets.newHashSet(moduleY), "Y");
|
final DistributionSet disSetY = testdataFactory.createDistributionSet(Sets.newHashSet(moduleY), "Y");
|
||||||
assignDistributionSet(disSetY, Arrays.asList(target));
|
assignDistributionSet(disSetY, Collections.singletonList(target));
|
||||||
|
|
||||||
// [STEP5]: Delete SoftwareModuleX
|
// [STEP5]: Delete SoftwareModuleX
|
||||||
softwareModuleManagement.delete(moduleX.getId());
|
softwareModuleManagement.delete(moduleX.getId());
|
||||||
@@ -444,12 +450,12 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
moduleX = softwareModuleManagement.get(moduleX.getId()).get();
|
moduleX = softwareModuleManagement.get(moduleX.getId()).get();
|
||||||
moduleY = softwareModuleManagement.get(moduleY.getId()).get();
|
moduleY = softwareModuleManagement.get(moduleY.getId()).get();
|
||||||
|
|
||||||
// verify: SoftwareModuleX and SofwtareModule are marked as deleted
|
// verify: SoftwareModuleX and SoftwareModule are marked as deleted
|
||||||
assertThat(moduleX).isNotNull();
|
assertThat(moduleX).isNotNull();
|
||||||
assertThat(moduleY).isNotNull();
|
assertThat(moduleY).isNotNull();
|
||||||
assertTrue(moduleX.isDeleted(), "The module should be flagged deleted");
|
assertTrue(moduleX.isDeleted(), "The module should be flagged deleted");
|
||||||
assertTrue(moduleY.isDeleted(), "The module should be flagged deleted");
|
assertTrue(moduleY.isDeleted(), "The module should be flagged deleted");
|
||||||
assertThat(softwareModuleManagement.findAll(PAGE)).hasSize(0);
|
assertThat(softwareModuleManagement.findAll(PAGE)).isEmpty();
|
||||||
assertThat(softwareModuleRepository.findAll()).hasSize(2);
|
assertThat(softwareModuleRepository.findAll()).hasSize(2);
|
||||||
|
|
||||||
// verify: binary data of artifact is deleted
|
// verify: binary data of artifact is deleted
|
||||||
@@ -506,7 +512,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test verfies that results are returned based on given filter parameters and in the specified order.")
|
@Description("Test verifies that results are returned based on given filter parameters and in the specified order.")
|
||||||
public void findSoftwareModuleOrderByDistributionModuleNameAscModuleVersionAsc() {
|
public void findSoftwareModuleOrderByDistributionModuleNameAscModuleVersionAsc() {
|
||||||
// test meta data
|
// test meta data
|
||||||
final SoftwareModuleType testType = softwareModuleTypeManagement
|
final SoftwareModuleType testType = softwareModuleTypeManagement
|
||||||
@@ -515,9 +521,9 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
.create(entityFactory.distributionSetType().create().key("key").name("name"));
|
.create(entityFactory.distributionSetType().create().key("key").name("name"));
|
||||||
|
|
||||||
distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(testDsType.getId(),
|
distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(testDsType.getId(),
|
||||||
Arrays.asList(osType.getId()));
|
Collections.singletonList(osType.getId()));
|
||||||
testDsType = distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(testDsType.getId(),
|
testDsType = distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(testDsType.getId(),
|
||||||
Arrays.asList(testType.getId()));
|
Collections.singletonList(testType.getId()));
|
||||||
|
|
||||||
// found in test
|
// found in test
|
||||||
final SoftwareModule unassigned = testdataFactory.createSoftwareModule("thetype", "unassignedfound", false);
|
final SoftwareModule unassigned = testdataFactory.createSoftwareModule("thetype", "unassignedfound", false);
|
||||||
@@ -567,9 +573,9 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
.create(entityFactory.distributionSetType().create().key("key").name("name"));
|
.create(entityFactory.distributionSetType().create().key("key").name("name"));
|
||||||
|
|
||||||
distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(testDsType.getId(),
|
distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(testDsType.getId(),
|
||||||
Arrays.asList(osType.getId()));
|
Collections.singletonList(osType.getId()));
|
||||||
testDsType = distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(testDsType.getId(),
|
testDsType = distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(testDsType.getId(),
|
||||||
Arrays.asList(testType.getId()));
|
Collections.singletonList(testType.getId()));
|
||||||
|
|
||||||
// found in test
|
// found in test
|
||||||
testdataFactory.createSoftwareModule("thetype", "unassignedfound", false);
|
testdataFactory.createSoftwareModule("thetype", "unassignedfound", false);
|
||||||
@@ -602,7 +608,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// one soft deleted
|
// one soft deleted
|
||||||
final SoftwareModule deleted = testdataFactory.createSoftwareModuleApp();
|
final SoftwareModule deleted = testdataFactory.createSoftwareModuleApp();
|
||||||
testdataFactory.createDistributionSet(Arrays.asList(deleted));
|
testdataFactory.createDistributionSet(Collections.singletonList(deleted));
|
||||||
softwareModuleManagement.delete(deleted.getId());
|
softwareModuleManagement.delete(deleted.getId());
|
||||||
|
|
||||||
assertThat(softwareModuleManagement.count()).as("Number of undeleted modules").isEqualTo(1);
|
assertThat(softwareModuleManagement.count()).as("Number of undeleted modules").isEqualTo(1);
|
||||||
@@ -610,7 +616,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that software modules are resturned that are assigned to given DS.")
|
@Description("Verfies that software modules are returned that are assigned to given DS.")
|
||||||
public void findSoftwareModuleByAssignedTo() {
|
public void findSoftwareModuleByAssignedTo() {
|
||||||
// test modules
|
// test modules
|
||||||
final SoftwareModule one = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule one = testdataFactory.createSoftwareModuleOs();
|
||||||
@@ -688,7 +694,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// add some meta data entries
|
// add some meta data entries
|
||||||
final SoftwareModule module3 = testdataFactory.createSoftwareModuleApp("m3");
|
final SoftwareModule module3 = testdataFactory.createSoftwareModuleApp("m3");
|
||||||
final int firstHalf = Math.round(maxMetaData / 2);
|
final int firstHalf = Math.round(((float) maxMetaData) / 2.f);
|
||||||
for (int i = 0; i < firstHalf; ++i) {
|
for (int i = 0; i < firstHalf; ++i) {
|
||||||
softwareModuleManagement.createMetaData(
|
softwareModuleManagement.createMetaData(
|
||||||
entityFactory.softwareModuleMetadata().create(module3.getId()).key("k" + i).value("v" + i));
|
entityFactory.softwareModuleMetadata().create(module3.getId()).key("k" + i).value("v" + i));
|
||||||
@@ -735,7 +741,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithUser(allSpPermissions = true)
|
@WithUser(allSpPermissions = true)
|
||||||
@Description("Checks that metadata for a software module can be updated.")
|
@Description("Checks that metadata for a software module can be updated.")
|
||||||
public void updateSoftwareModuleMetadata() throws InterruptedException {
|
public void updateSoftwareModuleMetadata() {
|
||||||
final String knownKey = "myKnownKey";
|
final String knownKey = "myKnownKey";
|
||||||
final String knownValue = "myKnownValue";
|
final String knownValue = "myKnownValue";
|
||||||
final String knownUpdateValue = "myNewUpdatedValue";
|
final String knownUpdateValue = "myNewUpdatedValue";
|
||||||
@@ -752,18 +758,16 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assertThat(softwareModuleMetadata.getValue()).isEqualTo(knownValue);
|
assertThat(softwareModuleMetadata.getValue()).isEqualTo(knownValue);
|
||||||
|
|
||||||
// base software module should have now the opt lock revision one
|
// base software module should have now the opt lock revision one
|
||||||
// because we are modifying the
|
// because we are modifying the base software module
|
||||||
// base software module
|
|
||||||
SoftwareModule changedLockRevisionModule = softwareModuleManagement.get(ah.getId()).get();
|
SoftwareModule changedLockRevisionModule = softwareModuleManagement.get(ah.getId()).get();
|
||||||
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(2);
|
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(2);
|
||||||
|
|
||||||
// update the software module metadata
|
// update the software module metadata
|
||||||
Thread.sleep(100);
|
|
||||||
final SoftwareModuleMetadata updated = softwareModuleManagement.updateMetaData(entityFactory
|
final SoftwareModuleMetadata updated = softwareModuleManagement.updateMetaData(entityFactory
|
||||||
.softwareModuleMetadata().update(ah.getId(), knownKey).value(knownUpdateValue).targetVisible(true));
|
.softwareModuleMetadata().update(ah.getId(), knownKey).value(knownUpdateValue).targetVisible(true));
|
||||||
// we are updating the sw meta data so also modiying the base software
|
|
||||||
// module so opt lock
|
// we are updating the sw metadata so also modifying the base software
|
||||||
// revision must be two
|
// module so opt lock revision must be two
|
||||||
changedLockRevisionModule = softwareModuleManagement.get(ah.getId()).get();
|
changedLockRevisionModule = softwareModuleManagement.get(ah.getId()).get();
|
||||||
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(3);
|
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(3);
|
||||||
|
|
||||||
@@ -776,7 +780,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that existing metadata can be deleted.")
|
@Description("Verifies that existing metadata can be deleted.")
|
||||||
public void deleteSoftwareModuleMetadata() {
|
public void deleteSoftwareModuleMetadata() {
|
||||||
final String knownKey1 = "myKnownKey1";
|
final String knownKey1 = "myKnownKey1";
|
||||||
final String knownValue1 = "myKnownValue1";
|
final String knownValue1 = "myKnownValue1";
|
||||||
@@ -796,11 +800,11 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
softwareModuleManagement.deleteMetaData(ah.getId(), knownKey1);
|
softwareModuleManagement.deleteMetaData(ah.getId(), knownKey1);
|
||||||
assertThat(
|
assertThat(
|
||||||
softwareModuleManagement.findMetaDataBySoftwareModuleId(PageRequest.of(0, 10), ah.getId()).getContent())
|
softwareModuleManagement.findMetaDataBySoftwareModuleId(PageRequest.of(0, 10), ah.getId()).getContent())
|
||||||
.as("Metadata elemenets are").isEmpty();
|
.as("Metadata elements are").isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that non existing metadata find results in exception.")
|
@Description("Verifies that non existing metadata find results in exception.")
|
||||||
public void findSoftwareModuleMetadataFailsIfEntryDoesNotExist() {
|
public void findSoftwareModuleMetadataFailsIfEntryDoesNotExist() {
|
||||||
final String knownKey1 = "myKnownKey1";
|
final String knownKey1 = "myKnownKey1";
|
||||||
final String knownValue1 = "myKnownValue1";
|
final String knownValue1 = "myKnownValue1";
|
||||||
@@ -854,7 +858,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assertThat(metadataSw1.getNumberOfElements()).isEqualTo(metadataCountSw1);
|
assertThat(metadataSw1.getNumberOfElements()).isEqualTo(metadataCountSw1);
|
||||||
assertThat(metadataSw1.getTotalElements()).isEqualTo(metadataCountSw1);
|
assertThat(metadataSw1.getTotalElements()).isEqualTo(metadataCountSw1);
|
||||||
|
|
||||||
assertThat(metadataSw2.getNumberOfElements()).isEqualTo(0);
|
assertThat(metadataSw2.getNumberOfElements()).isZero();
|
||||||
assertThat(metadataSw2.getTotalElements()).isEqualTo(0);
|
assertThat(metadataSw2.getTotalElements()).isZero();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.validation.ConstraintViolationException;
|
import javax.validation.ConstraintViolationException;
|
||||||
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.awaitility.Awaitility;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||||
import org.eclipse.hawkbit.repository.FilterParams;
|
import org.eclipse.hawkbit.repository.FilterParams;
|
||||||
import org.eclipse.hawkbit.repository.Identifiable;
|
import org.eclipse.hawkbit.repository.Identifiable;
|
||||||
@@ -77,7 +79,7 @@ import io.qameta.allure.Story;
|
|||||||
|
|
||||||
@Feature("Component Tests - Repository")
|
@Feature("Component Tests - Repository")
|
||||||
@Story("Target Management")
|
@Story("Target Management")
|
||||||
public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||||
|
|
||||||
private static final String WHITESPACE_ERROR = "target with whitespaces in controller id should not be created";
|
private static final String WHITESPACE_ERROR = "target with whitespaces in controller id should not be created";
|
||||||
|
|
||||||
@@ -85,7 +87,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
|
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
|
||||||
+ "of Optional not present.")
|
+ "of Optional not present.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
|
||||||
public void nonExistingEntityAccessReturnsNotPresent() {
|
void nonExistingEntityAccessReturnsNotPresent() {
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
assertThat(targetManagement.getByControllerID(NOT_EXIST_ID)).isNotPresent();
|
assertThat(targetManagement.getByControllerID(NOT_EXIST_ID)).isNotPresent();
|
||||||
assertThat(targetManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
assertThat(targetManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
||||||
@@ -97,7 +99,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
+ " by means of throwing EntityNotFoundException.")
|
+ " by means of throwing EntityNotFoundException.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetTagCreatedEvent.class, count = 1) })
|
@Expect(type = TargetTagCreatedEvent.class, count = 1) })
|
||||||
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
||||||
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("A"));
|
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("A"));
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
|
|
||||||
@@ -153,14 +155,15 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
verifyThrownExceptionBy(() -> targetManagement.update(entityFactory.target().update(NOT_EXIST_ID)), "Target");
|
verifyThrownExceptionBy(() -> targetManagement.update(entityFactory.target().update(NOT_EXIST_ID)), "Target");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> targetManagement.createMetaData(NOT_EXIST_ID,
|
verifyThrownExceptionBy(() -> targetManagement.createMetaData(NOT_EXIST_ID,
|
||||||
Arrays.asList(entityFactory.generateTargetMetadata("123", "123"))), "Target");
|
Collections.singletonList(entityFactory.generateTargetMetadata("123", "123"))), "Target");
|
||||||
verifyThrownExceptionBy(() -> targetManagement.deleteMetaData(NOT_EXIST_ID, "xxx"), "Target");
|
verifyThrownExceptionBy(() -> targetManagement.deleteMetaData(NOT_EXIST_ID, "xxx"), "Target");
|
||||||
verifyThrownExceptionBy(() -> targetManagement.deleteMetaData(target.getControllerId(), NOT_EXIST_ID),
|
verifyThrownExceptionBy(() -> targetManagement.deleteMetaData(target.getControllerId(), NOT_EXIST_ID),
|
||||||
"TargetMetadata");
|
"TargetMetadata");
|
||||||
verifyThrownExceptionBy(() -> targetManagement.getMetaDataByControllerId(NOT_EXIST_ID, "xxx"), "Target");
|
verifyThrownExceptionBy(() -> targetManagement.getMetaDataByControllerId(NOT_EXIST_ID, "xxx"), "Target");
|
||||||
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerId(PAGE, NOT_EXIST_ID), "Target");
|
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerId(PAGE, NOT_EXIST_ID),
|
||||||
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerIdAndRsql(PAGE, NOT_EXIST_ID, "key==*"),
|
|
||||||
"Target");
|
"Target");
|
||||||
|
verifyThrownExceptionBy(
|
||||||
|
() -> targetManagement.findMetaDataByControllerIdAndRsql(PAGE, NOT_EXIST_ID, "key==*"), "Target");
|
||||||
verifyThrownExceptionBy(
|
verifyThrownExceptionBy(
|
||||||
() -> targetManagement.updateMetadata(NOT_EXIST_ID, entityFactory.generateTargetMetadata("xxx", "xxx")),
|
() -> targetManagement.updateMetadata(NOT_EXIST_ID, entityFactory.generateTargetMetadata("xxx", "xxx")),
|
||||||
"Target");
|
"Target");
|
||||||
@@ -171,7 +174,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Ensures that retrieving the target security is only permitted with the necessary permissions.")
|
@Description("Ensures that retrieving the target security is only permitted with the necessary permissions.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
|
||||||
public void getTargetSecurityTokenOnlyWithCorrectPermission() throws Exception {
|
void getTargetSecurityTokenOnlyWithCorrectPermission() throws Exception {
|
||||||
final Target createdTarget = targetManagement
|
final Target createdTarget = targetManagement
|
||||||
.create(entityFactory.target().create().controllerId("targetWithSecurityToken").securityToken("token"));
|
.create(entityFactory.target().create().controllerId("targetWithSecurityToken").securityToken("token"));
|
||||||
|
|
||||||
@@ -197,8 +200,8 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists.")
|
@Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists.")
|
||||||
@WithUser(tenantId = "tenantWhichDoesNotExists", allSpPermissions = true, autoCreateTenant = false)
|
@WithUser(tenantId = "tenantWhichDoesNotExists", allSpPermissions = true, autoCreateTenant = false)
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void createTargetForTenantWhichDoesNotExistThrowsTenantNotExistException() {
|
void createTargetForTenantWhichDoesNotExistThrowsTenantNotExistException() {
|
||||||
try {
|
try {
|
||||||
targetManagement.create(entityFactory.target().create().controllerId("targetId123"));
|
targetManagement.create(entityFactory.target().create().controllerId("targetId123"));
|
||||||
fail("should not be possible as the tenant does not exist");
|
fail("should not be possible as the tenant does not exist");
|
||||||
@@ -210,7 +213,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that a target with same controller ID than another device cannot be created.")
|
@Description("Verify that a target with same controller ID than another device cannot be created.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
|
||||||
public void createTargetThatViolatesUniqueConstraintFails() {
|
void createTargetThatViolatesUniqueConstraintFails() {
|
||||||
targetManagement.create(entityFactory.target().create().controllerId("123"));
|
targetManagement.create(entityFactory.target().create().controllerId("123"));
|
||||||
|
|
||||||
assertThatExceptionOfType(EntityAlreadyExistsException.class)
|
assertThatExceptionOfType(EntityAlreadyExistsException.class)
|
||||||
@@ -220,8 +223,8 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that a target with with invalid properties cannot be created or updated")
|
@Description("Verify that a target with with invalid properties cannot be created or updated")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 0) })
|
@Expect(type = TargetUpdatedEvent.class) })
|
||||||
public void createAndUpdateTargetWithInvalidFields() {
|
void createAndUpdateTargetWithInvalidFields() {
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
|
|
||||||
createTargetWithInvalidControllerId();
|
createTargetWithInvalidControllerId();
|
||||||
@@ -235,54 +238,53 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
private void createAndUpdateTargetWithInvalidDescription(final Target target) {
|
private void createAndUpdateTargetWithInvalidDescription(final Target target) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too long description should not be created")
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||||
.description(RandomStringUtils.randomAlphanumeric(513))))
|
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||||
.as("target with too long description should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with invalid description should not be created")
|
||||||
.isThrownBy(() -> targetManagement
|
.isThrownBy(() -> targetManagement
|
||||||
.create(entityFactory.target().create().controllerId("a").description(INVALID_TEXT_HTML)))
|
.create(entityFactory.target().create().controllerId("a").description(INVALID_TEXT_HTML)));
|
||||||
.as("target with invalid description should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too long description should not be updated")
|
||||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||||
.description(RandomStringUtils.randomAlphanumeric(513))))
|
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||||
.as("target with too long description should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with invalid description should not be updated")
|
||||||
.isThrownBy(() -> targetManagement
|
.isThrownBy(() -> targetManagement
|
||||||
.update(entityFactory.target().update(target.getControllerId()).description(INVALID_TEXT_HTML)))
|
.update(entityFactory.target().update(target.getControllerId()).description(INVALID_TEXT_HTML)));
|
||||||
.as("target with invalid description should not be updated");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createAndUpdateTargetWithInvalidName(final Target target) {
|
private void createAndUpdateTargetWithInvalidName(final Target target) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too long name should not be created")
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))))
|
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||||
.as("target with too long name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with invalid name should not be created")
|
||||||
.isThrownBy(() -> targetManagement
|
.isThrownBy(() -> targetManagement
|
||||||
.create(entityFactory.target().create().controllerId("a").name(INVALID_TEXT_HTML)))
|
.create(entityFactory.target().create().controllerId("a").name(INVALID_TEXT_HTML)));
|
||||||
.as("target with invalid name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too long name should not be updated")
|
||||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))))
|
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||||
.as("target with too long name should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with invalid name should not be updated")
|
||||||
.isThrownBy(() -> targetManagement
|
.isThrownBy(() -> targetManagement
|
||||||
.update(entityFactory.target().update(target.getControllerId()).name(INVALID_TEXT_HTML)))
|
.update(entityFactory.target().update(target.getControllerId()).name(INVALID_TEXT_HTML)));
|
||||||
.as("target with invalid name should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too short name should not be updated")
|
||||||
.isThrownBy(
|
.isThrownBy(
|
||||||
() -> targetManagement.update(entityFactory.target().update(target.getControllerId()).name("")))
|
() -> targetManagement.update(entityFactory.target().update(target.getControllerId()).name("")));
|
||||||
.as("target with too short name should not be updated");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,90 +292,90 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
private void createAndUpdateTargetWithInvalidSecurityToken(final Target target) {
|
private void createAndUpdateTargetWithInvalidSecurityToken(final Target target) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too long token should not be created")
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||||
.securityToken(RandomStringUtils.randomAlphanumeric(Target.SECURITY_TOKEN_MAX_SIZE + 1))))
|
.securityToken(RandomStringUtils.randomAlphanumeric(Target.SECURITY_TOKEN_MAX_SIZE + 1))));
|
||||||
.as("target with too long token should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with invalid token should not be created")
|
||||||
.isThrownBy(() -> targetManagement
|
.isThrownBy(() -> targetManagement
|
||||||
.create(entityFactory.target().create().controllerId("a").securityToken(INVALID_TEXT_HTML)))
|
.create(entityFactory.target().create().controllerId("a").securityToken(INVALID_TEXT_HTML)));
|
||||||
.as("target with invalid token should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too long token should not be updated")
|
||||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||||
.securityToken(RandomStringUtils.randomAlphanumeric(Target.SECURITY_TOKEN_MAX_SIZE + 1))))
|
.securityToken(RandomStringUtils.randomAlphanumeric(Target.SECURITY_TOKEN_MAX_SIZE + 1))));
|
||||||
.as("target with too long token should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with invalid token should not be updated")
|
||||||
.isThrownBy(() -> targetManagement.update(
|
.isThrownBy(() -> targetManagement.update(
|
||||||
entityFactory.target().update(target.getControllerId()).securityToken(INVALID_TEXT_HTML)))
|
entityFactory.target().update(target.getControllerId()).securityToken(INVALID_TEXT_HTML)));
|
||||||
.as("target with invalid token should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too short token should not be updated")
|
||||||
.isThrownBy(() -> targetManagement
|
.isThrownBy(() -> targetManagement
|
||||||
.update(entityFactory.target().update(target.getControllerId()).securityToken("")))
|
.update(entityFactory.target().update(target.getControllerId()).securityToken("")));
|
||||||
.as("target with too short token should not be updated");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createAndUpdateTargetWithInvalidAddress(final Target target) {
|
private void createAndUpdateTargetWithInvalidAddress(final Target target) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too long address should not be created")
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||||
.address(RandomStringUtils.randomAlphanumeric(513))))
|
.address(RandomStringUtils.randomAlphanumeric(513))));
|
||||||
.as("target with too long address should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidTargetAddressException.class)
|
assertThatExceptionOfType(InvalidTargetAddressException.class)
|
||||||
|
.as("target with invalid should not be created")
|
||||||
.isThrownBy(() -> targetManagement
|
.isThrownBy(() -> targetManagement
|
||||||
.create(entityFactory.target().create().controllerId("a").address(INVALID_TEXT_HTML)))
|
.create(entityFactory.target().create().controllerId("a").address(INVALID_TEXT_HTML)));
|
||||||
.as("target with invalid should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too long address should not be updated")
|
||||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||||
.address(RandomStringUtils.randomAlphanumeric(513))))
|
.address(RandomStringUtils.randomAlphanumeric(513))));
|
||||||
.as("target with too long address should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(InvalidTargetAddressException.class)
|
assertThatExceptionOfType(InvalidTargetAddressException.class)
|
||||||
|
.as("target with invalid address should not be updated")
|
||||||
.isThrownBy(() -> targetManagement
|
.isThrownBy(() -> targetManagement
|
||||||
.update(entityFactory.target().update(target.getControllerId()).address(INVALID_TEXT_HTML)))
|
.update(entityFactory.target().update(target.getControllerId()).address(INVALID_TEXT_HTML)));
|
||||||
.as("target with invalid address should not be updated");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createTargetWithInvalidControllerId() {
|
private void createTargetWithInvalidControllerId() {
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("")))
|
.as("target with empty controller id should not be created")
|
||||||
.as("target with empty controller id should not be created");
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("")));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(null)))
|
.as("target with null controller id should not be created")
|
||||||
.as("target with null controller id should not be created");
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(null)));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with too long controller id should not be created")
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create()
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create()
|
||||||
.controllerId(RandomStringUtils.randomAlphanumeric(Target.CONTROLLER_ID_MAX_SIZE + 1))))
|
.controllerId(RandomStringUtils.randomAlphanumeric(Target.CONTROLLER_ID_MAX_SIZE + 1))));
|
||||||
.as("target with too long controller id should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("target with invalid controller id should not be created")
|
||||||
.isThrownBy(
|
.isThrownBy(
|
||||||
() -> targetManagement.create(entityFactory.target().create().controllerId(INVALID_TEXT_HTML)))
|
() -> targetManagement.create(entityFactory.target().create().controllerId(INVALID_TEXT_HTML)));
|
||||||
.as("target with invalid controller id should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")))
|
.as(WHITESPACE_ERROR)
|
||||||
.as(WHITESPACE_ERROR);
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a b")))
|
.as(WHITESPACE_ERROR)
|
||||||
.as(WHITESPACE_ERROR);
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a b")));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")))
|
.as(WHITESPACE_ERROR)
|
||||||
.as(WHITESPACE_ERROR);
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("aaa bbb")))
|
.as(WHITESPACE_ERROR)
|
||||||
.as(WHITESPACE_ERROR);
|
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("aaa bbb")));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +384,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 4),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 4),
|
||||||
@Expect(type = TargetTagCreatedEvent.class, count = 1),
|
@Expect(type = TargetTagCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 5) })
|
@Expect(type = TargetUpdatedEvent.class, count = 5) })
|
||||||
public void assignAndUnassignTargetsToTag() {
|
void assignAndUnassignTargetsToTag() {
|
||||||
final List<String> assignTarget = new ArrayList<>();
|
final List<String> assignTarget = new ArrayList<>();
|
||||||
assignTarget.add(
|
assignTarget.add(
|
||||||
targetManagement.create(entityFactory.target().create().controllerId("targetId123")).getControllerId());
|
targetManagement.create(entityFactory.target().create().controllerId("targetId123")).getControllerId());
|
||||||
@@ -400,7 +402,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assignedTargets.forEach(target -> assertThat(
|
assignedTargets.forEach(target -> assertThat(
|
||||||
targetTagManagement.findByTarget(PAGE, target.getControllerId()).getNumberOfElements()).isEqualTo(1));
|
targetTagManagement.findByTarget(PAGE, target.getControllerId()).getNumberOfElements()).isEqualTo(1));
|
||||||
|
|
||||||
TargetTag findTargetTag = targetTagManagement.getByName("Tag1").get();
|
TargetTag findTargetTag = targetTagManagement.getByName("Tag1").orElseThrow(IllegalStateException::new);
|
||||||
assertThat(assignedTargets.size()).as("Assigned targets are wrong")
|
assertThat(assignedTargets.size()).as("Assigned targets are wrong")
|
||||||
.isEqualTo(targetManagement.findByTag(PAGE, targetTag.getId()).getNumberOfElements());
|
.isEqualTo(targetManagement.findByTag(PAGE, targetTag.getId()).getNumberOfElements());
|
||||||
|
|
||||||
@@ -408,7 +410,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assertThat(unAssignTarget.getControllerId()).as("Controller id is wrong").isEqualTo("targetId123");
|
assertThat(unAssignTarget.getControllerId()).as("Controller id is wrong").isEqualTo("targetId123");
|
||||||
assertThat(targetTagManagement.findByTarget(PAGE, unAssignTarget.getControllerId())).as("Tag size is wrong")
|
assertThat(targetTagManagement.findByTarget(PAGE, unAssignTarget.getControllerId())).as("Tag size is wrong")
|
||||||
.isEmpty();
|
.isEmpty();
|
||||||
findTargetTag = targetTagManagement.getByName("Tag1").get();
|
targetTagManagement.getByName("Tag1").orElseThrow(NoSuchElementException::new);
|
||||||
assertThat(targetManagement.findByTag(PAGE, targetTag.getId())).as("Assigned targets are wrong").hasSize(3);
|
assertThat(targetManagement.findByTag(PAGE, targetTag.getId())).as("Assigned targets are wrong").hasSize(3);
|
||||||
assertThat(targetManagement.findByRsqlAndTag(PAGE, "controllerId==targetId123", targetTag.getId()))
|
assertThat(targetManagement.findByRsqlAndTag(PAGE, "controllerId==targetId123", targetTag.getId()))
|
||||||
.as("Assigned targets are wrong").isEmpty();
|
.as("Assigned targets are wrong").isEmpty();
|
||||||
@@ -421,17 +423,17 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Ensures that targets can deleted e.g. test all cascades")
|
@Description("Ensures that targets can deleted e.g. test all cascades")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 12),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 12),
|
||||||
@Expect(type = TargetDeletedEvent.class, count = 12), @Expect(type = TargetUpdatedEvent.class, count = 6) })
|
@Expect(type = TargetDeletedEvent.class, count = 12), @Expect(type = TargetUpdatedEvent.class, count = 6) })
|
||||||
public void deleteAndCreateTargets() {
|
void deleteAndCreateTargets() {
|
||||||
Target target = targetManagement.create(entityFactory.target().create().controllerId("targetId123"));
|
Target target = targetManagement.create(entityFactory.target().create().controllerId("targetId123"));
|
||||||
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(1);
|
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(1);
|
||||||
targetManagement.delete(Collections.singletonList(target.getId()));
|
targetManagement.delete(Collections.singletonList(target.getId()));
|
||||||
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(0);
|
assertThat(targetManagement.count()).as("target count is wrong").isZero();
|
||||||
|
|
||||||
target = createTargetWithAttributes("4711");
|
target = createTargetWithAttributes("4711");
|
||||||
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(1);
|
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(1);
|
||||||
assertThat(targetManagement.existsByControllerId("4711")).isTrue();
|
assertThat(targetManagement.existsByControllerId("4711")).isTrue();
|
||||||
targetManagement.delete(Collections.singletonList(target.getId()));
|
targetManagement.delete(Collections.singletonList(target.getId()));
|
||||||
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(0);
|
assertThat(targetManagement.count()).as("target count is wrong").isZero();
|
||||||
assertThat(targetManagement.existsByControllerId("4711")).isFalse();
|
assertThat(targetManagement.existsByControllerId("4711")).isFalse();
|
||||||
|
|
||||||
final List<Long> targets = new ArrayList<>();
|
final List<Long> targets = new ArrayList<>();
|
||||||
@@ -442,7 +444,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(10);
|
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(10);
|
||||||
targetManagement.delete(targets);
|
targetManagement.delete(targets);
|
||||||
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(0);
|
assertThat(targetManagement.count()).as("target count is wrong").isZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Target createTargetWithAttributes(final String controllerId) {
|
private Target createTargetWithAttributes(final String controllerId) {
|
||||||
@@ -466,60 +468,72 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void findTargetByControllerIDWithDetails() {
|
void findTargetByControllerIDWithDetails() {
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("test");
|
final DistributionSet testDs1 = testdataFactory.createDistributionSet("test");
|
||||||
final DistributionSet set2 = testdataFactory.createDistributionSet("test2");
|
final DistributionSet testDs2 = testdataFactory.createDistributionSet("test2");
|
||||||
|
|
||||||
assertThat(targetManagement.countByAssignedDistributionSet(set.getId())).as("Target count is wrong")
|
assertThat(targetManagement.countByAssignedDistributionSet(testDs1.getId()))
|
||||||
.isEqualTo(0);
|
.as("For newly created distributions sets the assigned target count should be zero")
|
||||||
assertThat(targetManagement.countByInstalledDistributionSet(set.getId())).as("Target count is wrong")
|
.isZero();
|
||||||
.isEqualTo(0);
|
assertThat(targetManagement.countByInstalledDistributionSet(testDs1.getId()))
|
||||||
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(set.getId())).as("Target count is wrong")
|
.as("For newly created distributions sets the installed target count should be zero")
|
||||||
|
.isZero();
|
||||||
|
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs1.getId()))
|
||||||
|
.as("Exists assigned or installed query should return false for new distribution sets")
|
||||||
.isFalse();
|
.isFalse();
|
||||||
assertThat(targetManagement.countByAssignedDistributionSet(set2.getId())).as("Target count is wrong")
|
assertThat(targetManagement.countByAssignedDistributionSet(testDs2.getId()))
|
||||||
.isEqualTo(0);
|
.as("For newly created distributions sets the assigned target count should be zero")
|
||||||
assertThat(targetManagement.countByInstalledDistributionSet(set2.getId())).as("Target count is wrong")
|
.isZero();
|
||||||
.isEqualTo(0);
|
assertThat(targetManagement.countByInstalledDistributionSet(testDs2.getId()))
|
||||||
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(set2.getId()))
|
.as("For newly created distributions sets the installed target count should be zero")
|
||||||
.as("Target count is wrong").isFalse();
|
.isZero();
|
||||||
|
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs2.getId()))
|
||||||
|
.as("For newly created distributions sets the assigned target count should be zero").isFalse();
|
||||||
|
|
||||||
Target target = createTargetWithAttributes("4711");
|
Target target = createTargetWithAttributes("4711");
|
||||||
|
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
controllerManagement.findOrRegisterTargetIfItDoesNotExist("4711", LOCALHOST);
|
controllerManagement.findOrRegisterTargetIfItDoesNotExist("4711", LOCALHOST);
|
||||||
|
|
||||||
final DistributionSetAssignmentResult result = assignDistributionSet(set.getId(), "4711");
|
final DistributionSetAssignmentResult result = assignDistributionSet(testDs1.getId(), "4711");
|
||||||
|
|
||||||
controllerManagement.addUpdateActionStatus(
|
controllerManagement.addUpdateActionStatus(
|
||||||
entityFactory.actionStatus().create(getFirstAssignedActionId(result)).status(Status.FINISHED));
|
entityFactory.actionStatus().create(getFirstAssignedActionId(result)).status(Status.FINISHED));
|
||||||
assignDistributionSet(set2.getId(), "4711");
|
assignDistributionSet(testDs2.getId(), "4711");
|
||||||
|
|
||||||
target = targetManagement.getByControllerID("4711").get();
|
target = targetManagement.getByControllerID("4711").orElseThrow(IllegalStateException::new);
|
||||||
// read data
|
// read data
|
||||||
|
|
||||||
assertThat(targetManagement.countByAssignedDistributionSet(set.getId())).as("Target count is wrong")
|
assertThat(targetManagement.countByAssignedDistributionSet(testDs1.getId())).as("Target count is wrong")
|
||||||
.isEqualTo(0);
|
.isZero();
|
||||||
assertThat(targetManagement.countByInstalledDistributionSet(set.getId())).as("Target count is wrong")
|
assertThat(targetManagement.countByInstalledDistributionSet(testDs1.getId())).as("Target count is wrong")
|
||||||
.isEqualTo(1);
|
.isEqualTo(1);
|
||||||
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(set.getId())).as("Target count is wrong")
|
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs1.getId())).as("Target count is wrong")
|
||||||
.isTrue();
|
.isTrue();
|
||||||
assertThat(targetManagement.countByAssignedDistributionSet(set2.getId())).as("Target count is wrong")
|
assertThat(targetManagement.countByAssignedDistributionSet(testDs2.getId())).as("Target count is wrong")
|
||||||
.isEqualTo(1);
|
.isEqualTo(1);
|
||||||
assertThat(targetManagement.countByInstalledDistributionSet(set2.getId())).as("Target count is wrong")
|
assertThat(targetManagement.countByInstalledDistributionSet(testDs2.getId())).as("Target count is wrong")
|
||||||
.isEqualTo(0);
|
.isZero();
|
||||||
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(set2.getId()))
|
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs2.getId()))
|
||||||
.as("Target count is wrong").isTrue();
|
.as("Target count is wrong").isTrue();
|
||||||
assertThat(target.getLastTargetQuery()).as("Target query is not work").isGreaterThanOrEqualTo(current);
|
assertThat(target.getLastTargetQuery()).as("Target query is not work").isGreaterThanOrEqualTo(current);
|
||||||
assertThat(deploymentManagement.getAssignedDistributionSet("4711").get()).as("Assigned ds size is wrong")
|
|
||||||
.isEqualTo(set2);
|
final DistributionSet assignedDs = deploymentManagement.getAssignedDistributionSet("4711")
|
||||||
assertThat(deploymentManagement.getInstalledDistributionSet("4711").get()).as("Installed ds is wrong")
|
.orElseThrow(NoSuchElementException::new);
|
||||||
.isEqualTo(set);
|
assertThat(assignedDs).as("Assigned ds size is wrong")
|
||||||
|
.isEqualTo(testDs2);
|
||||||
|
|
||||||
|
final DistributionSet installedDs = deploymentManagement.getInstalledDistributionSet("4711")
|
||||||
|
.orElseThrow(NoSuchElementException::new);
|
||||||
|
assertThat(installedDs)
|
||||||
|
.as("Installed ds is wrong")
|
||||||
|
.isEqualTo(testDs1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Checks if the EntityAlreadyExistsException is thrown if the targets with the same controller ID are created twice.")
|
@Description("Checks if the EntityAlreadyExistsException is thrown if the targets with the same controller ID are created twice.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 5) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 5) })
|
||||||
public void createMultipleTargetsDuplicate() {
|
void createMultipleTargetsDuplicate() {
|
||||||
testdataFactory.createTargets(5, "mySimpleTargs", "my simple targets");
|
testdataFactory.createTargets(5, "mySimpleTargs", "my simple targets");
|
||||||
try {
|
try {
|
||||||
testdataFactory.createTargets(5, "mySimpleTargs", "my simple targets");
|
testdataFactory.createTargets(5, "mySimpleTargs", "my simple targets");
|
||||||
@@ -532,7 +546,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Checks if the EntityAlreadyExistsException is thrown if a single target with the same controller ID are created twice.")
|
@Description("Checks if the EntityAlreadyExistsException is thrown if a single target with the same controller ID are created twice.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
|
||||||
public void createTargetDuplicate() {
|
void createTargetDuplicate() {
|
||||||
targetManagement.create(entityFactory.target().create().controllerId("4711"));
|
targetManagement.create(entityFactory.target().create().controllerId("4711"));
|
||||||
try {
|
try {
|
||||||
targetManagement.create(entityFactory.target().create().controllerId("4711"));
|
targetManagement.create(entityFactory.target().create().controllerId("4711"));
|
||||||
@@ -554,8 +568,6 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
* targets to be verified
|
* targets to be verified
|
||||||
* @param tags
|
* @param tags
|
||||||
* are contained within tags of all targets.
|
* are contained within tags of all targets.
|
||||||
* @param tags
|
|
||||||
* to be found in the tags of the targets
|
|
||||||
*/
|
*/
|
||||||
private void checkTargetHasTags(final boolean strict, final Iterable<Target> targets, final TargetTag... tags) {
|
private void checkTargetHasTags(final boolean strict, final Iterable<Target> targets, final TargetTag... tags) {
|
||||||
_target: for (final Target tl : targets) {
|
_target: for (final Target tl : targets) {
|
||||||
@@ -592,34 +604,29 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Creates and updates a target and verifies the changes in the repository.")
|
@Description("Creates and updates a target and verifies the changes in the repository.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1) })
|
||||||
public void singleTargetIsInsertedIntoRepo() throws Exception {
|
void singleTargetIsInsertedIntoRepo() throws Exception {
|
||||||
|
|
||||||
final String myCtrlID = "myCtrlID";
|
final String myCtrlID = "myCtrlID";
|
||||||
|
|
||||||
Target savedTarget = testdataFactory.createTarget(myCtrlID);
|
Target savedTarget = testdataFactory.createTarget(myCtrlID);
|
||||||
assertThat(savedTarget).isNotNull().as("The target should not be null");
|
assertThat(savedTarget).as("The target should not be null").isNotNull();
|
||||||
final Long createdAt = savedTarget.getCreatedAt();
|
final long createdAt = savedTarget.getCreatedAt();
|
||||||
Long modifiedAt = savedTarget.getLastModifiedAt();
|
long modifiedAt = savedTarget.getLastModifiedAt();
|
||||||
|
|
||||||
assertThat(createdAt).as("CreatedAt compared with modifiedAt").isEqualTo(modifiedAt);
|
assertThat(createdAt).as("CreatedAt compared with modifiedAt").isEqualTo(modifiedAt);
|
||||||
assertThat(savedTarget.getCreatedAt()).isNotNull()
|
|
||||||
.as("The createdAt attribute of the target should no be null");
|
|
||||||
assertThat(savedTarget.getLastModifiedAt()).isNotNull()
|
|
||||||
.as("The lastModifiedAt attribute of the target should no be null");
|
|
||||||
|
|
||||||
Thread.sleep(1);
|
Awaitility.await().until( () -> System.currentTimeMillis() > createdAt + 1);
|
||||||
|
|
||||||
savedTarget = targetManagement.update(
|
savedTarget = targetManagement.update(
|
||||||
entityFactory.target().update(savedTarget.getControllerId()).description("changed description"));
|
entityFactory.target().update(savedTarget.getControllerId()).description("changed description"));
|
||||||
assertThat(savedTarget.getLastModifiedAt()).isNotNull()
|
|
||||||
.as("The lastModifiedAt attribute of the target should not be null");
|
|
||||||
assertThat(createdAt).as("CreatedAt compared with saved modifiedAt")
|
assertThat(createdAt).as("CreatedAt compared with saved modifiedAt")
|
||||||
.isNotEqualTo(savedTarget.getLastModifiedAt());
|
.isNotEqualTo(savedTarget.getLastModifiedAt());
|
||||||
assertThat(modifiedAt).as("ModifiedAt compared with saved modifiedAt")
|
assertThat(modifiedAt).as("ModifiedAt compared with saved modifiedAt")
|
||||||
.isNotEqualTo(savedTarget.getLastModifiedAt());
|
.isNotEqualTo(savedTarget.getLastModifiedAt());
|
||||||
modifiedAt = savedTarget.getLastModifiedAt();
|
modifiedAt = savedTarget.getLastModifiedAt();
|
||||||
|
|
||||||
final Target foundTarget = targetManagement.getByControllerID(savedTarget.getControllerId()).get();
|
final Target foundTarget = targetManagement.getByControllerID(savedTarget.getControllerId()).orElseThrow(IllegalStateException::new);
|
||||||
assertThat(foundTarget).isNotNull().as("The target should not be null");
|
assertThat(foundTarget).as("The target should not be null").isNotNull();
|
||||||
assertThat(myCtrlID).as("ControllerId compared with saved controllerId")
|
assertThat(myCtrlID).as("ControllerId compared with saved controllerId")
|
||||||
.isEqualTo(foundTarget.getControllerId());
|
.isEqualTo(foundTarget.getControllerId());
|
||||||
assertThat(savedTarget).as("Target compared with saved target").isEqualTo(foundTarget);
|
assertThat(savedTarget).as("Target compared with saved target").isEqualTo(foundTarget);
|
||||||
@@ -634,7 +641,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 101),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 101),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 100),
|
@Expect(type = TargetUpdatedEvent.class, count = 100),
|
||||||
@Expect(type = TargetDeletedEvent.class, count = 51) })
|
@Expect(type = TargetDeletedEvent.class, count = 51) })
|
||||||
public void bulkTargetCreationAndDelete() throws Exception {
|
void bulkTargetCreationAndDelete() {
|
||||||
final String myCtrlID = "myCtrlID";
|
final String myCtrlID = "myCtrlID";
|
||||||
List<Target> firstList = testdataFactory.createTargets(100, myCtrlID, "first description");
|
List<Target> firstList = testdataFactory.createTargets(100, myCtrlID, "first description");
|
||||||
|
|
||||||
@@ -699,7 +706,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 2),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetTagCreatedEvent.class, count = 7),
|
@Expect(type = TargetTagCreatedEvent.class, count = 7),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 7) })
|
@Expect(type = TargetUpdatedEvent.class, count = 7) })
|
||||||
public void targetTagAssignment() {
|
void targetTagAssignment() {
|
||||||
final Target t1 = testdataFactory.createTarget("id-1");
|
final Target t1 = testdataFactory.createTarget("id-1");
|
||||||
final int noT2Tags = 4;
|
final int noT2Tags = 4;
|
||||||
final int noT1Tags = 3;
|
final int noT1Tags = 3;
|
||||||
@@ -711,13 +718,13 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
final List<TargetTag> t2Tags = testdataFactory.createTargetTags(noT2Tags, "tag2");
|
final List<TargetTag> t2Tags = testdataFactory.createTargetTags(noT2Tags, "tag2");
|
||||||
t2Tags.forEach(tag -> targetManagement.assignTag(Collections.singletonList(t2.getControllerId()), tag.getId()));
|
t2Tags.forEach(tag -> targetManagement.assignTag(Collections.singletonList(t2.getControllerId()), tag.getId()));
|
||||||
|
|
||||||
final Target t11 = targetManagement.getByControllerID(t1.getControllerId()).get();
|
final Target t11 = targetManagement.getByControllerID(t1.getControllerId()).orElseThrow(IllegalStateException::new);
|
||||||
assertThat(targetTagManagement.findByTarget(PAGE, t11.getControllerId()).getContent()).as("Tag size is wrong")
|
assertThat(targetTagManagement.findByTarget(PAGE, t11.getControllerId()).getContent()).as("Tag size is wrong")
|
||||||
.hasSize(noT1Tags).containsAll(t1Tags);
|
.hasSize(noT1Tags).containsAll(t1Tags);
|
||||||
assertThat(targetTagManagement.findByTarget(PAGE, t11.getControllerId()).getContent()).as("Tag size is wrong")
|
assertThat(targetTagManagement.findByTarget(PAGE, t11.getControllerId()).getContent()).as("Tag size is wrong")
|
||||||
.hasSize(noT1Tags).doesNotContain(Iterables.toArray(t2Tags, TargetTag.class));
|
.hasSize(noT1Tags).doesNotContain(Iterables.toArray(t2Tags, TargetTag.class));
|
||||||
|
|
||||||
final Target t21 = targetManagement.getByControllerID(t2.getControllerId()).get();
|
final Target t21 = targetManagement.getByControllerID(t2.getControllerId()).orElseThrow(IllegalStateException::new);
|
||||||
assertThat(targetTagManagement.findByTarget(PAGE, t21.getControllerId()).getContent()).as("Tag size is wrong")
|
assertThat(targetTagManagement.findByTarget(PAGE, t21.getControllerId()).getContent()).as("Tag size is wrong")
|
||||||
.hasSize(noT2Tags).containsAll(t2Tags);
|
.hasSize(noT2Tags).containsAll(t2Tags);
|
||||||
assertThat(targetTagManagement.findByTarget(PAGE, t21.getControllerId()).getContent()).as("Tag size is wrong")
|
assertThat(targetTagManagement.findByTarget(PAGE, t21.getControllerId()).getContent()).as("Tag size is wrong")
|
||||||
@@ -729,7 +736,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 50),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 50),
|
||||||
@Expect(type = TargetTagCreatedEvent.class, count = 4),
|
@Expect(type = TargetTagCreatedEvent.class, count = 4),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 80) })
|
@Expect(type = TargetUpdatedEvent.class, count = 80) })
|
||||||
public void targetTagBulkAssignments() {
|
void targetTagBulkAssignments() {
|
||||||
final List<Target> tagATargets = testdataFactory.createTargets(10, "tagATargets", "first description");
|
final List<Target> tagATargets = testdataFactory.createTargets(10, "tagATargets", "first description");
|
||||||
final List<Target> tagBTargets = testdataFactory.createTargets(10, "tagBTargets", "first description");
|
final List<Target> tagBTargets = testdataFactory.createTargets(10, "tagBTargets", "first description");
|
||||||
final List<Target> tagCTargets = testdataFactory.createTargets(10, "tagCTargets", "first description");
|
final List<Target> tagCTargets = testdataFactory.createTargets(10, "tagCTargets", "first description");
|
||||||
@@ -756,7 +763,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
toggleTagAssignment(tagABCTargets, tagC);
|
toggleTagAssignment(tagABCTargets, tagC);
|
||||||
|
|
||||||
assertThat(targetManagement.countByFilters(new FilterParams(null, null, null, null, Boolean.FALSE, "X")))
|
assertThat(targetManagement.countByFilters(new FilterParams(null, null, null, null, Boolean.FALSE, "X")))
|
||||||
.as("Target count is wrong").isEqualTo(0);
|
.as("Target count is wrong").isZero();
|
||||||
|
|
||||||
// search for targets with tag tagA
|
// search for targets with tag tagA
|
||||||
final List<Target> targetWithTagA = new ArrayList<>();
|
final List<Target> targetWithTagA = new ArrayList<>();
|
||||||
@@ -798,7 +805,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 3),
|
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 3),
|
||||||
@Expect(type = TargetCreatedEvent.class, count = 109),
|
@Expect(type = TargetCreatedEvent.class, count = 109),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 227) })
|
@Expect(type = TargetUpdatedEvent.class, count = 227) })
|
||||||
public void targetTagBulkUnassignments() {
|
void targetTagBulkUnassignments() {
|
||||||
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag"));
|
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag"));
|
||||||
final TargetTag targTagB = targetTagManagement.create(entityFactory.tag().create().name("Targ-B-Tag"));
|
final TargetTag targTagB = targetTagManagement.create(entityFactory.tag().create().name("Targ-B-Tag"));
|
||||||
final TargetTag targTagC = targetTagManagement.create(entityFactory.tag().create().name("Targ-C-Tag"));
|
final TargetTag targTagC = targetTagManagement.create(entityFactory.tag().create().name("Targ-C-Tag"));
|
||||||
@@ -856,7 +863,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetCreatedEvent.class, count = 50),
|
@Expect(type = TargetCreatedEvent.class, count = 50),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 25) })
|
@Expect(type = TargetUpdatedEvent.class, count = 25) })
|
||||||
public void findTargetsWithNoTag() {
|
void findTargetsWithNoTag() {
|
||||||
|
|
||||||
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag"));
|
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag"));
|
||||||
final List<Target> targAs = testdataFactory.createTargets(25, "target-id-A", "first description");
|
final List<Target> targAs = testdataFactory.createTargets(25, "target-id-A", "first description");
|
||||||
@@ -868,8 +875,8 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
final List<Target> targetsListWithNoTag = targetManagement
|
final List<Target> targetsListWithNoTag = targetManagement
|
||||||
.findByFilters(PAGE, new FilterParams(null, null, null, null, Boolean.TRUE, tagNames)).getContent();
|
.findByFilters(PAGE, new FilterParams(null, null, null, null, Boolean.TRUE, tagNames)).getContent();
|
||||||
|
|
||||||
assertThat(50L).as("Total targets").isEqualTo(targetManagement.count());
|
assertThat(targetManagement.count()).as("Total targets").isEqualTo(50L);
|
||||||
assertThat(25).as("Targets with no tag").isEqualTo(targetsListWithNoTag.size());
|
assertThat(targetsListWithNoTag.size()).as("Targets with no tag").isEqualTo(25);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -877,12 +884,13 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Tests the a target can be read with only the read target permission")
|
@Description("Tests the a target can be read with only the read target permission")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void targetCanBeReadWithOnlyReadTargetPermission() throws Exception {
|
void targetCanBeReadWithOnlyReadTargetPermission() throws Exception {
|
||||||
final String knownTargetControllerId = "readTarget";
|
final String knownTargetControllerId = "readTarget";
|
||||||
controllerManagement.findOrRegisterTargetIfItDoesNotExist(knownTargetControllerId, new URI("http://127.0.0.1"));
|
controllerManagement.findOrRegisterTargetIfItDoesNotExist(knownTargetControllerId, new URI("http://127.0.0.1"));
|
||||||
|
|
||||||
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withUser("bumlux", "READ_TARGET"), () -> {
|
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withUser("bumlux", "READ_TARGET"), () -> {
|
||||||
final Target findTargetByControllerID = targetManagement.getByControllerID(knownTargetControllerId).get();
|
final Target findTargetByControllerID = targetManagement.getByControllerID(knownTargetControllerId)
|
||||||
|
.orElseThrow(IllegalStateException::new);
|
||||||
assertThat(findTargetByControllerID).isNotNull();
|
assertThat(findTargetByControllerID).isNotNull();
|
||||||
assertThat(findTargetByControllerID.getPollStatus()).isNotNull();
|
assertThat(findTargetByControllerID.getPollStatus()).isNotNull();
|
||||||
return null;
|
return null;
|
||||||
@@ -892,7 +900,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test that RSQL filter finds targets with tags or specific ids.")
|
@Description("Test that RSQL filter finds targets with tags or specific ids.")
|
||||||
public void findTargetsWithTagOrId() {
|
void findTargetsWithTagOrId() {
|
||||||
final String rsqlFilter = "tag==Targ-A-Tag,id==target-id-B-00001,id==target-id-B-00008";
|
final String rsqlFilter = "tag==Targ-A-Tag,id==target-id-B-00001,id==target-id-B-00008";
|
||||||
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag"));
|
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag"));
|
||||||
final List<String> targAs = testdataFactory.createTargets(25, "target-id-A", "first description").stream()
|
final List<String> targAs = testdataFactory.createTargets(25, "target-id-A", "first description").stream()
|
||||||
@@ -910,7 +918,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that the find all targets by ids method contains the entities that we are looking for")
|
@Description("Verify that the find all targets by ids method contains the entities that we are looking for")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 12) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 12) })
|
||||||
public void verifyFindTargetAllById() {
|
void verifyFindTargetAllById() {
|
||||||
final List<Long> searchIds = Arrays.asList(testdataFactory.createTarget("target-4").getId(),
|
final List<Long> searchIds = Arrays.asList(testdataFactory.createTarget("target-4").getId(),
|
||||||
testdataFactory.createTarget("target-5").getId(), testdataFactory.createTarget("target-6").getId());
|
testdataFactory.createTarget("target-5").getId(), testdataFactory.createTarget("target-6").getId());
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
@@ -927,7 +935,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that the flag for requesting controller attributes is set correctly.")
|
@Description("Verify that the flag for requesting controller attributes is set correctly.")
|
||||||
public void verifyRequestControllerAttributes() {
|
void verifyRequestControllerAttributes() {
|
||||||
final String knownControllerId = "KnownControllerId";
|
final String knownControllerId = "KnownControllerId";
|
||||||
final Target target = createTargetWithAttributes(knownControllerId);
|
final Target target = createTargetWithAttributes(knownControllerId);
|
||||||
|
|
||||||
@@ -945,7 +953,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Checks that metadata for a target can be created.")
|
@Description("Checks that metadata for a target can be created.")
|
||||||
public void createTargetMetadata() {
|
void createTargetMetadata() {
|
||||||
final String knownKey = "targetMetaKnownKey";
|
final String knownKey = "targetMetaKnownKey";
|
||||||
final String knownValue = "targetMetaKnownValue";
|
final String knownValue = "targetMetaKnownValue";
|
||||||
|
|
||||||
@@ -968,7 +976,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies the enforcement of the metadata quota per target.")
|
@Description("Verifies the enforcement of the metadata quota per target.")
|
||||||
public void createTargetMetadataUntilQuotaIsExceeded() {
|
void createTargetMetadataUntilQuotaIsExceeded() {
|
||||||
|
|
||||||
// add meta data one by one
|
// add meta data one by one
|
||||||
final Target target1 = testdataFactory.createTarget("target1");
|
final Target target1 = testdataFactory.createTarget("target1");
|
||||||
@@ -1012,7 +1020,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithUser(allSpPermissions = true)
|
@WithUser(allSpPermissions = true)
|
||||||
@Description("Checks that metadata for a target can be updated.")
|
@Description("Checks that metadata for a target can be updated.")
|
||||||
public void updateTargetMetadata() throws InterruptedException {
|
void updateTargetMetadata() throws InterruptedException {
|
||||||
final String knownKey = "myKnownKey";
|
final String knownKey = "myKnownKey";
|
||||||
final String knownValue = "myKnownValue";
|
final String knownValue = "myKnownValue";
|
||||||
final String knownUpdateValue = "myNewUpdatedValue";
|
final String knownUpdateValue = "myNewUpdatedValue";
|
||||||
@@ -1025,21 +1033,20 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
// create target meta data entry
|
// create target meta data entry
|
||||||
insertTargetMetadata(knownKey, knownValue, target);
|
insertTargetMetadata(knownKey, knownValue, target);
|
||||||
|
|
||||||
Target changedLockRevisionTarget = targetManagement.get(target.getId()).get();
|
Target changedLockRevisionTarget = targetManagement.get(target.getId()).orElseThrow(NoSuchElementException::new);
|
||||||
assertThat(changedLockRevisionTarget.getOptLockRevision()).isEqualTo(2);
|
assertThat(changedLockRevisionTarget.getOptLockRevision()).isEqualTo(2);
|
||||||
|
|
||||||
Thread.sleep(100);
|
// Unsure if needed maybe to wait for a db flush?
|
||||||
|
// Thread.sleep(100);
|
||||||
|
|
||||||
// update the target metadata
|
// update the target metadata
|
||||||
final JpaTargetMetadata updated = (JpaTargetMetadata) targetManagement.updateMetadata(target.getControllerId(),
|
final JpaTargetMetadata updated = (JpaTargetMetadata) targetManagement.updateMetadata(target.getControllerId(),
|
||||||
entityFactory.generateTargetMetadata(knownKey, knownUpdateValue));
|
entityFactory.generateTargetMetadata(knownKey, knownUpdateValue));
|
||||||
// we are updating the target meta data so also modifying the base
|
// we are updating the target meta data so also modifying the base
|
||||||
// software
|
// software module so opt lock revision must be three
|
||||||
// module so opt lock
|
changedLockRevisionTarget = targetManagement.get(target.getId()).orElseThrow(NoSuchElementException::new);
|
||||||
// revision must be three
|
|
||||||
changedLockRevisionTarget = targetManagement.get(target.getId()).get();
|
|
||||||
assertThat(changedLockRevisionTarget.getOptLockRevision()).isEqualTo(3);
|
assertThat(changedLockRevisionTarget.getOptLockRevision()).isEqualTo(3);
|
||||||
assertThat(changedLockRevisionTarget.getLastModifiedAt()).isGreaterThan(0L);
|
assertThat(changedLockRevisionTarget.getLastModifiedAt()).isPositive();
|
||||||
|
|
||||||
// verify updated meta data contains the updated value
|
// verify updated meta data contains the updated value
|
||||||
assertThat(updated).isNotNull();
|
assertThat(updated).isNotNull();
|
||||||
@@ -1052,7 +1059,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithUser(allSpPermissions = true)
|
@WithUser(allSpPermissions = true)
|
||||||
@Description("Checks that target type for a target can be created, updated and unassigned.")
|
@Description("Checks that target type for a target can be created, updated and unassigned.")
|
||||||
public void createAndUpdateTargetTypeInTarget() {
|
void createAndUpdateTargetTypeInTarget() {
|
||||||
// create a target type
|
// create a target type
|
||||||
final List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 2);
|
final List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 2);
|
||||||
assertThat(targetTypes).hasSize(2);
|
assertThat(targetTypes).hasSize(2);
|
||||||
@@ -1088,7 +1095,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithUser(allSpPermissions = true)
|
@WithUser(allSpPermissions = true)
|
||||||
@Description("Checks that target type to a target can be assigned.")
|
@Description("Checks that target type to a target can be assigned.")
|
||||||
public void assignTargetTypeInTarget() {
|
void assignTargetTypeInTarget() {
|
||||||
// create a target
|
// create a target
|
||||||
final Target target = testdataFactory.createTarget("target1", "testtarget");
|
final Target target = testdataFactory.createTarget("target1", "testtarget");
|
||||||
// initial opt lock revision must be one
|
// initial opt lock revision must be one
|
||||||
@@ -1117,7 +1124,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 20),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 20),
|
||||||
@Expect(type = TargetTypeCreatedEvent.class, count = 2),
|
@Expect(type = TargetTypeCreatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 29), @Expect(type = TargetDeletedEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 29), @Expect(type = TargetDeletedEvent.class, count = 1) })
|
||||||
public void targetTypeBulkAssignments() {
|
void targetTypeBulkAssignments() {
|
||||||
final List<Target> typeATargets = testdataFactory.createTargets(10, "typeATargets", "first description");
|
final List<Target> typeATargets = testdataFactory.createTargets(10, "typeATargets", "first description");
|
||||||
final List<Target> typeBTargets = testdataFactory.createTargets(10, "typeBTargets", "first description");
|
final List<Target> typeBTargets = testdataFactory.createTargets(10, "typeBTargets", "first description");
|
||||||
|
|
||||||
@@ -1163,7 +1170,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Queries and loads the metadata related to a given target.")
|
@Description("Queries and loads the metadata related to a given target.")
|
||||||
public void findAllTargetMetadataByControllerId() {
|
void findAllTargetMetadataByControllerId() {
|
||||||
// create targets
|
// create targets
|
||||||
final Target target1 = createTargetWithMetadata("target1", 10);
|
final Target target1 = createTargetWithMetadata("target1", 10);
|
||||||
final Target target2 = createTargetWithMetadata("target2", 8);
|
final Target target2 = createTargetWithMetadata("target2", 8);
|
||||||
@@ -1194,7 +1201,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithUser(allSpPermissions = true)
|
@WithUser(allSpPermissions = true)
|
||||||
@Description("Checks that target type is not assigned to target if invalid.")
|
@Description("Checks that target type is not assigned to target if invalid.")
|
||||||
public void assignInvalidTargetTypeToTarget() {
|
void assignInvalidTargetTypeToTarget() {
|
||||||
// create a target
|
// create a target
|
||||||
final Target target = testdataFactory.createTarget("target1", "testtarget");
|
final Target target = testdataFactory.createTarget("target1", "testtarget");
|
||||||
// initial opt lock revision must be one
|
// initial opt lock revision must be one
|
||||||
@@ -1205,12 +1212,12 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// assign target type to target
|
// assign target type to target
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetManagement.assignType(targetFound.get().getControllerId(), null))
|
.as("target type with id=null cannot be assigned")
|
||||||
.as("target type with id=null cannot be assigned");
|
.isThrownBy(() -> targetManagement.assignType(targetFound.get().getControllerId(), null));
|
||||||
|
|
||||||
assertThatExceptionOfType(EntityNotFoundException.class)
|
assertThatExceptionOfType(EntityNotFoundException.class)
|
||||||
.isThrownBy(() -> targetManagement.assignType(targetFound.get().getControllerId(), 114L))
|
.as("target type with id that does not exists cannot be assigned")
|
||||||
.as("target type with id that does not exists cannot be assigned");
|
.isThrownBy(() -> targetManagement.assignType(targetFound.get().getControllerId(), 114L));
|
||||||
|
|
||||||
// opt lock revision is not changed
|
// opt lock revision is not changed
|
||||||
Optional<JpaTarget> targetFound1 = targetRepository.findById(target.getId());
|
Optional<JpaTarget> targetFound1 = targetRepository.findById(target.getId());
|
||||||
@@ -1221,7 +1228,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithUser(allSpPermissions = true)
|
@WithUser(allSpPermissions = true)
|
||||||
@Description("Checks that target type can be unassigned from target.")
|
@Description("Checks that target type can be unassigned from target.")
|
||||||
public void unAssignTargetTypeFromTarget() {
|
void unAssignTargetTypeFromTarget() {
|
||||||
// create a target type
|
// create a target type
|
||||||
TargetType targetType = testdataFactory.findOrCreateTargetType("targettype");
|
TargetType targetType = testdataFactory.findOrCreateTargetType("targettype");
|
||||||
assertThat(targetType).isNotNull();
|
assertThat(targetType).isNotNull();
|
||||||
@@ -1245,7 +1252,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test that RSQL filter finds targets with metadata and/or controllerId.")
|
@Description("Test that RSQL filter finds targets with metadata and/or controllerId.")
|
||||||
public void findTargetsByRsqlWithMetadata() {
|
void findTargetsByRsqlWithMetadata() {
|
||||||
final String controllerId1 = "target1";
|
final String controllerId1 = "target1";
|
||||||
final String controllerId2 = "target2";
|
final String controllerId2 = "target2";
|
||||||
createTargetWithMetadata(controllerId1, 2);
|
createTargetWithMetadata(controllerId1, 2);
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.repository.jpa;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -34,12 +33,12 @@ import org.eclipse.hawkbit.repository.model.TargetTag;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
|
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
import io.qameta.allure.Step;
|
import io.qameta.allure.Step;
|
||||||
import io.qameta.allure.Story;
|
import io.qameta.allure.Story;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test class for {@link TargetTagManagement}.
|
* Test class for {@link TargetTagManagement}.
|
||||||
@@ -47,13 +46,13 @@ import org.junit.jupiter.api.Test;
|
|||||||
*/
|
*/
|
||||||
@Feature("Component Tests - Repository")
|
@Feature("Component Tests - Repository")
|
||||||
@Story("Target Tag Management")
|
@Story("Target Tag Management")
|
||||||
public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that management get access reacts as specfied on calls for non existing entities by means "
|
@Description("Verifies that management get access reacts as specfied on calls for non existing entities by means "
|
||||||
+ "of Optional not present.")
|
+ "of Optional not present.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||||
public void nonExistingEntityAccessReturnsNotPresent() {
|
void nonExistingEntityAccessReturnsNotPresent() {
|
||||||
assertThat(targetTagManagement.getByName(NOT_EXIST_ID)).isNotPresent();
|
assertThat(targetTagManagement.getByName(NOT_EXIST_ID)).isNotPresent();
|
||||||
assertThat(targetTagManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
assertThat(targetTagManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
||||||
}
|
}
|
||||||
@@ -61,9 +60,8 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verifies that management queries react as specfied on calls for non existing entities "
|
@Description("Verifies that management queries react as specfied on calls for non existing entities "
|
||||||
+ " by means of throwing EntityNotFoundException.")
|
+ " by means of throwing EntityNotFoundException.")
|
||||||
@ExpectEvents({ @Expect(type = DistributionSetTagUpdatedEvent.class, count = 0),
|
@ExpectEvents({ @Expect(type = DistributionSetTagUpdatedEvent.class), @Expect(type = TargetTagUpdatedEvent.class) })
|
||||||
@Expect(type = TargetTagUpdatedEvent.class, count = 0) })
|
void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
||||||
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
|
||||||
verifyThrownExceptionBy(() -> targetTagManagement.delete(NOT_EXIST_ID), "TargetTag");
|
verifyThrownExceptionBy(() -> targetTagManagement.delete(NOT_EXIST_ID), "TargetTag");
|
||||||
|
|
||||||
verifyThrownExceptionBy(() -> targetTagManagement.update(entityFactory.tag().update(NOT_EXIST_IDL)),
|
verifyThrownExceptionBy(() -> targetTagManagement.update(entityFactory.tag().update(NOT_EXIST_IDL)),
|
||||||
@@ -74,7 +72,7 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that a tag with with invalid properties cannot be created or updated")
|
@Description("Verify that a tag with with invalid properties cannot be created or updated")
|
||||||
public void createAndUpdateTagWithInvalidFields() {
|
void createAndUpdateTagWithInvalidFields() {
|
||||||
final TargetTag tag = targetTagManagement
|
final TargetTag tag = targetTagManagement
|
||||||
.create(entityFactory.tag().create().name("tag1").description("tagdesc1"));
|
.create(entityFactory.tag().create().name("tag1").description("tagdesc1"));
|
||||||
|
|
||||||
@@ -87,80 +85,81 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
private void createAndUpdateTagWithInvalidDescription(final Tag tag) {
|
private void createAndUpdateTagWithInvalidDescription(final Tag tag) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("tag with too long description should not be created")
|
||||||
.isThrownBy(() -> targetTagManagement.create(
|
.isThrownBy(() -> targetTagManagement.create(
|
||||||
entityFactory.tag().create().name("a").description(RandomStringUtils.randomAlphanumeric(513))))
|
entityFactory.tag().create().name("a").description(RandomStringUtils.randomAlphanumeric(513))));
|
||||||
.as("tag with too long description should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
|
||||||
() -> targetTagManagement.create(entityFactory.tag().create().name("a").description(INVALID_TEXT_HTML)))
|
|
||||||
.as("tag with invalid description should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("tag with invalid description should not be created").isThrownBy(() -> targetTagManagement
|
||||||
|
.create(entityFactory.tag().create().name("a").description(INVALID_TEXT_HTML)));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("tag with too long description should not be updated")
|
||||||
.isThrownBy(() -> targetTagManagement.update(
|
.isThrownBy(() -> targetTagManagement.update(
|
||||||
entityFactory.tag().update(tag.getId()).description(RandomStringUtils.randomAlphanumeric(513))))
|
entityFactory.tag().update(tag.getId())
|
||||||
.as("tag with too long description should not be updated");
|
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("tag with invalid description should not be updated")
|
||||||
.isThrownBy(() -> targetTagManagement
|
.isThrownBy(() -> targetTagManagement
|
||||||
.update(entityFactory.tag().update(tag.getId()).description(INVALID_TEXT_HTML)))
|
.update(entityFactory.tag().update(tag.getId()).description(INVALID_TEXT_HTML)));
|
||||||
.as("tag with invalid description should not be updated");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createAndUpdateTagWithInvalidColour(final Tag tag) {
|
private void createAndUpdateTagWithInvalidColour(final Tag tag) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("tag with too long colour should not be created")
|
||||||
.isThrownBy(() -> targetTagManagement.create(
|
.isThrownBy(() -> targetTagManagement.create(
|
||||||
entityFactory.tag().create().name("a").colour(RandomStringUtils.randomAlphanumeric(17))))
|
entityFactory.tag().create().name("a").colour(RandomStringUtils.randomAlphanumeric(17))));
|
||||||
.as("tag with too long colour should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
|
||||||
() -> targetTagManagement.create(entityFactory.tag().create().name("a").colour(INVALID_TEXT_HTML)))
|
|
||||||
.as("tag with invalid colour should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetTagManagement.update(
|
.as("tag with invalid colour should not be created").isThrownBy(() -> targetTagManagement
|
||||||
entityFactory.tag().update(tag.getId()).colour(RandomStringUtils.randomAlphanumeric(17))))
|
.create(entityFactory.tag().create().name("a").colour(INVALID_TEXT_HTML)));
|
||||||
.as("tag with too long colour should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).colour(INVALID_TEXT_HTML)))
|
.as("tag with too long colour should not be updated")
|
||||||
.as("tag with invalid colour should not be updated");
|
.isThrownBy(() -> targetTagManagement.update(
|
||||||
|
entityFactory.tag().update(tag.getId()).colour(RandomStringUtils.randomAlphanumeric(17))));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("tag with invalid colour should not be updated").isThrownBy(() -> targetTagManagement
|
||||||
|
.update(entityFactory.tag().update(tag.getId()).colour(INVALID_TEXT_HTML)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createAndUpdateTagWithInvalidName(final Tag tag) {
|
private void createAndUpdateTagWithInvalidName(final Tag tag) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("tag with too long name should not be created")
|
||||||
.isThrownBy(() -> targetTagManagement
|
.isThrownBy(() -> targetTagManagement
|
||||||
.create(entityFactory.tag().create().name(RandomStringUtils.randomAlphanumeric(
|
.create(entityFactory.tag().create().name(RandomStringUtils.randomAlphanumeric(
|
||||||
NamedEntity.NAME_MAX_SIZE + 1))))
|
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||||
.as("tag with too long name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetTagManagement.create(entityFactory.tag().create().name(INVALID_TEXT_HTML)))
|
.as("tag with invalidname should not be created")
|
||||||
.as("tag with invalidname should not be created");
|
.isThrownBy(() -> targetTagManagement.create(entityFactory.tag().create().name(INVALID_TEXT_HTML)));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("tag with too long name should not be updated")
|
||||||
.isThrownBy(() -> targetTagManagement
|
.isThrownBy(() -> targetTagManagement
|
||||||
.update(entityFactory.tag().update(tag.getId()).name(RandomStringUtils.randomAlphanumeric(
|
.update(entityFactory.tag().update(tag.getId()).name(RandomStringUtils.randomAlphanumeric(
|
||||||
NamedEntity.NAME_MAX_SIZE + 1))))
|
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||||
.as("tag with too long name should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
assertThatExceptionOfType(ConstraintViolationException.class).as("tag with invalid name should not be updated")
|
||||||
() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name(INVALID_TEXT_HTML)))
|
.isThrownBy(() -> targetTagManagement
|
||||||
.as("tag with invalid name should not be updated");
|
.update(entityFactory.tag().update(tag.getId()).name(INVALID_TEXT_HTML)));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("")))
|
.as("tag with too short name should not be updated")
|
||||||
.as("tag with too short name should not be updated");
|
.isThrownBy(() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("")));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies the toogle mechanism by means on assigning tag if at least on target in the list does not have"
|
@Description("Verifies the toogle mechanism by means on assigning tag if at least on target in the list does not have"
|
||||||
+ "the tag yet. Unassign if all of them have the tag already.")
|
+ "the tag yet. Unassign if all of them have the tag already.")
|
||||||
public void assignAndUnassignTargetTags() {
|
void assignAndUnassignTargetTags() {
|
||||||
final List<Target> groupA = testdataFactory.createTargets(20);
|
final List<Target> groupA = testdataFactory.createTargets(20);
|
||||||
final List<Target> groupB = testdataFactory.createTargets(20, "groupb", "groupb");
|
final List<Target> groupB = testdataFactory.createTargets(20, "groupb", "groupb");
|
||||||
|
|
||||||
@@ -169,11 +168,11 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// toggle A only -> A is now assigned
|
// toggle A only -> A is now assigned
|
||||||
TargetTagAssignmentResult result = toggleTagAssignment(groupA, tag);
|
TargetTagAssignmentResult result = toggleTagAssignment(groupA, tag);
|
||||||
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
|
assertThat(result.getAlreadyAssigned()).isZero();
|
||||||
assertThat(result.getAssigned()).isEqualTo(20);
|
assertThat(result.getAssigned()).isEqualTo(20);
|
||||||
assertThat(result.getAssignedEntity()).containsAll(targetManagement
|
assertThat(result.getAssignedEntity()).containsAll(targetManagement
|
||||||
.getByControllerID(groupA.stream().map(Target::getControllerId).collect(Collectors.toList())));
|
.getByControllerID(groupA.stream().map(Target::getControllerId).collect(Collectors.toList())));
|
||||||
assertThat(result.getUnassigned()).isEqualTo(0);
|
assertThat(result.getUnassigned()).isZero();
|
||||||
assertThat(result.getUnassignedEntity()).isEmpty();
|
assertThat(result.getUnassignedEntity()).isEmpty();
|
||||||
assertThat(result.getTargetTag()).isEqualTo(tag);
|
assertThat(result.getTargetTag()).isEqualTo(tag);
|
||||||
|
|
||||||
@@ -183,14 +182,14 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assertThat(result.getAssigned()).isEqualTo(20);
|
assertThat(result.getAssigned()).isEqualTo(20);
|
||||||
assertThat(result.getAssignedEntity()).containsAll(targetManagement
|
assertThat(result.getAssignedEntity()).containsAll(targetManagement
|
||||||
.getByControllerID(groupB.stream().map(Target::getControllerId).collect(Collectors.toList())));
|
.getByControllerID(groupB.stream().map(Target::getControllerId).collect(Collectors.toList())));
|
||||||
assertThat(result.getUnassigned()).isEqualTo(0);
|
assertThat(result.getUnassigned()).isZero();
|
||||||
assertThat(result.getUnassignedEntity()).isEmpty();
|
assertThat(result.getUnassignedEntity()).isEmpty();
|
||||||
assertThat(result.getTargetTag()).isEqualTo(tag);
|
assertThat(result.getTargetTag()).isEqualTo(tag);
|
||||||
|
|
||||||
// toggle A+B -> both unassigned
|
// toggle A+B -> both unassigned
|
||||||
result = toggleTagAssignment(concat(groupA, groupB), tag);
|
result = toggleTagAssignment(concat(groupA, groupB), tag);
|
||||||
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
|
assertThat(result.getAlreadyAssigned()).isZero();
|
||||||
assertThat(result.getAssigned()).isEqualTo(0);
|
assertThat(result.getAssigned()).isZero();
|
||||||
assertThat(result.getAssignedEntity()).isEmpty();
|
assertThat(result.getAssignedEntity()).isEmpty();
|
||||||
assertThat(result.getUnassigned()).isEqualTo(40);
|
assertThat(result.getUnassigned()).isEqualTo(40);
|
||||||
assertThat(result.getUnassignedEntity()).containsAll(targetManagement.getByControllerID(
|
assertThat(result.getUnassignedEntity()).containsAll(targetManagement.getByControllerID(
|
||||||
@@ -208,7 +207,7 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that all tags are retrieved through repository.")
|
@Description("Ensures that all tags are retrieved through repository.")
|
||||||
public void findAllTargetTags() {
|
void findAllTargetTags() {
|
||||||
final List<JpaTargetTag> tags = createTargetsWithTags();
|
final List<JpaTargetTag> tags = createTargetsWithTags();
|
||||||
|
|
||||||
assertThat(targetTagRepository.findAll()).isEqualTo(targetTagRepository.findAll()).isEqualTo(tags)
|
assertThat(targetTagRepository.findAll()).isEqualTo(targetTagRepository.findAll()).isEqualTo(tags)
|
||||||
@@ -217,7 +216,7 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a created tag is persisted in the repository as defined.")
|
@Description("Ensures that a created tag is persisted in the repository as defined.")
|
||||||
public void createTargetTag() {
|
void createTargetTag() {
|
||||||
final Tag tag = targetTagManagement
|
final Tag tag = targetTagManagement
|
||||||
.create(entityFactory.tag().create().name("kai1").description("kai2").colour("colour"));
|
.create(entityFactory.tag().create().name("kai1").description("kai2").colour("colour"));
|
||||||
|
|
||||||
@@ -229,7 +228,7 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a deleted tag is removed from the repository as defined.")
|
@Description("Ensures that a deleted tag is removed from the repository as defined.")
|
||||||
public void deleteTargetTags() {
|
void deleteTargetTags() {
|
||||||
|
|
||||||
// create test data
|
// create test data
|
||||||
final Iterable<JpaTargetTag> tags = createTargetsWithTags();
|
final Iterable<JpaTargetTag> tags = createTargetsWithTags();
|
||||||
@@ -254,7 +253,7 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the name update of a target tag.")
|
@Description("Tests the name update of a target tag.")
|
||||||
public void updateTargetTag() {
|
void updateTargetTag() {
|
||||||
final List<JpaTargetTag> tags = createTargetsWithTags();
|
final List<JpaTargetTag> tags = createTargetsWithTags();
|
||||||
|
|
||||||
// change data
|
// change data
|
||||||
@@ -273,29 +272,20 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a tag cannot be created if one exists already with that name (ecpects EntityAlreadyExistsException).")
|
@Description("Ensures that a tag cannot be created if one exists already with that name (ecpects EntityAlreadyExistsException).")
|
||||||
public void failedDuplicateTargetTagNameException() {
|
void failedDuplicateTargetTagNameException() {
|
||||||
targetTagManagement.create(entityFactory.tag().create().name("A"));
|
targetTagManagement.create(entityFactory.tag().create().name("A"));
|
||||||
|
assertThatExceptionOfType(EntityAlreadyExistsException.class)
|
||||||
try {
|
.isThrownBy(() -> targetTagManagement.create(entityFactory.tag().create().name("A")));
|
||||||
targetTagManagement.create(entityFactory.tag().create().name("A"));
|
|
||||||
fail("should not have worked as tag already exists");
|
|
||||||
} catch (final EntityAlreadyExistsException e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a tag cannot be updated to a name that already exists on another tag (ecpects EntityAlreadyExistsException).")
|
@Description("Ensures that a tag cannot be updated to a name that already exists on another tag (ecpects EntityAlreadyExistsException).")
|
||||||
public void failedDuplicateTargetTagNameExceptionAfterUpdate() {
|
void failedDuplicateTargetTagNameExceptionAfterUpdate() {
|
||||||
targetTagManagement.create(entityFactory.tag().create().name("A"));
|
targetTagManagement.create(entityFactory.tag().create().name("A"));
|
||||||
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("B"));
|
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("B"));
|
||||||
|
|
||||||
try {
|
assertThatExceptionOfType(EntityAlreadyExistsException.class)
|
||||||
targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("A"));
|
.isThrownBy(() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("A")));
|
||||||
fail("should not have worked as tag already exists");
|
|
||||||
} catch (final EntityAlreadyExistsException e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<JpaTargetTag> createTargetsWithTags() {
|
private List<JpaTargetTag> createTargetsWithTags() {
|
||||||
|
|||||||
@@ -8,10 +8,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa;
|
package org.eclipse.hawkbit.repository.jpa;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import io.qameta.allure.Feature;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import io.qameta.allure.Step;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import io.qameta.allure.Story;
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.validation.ConstraintViolationException;
|
||||||
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeCreatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeCreatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeUpdatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeUpdatedEvent;
|
||||||
@@ -24,23 +29,20 @@ import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
|||||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import javax.validation.ConstraintViolationException;
|
import io.qameta.allure.Description;
|
||||||
import java.util.Collections;
|
import io.qameta.allure.Feature;
|
||||||
import java.util.Optional;
|
import io.qameta.allure.Step;
|
||||||
|
import io.qameta.allure.Story;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
|
|
||||||
@Feature("Component Tests - Repository")
|
@Feature("Component Tests - Repository")
|
||||||
@Story("Target Type Management")
|
@Story("Target Type Management")
|
||||||
public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
|
class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
|
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
|
||||||
+ "of Optional not present.")
|
+ "of Optional not present.")
|
||||||
@ExpectEvents({ @Expect(type = TargetTypeCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetTypeCreatedEvent.class) })
|
||||||
public void nonExistingEntityAccessReturnsNotPresent() {
|
void nonExistingEntityAccessReturnsNotPresent() {
|
||||||
assertThat(targetTypeManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
assertThat(targetTypeManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
||||||
assertThat(targetTypeManagement.getByName(NOT_EXIST_ID)).isNotPresent();
|
assertThat(targetTypeManagement.getByName(NOT_EXIST_ID)).isNotPresent();
|
||||||
}
|
}
|
||||||
@@ -48,8 +50,8 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verifies that management queries react as specified on calls for non existing entities "
|
@Description("Verifies that management queries react as specified on calls for non existing entities "
|
||||||
+ " by means of throwing EntityNotFoundException.")
|
+ " by means of throwing EntityNotFoundException.")
|
||||||
@ExpectEvents({ @Expect(type = TargetTypeUpdatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetTypeUpdatedEvent.class) })
|
||||||
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
||||||
verifyThrownExceptionBy(() -> targetTypeManagement.delete(NOT_EXIST_IDL), "TargetType");
|
verifyThrownExceptionBy(() -> targetTypeManagement.delete(NOT_EXIST_IDL), "TargetType");
|
||||||
verifyThrownExceptionBy(() -> targetTypeManagement.update(entityFactory.targetType().update(NOT_EXIST_IDL)),
|
verifyThrownExceptionBy(() -> targetTypeManagement.update(entityFactory.targetType().update(NOT_EXIST_IDL)),
|
||||||
"TargetType");
|
"TargetType");
|
||||||
@@ -57,7 +59,7 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that a target type with invalid properties cannot be created or updated")
|
@Description("Verify that a target type with invalid properties cannot be created or updated")
|
||||||
public void createAndUpdateTargetTypeWithInvalidFields() {
|
void createAndUpdateTargetTypeWithInvalidFields() {
|
||||||
final TargetType targetType = targetTypeManagement
|
final TargetType targetType = targetTypeManagement
|
||||||
.create(entityFactory.targetType().create().name("targettype1").description("targettypedes1"));
|
.create(entityFactory.targetType().create().name("targettype1").description("targettypedes1"));
|
||||||
|
|
||||||
@@ -67,82 +69,86 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createAndUpdateTargetTypeWithInvalidDescription(final TargetType targetType) {
|
void createAndUpdateTargetTypeWithInvalidDescription(final TargetType targetType) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("targetType with too long description should not be created")
|
||||||
.isThrownBy(() -> targetTypeManagement.create(
|
.isThrownBy(() -> targetTypeManagement.create(
|
||||||
entityFactory.targetType().create().name("a").description(RandomStringUtils.randomAlphanumeric(TargetType.DESCRIPTION_MAX_SIZE + 1))))
|
entityFactory.targetType().create().name("a").description(
|
||||||
.as("targetType with too long description should not be created");
|
RandomStringUtils.randomAlphanumeric(TargetType.DESCRIPTION_MAX_SIZE + 1))));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
|
||||||
() -> targetTypeManagement.create(entityFactory.targetType().create().name("a").description(INVALID_TEXT_HTML)))
|
|
||||||
.as("targetType with invalid description should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("targetType with invalid description should not be created").isThrownBy(() -> targetTypeManagement
|
||||||
|
.create(entityFactory.targetType().create().name("a").description(INVALID_TEXT_HTML)));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("targetType with too long description should not be updated")
|
||||||
.isThrownBy(() -> targetTypeManagement.update(
|
.isThrownBy(() -> targetTypeManagement.update(
|
||||||
entityFactory.targetType().update(targetType.getId()).description(RandomStringUtils.randomAlphanumeric(TargetType.DESCRIPTION_MAX_SIZE + 1))))
|
entityFactory.targetType().update(targetType.getId()).description(
|
||||||
.as("targetType with too long description should not be updated");
|
RandomStringUtils.randomAlphanumeric(TargetType.DESCRIPTION_MAX_SIZE + 1))));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("targetType with invalid description should not be updated")
|
||||||
.isThrownBy(() -> targetTypeManagement
|
.isThrownBy(() -> targetTypeManagement
|
||||||
.update(entityFactory.targetType().update(targetType.getId()).description(INVALID_TEXT_HTML)))
|
.update(entityFactory.targetType().update(targetType.getId()).description(INVALID_TEXT_HTML)));
|
||||||
.as("targetType with invalid description should not be updated");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createAndUpdateTargetTypeWithInvalidColour(final TargetType targetType) {
|
private void createAndUpdateTargetTypeWithInvalidColour(final TargetType targetType) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("targetType with too long colour should not be created")
|
||||||
.isThrownBy(() -> targetTypeManagement.create(
|
.isThrownBy(() -> targetTypeManagement.create(
|
||||||
entityFactory.targetType().create().name("a").colour(RandomStringUtils.randomAlphanumeric(TargetType.COLOUR_MAX_SIZE + 1))))
|
entityFactory.targetType().create().name("a")
|
||||||
.as("targetType with too long colour should not be created");
|
.colour(RandomStringUtils.randomAlphanumeric(TargetType.COLOUR_MAX_SIZE + 1))));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
|
||||||
() -> targetTypeManagement.create(entityFactory.targetType().create().name("a").colour(INVALID_TEXT_HTML)))
|
|
||||||
.as("targetType with invalid colour should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetTypeManagement.update(
|
.as("targetType with invalid colour should not be created").isThrownBy(() -> targetTypeManagement
|
||||||
entityFactory.targetType().update(targetType.getId()).colour(RandomStringUtils.randomAlphanumeric(TargetType.COLOUR_MAX_SIZE + 1))))
|
.create(entityFactory.targetType().create().name("a").colour(INVALID_TEXT_HTML)));
|
||||||
.as("targetType with too long colour should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
() -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).colour(INVALID_TEXT_HTML)))
|
.as("targetType with too long colour should not be updated")
|
||||||
.as("targetType with invalid colour should not be updated");
|
.isThrownBy(() -> targetTypeManagement.update(
|
||||||
|
entityFactory.targetType().update(targetType.getId())
|
||||||
|
.colour(RandomStringUtils.randomAlphanumeric(TargetType.COLOUR_MAX_SIZE + 1))));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("targetType with invalid colour should not be updated").isThrownBy(() -> targetTypeManagement
|
||||||
|
.update(entityFactory.targetType().update(targetType.getId()).colour(INVALID_TEXT_HTML)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void createAndUpdateTargetTypeWithInvalidName(final TargetType targetType) {
|
private void createAndUpdateTargetTypeWithInvalidName(final TargetType targetType) {
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("targetType with too long name should not be created")
|
||||||
.isThrownBy(() -> targetTypeManagement
|
.isThrownBy(() -> targetTypeManagement
|
||||||
.create(entityFactory.targetType().create().name(RandomStringUtils.randomAlphanumeric(
|
.create(entityFactory.targetType().create().name(RandomStringUtils.randomAlphanumeric(
|
||||||
NamedEntity.NAME_MAX_SIZE + 1))))
|
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||||
.as("targetType with too long name should not be created");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetTypeManagement.create(entityFactory.targetType().create().name(INVALID_TEXT_HTML)))
|
.as("targetType with invalid name should not be created").isThrownBy(
|
||||||
.as("targetType with invalid name should not be created");
|
() -> targetTypeManagement.create(entityFactory.targetType().create().name(INVALID_TEXT_HTML)));
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("targetType with too long name should not be updated")
|
||||||
.isThrownBy(() -> targetTypeManagement
|
.isThrownBy(() -> targetTypeManagement
|
||||||
.update(entityFactory.targetType().update(targetType.getId()).name(RandomStringUtils.randomAlphanumeric(
|
.update(entityFactory.targetType().update(targetType.getId()).name(RandomStringUtils.randomAlphanumeric(
|
||||||
NamedEntity.NAME_MAX_SIZE + 1))))
|
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||||
.as("targetType with too long name should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
|
|
||||||
() -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).name(INVALID_TEXT_HTML)))
|
|
||||||
.as("targetType with invalid name should not be updated");
|
|
||||||
|
|
||||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
.isThrownBy(() -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).name("")))
|
.as("targetType with invalid name should not be updated").isThrownBy(() -> targetTypeManagement
|
||||||
.as("targetType with too short name should not be updated");
|
.update(entityFactory.targetType().update(targetType.getId()).name(INVALID_TEXT_HTML)));
|
||||||
|
|
||||||
|
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||||
|
.as("targetType with too short name should not be updated").isThrownBy(() -> targetTypeManagement
|
||||||
|
.update(entityFactory.targetType().update(targetType.getId()).name("")));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the successful assignment of compatible distribution set types to a target type")
|
@Description("Tests the successful assignment of compatible distribution set types to a target type")
|
||||||
public void assignCompatibleDistributionSetTypesToTargetType(){
|
void assignCompatibleDistributionSetTypesToTargetType() {
|
||||||
final TargetType targetType = targetTypeManagement
|
final TargetType targetType = targetTypeManagement
|
||||||
.create(entityFactory.targetType().create().name("targettype1").description("targettypedes1"));
|
.create(entityFactory.targetType().create().name("targettype1").description("targettypedes1"));
|
||||||
DistributionSetType distributionSetType = testdataFactory.findOrCreateDistributionSetType("testDst", "dst1");
|
DistributionSetType distributionSetType = testdataFactory.findOrCreateDistributionSetType("testDst", "dst1");
|
||||||
@@ -155,7 +161,7 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the successful removal of compatible distribution set types to a target type")
|
@Description("Tests the successful removal of compatible distribution set types to a target type")
|
||||||
public void unassignCompatibleDistributionSetTypesToTargetType(){
|
void unassignCompatibleDistributionSetTypesToTargetType() {
|
||||||
final TargetType targetType = targetTypeManagement
|
final TargetType targetType = targetTypeManagement
|
||||||
.create(entityFactory.targetType().create().name("targettype11").description("targettypedes11"));
|
.create(entityFactory.targetType().create().name("targettype11").description("targettypedes11"));
|
||||||
DistributionSetType distributionSetType = testdataFactory.findOrCreateDistributionSetType("testDst1", "dst11");
|
DistributionSetType distributionSetType = testdataFactory.findOrCreateDistributionSetType("testDst1", "dst11");
|
||||||
@@ -166,19 +172,19 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
|
|||||||
targetTypeManagement.unassignDistributionSetType(targetType.getId(),distributionSetType.getId());
|
targetTypeManagement.unassignDistributionSetType(targetType.getId(),distributionSetType.getId());
|
||||||
Optional<JpaTargetType> targetTypeWithDsTypes1 = targetTypeRepository.findById(targetType.getId());
|
Optional<JpaTargetType> targetTypeWithDsTypes1 = targetTypeRepository.findById(targetType.getId());
|
||||||
assertThat(targetTypeWithDsTypes1).isPresent();
|
assertThat(targetTypeWithDsTypes1).isPresent();
|
||||||
assertThat(targetTypeWithDsTypes1.get().getCompatibleDistributionSetTypes()).hasSize(0);
|
assertThat(targetTypeWithDsTypes1.get().getCompatibleDistributionSetTypes()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that all types are retrieved through repository.")
|
@Description("Ensures that all types are retrieved through repository.")
|
||||||
public void findAllTargetTypes() {
|
void findAllTargetTypes() {
|
||||||
testdataFactory.createTargetTypes("targettype", 10);
|
testdataFactory.createTargetTypes("targettype", 10);
|
||||||
assertThat(targetTypeRepository.findAll()).as("Target type size").hasSize(10);
|
assertThat(targetTypeRepository.findAll()).as("Target type size").hasSize(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a created target type is persisted in the repository as defined.")
|
@Description("Ensures that a created target type is persisted in the repository as defined.")
|
||||||
public void createTargetType() {
|
void createTargetType() {
|
||||||
final TargetType targetType = targetTypeManagement
|
final TargetType targetType = targetTypeManagement
|
||||||
.create(entityFactory.targetType().create().name("targettype1").description("targettypedes1").colour("colour1"));
|
.create(entityFactory.targetType().create().name("targettype1").description("targettypedes1").colour("colour1"));
|
||||||
|
|
||||||
@@ -190,7 +196,7 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a deleted target type is removed from the repository as defined.")
|
@Description("Ensures that a deleted target type is removed from the repository as defined.")
|
||||||
public void deleteTargetType() {
|
void deleteTargetType() {
|
||||||
// create test data
|
// create test data
|
||||||
final TargetType targetType = targetTypeManagement
|
final TargetType targetType = targetTypeManagement
|
||||||
.create(entityFactory.targetType().create().name("targettype11").description("targettypedes11"));
|
.create(entityFactory.targetType().create().name("targettype11").description("targettypedes11"));
|
||||||
@@ -203,7 +209,7 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the name update of a target type.")
|
@Description("Tests the name update of a target type.")
|
||||||
public void updateTargetType() {
|
void updateTargetType() {
|
||||||
final TargetType targetType = targetTypeManagement
|
final TargetType targetType = targetTypeManagement
|
||||||
.create(entityFactory.targetType().create().name("targettype111").description("targettypedes111"));
|
.create(entityFactory.targetType().create().name("targettype111").description("targettypedes111"));
|
||||||
assertThat(targetTypeRepository.findByName("targettype111").get().getDescription()).as("type found")
|
assertThat(targetTypeRepository.findByName("targettype111").get().getDescription()).as("type found")
|
||||||
@@ -214,14 +220,14 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a target type cannot be created if one exists already with that name (expects EntityAlreadyExistsException).")
|
@Description("Ensures that a target type cannot be created if one exists already with that name (expects EntityAlreadyExistsException).")
|
||||||
public void failedDuplicateTargetTypeNameException() {
|
void failedDuplicateTargetTypeNameException() {
|
||||||
targetTypeManagement.create(entityFactory.targetType().create().name("targettype123"));
|
targetTypeManagement.create(entityFactory.targetType().create().name("targettype123"));
|
||||||
assertThrows(EntityAlreadyExistsException.class, () -> targetTypeManagement.create(entityFactory.targetType().create().name("targettype123")));
|
assertThrows(EntityAlreadyExistsException.class, () -> targetTypeManagement.create(entityFactory.targetType().create().name("targettype123")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a target type cannot be updated to a name that already exists (expects EntityAlreadyExistsException).")
|
@Description("Ensures that a target type cannot be updated to a name that already exists (expects EntityAlreadyExistsException).")
|
||||||
public void failedDuplicateTargetTypeNameExceptionAfterUpdate() {
|
void failedDuplicateTargetTypeNameExceptionAfterUpdate() {
|
||||||
targetTypeManagement.create(entityFactory.targetType().create().name("targettype1234"));
|
targetTypeManagement.create(entityFactory.targetType().create().name("targettype1234"));
|
||||||
TargetType targetType = targetTypeManagement.create(entityFactory.targetType().create().name("targettype12345"));
|
TargetType targetType = targetTypeManagement.create(entityFactory.targetType().create().name("targettype12345"));
|
||||||
assertThrows(EntityAlreadyExistsException.class, () -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).name("targettype1234")));
|
assertThrows(EntityAlreadyExistsException.class, () -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).name("targettype1234")));
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import io.qameta.allure.Story;
|
|||||||
|
|
||||||
@Feature("Component Tests - Repository")
|
@Feature("Component Tests - Repository")
|
||||||
@Story("RSQL filter target")
|
@Story("RSQL filter target")
|
||||||
public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
||||||
|
|
||||||
private Target target;
|
private Target target;
|
||||||
private Target target2;
|
private Target target2;
|
||||||
@@ -47,7 +47,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
private static final String AND = ";";
|
private static final String AND = ";";
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setupBeforeTest() throws InterruptedException {
|
void setupBeforeTest() {
|
||||||
|
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("AssignedDs");
|
final DistributionSet ds = testdataFactory.createDistributionSet("AssignedDs");
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
target2 = targetManagement
|
target2 = targetManagement
|
||||||
.create(entityFactory.target().create().controllerId("targetId1234").description("targetId1234"));
|
.create(entityFactory.target().create().controllerId("targetId1234").description("targetId1234"));
|
||||||
attributes.put("revision", "1.2");
|
attributes.put("revision", "1.2");
|
||||||
Thread.sleep(1);
|
|
||||||
target2 = controllerManagement.updateControllerAttributes(target2.getControllerId(), attributes, null);
|
target2 = controllerManagement.updateControllerAttributes(target2.getControllerId(), attributes, null);
|
||||||
target2 = controllerManagement.findOrRegisterTargetIfItDoesNotExist(target2.getControllerId(), LOCALHOST);
|
target2 = controllerManagement.findOrRegisterTargetIfItDoesNotExist(target2.getControllerId(), LOCALHOST);
|
||||||
createTargetMetadata(target2.getControllerId(), entityFactory.generateTargetMetadata("metaKey", "value"));
|
createTargetMetadata(target2.getControllerId(), entityFactory.generateTargetMetadata("metaKey", "value"));
|
||||||
@@ -97,7 +97,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by (controller) id")
|
@Description("Test filter target by (controller) id")
|
||||||
public void testFilterByParameterId() {
|
void testFilterByParameterId() {
|
||||||
assertRSQLQuery(TargetFields.ID.name() + "==targetId123", 1);
|
assertRSQLQuery(TargetFields.ID.name() + "==targetId123", 1);
|
||||||
assertRSQLQuery(TargetFields.ID.name() + "==target*", 5);
|
assertRSQLQuery(TargetFields.ID.name() + "==target*", 5);
|
||||||
assertRSQLQuery(TargetFields.ID.name() + "==noExist*", 0);
|
assertRSQLQuery(TargetFields.ID.name() + "==noExist*", 0);
|
||||||
@@ -108,7 +108,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by name")
|
@Description("Test filter target by name")
|
||||||
public void testFilterByParameterName() {
|
void testFilterByParameterName() {
|
||||||
assertRSQLQuery(TargetFields.NAME.name() + "==targetName123", 1);
|
assertRSQLQuery(TargetFields.NAME.name() + "==targetName123", 1);
|
||||||
assertRSQLQuery(TargetFields.NAME.name() + "==target*", 5);
|
assertRSQLQuery(TargetFields.NAME.name() + "==target*", 5);
|
||||||
assertRSQLQuery(TargetFields.NAME.name() + "==noExist*", 0);
|
assertRSQLQuery(TargetFields.NAME.name() + "==noExist*", 0);
|
||||||
@@ -119,7 +119,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by description")
|
@Description("Test filter target by description")
|
||||||
public void testFilterByParameterDescription() {
|
void testFilterByParameterDescription() {
|
||||||
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "==''", 3);
|
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "==''", 3);
|
||||||
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "!=''", 2);
|
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "!=''", 2);
|
||||||
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "==targetDesc123", 1);
|
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "==targetDesc123", 1);
|
||||||
@@ -132,7 +132,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by controller id")
|
@Description("Test filter target by controller id")
|
||||||
public void testFilterByParameterControllerId() {
|
void testFilterByParameterControllerId() {
|
||||||
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==targetId123", 1);
|
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==targetId123", 1);
|
||||||
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==target*", 5);
|
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==target*", 5);
|
||||||
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==noExist*", 0);
|
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==noExist*", 0);
|
||||||
@@ -143,7 +143,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by status")
|
@Description("Test filter target by status")
|
||||||
public void testFilterByParameterUpdateStatus() {
|
void testFilterByParameterUpdateStatus() {
|
||||||
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "==pending", 1);
|
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "==pending", 1);
|
||||||
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "!=pending", 4);
|
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "!=pending", 4);
|
||||||
try {
|
try {
|
||||||
@@ -158,8 +158,9 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by attribute")
|
@Description("Test filter target by attribute")
|
||||||
public void testFilterByAttribute() {
|
void testFilterByAttribute() {
|
||||||
createTargetWithAttributes("test.dot", "value.dot");
|
controllerManagement.updateControllerAttributes(testdataFactory.createTarget().getControllerId(),
|
||||||
|
Maps.newHashMap("test.dot", "value.dot"), null);
|
||||||
|
|
||||||
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision==1.1", 1);
|
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision==1.1", 1);
|
||||||
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision!=1.1", 1);
|
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision!=1.1", 1);
|
||||||
@@ -174,17 +175,14 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".key*==value.dot", 0);
|
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".key*==value.dot", 0);
|
||||||
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".*==value.dot", 0);
|
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".*==value.dot", 0);
|
||||||
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + "..==value.dot", 0);
|
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + "..==value.dot", 0);
|
||||||
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + ".==value.dot",
|
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + ".==value.dot");
|
||||||
RSQLParameterUnsupportedFieldException.class);
|
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + "*==value.dot");
|
||||||
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + "*==value.dot",
|
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + "==value.dot");
|
||||||
RSQLParameterUnsupportedFieldException.class);
|
|
||||||
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + "==value.dot",
|
|
||||||
RSQLParameterUnsupportedFieldException.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by assigned ds name")
|
@Description("Test filter target by assigned ds name")
|
||||||
public void testFilterByAssignedDsName() {
|
void testFilterByAssignedDsName() {
|
||||||
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==AssignedDs", 1);
|
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==AssignedDs", 1);
|
||||||
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==A*", 1);
|
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==A*", 1);
|
||||||
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==noExist*", 0);
|
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==noExist*", 0);
|
||||||
@@ -194,7 +192,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by assigned ds version")
|
@Description("Test filter target by assigned ds version")
|
||||||
public void testFilterByAssignedDsVersion() {
|
void testFilterByAssignedDsVersion() {
|
||||||
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==" + TestdataFactory.DEFAULT_VERSION, 1);
|
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==" + TestdataFactory.DEFAULT_VERSION, 1);
|
||||||
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==*1*", 1);
|
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==*1*", 1);
|
||||||
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==noExist*", 0);
|
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==noExist*", 0);
|
||||||
@@ -206,7 +204,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by tag name")
|
@Description("Test filter target by tag name")
|
||||||
public void testFilterByTag() {
|
void testFilterByTag() {
|
||||||
assertRSQLQuery(TargetFields.TAG.name() + "==Tag1", 2);
|
assertRSQLQuery(TargetFields.TAG.name() + "==Tag1", 2);
|
||||||
assertRSQLQuery(TargetFields.TAG.name() + "!=Tag1", 3);
|
assertRSQLQuery(TargetFields.TAG.name() + "!=Tag1", 3);
|
||||||
assertRSQLQuery(TargetFields.TAG.name() + "==T*", 4);
|
assertRSQLQuery(TargetFields.TAG.name() + "==T*", 4);
|
||||||
@@ -226,7 +224,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by lastTargetQuery")
|
@Description("Test filter target by lastTargetQuery")
|
||||||
public void testFilterByLastTargetQuery() throws InterruptedException {
|
void testFilterByLastTargetQuery() {
|
||||||
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "==" + target.getLastTargetQuery(), 1);
|
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "==" + target.getLastTargetQuery(), 1);
|
||||||
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "!=" + target.getLastTargetQuery(), 4);
|
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "!=" + target.getLastTargetQuery(), 4);
|
||||||
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "=lt=" + target.getLastTargetQuery(), 0);
|
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "=lt=" + target.getLastTargetQuery(), 0);
|
||||||
@@ -239,8 +237,9 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter target by metadata")
|
@Description("Test filter target by metadata")
|
||||||
public void testFilterByMetadata() {
|
void testFilterByMetadata() {
|
||||||
createTargetWithMetadata("key.dot", "value.dot");
|
createTargetMetadata(testdataFactory.createTarget().getControllerId(),
|
||||||
|
entityFactory.generateTargetMetadata("key.dot", "value.dot"));
|
||||||
|
|
||||||
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==metaValue", 1);
|
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==metaValue", 1);
|
||||||
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==*v*", 2);
|
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==*v*", 2);
|
||||||
@@ -258,17 +257,14 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
assertRSQLQuery(TargetFields.METADATA.name() + ".key*==value.dot", 0);
|
assertRSQLQuery(TargetFields.METADATA.name() + ".key*==value.dot", 0);
|
||||||
assertRSQLQuery(TargetFields.METADATA.name() + ".*==value.dot", 0);
|
assertRSQLQuery(TargetFields.METADATA.name() + ".*==value.dot", 0);
|
||||||
assertRSQLQuery(TargetFields.METADATA.name() + "..==value.dot", 0);
|
assertRSQLQuery(TargetFields.METADATA.name() + "..==value.dot", 0);
|
||||||
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + ".==value.dot",
|
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + ".==value.dot");
|
||||||
RSQLParameterUnsupportedFieldException.class);
|
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + "*==value.dot");
|
||||||
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + "*==value.dot",
|
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + "==value.dot");
|
||||||
RSQLParameterUnsupportedFieldException.class);
|
|
||||||
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + "==value.dot",
|
|
||||||
RSQLParameterUnsupportedFieldException.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter based on more complex RSQL queries")
|
@Description("Test filter based on more complex RSQL queries")
|
||||||
public void testFilterByComplexQueries() {
|
void testFilterByComplexQueries() {
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(
|
||||||
TargetFields.NAME.name() + "!=targetName123" + AND + TargetFields.METADATA.name() + ".metaKey!=value",
|
TargetFields.NAME.name() + "!=targetName123" + AND + TargetFields.METADATA.name() + ".metaKey!=value",
|
||||||
0);
|
0);
|
||||||
@@ -278,7 +274,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing allowed RSQL keys based on TargetFields definition")
|
@Description("Testing allowed RSQL keys based on TargetFields definition")
|
||||||
public void rsqlValidTargetFields() {
|
void rsqlValidTargetFields() {
|
||||||
final String rsql1 = "ID == '0123' and NAME == abcd and DESCRIPTION == absd"
|
final String rsql1 = "ID == '0123' and NAME == abcd and DESCRIPTION == absd"
|
||||||
+ " and CREATEDAT =lt= 0123 and LASTMODIFIEDAT =gt= 0123"
|
+ " and CREATEDAT =lt= 0123 and LASTMODIFIEDAT =gt= 0123"
|
||||||
+ " and CONTROLLERID == 0123 and UPDATESTATUS == PENDING"
|
+ " and CONTROLLERID == 0123 and UPDATESTATUS == PENDING"
|
||||||
@@ -308,7 +304,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test filter by target type")
|
@Description("Test filter by target type")
|
||||||
public void shouldFilterTargetsByTypeIdNameAndDescription() {
|
void shouldFilterTargetsByTypeIdNameAndDescription() {
|
||||||
assertRSQLQuery("targettype." + TargetTypeFields.NAME.name() + "==" + targetType1.getName(), 1);
|
assertRSQLQuery("targettype." + TargetTypeFields.NAME.name() + "==" + targetType1.getName(), 1);
|
||||||
assertRSQLQuery("targettype." + TargetTypeFields.NAME.name() + "==*1", 1);
|
assertRSQLQuery("targettype." + TargetTypeFields.NAME.name() + "==*1", 1);
|
||||||
assertRSQLQuery("targettype." + TargetTypeFields.NAME.name() + "!=" + targetType2.getName(), 4);
|
assertRSQLQuery("targettype." + TargetTypeFields.NAME.name() + "!=" + targetType2.getName(), 4);
|
||||||
@@ -327,23 +323,8 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
assertThat(countTargetsAll).isEqualTo(expectedTargets);
|
assertThat(countTargetsAll).isEqualTo(expectedTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends Throwable> void assertRSQLQueryThrowsException(final String rsqlParam,
|
private void assertRSQLQueryThrowsException(final String rsqlParam) {
|
||||||
final Class<T> expectedException) {
|
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
||||||
assertThatExceptionOfType(expectedException)
|
|
||||||
.isThrownBy(() -> RSQLUtility.validateRsqlFor(rsqlParam, TargetFields.class));
|
.isThrownBy(() -> RSQLUtility.validateRsqlFor(rsqlParam, TargetFields.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Target createTargetWithMetadata(final String metadataKeyName, final String metadataValue) {
|
|
||||||
final Target target = testdataFactory.createTarget();
|
|
||||||
createTargetMetadata(target.getControllerId(),
|
|
||||||
entityFactory.generateTargetMetadata(metadataKeyName, metadataValue));
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Target createTargetWithAttributes(final String attributeName, final String attributeValue) {
|
|
||||||
final Target target = testdataFactory.createTarget();
|
|
||||||
controllerManagement.updateControllerAttributes(target.getControllerId(),
|
|
||||||
Maps.newHashMap(attributeName, attributeValue), null);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.rsql;
|
package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.apache.commons.lang3.text.StrSubstitutor;
|
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||||
@@ -23,6 +20,8 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.T
|
|||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@@ -70,34 +69,15 @@ public class VirtualPropertyResolverTest {
|
|||||||
StrSubstitutor.DEFAULT_SUFFIX, StrSubstitutor.DEFAULT_ESCAPE);
|
StrSubstitutor.DEFAULT_SUFFIX, StrSubstitutor.DEFAULT_ESCAPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = { "${NOW_TS}", "${OVERDUE_TS}", "${overdue_ts}" })
|
||||||
@Description("Tests resolution of NOW_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.")
|
@Description("Tests resolution of NOW_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.")
|
||||||
public void resolveNowTimestampPlaceholder() {
|
void resolveNowTimestampPlaceholder(final String placeholder) {
|
||||||
final String placeholder = "${NOW_TS}";
|
|
||||||
final String testString = "lhs=lt=" + placeholder;
|
final String testString = "lhs=lt=" + placeholder;
|
||||||
|
|
||||||
final String resolvedPlaceholders = substitutor.replace(testString);
|
final String resolvedPlaceholders = substitutor.replace(testString);
|
||||||
assertThat("NOW_TS has to be resolved!", resolvedPlaceholders, not(containsString(placeholder)));
|
assertThat(resolvedPlaceholders).as("'%s' placeholder was not replaced", placeholder)
|
||||||
}
|
.doesNotContain(placeholder);
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests resolution of OVERDUE_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.")
|
|
||||||
public void resolveOverdueTimestampPlaceholder() {
|
|
||||||
final String placeholder = "${OVERDUE_TS}";
|
|
||||||
final String testString = "lhs=lt=" + placeholder;
|
|
||||||
|
|
||||||
final String resolvedPlaceholders = substitutor.replace(testString);
|
|
||||||
assertThat("OVERDUE_TS has to be resolved!", resolvedPlaceholders, not(containsString(placeholder)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests case insensititity of VirtualPropertyResolver.")
|
|
||||||
public void resolveOverdueTimestampPlaceholderLowerCase() {
|
|
||||||
final String placeholder = "${overdue_ts}";
|
|
||||||
final String testString = "lhs=lt=" + placeholder;
|
|
||||||
|
|
||||||
final String resolvedPlaceholders = substitutor.replace(testString);
|
|
||||||
assertThat("overdue_ts has to be resolved!", resolvedPlaceholders, not(containsString(placeholder)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -107,7 +87,7 @@ public class VirtualPropertyResolverTest {
|
|||||||
final String testString = "lhs=lt=" + placeholder;
|
final String testString = "lhs=lt=" + placeholder;
|
||||||
|
|
||||||
final String resolvedPlaceholders = substitutor.replace(testString);
|
final String resolvedPlaceholders = substitutor.replace(testString);
|
||||||
assertThat("unknown should not be resolved!", resolvedPlaceholders, containsString(placeholder));
|
assertThat(resolvedPlaceholders).as("unknown should not be resolved!").contains(placeholder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -118,6 +98,6 @@ public class VirtualPropertyResolverTest {
|
|||||||
final String testString = "lhs=lt=" + escaptedPlaceholder;
|
final String testString = "lhs=lt=" + escaptedPlaceholder;
|
||||||
|
|
||||||
final String resolvedPlaceholders = substitutor.replace(testString);
|
final String resolvedPlaceholders = substitutor.replace(testString);
|
||||||
assertThat("Escaped OVERDUE_TS should not be resolved!", resolvedPlaceholders, containsString(placeholder));
|
assertThat(resolvedPlaceholders).as("Escaped OVERDUE_TS should not be resolved!").contains(placeholder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,94 +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.repository.jpa.utils;
|
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper to call a request multiple times regarding a given condition until
|
|
||||||
* timeout is reached.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public final class MultipleInvokeHelper {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call with timeout until result is not null.
|
|
||||||
*
|
|
||||||
* @param callable
|
|
||||||
* class
|
|
||||||
* @param timeout
|
|
||||||
* value
|
|
||||||
* @param pollInterval
|
|
||||||
* value
|
|
||||||
* @return
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public static <T> T doWithTimeoutUntilResultIsNotNull(final Callable<T> callable, final long timeout,
|
|
||||||
final long pollInterval) throws Exception // NOPMD
|
|
||||||
{
|
|
||||||
return doWithTimeout(callable, new SuccessCondition<T>() {
|
|
||||||
@Override
|
|
||||||
public boolean success(final T result) {
|
|
||||||
return result != null;
|
|
||||||
};
|
|
||||||
}, timeout, pollInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call with timeout.
|
|
||||||
*
|
|
||||||
* @param callable
|
|
||||||
* class
|
|
||||||
* @param successCondition
|
|
||||||
* class
|
|
||||||
* @param timeout
|
|
||||||
* value
|
|
||||||
* @param pollInterval
|
|
||||||
* value
|
|
||||||
* @return
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public static <T> T doWithTimeout(final Callable<T> callable, final SuccessCondition<T> successCondition,
|
|
||||||
final long timeout, final long pollInterval) throws Exception // NOPMD
|
|
||||||
{
|
|
||||||
|
|
||||||
if (pollInterval < 0) {
|
|
||||||
throw new IllegalArgumentException("pollInterval must non negative");
|
|
||||||
}
|
|
||||||
|
|
||||||
long duration = 0;
|
|
||||||
Exception exception = null;
|
|
||||||
T returnValue = null;
|
|
||||||
while (untilTimeoutReached(timeout, duration)) {
|
|
||||||
try {
|
|
||||||
returnValue = callable.call();
|
|
||||||
// clear exception
|
|
||||||
exception = null;
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
exception = ex;
|
|
||||||
}
|
|
||||||
Thread.sleep(pollInterval);
|
|
||||||
duration += pollInterval > 0 ? pollInterval : 1;
|
|
||||||
if (exception == null && successCondition.success(returnValue)) {
|
|
||||||
return returnValue;
|
|
||||||
} else {
|
|
||||||
returnValue = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (exception != null) {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean untilTimeoutReached(final long timeout, final long duration) {
|
|
||||||
return duration <= timeout || timeout < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,27 +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.repository.jpa.utils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SuccessCondition Interface.
|
|
||||||
*
|
|
||||||
* @param <T>
|
|
||||||
* type of the value to get verified
|
|
||||||
*/
|
|
||||||
public interface SuccessCondition<T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The implementation of the success condition.
|
|
||||||
*
|
|
||||||
* @param result
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
boolean success(final T result);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -17,11 +17,10 @@ import java.io.IOException;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
@@ -59,7 +58,6 @@ import org.eclipse.hawkbit.repository.model.MetaData;
|
|||||||
import org.eclipse.hawkbit.repository.model.RepositoryModelConstants;
|
import org.eclipse.hawkbit.repository.model.RepositoryModelConstants;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetMetadata;
|
|
||||||
import org.eclipse.hawkbit.repository.test.TestConfiguration;
|
import org.eclipse.hawkbit.repository.test.TestConfiguration;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.EventVerifier;
|
import org.eclipse.hawkbit.repository.test.matcher.EventVerifier;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
@@ -103,7 +101,7 @@ import org.springframework.test.context.TestPropertySource;
|
|||||||
// Cleaning repository will fire "delete" events. We won't count them to the
|
// Cleaning repository will fire "delete" events. We won't count them to the
|
||||||
// test execution. So, the order execution between EventVerifier and Cleanup is
|
// test execution. So, the order execution between EventVerifier and Cleanup is
|
||||||
// important!
|
// important!
|
||||||
@TestExecutionListeners(inheritListeners = true, listeners = { EventVerifier.class, CleanupTestExecutionListener.class,
|
@TestExecutionListeners(listeners = { EventVerifier.class, CleanupTestExecutionListener.class,
|
||||||
MySqlTestDatabase.class, MsSqlTestDatabase.class,
|
MySqlTestDatabase.class, MsSqlTestDatabase.class,
|
||||||
PostgreSqlTestDatabase.class }, mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
|
PostgreSqlTestDatabase.class }, mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
|
||||||
@TestPropertySource(properties = "spring.main.allow-bean-definition-overriding=true")
|
@TestPropertySource(properties = "spring.main.allow-bean-definition-overriding=true")
|
||||||
@@ -302,7 +300,7 @@ public abstract class AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected DistributionSetAssignmentResult assignDistributionSet(final DistributionSet pset, final Target target) {
|
protected DistributionSetAssignmentResult assignDistributionSet(final DistributionSet pset, final Target target) {
|
||||||
return assignDistributionSet(pset, Arrays.asList(target));
|
return assignDistributionSet(pset, Collections.singletonList(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DistributionSetAssignmentResult assignDistributionSet(final long dsId, final String targetId,
|
protected DistributionSetAssignmentResult assignDistributionSet(final long dsId, final String targetId,
|
||||||
@@ -322,16 +320,16 @@ public abstract class AbstractIntegrationTest {
|
|||||||
return distributionSetManagement.createMetaData(dsId, md);
|
return distributionSetManagement.createMetaData(dsId, md);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TargetMetadata createTargetMetadata(final String controllerId, final MetaData md) {
|
protected void createTargetMetadata(final String controllerId, final MetaData md) {
|
||||||
return createTargetMetadata(controllerId, Collections.singletonList(md)).get(0);
|
createTargetMetadata(controllerId, Collections.singletonList(md));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<TargetMetadata> createTargetMetadata(final String controllerId, final List<MetaData> md) {
|
private void createTargetMetadata(final String controllerId, final List<MetaData> md) {
|
||||||
return targetManagement.createMetaData(controllerId, md);
|
targetManagement.createMetaData(controllerId, md);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Long getOsModule(final DistributionSet ds) {
|
protected Long getOsModule(final DistributionSet ds) {
|
||||||
return ds.findFirstModuleByType(osType).get().getId();
|
return ds.findFirstModuleByType(osType).orElseThrow(NoSuchElementException::new).getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Action prepareFinishedUpdate() {
|
protected Action prepareFinishedUpdate() {
|
||||||
@@ -386,7 +384,7 @@ public abstract class AbstractIntegrationTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String artifactDirectory = createTempDir();
|
private static final String ARTIFACT_DIRECTORY = createTempDir();
|
||||||
|
|
||||||
private static String createTempDir() {
|
private static String createTempDir() {
|
||||||
try {
|
try {
|
||||||
@@ -398,9 +396,9 @@ public abstract class AbstractIntegrationTest {
|
|||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void cleanUp() {
|
public void cleanUp() {
|
||||||
if (new File(artifactDirectory).exists()) {
|
if (new File(ARTIFACT_DIRECTORY).exists()) {
|
||||||
try {
|
try {
|
||||||
FileUtils.cleanDirectory(new File(artifactDirectory));
|
FileUtils.cleanDirectory(new File(ARTIFACT_DIRECTORY));
|
||||||
} catch (final IOException | IllegalArgumentException e) {
|
} catch (final IOException | IllegalArgumentException e) {
|
||||||
LOG.warn("Cannot cleanup file-directory", e);
|
LOG.warn("Cannot cleanup file-directory", e);
|
||||||
}
|
}
|
||||||
@@ -409,14 +407,14 @@ public abstract class AbstractIntegrationTest {
|
|||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void beforeClass() {
|
public static void beforeClass() {
|
||||||
System.setProperty("org.eclipse.hawkbit.repository.file.path", artifactDirectory);
|
System.setProperty("org.eclipse.hawkbit.repository.file.path", ARTIFACT_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterAll
|
@AfterAll
|
||||||
public static void afterClass() {
|
public static void afterClass() {
|
||||||
if (new File(artifactDirectory).exists()) {
|
if (new File(ARTIFACT_DIRECTORY).exists()) {
|
||||||
try {
|
try {
|
||||||
FileUtils.deleteDirectory(new File(artifactDirectory));
|
FileUtils.deleteDirectory(new File(ARTIFACT_DIRECTORY));
|
||||||
} catch (final IOException | IllegalArgumentException e) {
|
} catch (final IOException | IllegalArgumentException e) {
|
||||||
LOG.warn("Cannot delete file-directory", e);
|
LOG.warn("Cannot delete file-directory", e);
|
||||||
}
|
}
|
||||||
@@ -449,20 +447,6 @@ public abstract class AbstractIntegrationTest {
|
|||||||
return currentTime.getOffset().getId().replace("Z", "+00:00");
|
return currentTime.getOffset().getId().replace("Z", "+00:00");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static String generateRandomStringWithLength(final int length) {
|
|
||||||
final StringBuilder randomStringBuilder = new StringBuilder(length);
|
|
||||||
final Random rand = new Random();
|
|
||||||
final int lowercaseACode = 97;
|
|
||||||
final int lowercaseZCode = 122;
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
final char randomCharacter = (char) (rand.nextInt(lowercaseZCode - lowercaseACode + 1) + lowercaseACode);
|
|
||||||
randomStringBuilder.append(randomCharacter);
|
|
||||||
}
|
|
||||||
|
|
||||||
return randomStringBuilder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static Action getFirstAssignedAction(
|
protected static Action getFirstAssignedAction(
|
||||||
final DistributionSetAssignmentResult distributionSetAssignmentResult) {
|
final DistributionSetAssignmentResult distributionSetAssignmentResult) {
|
||||||
return distributionSetAssignmentResult.getAssignedEntity().stream().findFirst()
|
return distributionSetAssignmentResult.getAssignedEntity().stream().findFirst()
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Bosch.IO 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.test.util;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
|
|
||||||
|
public class TargetTestData {
|
||||||
|
public static final String ATTRIBUTE_KEY_TOO_LONG;
|
||||||
|
public static final String ATTRIBUTE_KEY_VALID;
|
||||||
|
public static final String ATTRIBUTE_VALUE_TOO_LONG;
|
||||||
|
public static final String ATTRIBUTE_VALUE_VALID;
|
||||||
|
|
||||||
|
static {
|
||||||
|
final Random rand = new Random();
|
||||||
|
ATTRIBUTE_KEY_TOO_LONG = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE + 1, rand);
|
||||||
|
ATTRIBUTE_KEY_VALID = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE, rand);
|
||||||
|
ATTRIBUTE_VALUE_TOO_LONG = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE + 1, rand);
|
||||||
|
ATTRIBUTE_VALUE_VALID = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE, rand);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String generateRandomStringWithLength(final int length, final Random rand) {
|
||||||
|
final StringBuilder randomStringBuilder = new StringBuilder(length);
|
||||||
|
final int lowercaseACode = 97;
|
||||||
|
final int lowercaseZCode = 122;
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
final char randomCharacter = (char) (rand.nextInt(lowercaseZCode - lowercaseACode + 1) + lowercaseACode);
|
||||||
|
randomStringBuilder.append(randomCharacter);
|
||||||
|
}
|
||||||
|
return randomStringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private TargetTestData() {
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,9 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.test.util;
|
package org.eclipse.hawkbit.repository.test.util;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Field;
|
import java.util.Arrays;
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
@@ -29,6 +27,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||||||
|
|
||||||
public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCallback {
|
public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCallback {
|
||||||
|
|
||||||
|
public static final String DEFAULT_TENANT = "default";
|
||||||
private SecurityContext oldContext;
|
private SecurityContext oldContext;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -85,35 +84,14 @@ public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCal
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String[] getAllAuthorities(final String[] additionalAuthorities, final String[] notInclude) {
|
private String[] getAllAuthorities(final String[] additionalAuthorities, final String[] notInclude) {
|
||||||
final List<String> allPermissions = new ArrayList<>();
|
final List<String> permissions = SpPermission.getAllAuthorities();
|
||||||
final Field[] declaredFields = SpPermission.class.getDeclaredFields();
|
|
||||||
for (final Field field : declaredFields) {
|
|
||||||
if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
try {
|
|
||||||
boolean addPermission = true;
|
|
||||||
final String permissionName = (String) field.get(null);
|
|
||||||
if (notInclude != null) {
|
if (notInclude != null) {
|
||||||
for (final String notInlcudePerm : notInclude) {
|
permissions.removeAll(Arrays.asList(notInclude));
|
||||||
if (permissionName.equals(notInlcudePerm)) {
|
|
||||||
addPermission = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (additionalAuthorities != null) {
|
||||||
|
permissions.addAll(Arrays.asList(additionalAuthorities));
|
||||||
}
|
}
|
||||||
}
|
return permissions.toArray(new String[0]);
|
||||||
if (addPermission) {
|
|
||||||
allPermissions.add(permissionName);
|
|
||||||
}
|
|
||||||
// don't want to log this exceptions.
|
|
||||||
} catch (@SuppressWarnings("squid:S1166") IllegalArgumentException | IllegalAccessException e) {
|
|
||||||
// nope
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (final String authority : additionalAuthorities) {
|
|
||||||
allPermissions.add(authority);
|
|
||||||
}
|
|
||||||
return allPermissions.toArray(new String[allPermissions.size()]);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -146,23 +124,23 @@ public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCal
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static WithUser withController(final String principal, final String... authorities) {
|
public static WithUser withController(final String principal, final String... authorities) {
|
||||||
return withUserAndTenant(principal, "default", true, true, true, authorities);
|
return withUserAndTenant(principal, DEFAULT_TENANT, true, true, true, authorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WithUser withUser(final String principal, final String... authorities) {
|
public static WithUser withUser(final String principal, final String... authorities) {
|
||||||
return withUserAndTenant(principal, "default", true, true, false, authorities);
|
return withUserAndTenant(principal, DEFAULT_TENANT, true, true, false, authorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WithUser withUser(final String principal, final boolean allSpPermision, final String... authorities) {
|
public static WithUser withUser(final String principal, final boolean allSpPermision, final String... authorities) {
|
||||||
return withUserAndTenant(principal, "default", true, allSpPermision, false, authorities);
|
return withUserAndTenant(principal, DEFAULT_TENANT, true, allSpPermision, false, authorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WithUser withUser(final boolean autoCreateTenant) {
|
public static WithUser withUser(final boolean autoCreateTenant) {
|
||||||
return withUserAndTenant("bumlux", "default", autoCreateTenant, true, false, new String[] {});
|
return withUserAndTenant("bumlux", DEFAULT_TENANT, autoCreateTenant, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WithUser withUserAndTenant(final String principal, final String tenant, final String... authorities) {
|
public static WithUser withUserAndTenant(final String principal, final String tenant, final String... authorities) {
|
||||||
return withUserAndTenant(principal, tenant, true, true, false, new String[] {});
|
return withUserAndTenant(principal, tenant, true, true, false, authorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WithUser withUserAndTenant(final String principal, final String tenant,
|
public static WithUser withUserAndTenant(final String principal, final String tenant,
|
||||||
@@ -172,8 +150,7 @@ public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCal
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static WithUser privilegedUser() {
|
private static WithUser privilegedUser() {
|
||||||
return createWithUser("bumlux", "default", true, true, false,
|
return createWithUser("bumlux", DEFAULT_TENANT, true, true, false, "ROLE_CONTROLLER", "ROLE_SYSTEM_CODE");
|
||||||
new String[] { "ROLE_CONTROLLER", "ROLE_SYSTEM_CODE" });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static WithUser createWithUser(final String principal, final String tenant, final boolean autoCreateTenant,
|
private static WithUser createWithUser(final String principal, final String tenant, final boolean autoCreateTenant,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
@@ -130,7 +131,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
@PathVariable("softwareModuleId") final Long softwareModuleId) {
|
@PathVariable("softwareModuleId") final Long softwareModuleId) {
|
||||||
LOG.debug("getSoftwareModulesArtifacts({})", controllerId);
|
LOG.debug("getSoftwareModulesArtifacts({})", controllerId);
|
||||||
|
|
||||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
final Target target = findTarget(controllerId);
|
||||||
|
|
||||||
final SoftwareModule softwareModule = controllerManagement.getSoftwareModule(softwareModuleId)
|
final SoftwareModule softwareModule = controllerManagement.getSoftwareModule(softwareModuleId)
|
||||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
||||||
@@ -169,20 +170,16 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
@PathVariable("fileName") final String fileName) {
|
@PathVariable("fileName") final String fileName) {
|
||||||
final ResponseEntity<InputStream> result;
|
final ResponseEntity<InputStream> result;
|
||||||
|
|
||||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
final Target target = findTarget(controllerId);
|
||||||
final SoftwareModule module = controllerManagement.getSoftwareModule(softwareModuleId)
|
final SoftwareModule module = controllerManagement.getSoftwareModule(softwareModuleId)
|
||||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
||||||
|
|
||||||
if (checkModule(fileName, module)) {
|
if (checkModule(fileName, module)) {
|
||||||
LOG.warn("Softare module with id {} could not be found.", softwareModuleId);
|
LOG.warn("Software module with id {} could not be found.", softwareModuleId);
|
||||||
result = ResponseEntity.notFound().build();
|
result = ResponseEntity.notFound().build();
|
||||||
} else {
|
} else {
|
||||||
|
// Artifact presence is ensured in 'checkModule'
|
||||||
// Exception squid:S3655 - Optional access is checked in checkModule
|
final Artifact artifact = module.getArtifactByFilename(fileName).orElseThrow(NoSuchElementException::new);
|
||||||
// subroutine
|
|
||||||
@SuppressWarnings("squid:S3655")
|
|
||||||
final Artifact artifact = module.getArtifactByFilename(fileName).get();
|
|
||||||
|
|
||||||
final DbArtifact file = artifactManagement
|
final DbArtifact file = artifactManagement
|
||||||
.loadArtifactBinary(artifact.getSha1Hash(), module.getId(), module.isEncrypted())
|
.loadArtifactBinary(artifact.getSha1Hash(), module.getId(), module.isEncrypted())
|
||||||
.orElseThrow(() -> new ArtifactBinaryNotFoundException(artifact.getSha1Hash()));
|
.orElseThrow(() -> new ArtifactBinaryNotFoundException(artifact.getSha1Hash()));
|
||||||
@@ -239,7 +236,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
@PathVariable("controllerId") final String controllerId,
|
@PathVariable("controllerId") final String controllerId,
|
||||||
@PathVariable("softwareModuleId") final Long softwareModuleId,
|
@PathVariable("softwareModuleId") final Long softwareModuleId,
|
||||||
@PathVariable("fileName") final String fileName) {
|
@PathVariable("fileName") final String fileName) {
|
||||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
final Target target = findTarget(controllerId);
|
||||||
|
|
||||||
final SoftwareModule module = controllerManagement.getSoftwareModule(softwareModuleId)
|
final SoftwareModule module = controllerManagement.getSoftwareModule(softwareModuleId)
|
||||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
||||||
@@ -274,9 +271,8 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
@RequestParam(value = "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount) {
|
@RequestParam(value = "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount) {
|
||||||
LOG.debug("getControllerBasedeploymentAction({},{})", controllerId, resource);
|
LOG.debug("getControllerBasedeploymentAction({},{})", controllerId, resource);
|
||||||
|
|
||||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
final Target target = findTarget(controllerId);
|
||||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
final Action action = findActionForTarget(actionId, target);
|
||||||
verifyActionAssignedToTarget(target, action);
|
|
||||||
|
|
||||||
checkAndCancelExpiredAction(action);
|
checkAndCancelExpiredAction(action);
|
||||||
|
|
||||||
@@ -296,7 +292,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static HandlingType calculateDownloadType(final Action action) {
|
private static HandlingType calculateDownloadType(final Action action) {
|
||||||
if (action.isDownloadOnly() || action.isForce()) {
|
if (action.isDownloadOnly() || action.isForcedOrTimeForced()) {
|
||||||
return HandlingType.FORCED;
|
return HandlingType.FORCED;
|
||||||
}
|
}
|
||||||
return HandlingType.ATTEMPT;
|
return HandlingType.ATTEMPT;
|
||||||
@@ -325,9 +321,9 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
@PathVariable("actionId") @NotEmpty final Long actionId) {
|
@PathVariable("actionId") @NotEmpty final Long actionId) {
|
||||||
LOG.debug("provideBasedeploymentActionFeedback for target [{},{}]: {}", controllerId, actionId, feedback);
|
LOG.debug("provideBasedeploymentActionFeedback for target [{},{}]: {}", controllerId, actionId, feedback);
|
||||||
|
|
||||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
final Target target = findTarget(controllerId);
|
||||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
final Action action = findActionForTarget(actionId, target);
|
||||||
verifyActionAssignedToTarget(target, action);
|
|
||||||
|
|
||||||
if (!action.isActive()) {
|
if (!action.isActive()) {
|
||||||
LOG.warn("Updating action {} with feedback {} not possible since action not active anymore.",
|
LOG.warn("Updating action {} with feedback {} not possible since action not active anymore.",
|
||||||
@@ -342,7 +338,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ActionStatusCreate generateUpdateStatus(final DdiActionFeedback feedback, final String controllerId,
|
private ActionStatusCreate generateUpdateStatus(final DdiActionFeedback feedback, final String controllerId,
|
||||||
final Long actionid) {
|
final Long actionId) {
|
||||||
|
|
||||||
final List<String> messages = new ArrayList<>();
|
final List<String> messages = new ArrayList<>();
|
||||||
|
|
||||||
@@ -353,38 +349,38 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
Status status;
|
Status status;
|
||||||
switch (feedback.getStatus().getExecution()) {
|
switch (feedback.getStatus().getExecution()) {
|
||||||
case CANCELED:
|
case CANCELED:
|
||||||
LOG.debug("Controller confirmed cancel (actionid: {}, controllerId: {}) as we got {} report.", actionid,
|
LOG.debug("Controller confirmed cancel (actionId: {}, controllerId: {}) as we got {} report.", actionId,
|
||||||
controllerId, feedback.getStatus().getExecution());
|
controllerId, feedback.getStatus().getExecution());
|
||||||
status = Status.CANCELED;
|
status = Status.CANCELED;
|
||||||
addMessageIfEmpty("Target confirmed cancelation.", messages);
|
addMessageIfEmpty("Target confirmed cancellation.", messages);
|
||||||
break;
|
break;
|
||||||
case REJECTED:
|
case REJECTED:
|
||||||
LOG.info("Controller reported internal error (actionid: {}, controllerId: {}) as we got {} report.",
|
LOG.info("Controller reported internal error (actionId: {}, controllerId: {}) as we got {} report.",
|
||||||
actionid, controllerId, feedback.getStatus().getExecution());
|
actionId, controllerId, feedback.getStatus().getExecution());
|
||||||
status = Status.WARNING;
|
status = Status.WARNING;
|
||||||
addMessageIfEmpty("Target REJECTED update", messages);
|
addMessageIfEmpty("Target REJECTED update", messages);
|
||||||
break;
|
break;
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
status = handleClosedCase(feedback, controllerId, actionid, messages);
|
status = handleClosedCase(feedback, controllerId, actionId, messages);
|
||||||
break;
|
break;
|
||||||
case DOWNLOAD:
|
case DOWNLOAD:
|
||||||
LOG.debug("Controller confirmed status of download (actionId: {}, controllerId: {}) as we got {} report.",
|
LOG.debug("Controller confirmed status of download (actionId: {}, controllerId: {}) as we got {} report.",
|
||||||
actionid, controllerId, feedback.getStatus().getExecution());
|
actionId, controllerId, feedback.getStatus().getExecution());
|
||||||
status = Status.DOWNLOAD;
|
status = Status.DOWNLOAD;
|
||||||
addMessageIfEmpty("Target confirmed download start", messages);
|
addMessageIfEmpty("Target confirmed download start", messages);
|
||||||
break;
|
break;
|
||||||
case DOWNLOADED:
|
case DOWNLOADED:
|
||||||
LOG.debug("Controller confirmed download (actionId: {}, controllerId: {}) as we got {} report.", actionid,
|
LOG.debug("Controller confirmed download (actionId: {}, controllerId: {}) as we got {} report.", actionId,
|
||||||
controllerId, feedback.getStatus().getExecution());
|
controllerId, feedback.getStatus().getExecution());
|
||||||
status = Status.DOWNLOADED;
|
status = Status.DOWNLOADED;
|
||||||
addMessageIfEmpty("Target confirmed download finished", messages);
|
addMessageIfEmpty("Target confirmed download finished", messages);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
status = handleDefaultCase(feedback, controllerId, actionid, messages);
|
status = handleDefaultCase(feedback, controllerId, actionId, messages);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return entityFactory.actionStatus().create(actionid).status(status).messages(messages);
|
return entityFactory.actionStatus().create(actionId).status(status).messages(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addMessageIfEmpty(final String text, final List<String> messages) {
|
private static void addMessageIfEmpty(final String text, final List<String> messages) {
|
||||||
@@ -393,20 +389,20 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Status handleDefaultCase(final DdiActionFeedback feedback, final String controllerId, final Long actionid,
|
private Status handleDefaultCase(final DdiActionFeedback feedback, final String controllerId, final Long actionId,
|
||||||
final List<String> messages) {
|
final List<String> messages) {
|
||||||
Status status;
|
Status status;
|
||||||
LOG.debug("Controller reported intermediate status (actionid: {}, controllerId: {}) as we got {} report.",
|
LOG.debug("Controller reported intermediate status (actionId: {}, controllerId: {}) as we got {} report.",
|
||||||
actionid, controllerId, feedback.getStatus().getExecution());
|
actionId, controllerId, feedback.getStatus().getExecution());
|
||||||
status = Status.RUNNING;
|
status = Status.RUNNING;
|
||||||
addMessageIfEmpty("Target reported " + feedback.getStatus().getExecution(), messages);
|
addMessageIfEmpty("Target reported " + feedback.getStatus().getExecution(), messages);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Status handleClosedCase(final DdiActionFeedback feedback, final String controllerId, final Long actionid,
|
private Status handleClosedCase(final DdiActionFeedback feedback, final String controllerId, final Long actionId,
|
||||||
final List<String> messages) {
|
final List<String> messages) {
|
||||||
Status status;
|
Status status;
|
||||||
LOG.debug("Controller reported closed (actionid: {}, controllerId: {}) as we got {} report.", actionid,
|
LOG.debug("Controller reported closed (actionId: {}, controllerId: {}) as we got {} report.", actionId,
|
||||||
controllerId, feedback.getStatus().getExecution());
|
controllerId, feedback.getStatus().getExecution());
|
||||||
if (feedback.getStatus().getResult().getFinished() == FinalResult.FAILURE) {
|
if (feedback.getStatus().getResult().getFinished() == FinalResult.FAILURE) {
|
||||||
status = Status.ERROR;
|
status = Status.ERROR;
|
||||||
@@ -432,9 +428,9 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
@PathVariable("actionId") @NotEmpty final Long actionId) {
|
@PathVariable("actionId") @NotEmpty final Long actionId) {
|
||||||
LOG.debug("getControllerCancelAction({})", controllerId);
|
LOG.debug("getControllerCancelAction({})", controllerId);
|
||||||
|
|
||||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
final Target target = findTarget(controllerId);
|
||||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
final Action action = findActionForTarget(actionId, target);
|
||||||
verifyActionAssignedToTarget(target, action);
|
|
||||||
|
|
||||||
if (action.isCancelingOrCanceled()) {
|
if (action.isCancelingOrCanceled()) {
|
||||||
final DdiCancel cancel = new DdiCancel(String.valueOf(action.getId()),
|
final DdiCancel cancel = new DdiCancel(String.valueOf(action.getId()),
|
||||||
@@ -443,7 +439,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
LOG.debug("Found an active CancelAction for target {}. returning cancel: {}", controllerId, cancel);
|
LOG.debug("Found an active CancelAction for target {}. returning cancel: {}", controllerId, cancel);
|
||||||
|
|
||||||
controllerManagement.registerRetrieved(action.getId(), RepositoryConstants.SERVER_MESSAGE_PREFIX
|
controllerManagement.registerRetrieved(action.getId(), RepositoryConstants.SERVER_MESSAGE_PREFIX
|
||||||
+ "Target retrieved cancel action and should start now the cancelation.");
|
+ "Target retrieved cancel action and should start now the cancellation.");
|
||||||
|
|
||||||
return new ResponseEntity<>(cancel, HttpStatus.OK);
|
return new ResponseEntity<>(cancel, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -458,12 +454,11 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
@PathVariable("actionId") @NotEmpty final Long actionId) {
|
@PathVariable("actionId") @NotEmpty final Long actionId) {
|
||||||
LOG.debug("provideCancelActionFeedback for target [{}]: {}", controllerId, feedback);
|
LOG.debug("provideCancelActionFeedback for target [{}]: {}", controllerId, feedback);
|
||||||
|
|
||||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
final Target target = findTarget(controllerId);
|
||||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
final Action action = findActionForTarget(actionId, target);
|
||||||
verifyActionAssignedToTarget(target, action);
|
|
||||||
|
|
||||||
controllerManagement
|
controllerManagement
|
||||||
.addCancelActionStatus(generateActionCancelStatus(feedback, target, actionId, entityFactory));
|
.addCancelActionStatus(generateActionCancelStatus(feedback, target, action.getId(), entityFactory));
|
||||||
return ResponseEntity.ok().build();
|
return ResponseEntity.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,9 +468,8 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
@RequestParam(value = "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount) {
|
@RequestParam(value = "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount) {
|
||||||
LOG.debug("getControllerInstalledAction({})", controllerId);
|
LOG.debug("getControllerInstalledAction({})", controllerId);
|
||||||
|
|
||||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
final Target target = findTarget(controllerId);
|
||||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
final Action action = findActionForTarget(actionId, target);
|
||||||
verifyActionAssignedToTarget(target, action);
|
|
||||||
|
|
||||||
if (action.isActive() || action.isCancelingOrCanceled()) {
|
if (action.isActive() || action.isCancelingOrCanceled()) {
|
||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
@@ -511,19 +505,19 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static ActionStatusCreate generateActionCancelStatus(final DdiActionFeedback feedback, final Target target,
|
private static ActionStatusCreate generateActionCancelStatus(final DdiActionFeedback feedback, final Target target,
|
||||||
final Long actionid, final EntityFactory entityFactory) {
|
final Long actionId, final EntityFactory entityFactory) {
|
||||||
|
|
||||||
final List<String> messages = new ArrayList<>();
|
final List<String> messages = new ArrayList<>();
|
||||||
Status status;
|
Status status;
|
||||||
switch (feedback.getStatus().getExecution()) {
|
switch (feedback.getStatus().getExecution()) {
|
||||||
case CANCELED:
|
case CANCELED:
|
||||||
status = handleCaseCancelCanceled(feedback, target, actionid, messages);
|
status = handleCaseCancelCanceled(feedback, target, actionId, messages);
|
||||||
break;
|
break;
|
||||||
case REJECTED:
|
case REJECTED:
|
||||||
LOG.info("Target rejected the cancelation request (actionid: {}, controllerId: {}).", actionid,
|
LOG.info("Target rejected the cancellation request (actionId: {}, controllerId: {}).", actionId,
|
||||||
target.getControllerId());
|
target.getControllerId());
|
||||||
status = Status.CANCEL_REJECTED;
|
status = Status.CANCEL_REJECTED;
|
||||||
messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target rejected the cancelation request.");
|
messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target rejected the cancellation request.");
|
||||||
break;
|
break;
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
status = handleCancelClosedCase(feedback, messages);
|
status = handleCancelClosedCase(feedback, messages);
|
||||||
@@ -537,7 +531,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
messages.addAll(feedback.getStatus().getDetails());
|
messages.addAll(feedback.getStatus().getDetails());
|
||||||
}
|
}
|
||||||
|
|
||||||
return entityFactory.actionStatus().create(actionid).status(status).messages(messages);
|
return entityFactory.actionStatus().create(actionId).status(status).messages(messages);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,41 +539,44 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
Status status;
|
Status status;
|
||||||
if (feedback.getStatus().getResult().getFinished() == FinalResult.FAILURE) {
|
if (feedback.getStatus().getResult().getFinished() == FinalResult.FAILURE) {
|
||||||
status = Status.ERROR;
|
status = Status.ERROR;
|
||||||
addMessageIfEmpty("Target was not able to complete cancelation", messages);
|
addMessageIfEmpty("Target was not able to complete cancellation", messages);
|
||||||
} else {
|
} else {
|
||||||
status = Status.CANCELED;
|
status = Status.CANCELED;
|
||||||
addMessageIfEmpty("Cancelation confirmed", messages);
|
addMessageIfEmpty("Cancellation confirmed", messages);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Status handleCaseCancelCanceled(final DdiActionFeedback feedback, final Target target,
|
private static Status handleCaseCancelCanceled(final DdiActionFeedback feedback, final Target target,
|
||||||
final Long actionid, final List<String> messages) {
|
final Long actionId, final List<String> messages) {
|
||||||
Status status;
|
Status status;
|
||||||
LOG.error(
|
LOG.error(
|
||||||
"Target reported cancel for a cancel which is not supported by the server (actionid: {}, controllerId: {}) as we got {} report.",
|
"Target reported cancel for a cancel which is not supported by the server (actionId: {}, controllerId: {}) as we got {} report.",
|
||||||
actionid, target.getControllerId(), feedback.getStatus().getExecution());
|
actionId, target.getControllerId(), feedback.getStatus().getExecution());
|
||||||
status = Status.WARNING;
|
status = Status.WARNING;
|
||||||
messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX
|
messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX
|
||||||
+ "Target reported cancel for a cancel which is not supported by the server.");
|
+ "Target reported cancel for a cancel which is not supported by the server.");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Target findTargetWithExceptionIfNotFound(final String controllerId) {
|
private Target findTarget(final String controllerId) {
|
||||||
return controllerManagement.getByControllerId(controllerId)
|
return controllerManagement.getByControllerId(controllerId)
|
||||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action findActionWithExceptionIfNotFound(final Long actionId) {
|
private Action findActionForTarget(final Long actionId, final Target target) {
|
||||||
return controllerManagement.findActionWithDetails(actionId)
|
final Action action = controllerManagement.findActionWithDetails(actionId)
|
||||||
.orElseThrow(() -> new EntityNotFoundException(Action.class, actionId));
|
.orElseThrow(() -> new EntityNotFoundException(Action.class, actionId));
|
||||||
|
return verifyActionBelongsToTarget(action, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyActionAssignedToTarget(final Target target, final Action action) {
|
private Action verifyActionBelongsToTarget(Action action, Target target) {
|
||||||
if (!action.getTarget().getId().equals(target.getId())) {
|
if (!action.getTarget().getId().equals(target.getId())) {
|
||||||
LOG.warn(GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET, action.getId(), target.getId());
|
LOG.debug(GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET, action.getId(), target.getId());
|
||||||
throw new EntityNotFoundException(Action.class, action.getId());
|
throw new EntityNotFoundException(
|
||||||
|
"Not a valid action (" + action.getId() + ") for target: " + target.getControllerId(), null);
|
||||||
}
|
}
|
||||||
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -594,7 +591,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
try {
|
try {
|
||||||
controllerManagement.cancelAction(action.getId());
|
controllerManagement.cancelAction(action.getId());
|
||||||
} catch (final CancelActionNotAllowedException e) {
|
} catch (final CancelActionNotAllowedException e) {
|
||||||
LOG.info("Cancel action not allowed exception :{}", e);
|
LOG.info("Cancel action not allowed: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ import io.qameta.allure.Story;
|
|||||||
*/
|
*/
|
||||||
@Feature("Component Tests - Direct Device Integration API")
|
@Feature("Component Tests - Direct Device Integration API")
|
||||||
@Story("Cancel Action Resource")
|
@Story("Cancel Action Resource")
|
||||||
public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests that the cancel action resource can be used with CBOR.")
|
@Description("Tests that the cancel action resource can be used with CBOR.")
|
||||||
public void cancelActionCbor() throws Exception {
|
void cancelActionCbor() throws Exception {
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final Long actionId = getFirstAssignedActionId(
|
final Long actionId = getFirstAssignedActionId(
|
||||||
@@ -75,7 +75,7 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test of the controller can continue a started update even after a cancel command if it so desires.")
|
@Description("Test of the controller can continue a started update even after a cancel command if it so desires.")
|
||||||
public void rootRsCancelActionButContinueAnyway() throws Exception {
|
void rootRsCancelActionButContinueAnyway() throws Exception {
|
||||||
// prepare test data
|
// prepare test data
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
final Target savedTarget = testdataFactory.createTarget();
|
final Target savedTarget = testdataFactory.createTarget();
|
||||||
@@ -130,14 +130,14 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test for cancel operation of a update action.")
|
@Description("Test for cancel operation of a update action.")
|
||||||
public void rootRsCancelAction() throws Exception {
|
void rootRsCancelAction() throws Exception {
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
final Target savedTarget = testdataFactory.createTarget();
|
final Target savedTarget = testdataFactory.createTarget();
|
||||||
|
|
||||||
final Long actionId = getFirstAssignedActionId(
|
final Long actionId = getFirstAssignedActionId(
|
||||||
assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
||||||
|
|
||||||
long current = System.currentTimeMillis();
|
final long timeBeforeFirstPoll = System.currentTimeMillis();
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controller}", tenantAware.getCurrentTenant(),
|
mvc.perform(get("/{tenant}/controller/v1/{controller}", tenantAware.getCurrentTenant(),
|
||||||
TestdataFactory.DEFAULT_CONTROLLER_ID).accept(MediaTypes.HAL_JSON))
|
TestdataFactory.DEFAULT_CONTROLLER_ID).accept(MediaTypes.HAL_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
@@ -146,13 +146,9 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
startsWith("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||||
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId)));
|
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId)));
|
||||||
Thread.sleep(1); // is required: otherwise processing the next line is
|
final long timeAfterFirstPoll = System.currentTimeMillis() + 1;
|
||||||
// often too fast and
|
|
||||||
// the following assert will fail
|
|
||||||
assertThat(targetManagement.getByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
assertThat(targetManagement.getByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
.isBetween(timeBeforeFirstPoll, timeAfterFirstPoll);
|
||||||
assertThat(targetManagement.getByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
|
||||||
.isGreaterThanOrEqualTo(current);
|
|
||||||
|
|
||||||
// Retrieved is reported
|
// Retrieved is reported
|
||||||
|
|
||||||
@@ -171,7 +167,7 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
assertThat(activeActionsByTarget).hasSize(1);
|
assertThat(activeActionsByTarget).hasSize(1);
|
||||||
assertThat(activeActionsByTarget.get(0).getStatus()).isEqualTo(Status.CANCELING);
|
assertThat(activeActionsByTarget.get(0).getStatus()).isEqualTo(Status.CANCELING);
|
||||||
|
|
||||||
current = System.currentTimeMillis();
|
final long timeBefore2ndPoll = System.currentTimeMillis();
|
||||||
mvc.perform(get("/{tenant}/controller/v1/{controller}", tenantAware.getCurrentTenant(),
|
mvc.perform(get("/{tenant}/controller/v1/{controller}", tenantAware.getCurrentTenant(),
|
||||||
TestdataFactory.DEFAULT_CONTROLLER_ID)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
TestdataFactory.DEFAULT_CONTROLLER_ID)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
@@ -179,17 +175,10 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
.andExpect(jsonPath("$._links.cancelAction.href",
|
.andExpect(jsonPath("$._links.cancelAction.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||||
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction.getId())));
|
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction.getId())));
|
||||||
Thread.sleep(1); // is required: otherwise processing the next line is
|
final long timeAfter2ndPoll = System.currentTimeMillis() + 1;
|
||||||
// often too fast and
|
|
||||||
// the following assert will fail
|
|
||||||
assertThat(targetManagement.getByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
assertThat(targetManagement.getByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
.isBetween(timeBefore2ndPoll, timeAfter2ndPoll);
|
||||||
assertThat(targetManagement.getByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
|
||||||
.isGreaterThanOrEqualTo(current);
|
|
||||||
|
|
||||||
current = System.currentTimeMillis();
|
|
||||||
assertThat(targetManagement.getByControllerID(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
|
||||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
|
||||||
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId(), tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
+ cancelAction.getId(), tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
@@ -208,7 +197,7 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
activeActionsByTarget = deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())
|
activeActionsByTarget = deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())
|
||||||
.getContent();
|
.getContent();
|
||||||
assertThat(activeActionsByTarget).hasSize(0);
|
assertThat(activeActionsByTarget).isEmpty();
|
||||||
final Action canceledAction = deploymentManagement.findAction(cancelAction.getId()).get();
|
final Action canceledAction = deploymentManagement.findAction(cancelAction.getId()).get();
|
||||||
assertThat(canceledAction.isActive()).isFalse();
|
assertThat(canceledAction.isActive()).isFalse();
|
||||||
assertThat(canceledAction.getStatus()).isEqualTo(Status.CANCELED);
|
assertThat(canceledAction.getStatus()).isEqualTo(Status.CANCELED);
|
||||||
@@ -217,7 +206,7 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests various bad requests and if the server handles them as expected.")
|
@Description("Tests various bad requests and if the server handles them as expected.")
|
||||||
public void badCancelAction() throws Exception {
|
void badCancelAction() throws Exception {
|
||||||
|
|
||||||
// not allowed methods
|
// not allowed methods
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/1",
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/1",
|
||||||
@@ -258,7 +247,7 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the feedback channel of the cancel operation.")
|
@Description("Tests the feedback channel of the cancel operation.")
|
||||||
public void rootRsCancelActionFeedback() throws Exception {
|
void rootRsCancelActionFeedback() throws Exception {
|
||||||
|
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
@@ -327,12 +316,12 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||||
assertThat(deploymentManagement.countActionStatusAll()).isEqualTo(8);
|
assertThat(deploymentManagement.countActionStatusAll()).isEqualTo(8);
|
||||||
assertThat(deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())).hasSize(0);
|
assertThat(deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the feeback chanel of for multiple open cancel operations on the same target.")
|
@Description("Tests the feeback chanel of for multiple open cancel operations on the same target.")
|
||||||
public void multipleCancelActionFeedback() throws Exception {
|
void multipleCancelActionFeedback() throws Exception {
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
|
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
|
||||||
final DistributionSet ds2 = testdataFactory.createDistributionSet("2", true);
|
final DistributionSet ds2 = testdataFactory.createDistributionSet("2", true);
|
||||||
final DistributionSet ds3 = testdataFactory.createDistributionSet("3", true);
|
final DistributionSet ds3 = testdataFactory.createDistributionSet("3", true);
|
||||||
@@ -443,13 +432,13 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
assertThat(deploymentManagement.countActionStatusAll()).isEqualTo(13);
|
assertThat(deploymentManagement.countActionStatusAll()).isEqualTo(13);
|
||||||
|
|
||||||
// final status
|
// final status
|
||||||
assertThat(deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())).hasSize(0);
|
assertThat(deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())).isEmpty();
|
||||||
assertThat(deploymentManagement.countActionsByTarget(savedTarget.getControllerId())).isEqualTo(3);
|
assertThat(deploymentManagement.countActionsByTarget(savedTarget.getControllerId())).isEqualTo(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the feeback channel closing for too many feedbacks, i.e. denial of service prevention.")
|
@Description("Tests the feeback channel closing for too many feedbacks, i.e. denial of service prevention.")
|
||||||
public void tooMuchCancelActionFeedback() throws Exception {
|
void tooMuchCancelActionFeedback() throws Exception {
|
||||||
testdataFactory.createTarget();
|
testdataFactory.createTarget();
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
@@ -477,9 +466,9 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("test the correct rejection of various invalid feedback requests")
|
@Description("test the correct rejection of various invalid feedback requests")
|
||||||
public void badCancelActionFeedback() throws Exception {
|
void badCancelActionFeedback() throws Exception {
|
||||||
final Action cancelAction = createCancelAction(TestdataFactory.DEFAULT_CONTROLLER_ID);
|
final Action cancelAction = createCancelAction(TestdataFactory.DEFAULT_CONTROLLER_ID);
|
||||||
final Action cancelAction2 = createCancelAction("4715");
|
createCancelAction("4715");
|
||||||
|
|
||||||
// not allowed methods
|
// not allowed methods
|
||||||
mvc.perform(put("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(put("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
@@ -524,12 +513,11 @@ public class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
|||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest());
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest());
|
||||||
|
|
||||||
// finally get it right :)
|
// finaly, get it right :)
|
||||||
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||||
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
+ cancelAction.getId() + "/feedback", tenantAware.getCurrentTenant())
|
||||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "closed"))
|
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "closed"))
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
package org.eclipse.hawkbit.ddi.rest.resource;
|
package org.eclipse.hawkbit.ddi.rest.resource;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.eclipse.hawkbit.repository.test.util.TargetTestData.ATTRIBUTE_KEY_TOO_LONG;
|
||||||
|
import static org.eclipse.hawkbit.repository.test.util.TargetTestData.ATTRIBUTE_KEY_VALID;
|
||||||
|
import static org.eclipse.hawkbit.repository.test.util.TargetTestData.ATTRIBUTE_VALUE_TOO_LONG;
|
||||||
|
import static org.eclipse.hawkbit.repository.test.util.TargetTestData.ATTRIBUTE_VALUE_VALID;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
@@ -21,6 +25,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
@@ -40,41 +45,39 @@ import io.qameta.allure.Description;
|
|||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
import io.qameta.allure.Step;
|
import io.qameta.allure.Step;
|
||||||
import io.qameta.allure.Story;
|
import io.qameta.allure.Story;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test config data from the controller.
|
* Test config data from the controller.
|
||||||
*/
|
*/
|
||||||
@ActiveProfiles({ "im", "test" })
|
@ActiveProfiles({ "im", "test" })
|
||||||
@Feature("Component Tests - Direct Device Integration API")
|
@Feature("Component Tests - Direct Device Integration API")
|
||||||
@Story("Config Data Resource")
|
@Story("Config Data Resource")
|
||||||
public class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
||||||
|
|
||||||
private static final String KEY_TOO_LONG = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE + 1);
|
public static final String TARGET1_ID = "4717";
|
||||||
private static final String KEY_VALID = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE);
|
public static final String TARGET1_CONFIGDATA_PATH = "/{tenant}/controller/v1/" + TARGET1_ID + "/configData";
|
||||||
private static final String VALUE_TOO_LONG = generateRandomStringWithLength(
|
public static final String TARGET2_ID = "4718";
|
||||||
Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE + 1);
|
public static final String TARGET2_CONFIGDATA_PATH = "/{tenant}/controller/v1/" + TARGET2_ID + "/configData";
|
||||||
private static final String VALUE_VALID = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that config data can be uploaded as CBOR")
|
@Description("Verify that config data can be uploaded as CBOR")
|
||||||
public void putConfigDataAsCbor() throws Exception {
|
void putConfigDataAsCbor() throws Exception {
|
||||||
testdataFactory.createTarget("4717");
|
testdataFactory.createTarget(TARGET1_ID);
|
||||||
|
|
||||||
final Map<String, String> attributes = new HashMap<>();
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
attributes.put(KEY_VALID, VALUE_VALID);
|
attributes.put(ATTRIBUTE_KEY_VALID, ATTRIBUTE_VALUE_VALID);
|
||||||
|
|
||||||
mvc.perform(put("/{tenant}/controller/v1/4717/configData", tenantAware.getCurrentTenant())
|
mvc.perform(put(TARGET1_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
.content(jsonToCbor(JsonBuilder.configData(attributes).toString()))
|
.content(jsonToCbor(JsonBuilder.configData(attributes).toString()))
|
||||||
.contentType(DdiRestConstants.MEDIA_TYPE_CBOR)).andDo(MockMvcResultPrinter.print())
|
.contentType(DdiRestConstants.MEDIA_TYPE_CBOR)).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
assertThat(targetManagement.getControllerAttributes("4717")).isEqualTo(attributes);
|
assertThat(targetManagement.getControllerAttributes(TARGET1_ID)).isEqualTo(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
||||||
+ "are requested only once from the device.")
|
+ "are requested only once from the device.")
|
||||||
@SuppressWarnings("squid:S2925")
|
@SuppressWarnings("squid:S2925")
|
||||||
public void requestConfigDataIfEmpty() throws Exception {
|
void requestConfigDataIfEmpty() throws Exception {
|
||||||
final Target savedTarget = testdataFactory.createTarget("4712");
|
final Target savedTarget = testdataFactory.createTarget("4712");
|
||||||
|
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
@@ -88,9 +91,11 @@ public class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
Thread.sleep(1); // is required: otherwise processing the next line is
|
Thread.sleep(1); // is required: otherwise processing the next line is
|
||||||
// often too fast and
|
// often too fast and
|
||||||
// the following assert will fail
|
// the following assert will fail
|
||||||
assertThat(targetManagement.getByControllerID("4712").get().getLastTargetQuery())
|
assertThat(targetManagement.getByControllerID("4712").orElseThrow(NoSuchElementException::new)
|
||||||
|
.getLastTargetQuery())
|
||||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||||
assertThat(targetManagement.getByControllerID("4712").get().getLastTargetQuery())
|
assertThat(targetManagement.getByControllerID("4712").orElseThrow(NoSuchElementException::new)
|
||||||
|
.getLastTargetQuery())
|
||||||
.isGreaterThanOrEqualTo(current);
|
.isGreaterThanOrEqualTo(current);
|
||||||
|
|
||||||
final Map<String, String> attributes = Maps.newHashMapWithExpectedSize(1);
|
final Map<String, String> attributes = Maps.newHashMapWithExpectedSize(1);
|
||||||
@@ -113,44 +118,44 @@ public class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
||||||
+ "can be uploaded correctly by the controller.")
|
+ "can be uploaded correctly by the controller.")
|
||||||
public void putConfigData() throws Exception {
|
void putConfigData() throws Exception {
|
||||||
testdataFactory.createTarget("4717");
|
testdataFactory.createTarget(TARGET1_ID);
|
||||||
|
|
||||||
// initial
|
// initial
|
||||||
final Map<String, String> attributes = new HashMap<>();
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
attributes.put(KEY_VALID, VALUE_VALID);
|
attributes.put(ATTRIBUTE_KEY_VALID, ATTRIBUTE_VALUE_VALID);
|
||||||
|
|
||||||
mvc.perform(put("/{tenant}/controller/v1/4717/configData", tenantAware.getCurrentTenant())
|
mvc.perform(put(TARGET1_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||||
assertThat(targetManagement.getControllerAttributes("4717")).isEqualTo(attributes);
|
assertThat(targetManagement.getControllerAttributes(TARGET1_ID)).isEqualTo(attributes);
|
||||||
|
|
||||||
// update
|
// update
|
||||||
attributes.put("sdsds", "123412");
|
attributes.put("sdsds", "123412");
|
||||||
mvc.perform(put("/{tenant}/controller/v1/4717/configData", tenantAware.getCurrentTenant())
|
mvc.perform(put(TARGET1_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||||
assertThat(targetManagement.getControllerAttributes("4717")).isEqualTo(attributes);
|
assertThat(targetManagement.getControllerAttributes(TARGET1_ID)).isEqualTo(attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
||||||
+ "upload quota is enforced to protect the server from malicious attempts.")
|
+ "upload quota is enforced to protect the server from malicious attempts.")
|
||||||
public void putTooMuchConfigData() throws Exception {
|
void putTooMuchConfigData() throws Exception {
|
||||||
testdataFactory.createTarget("4717");
|
testdataFactory.createTarget(TARGET1_ID);
|
||||||
|
|
||||||
// initial
|
// initial
|
||||||
Map<String, String> attributes = new HashMap<>();
|
Map<String, String> attributes = new HashMap<>();
|
||||||
for (int i = 0; i < quotaManagement.getMaxAttributeEntriesPerTarget(); i++) {
|
for (int i = 0; i < quotaManagement.getMaxAttributeEntriesPerTarget(); i++) {
|
||||||
attributes.put("dsafsdf" + i, "sdsds" + i);
|
attributes.put("dsafsdf" + i, "sdsds" + i);
|
||||||
}
|
}
|
||||||
mvc.perform(put("/{tenant}/controller/v1/4717/configData", tenantAware.getCurrentTenant())
|
mvc.perform(put(TARGET1_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
attributes = new HashMap<>();
|
attributes = new HashMap<>();
|
||||||
attributes.put("on too many", "sdsds");
|
attributes.put("on too many", "sdsds");
|
||||||
mvc.perform(put("/{tenant}/controller/v1/4717/configData", tenantAware.getCurrentTenant())
|
mvc.perform(put(TARGET1_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isForbidden())
|
.andExpect(status().isForbidden())
|
||||||
.andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName())))
|
.andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName())))
|
||||||
@@ -161,7 +166,7 @@ public class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
||||||
+ "resource behaves as expected in case of invalid request attempts.")
|
+ "resource behaves as expected in case of invalid request attempts.")
|
||||||
public void badConfigData() throws Exception {
|
void badConfigData() throws Exception {
|
||||||
testdataFactory.createTarget("4712");
|
testdataFactory.createTarget("4712");
|
||||||
|
|
||||||
// not allowed methods
|
// not allowed methods
|
||||||
@@ -195,23 +200,17 @@ public class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that invalid config data attributes are handled correctly.")
|
@Description("Verifies that invalid config data attributes are handled correctly.")
|
||||||
public void putConfigDataWithInvalidAttributes() throws Exception {
|
void putConfigDataWithInvalidAttributes() throws Exception {
|
||||||
// create a target
|
// create a target
|
||||||
final String controllerId = "4718";
|
testdataFactory.createTarget(TARGET2_ID);
|
||||||
testdataFactory.createTarget(controllerId);
|
putAndVerifyConfigDataWithKeyTooLong();
|
||||||
final String configDataPath = "/{tenant}/controller/v1/" + controllerId + "/configData";
|
putAndVerifyConfigDataWithValueTooLong();
|
||||||
|
|
||||||
putAndVerifyConfigDataWithKeyTooLong(configDataPath);
|
|
||||||
|
|
||||||
putAndVerifyConfigDataWithValueTooLong(configDataPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void putAndVerifyConfigDataWithKeyTooLong(final String configDataPath) throws Exception {
|
private void putAndVerifyConfigDataWithKeyTooLong() throws Exception {
|
||||||
|
final Map<String, String> attributes = Collections.singletonMap(ATTRIBUTE_KEY_TOO_LONG, ATTRIBUTE_VALUE_VALID);
|
||||||
final Map<String, String> attributes = Collections.singletonMap(KEY_TOO_LONG, VALUE_VALID);
|
mvc.perform(put(DdiConfigDataTest.TARGET2_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
|
|
||||||
mvc.perform(put(configDataPath, tenantAware.getCurrentTenant())
|
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isBadRequest())
|
.andExpect(status().isBadRequest())
|
||||||
.andExpect(jsonPath("$.exceptionClass", equalTo(InvalidTargetAttributeException.class.getName())))
|
.andExpect(jsonPath("$.exceptionClass", equalTo(InvalidTargetAttributeException.class.getName())))
|
||||||
@@ -219,11 +218,9 @@ public class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void putAndVerifyConfigDataWithValueTooLong(final String configDataPath) throws Exception {
|
private void putAndVerifyConfigDataWithValueTooLong() throws Exception {
|
||||||
|
final Map<String, String> attributes = Collections.singletonMap(ATTRIBUTE_KEY_VALID, ATTRIBUTE_VALUE_TOO_LONG);
|
||||||
final Map<String, String> attributes = Collections.singletonMap(KEY_VALID, VALUE_TOO_LONG);
|
mvc.perform(put(DdiConfigDataTest.TARGET2_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
|
|
||||||
mvc.perform(put(configDataPath, tenantAware.getCurrentTenant())
|
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isBadRequest())
|
.andExpect(status().isBadRequest())
|
||||||
.andExpect(jsonPath("$.exceptionClass", equalTo(InvalidTargetAttributeException.class.getName())))
|
.andExpect(jsonPath("$.exceptionClass", equalTo(InvalidTargetAttributeException.class.getName())))
|
||||||
@@ -232,139 +229,133 @@ public class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify that config data (device attributes) can be updated by the controller using different update modes (merge, replace, remove).")
|
@Description("Verify that config data (device attributes) can be updated by the controller using different update modes (merge, replace, remove).")
|
||||||
public void putConfigDataWithDifferentUpdateModes() throws Exception {
|
void putConfigDataWithDifferentUpdateModes() throws Exception {
|
||||||
|
|
||||||
// create a target
|
// create a target
|
||||||
final String controllerId = "4717";
|
testdataFactory.createTarget(TARGET1_ID);
|
||||||
testdataFactory.createTarget(controllerId);
|
|
||||||
final String configDataPath = "/{tenant}/controller/v1/" + controllerId + "/configData";
|
|
||||||
|
|
||||||
// no update mode
|
// no update mode
|
||||||
putConfigDataWithoutUpdateMode(controllerId, configDataPath);
|
putConfigDataWithoutUpdateMode();
|
||||||
|
|
||||||
// update mode REPLACE
|
// update mode REPLACE
|
||||||
putConfigDataWithUpdateModeReplace(controllerId, configDataPath);
|
putConfigDataWithUpdateModeReplace();
|
||||||
|
|
||||||
// update mode MERGE
|
// update mode MERGE
|
||||||
putConfigDataWithUpdateModeMerge(controllerId, configDataPath);
|
putConfigDataWithUpdateModeMerge();
|
||||||
|
|
||||||
// update mode REMOVE
|
// update mode REMOVE
|
||||||
putConfigDataWithUpdateModeRemove(controllerId, configDataPath);
|
putConfigDataWithUpdateModeRemove();
|
||||||
|
|
||||||
// invalid update mode
|
// invalid update mode
|
||||||
putConfigDataWithInvalidUpdateMode(configDataPath);
|
putConfigDataWithInvalidUpdateMode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void putConfigDataWithInvalidUpdateMode(final String configDataPath) throws Exception {
|
private void putConfigDataWithInvalidUpdateMode() throws Exception {
|
||||||
|
|
||||||
// create some attriutes
|
// create some attriutes
|
||||||
final Map<String, String> attributes = new HashMap<>();
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
attributes.put("k0", "v0");
|
attributes.put("k0", "v0");
|
||||||
attributes.put("k1", "v1");
|
attributes.put("k1", "v1");
|
||||||
|
|
||||||
// use an invalid update mode
|
// use an invalid update mode
|
||||||
mvc.perform(put(configDataPath, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
.content(JsonBuilder.configData(attributes, "KJHGKJHGKJHG").toString())
|
.content(JsonBuilder.configData(attributes, "KJHGKJHGKJHG").toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void putConfigDataWithUpdateModeRemove(final String controllerId, final String configDataPath)
|
private void putConfigDataWithUpdateModeRemove() throws Exception {
|
||||||
throws Exception {
|
|
||||||
|
|
||||||
// get the current attributes
|
// get the current attributes
|
||||||
final int previousSize = targetManagement.getControllerAttributes(controllerId).size();
|
final int previousSize = targetManagement.getControllerAttributes(DdiConfigDataTest.TARGET1_ID).size();
|
||||||
|
|
||||||
// update the attributes using update mode REMOVE
|
// update the attributes using update mode REMOVE
|
||||||
final Map<String, String> removeAttributes = new HashMap<>();
|
final Map<String, String> removeAttributes = new HashMap<>();
|
||||||
removeAttributes.put("k1", "foo");
|
removeAttributes.put("k1", "foo");
|
||||||
removeAttributes.put("k3", "bar");
|
removeAttributes.put("k3", "bar");
|
||||||
|
|
||||||
mvc.perform(put(configDataPath, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
.content(JsonBuilder.configData(removeAttributes, "remove").toString())
|
.content(JsonBuilder.configData(removeAttributes, "remove").toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
// verify attribute removal
|
// verify attribute removal
|
||||||
final Map<String, String> updatedAttributes = targetManagement.getControllerAttributes(controllerId);
|
final Map<String, String> updatedAttributes = targetManagement
|
||||||
assertThat(updatedAttributes.size()).isEqualTo(previousSize - 2);
|
.getControllerAttributes(DdiConfigDataTest.TARGET1_ID);
|
||||||
|
assertThat(updatedAttributes).hasSize(previousSize - 2);
|
||||||
assertThat(updatedAttributes).doesNotContainKeys("k1", "k3");
|
assertThat(updatedAttributes).doesNotContainKeys("k1", "k3");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void putConfigDataWithUpdateModeMerge(final String controllerId, final String configDataPath)
|
private void putConfigDataWithUpdateModeMerge()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
// get the current attributes
|
// get the current attributes
|
||||||
final Map<String, String> attributes = new HashMap<>(targetManagement.getControllerAttributes(controllerId));
|
final Map<String, String> attributes = new HashMap<>(
|
||||||
|
targetManagement.getControllerAttributes(DdiConfigDataTest.TARGET1_ID));
|
||||||
|
|
||||||
// update the attributes using update mode MERGE
|
// update the attributes using update mode MERGE
|
||||||
final Map<String, String> mergeAttributes = new HashMap<>();
|
final Map<String, String> mergeAttributes = new HashMap<>();
|
||||||
mergeAttributes.put("k1", "v1_modified_again");
|
mergeAttributes.put("k1", "v1_modified_again");
|
||||||
mergeAttributes.put("k4", "v4");
|
mergeAttributes.put("k4", "v4");
|
||||||
mvc.perform(put(configDataPath, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
.content(JsonBuilder.configData(mergeAttributes, "merge").toString())
|
.content(JsonBuilder.configData(mergeAttributes, "merge").toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
// verify attribute merge
|
// verify attribute merge
|
||||||
final Map<String, String> updatedAttributes = targetManagement.getControllerAttributes(controllerId);
|
final Map<String, String> updatedAttributes = targetManagement
|
||||||
assertThat(updatedAttributes.size()).isEqualTo(4);
|
.getControllerAttributes(DdiConfigDataTest.TARGET1_ID);
|
||||||
|
assertThat(updatedAttributes).hasSize(4);
|
||||||
assertThat(updatedAttributes).containsAllEntriesOf(mergeAttributes);
|
assertThat(updatedAttributes).containsAllEntriesOf(mergeAttributes);
|
||||||
assertThat(updatedAttributes.get("k1")).isEqualTo("v1_modified_again");
|
assertThat(updatedAttributes).containsEntry("k1", "v1_modified_again");
|
||||||
attributes.keySet().forEach(assertThat(updatedAttributes)::containsKey);
|
attributes.keySet().forEach(assertThat(updatedAttributes)::containsKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void putConfigDataWithUpdateModeReplace(final String controllerId, final String configDataPath)
|
private void putConfigDataWithUpdateModeReplace()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
// get the current attributes
|
// get the current attributes
|
||||||
final Map<String, String> attributes = new HashMap<>(targetManagement.getControllerAttributes(controllerId));
|
final Map<String, String> attributes = new HashMap<>(
|
||||||
|
targetManagement.getControllerAttributes(DdiConfigDataTest.TARGET1_ID));
|
||||||
|
|
||||||
// update the attributes using update mode REPLACE
|
// update the attributes using update mode REPLACE
|
||||||
final Map<String, String> replacementAttributes = new HashMap<>();
|
final Map<String, String> replacementAttributes = new HashMap<>();
|
||||||
replacementAttributes.put("k1", "v1_modified");
|
replacementAttributes.put("k1", "v1_modified");
|
||||||
replacementAttributes.put("k2", "v2");
|
replacementAttributes.put("k2", "v2");
|
||||||
replacementAttributes.put("k3", "v3");
|
replacementAttributes.put("k3", "v3");
|
||||||
mvc.perform(put(configDataPath, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
.content(JsonBuilder.configData(replacementAttributes, "replace").toString())
|
.content(JsonBuilder.configData(replacementAttributes, "replace").toString())
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
// verify attribute replacement
|
// verify attribute replacement
|
||||||
final Map<String, String> updatedAttributes = targetManagement.getControllerAttributes(controllerId);
|
final Map<String, String> updatedAttributes = targetManagement
|
||||||
assertThat(updatedAttributes.size()).isEqualTo(replacementAttributes.size());
|
.getControllerAttributes(DdiConfigDataTest.TARGET1_ID);
|
||||||
|
assertThat(updatedAttributes).hasSize(replacementAttributes.size());
|
||||||
assertThat(updatedAttributes).containsAllEntriesOf(replacementAttributes);
|
assertThat(updatedAttributes).containsAllEntriesOf(replacementAttributes);
|
||||||
assertThat(updatedAttributes.get("k1")).isEqualTo("v1_modified");
|
assertThat(updatedAttributes).containsEntry("k1", "v1_modified");
|
||||||
attributes.entrySet().forEach(assertThat(updatedAttributes)::doesNotContain);
|
attributes.entrySet().forEach(assertThat(updatedAttributes)::doesNotContain);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void putConfigDataWithoutUpdateMode(final String controllerId, final String configDataPath)
|
private void putConfigDataWithoutUpdateMode()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
// create some attriutes
|
// create some attriutes
|
||||||
final Map<String, String> attributes = new HashMap<>();
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
attributes.put("k0", "v0");
|
attributes.put("k0", "v0");
|
||||||
attributes.put("k1", "v1");
|
attributes.put("k1", "v1");
|
||||||
|
|
||||||
// set the initial attributes
|
// set the initial attributes
|
||||||
mvc.perform(put(configDataPath, tenantAware.getCurrentTenant())
|
mvc.perform(put(DdiConfigDataTest.TARGET1_CONFIGDATA_PATH, tenantAware.getCurrentTenant())
|
||||||
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.configData(attributes).toString()).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||||
|
|
||||||
// verify the initial parameters
|
// verify the initial parameters
|
||||||
final Map<String, String> updatedAttributes = targetManagement.getControllerAttributes(controllerId);
|
final Map<String, String> updatedAttributes = targetManagement
|
||||||
assertThat(updatedAttributes.size()).isEqualTo(attributes.size());
|
.getControllerAttributes(DdiConfigDataTest.TARGET1_ID);
|
||||||
assertThat(updatedAttributes).containsAllEntriesOf(attributes);
|
assertThat(updatedAttributes).containsExactlyEntriesOf(attributes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ import io.qameta.allure.Story;
|
|||||||
*/
|
*/
|
||||||
@Feature("Component Tests - Direct Device Integration API")
|
@Feature("Component Tests - Direct Device Integration API")
|
||||||
@Story("Root Poll Resource")
|
@Story("Root Poll Resource")
|
||||||
public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||||
|
|
||||||
private static final String TARGET_COMPLETED_INSTALLATION_MSG = "Target completed installation.";
|
private static final String TARGET_COMPLETED_INSTALLATION_MSG = "Target completed installation.";
|
||||||
private static final String TARGET_PROCEEDING_INSTALLATION_MSG = "Target proceeding installation.";
|
private static final String TARGET_PROCEEDING_INSTALLATION_MSG = "Target proceeding installation.";
|
||||||
@@ -87,7 +87,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensure that the root poll resource is available as CBOR")
|
@Description("Ensure that the root poll resource is available as CBOR")
|
||||||
public void rootPollResourceCbor() throws Exception {
|
void rootPollResourceCbor() throws Exception {
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711)
|
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711)
|
||||||
.accept(DdiRestConstants.MEDIA_TYPE_CBOR)).andDo(MockMvcResultPrinter.print())
|
.accept(DdiRestConstants.MEDIA_TYPE_CBOR)).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(content().contentType(DdiRestConstants.MEDIA_TYPE_CBOR)).andExpect(status().isOk());
|
.andExpect(content().contentType(DdiRestConstants.MEDIA_TYPE_CBOR)).andExpect(status().isOk());
|
||||||
@@ -95,7 +95,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the API returns JSON when no Accept header is specified by the client.")
|
@Description("Ensures that the API returns JSON when no Accept header is specified by the client.")
|
||||||
public void apiReturnsJSONByDefault() throws Exception {
|
void apiReturnsJSONByDefault() throws Exception {
|
||||||
final MvcResult result = mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711))
|
final MvcResult result = mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON)).andReturn();
|
.andExpect(content().contentType(MediaTypes.HAL_JSON)).andReturn();
|
||||||
@@ -113,7 +113,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Expect(type = TargetPollEvent.class, count = 1),
|
@Expect(type = TargetPollEvent.class, count = 1),
|
||||||
@Expect(type = DistributionSetTypeCreatedEvent.class, count = 3),
|
@Expect(type = DistributionSetTypeCreatedEvent.class, count = 3),
|
||||||
@Expect(type = SoftwareModuleTypeCreatedEvent.class, count = 2) })
|
@Expect(type = SoftwareModuleTypeCreatedEvent.class, count = 2) })
|
||||||
public void targetCannotBeRegisteredIfTenantDoesNotExistsButWhenExists() throws Exception {
|
void targetCannotBeRegisteredIfTenantDoesNotExistsButWhenExists() throws Exception {
|
||||||
|
|
||||||
mvc.perform(get("/default-tenant/", tenantAware.getCurrentTenant())).andDo(MockMvcResultPrinter.print())
|
mvc.perform(get("/default-tenant/", tenantAware.getCurrentTenant())).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
@@ -137,14 +137,13 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
SpPermission.CREATE_TARGET }, allSpPermissions = false)
|
SpPermission.CREATE_TARGET }, allSpPermissions = false)
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void targetPollDoesNotModifyAuditData() throws Exception {
|
void targetPollDoesNotModifyAuditData() throws Exception {
|
||||||
// create target first with "knownPrincipal" user and audit data
|
// create target first with "knownPrincipal" user and audit data
|
||||||
final String knownTargetControllerId = "target1";
|
final String knownTargetControllerId = "target1";
|
||||||
final String knownCreatedBy = "knownPrincipal";
|
final String knownCreatedBy = "knownPrincipal";
|
||||||
testdataFactory.createTarget(knownTargetControllerId);
|
testdataFactory.createTarget(knownTargetControllerId);
|
||||||
final Target findTargetByControllerID = targetManagement.getByControllerID(knownTargetControllerId).get();
|
final Target findTargetByControllerID = targetManagement.getByControllerID(knownTargetControllerId).get();
|
||||||
assertThat(findTargetByControllerID.getCreatedBy()).isEqualTo(knownCreatedBy);
|
assertThat(findTargetByControllerID.getCreatedBy()).isEqualTo(knownCreatedBy);
|
||||||
assertThat(findTargetByControllerID.getCreatedAt()).isNotNull();
|
|
||||||
|
|
||||||
// make a poll, audit information should not be changed, run as
|
// make a poll, audit information should not be changed, run as
|
||||||
// controller principal!
|
// controller principal!
|
||||||
@@ -165,7 +164,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Ensures that server returns a not found response in case of empty controller ID.")
|
@Description("Ensures that server returns a not found response in case of empty controller ID.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
||||||
public void rootRsWithoutId() throws Exception {
|
void rootRsWithoutId() throws Exception {
|
||||||
mvc.perform(get("/controller/v1/")).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
mvc.perform(get("/controller/v1/")).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +172,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Description("Ensures that the system creates a new target in plug and play manner, i.e. target is authenticated but does not exist yet.")
|
@Description("Ensures that the system creates a new target in plug and play manner, i.e. target is authenticated but does not exist yet.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void rootRsPlugAndPlay() throws Exception {
|
void rootRsPlugAndPlay() throws Exception {
|
||||||
|
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
String controllerId = "4711";
|
String controllerId = "4711";
|
||||||
@@ -204,7 +203,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 1),
|
@Expect(type = TargetPollEvent.class, count = 1),
|
||||||
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
|
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
|
||||||
public void pollWithModifiedGlobalPollingTime() throws Exception {
|
void pollWithModifiedGlobalPollingTime() throws Exception {
|
||||||
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION), () -> {
|
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION), () -> {
|
||||||
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL,
|
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL,
|
||||||
"00:02:00");
|
"00:02:00");
|
||||||
@@ -230,7 +229,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Expect(type = ActionCreatedEvent.class, count = 2),
|
@Expect(type = ActionCreatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
|
||||||
public void rootRsNotModified() throws Exception {
|
void rootRsNotModified() throws Exception {
|
||||||
String controllerId = "4711";
|
String controllerId = "4711";
|
||||||
final String etag = mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId))
|
final String etag = mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
@@ -308,7 +307,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
+ "UNKNOWN to REGISTERED when the target polls for the first time.")
|
+ "UNKNOWN to REGISTERED when the target polls for the first time.")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void rootRsPrecommissioned() throws Exception {
|
void rootRsPrecommissioned() throws Exception {
|
||||||
String controllerId = "4711";
|
String controllerId = "4711";
|
||||||
testdataFactory.createTarget(controllerId);
|
testdataFactory.createTarget(controllerId);
|
||||||
|
|
||||||
@@ -334,7 +333,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Description("Ensures that the source IP address of the polling target is correctly stored in repository")
|
@Description("Ensures that the source IP address of the polling target is correctly stored in repository")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void rootRsPlugAndPlayIpAddress() throws Exception {
|
void rootRsPlugAndPlayIpAddress() throws Exception {
|
||||||
// test
|
// test
|
||||||
final String knownControllerId1 = "0815";
|
final String knownControllerId1 = "0815";
|
||||||
final long create = System.currentTimeMillis();
|
final long create = System.currentTimeMillis();
|
||||||
@@ -361,7 +360,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Description("Ensures that the source IP address of the polling target is not stored in repository if disabled")
|
@Description("Ensures that the source IP address of the polling target is not stored in repository if disabled")
|
||||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||||
public void rootRsIpAddressNotStoredIfDisabled() throws Exception {
|
void rootRsIpAddressNotStoredIfDisabled() throws Exception {
|
||||||
securityProperties.getClients().setTrackRemoteIp(false);
|
securityProperties.getClients().setTrackRemoteIp(false);
|
||||||
|
|
||||||
// test
|
// test
|
||||||
@@ -384,7 +383,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void tryToFinishAnUpdateProcessAfterItHasBeenFinished() throws Exception {
|
void tryToFinishAnUpdateProcessAfterItHasBeenFinished() throws Exception {
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
Target savedTarget = testdataFactory.createTarget("911");
|
Target savedTarget = testdataFactory.createTarget("911");
|
||||||
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
||||||
@@ -409,7 +408,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Expect(type = TargetUpdatedEvent.class, count = 6), @Expect(type = TargetPollEvent.class, count = 4),
|
@Expect(type = TargetUpdatedEvent.class, count = 6), @Expect(type = TargetPollEvent.class, count = 4),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1) })
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1) })
|
||||||
public void attributeUpdateRequestSendingAfterSuccessfulDeployment() throws Exception {
|
void attributeUpdateRequestSendingAfterSuccessfulDeployment() throws Exception {
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("1");
|
final DistributionSet ds = testdataFactory.createDistributionSet("1");
|
||||||
final Target savedTarget = testdataFactory.createTarget("922");
|
final Target savedTarget = testdataFactory.createTarget("922");
|
||||||
final Map<String, String> attributes = Collections.singletonMap("AttributeKey", "AttributeValue");
|
final Map<String, String> attributes = Collections.singletonMap("AttributeKey", "AttributeValue");
|
||||||
@@ -487,7 +486,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void testActionHistoryCount() throws Exception {
|
void testActionHistoryCount() throws Exception {
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
Target savedTarget = testdataFactory.createTarget("911");
|
Target savedTarget = testdataFactory.createTarget("911");
|
||||||
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
||||||
@@ -524,7 +523,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void testActionHistoryZeroInput() throws Exception {
|
void testActionHistoryZeroInput() throws Exception {
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
Target savedTarget = testdataFactory.createTarget("911");
|
Target savedTarget = testdataFactory.createTarget("911");
|
||||||
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
||||||
@@ -561,7 +560,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||||
public void testActionHistoryNegativeInput() throws Exception {
|
void testActionHistoryNegativeInput() throws Exception {
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
Target savedTarget = testdataFactory.createTarget("911");
|
Target savedTarget = testdataFactory.createTarget("911");
|
||||||
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
||||||
@@ -591,7 +590,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test the polling time based on different maintenance window start and end time.")
|
@Description("Test the polling time based on different maintenance window start and end time.")
|
||||||
public void sleepTimeResponseForDifferentMaintenanceWindowParameters() throws Exception {
|
void sleepTimeResponseForDifferentMaintenanceWindowParameters() throws Exception {
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION), () -> {
|
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION), () -> {
|
||||||
@@ -638,7 +637,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test download and update values before maintenance window start time.")
|
@Description("Test download and update values before maintenance window start time.")
|
||||||
public void downloadAndUpdateStatusBeforeMaintenanceWindowStartTime() throws Exception {
|
void downloadAndUpdateStatusBeforeMaintenanceWindowStartTime() throws Exception {
|
||||||
Target savedTarget = testdataFactory.createTarget("1911");
|
Target savedTarget = testdataFactory.createTarget("1911");
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
savedTarget = getFirstAssignedTarget(assignDistributionSetWithMaintenanceWindow(ds.getId(),
|
savedTarget = getFirstAssignedTarget(assignDistributionSetWithMaintenanceWindow(ds.getId(),
|
||||||
@@ -658,7 +657,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test download and update values after maintenance window start time.")
|
@Description("Test download and update values after maintenance window start time.")
|
||||||
public void downloadAndUpdateStatusDuringMaintenanceWindow() throws Exception {
|
void downloadAndUpdateStatusDuringMaintenanceWindow() throws Exception {
|
||||||
Target savedTarget = testdataFactory.createTarget("1911");
|
Target savedTarget = testdataFactory.createTarget("1911");
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
savedTarget = getFirstAssignedTarget(assignDistributionSetWithMaintenanceWindow(ds.getId(),
|
savedTarget = getFirstAssignedTarget(assignDistributionSetWithMaintenanceWindow(ds.getId(),
|
||||||
@@ -678,7 +677,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Assign multiple DS in multi-assignment mode. The earliest active Action is exposed to the controller.")
|
@Description("Assign multiple DS in multi-assignment mode. The earliest active Action is exposed to the controller.")
|
||||||
public void earliestActionIsExposedToControllerInMultiAssignMode() throws Exception {
|
void earliestActionIsExposedToControllerInMultiAssignMode() throws Exception {
|
||||||
enableMultiAssignments();
|
enableMultiAssignments();
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
final DistributionSet ds1 = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
final DistributionSet ds1 = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
||||||
@@ -695,7 +694,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("The system should not create a new target because of a too long controller id.")
|
@Description("The system should not create a new target because of a too long controller id.")
|
||||||
public void rootRsWithInvalidControllerId() throws Exception {
|
void rootRsWithInvalidControllerId() throws Exception {
|
||||||
final String invalidControllerId = RandomStringUtils.randomAlphabetic(Target.CONTROLLER_ID_MAX_SIZE + 1);
|
final String invalidControllerId = RandomStringUtils.randomAlphabetic(Target.CONTROLLER_ID_MAX_SIZE + 1);
|
||||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), invalidControllerId))
|
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), invalidControllerId))
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import io.qameta.allure.Story;
|
|||||||
@ActiveProfiles({ "test" })
|
@ActiveProfiles({ "test" })
|
||||||
@Feature("Component Tests - REST Security")
|
@Feature("Component Tests - REST Security")
|
||||||
@Story("Denial of Service protection filter")
|
@Story("Denial of Service protection filter")
|
||||||
public class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DefaultMockMvcBuilder createMvcWebAppContext(final WebApplicationContext context) {
|
protected DefaultMockMvcBuilder createMvcWebAppContext(final WebApplicationContext context) {
|
||||||
@@ -52,14 +52,14 @@ public class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that clients that are on the blacklist are forbidded ")
|
@Description("Ensures that clients that are on the blacklist are forbidded ")
|
||||||
public void blackListedClientIsForbidden() throws Exception {
|
void blackListedClientIsForbidden() throws Exception {
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
||||||
.header(HttpHeaders.X_FORWARDED_FOR, "192.168.0.4 , 10.0.0.1 ")).andExpect(status().isForbidden());
|
.header(HttpHeaders.X_FORWARDED_FOR, "192.168.0.4 , 10.0.0.1 ")).andExpect(status().isForbidden());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a READ DoS attempt is blocked ")
|
@Description("Ensures that a READ DoS attempt is blocked ")
|
||||||
public void getFloddingAttackThatisPrevented() throws Exception {
|
void getFloddingAttackThatisPrevented() throws Exception {
|
||||||
|
|
||||||
MvcResult result = null;
|
MvcResult result = null;
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ public class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that an assumed READ DoS attempt is not blocked as the client (with IPv4 address) is on a whitelist")
|
@Description("Ensures that an assumed READ DoS attempt is not blocked as the client (with IPv4 address) is on a whitelist")
|
||||||
public void unacceptableGetLoadButOnWhitelistIPv4() throws Exception {
|
void unacceptableGetLoadButOnWhitelistIPv4() throws Exception {
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
||||||
.header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1")).andExpect(status().isOk());
|
.header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1")).andExpect(status().isOk());
|
||||||
@@ -88,7 +88,7 @@ public class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that an assumed READ DoS attempt is not blocked as the client (with IPv6 address) is on a whitelist")
|
@Description("Ensures that an assumed READ DoS attempt is not blocked as the client (with IPv6 address) is on a whitelist")
|
||||||
public void unacceptableGetLoadButOnWhitelistIPv6() throws Exception {
|
void unacceptableGetLoadButOnWhitelistIPv6() throws Exception {
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
||||||
.header(HttpHeaders.X_FORWARDED_FOR, "0:0:0:0:0:0:0:1")).andExpect(status().isOk());
|
.header(HttpHeaders.X_FORWARDED_FOR, "0:0:0:0:0:0:0:1")).andExpect(status().isOk());
|
||||||
@@ -97,7 +97,8 @@ public class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a relatively high number of READ requests is allowed if it is below the DoS detection threshold")
|
@Description("Ensures that a relatively high number of READ requests is allowed if it is below the DoS detection threshold")
|
||||||
public void acceptableGetLoad() throws Exception {
|
@SuppressWarnings("squid:S2925") // No idea how to get rid of the Thread.sleep here
|
||||||
|
void acceptableGetLoad() throws Exception {
|
||||||
|
|
||||||
for (int x = 0; x < 3; x++) {
|
for (int x = 0; x < 3; x++) {
|
||||||
// sleep for one second
|
// sleep for one second
|
||||||
@@ -111,7 +112,7 @@ public class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a WRITE DoS attempt is blocked ")
|
@Description("Ensures that a WRITE DoS attempt is blocked ")
|
||||||
public void putPostFloddingAttackThatisPrevented() throws Exception {
|
void putPostFloddingAttackThatisPrevented() throws Exception {
|
||||||
final Long actionId = prepareDeploymentBase();
|
final Long actionId = prepareDeploymentBase();
|
||||||
final String feedback = JsonBuilder.deploymentActionFeedback(actionId.toString(), "proceeding");
|
final String feedback = JsonBuilder.deploymentActionFeedback(actionId.toString(), "proceeding");
|
||||||
|
|
||||||
@@ -135,7 +136,8 @@ public class DosFilterTest extends AbstractDDiApiIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a relatively high number of WRITE requests is allowed if it is below the DoS detection threshold")
|
@Description("Ensures that a relatively high number of WRITE requests is allowed if it is below the DoS detection threshold")
|
||||||
public void acceptablePutPostLoad() throws Exception {
|
@SuppressWarnings("squid:S2925") // No idea how to get rid of the Thread.sleep here
|
||||||
|
void acceptablePutPostLoad() throws Exception {
|
||||||
final Long actionId = prepareDeploymentBase();
|
final Long actionId = prepareDeploymentBase();
|
||||||
final String feedback = JsonBuilder.deploymentActionFeedback(actionId.toString(), "proceeding");
|
final String feedback = JsonBuilder.deploymentActionFeedback(actionId.toString(), "proceeding");
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.validation.ValidationException;
|
import javax.validation.ValidationException;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||||
@@ -29,6 +28,7 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
|||||||
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
|
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
|
||||||
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
|
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||||
@@ -108,17 +108,22 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
|
|||||||
|
|
||||||
// first check the given RSQL query if it's well formed, otherwise and
|
// first check the given RSQL query if it's well formed, otherwise and
|
||||||
// exception is thrown
|
// exception is thrown
|
||||||
targetFilterQueryManagement.verifyTargetFilterQuerySyntax(rolloutRequestBody.getTargetFilterQuery());
|
final String targetFilterQuery = rolloutRequestBody.getTargetFilterQuery();
|
||||||
|
if (targetFilterQuery == null) {
|
||||||
final DistributionSet distributionSet = distributionSetManagement
|
// Use RSQLParameterSyntaxException due to backwards compatibility
|
||||||
.getValidAndComplete(rolloutRequestBody.getDistributionSetId());
|
throw new RSQLParameterSyntaxException("Cannot create a Rollout with an empty target query filter!");
|
||||||
|
}
|
||||||
|
targetFilterQueryManagement.verifyTargetFilterQuerySyntax(targetFilterQuery);
|
||||||
|
final DistributionSet distributionSet = distributionSetManagement.getValidAndComplete(
|
||||||
|
rolloutRequestBody.getDistributionSetId());
|
||||||
final RolloutGroupConditions rolloutGroupConditions = MgmtRolloutMapper.fromRequest(rolloutRequestBody, true);
|
final RolloutGroupConditions rolloutGroupConditions = MgmtRolloutMapper.fromRequest(rolloutRequestBody, true);
|
||||||
|
|
||||||
final RolloutCreate create = MgmtRolloutMapper.fromRequest(entityFactory, rolloutRequestBody, distributionSet);
|
final RolloutCreate create = MgmtRolloutMapper.fromRequest(entityFactory, rolloutRequestBody, distributionSet);
|
||||||
|
|
||||||
Rollout rollout;
|
Rollout rollout;
|
||||||
if (rolloutRequestBody.getGroups() != null) {
|
if (rolloutRequestBody.getGroups() != null) {
|
||||||
final List<RolloutGroupCreate> rolloutGroups = rolloutRequestBody.getGroups().stream()
|
final List<RolloutGroupCreate> rolloutGroups = rolloutRequestBody.getGroups()
|
||||||
|
.stream()
|
||||||
.map(mgmtRolloutGroup -> MgmtRolloutMapper.fromRequest(entityFactory, mgmtRolloutGroup))
|
.map(mgmtRolloutGroup -> MgmtRolloutMapper.fromRequest(entityFactory, mgmtRolloutGroup))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
rollout = rolloutManagement.create(create, rolloutGroups, rolloutGroupConditions);
|
rollout = rolloutManagement.create(create, rolloutGroups, rolloutGroupConditions);
|
||||||
|
|||||||
@@ -25,8 +25,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.awaitility.Awaitility;
|
||||||
|
import org.awaitility.Duration;
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||||
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
||||||
@@ -40,10 +43,10 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
|||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
|
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
|
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
|
||||||
|
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||||
import org.eclipse.hawkbit.rest.util.JsonBuilder;
|
import org.eclipse.hawkbit.rest.util.JsonBuilder;
|
||||||
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
||||||
import org.eclipse.hawkbit.rest.util.SuccessCondition;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
@@ -60,21 +63,21 @@ import io.qameta.allure.Story;
|
|||||||
*/
|
*/
|
||||||
@Feature("Component Tests - Management API")
|
@Feature("Component Tests - Management API")
|
||||||
@Story("Rollout Resource")
|
@Story("Rollout Resource")
|
||||||
public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||||
|
|
||||||
private static final String HREF_ROLLOUT_PREFIX = "http://localhost/rest/v1/rollouts/";
|
private static final String HREF_ROLLOUT_PREFIX = "http://localhost/rest/v1/rollouts/";
|
||||||
|
|
||||||
@Autowired
|
@Autowired private RolloutManagement rolloutManagement;
|
||||||
private RolloutManagement rolloutManagement;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired private RolloutGroupManagement rolloutGroupManagement;
|
||||||
private RolloutGroupManagement rolloutGroupManagement;
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that creating rollout with wrong body returns bad request")
|
@Description("Testing that creating rollout with wrong body returns bad request")
|
||||||
public void createRolloutWithInvalidBodyReturnsBadRequest() throws Exception {
|
void createRolloutWithInvalidBodyReturnsBadRequest() throws Exception {
|
||||||
mvc.perform(post("/rest/v1/rollouts").content("invalid body").contentType(MediaType.APPLICATION_JSON)
|
mvc.perform(post("/rest/v1/rollouts").content("invalid body")
|
||||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isBadRequest())
|
.andExpect(status().isBadRequest())
|
||||||
.andExpect(jsonPath("errorCode", equalTo("hawkbit.server.error.rest.body.notReadable")));
|
.andExpect(jsonPath("errorCode", equalTo("hawkbit.server.error.rest.body.notReadable")));
|
||||||
}
|
}
|
||||||
@@ -82,36 +85,45 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
@Test
|
@Test
|
||||||
@Description("Testing that creating rollout with insufficient permission returns forbidden")
|
@Description("Testing that creating rollout with insufficient permission returns forbidden")
|
||||||
@WithUser(allSpPermissions = true, removeFromAllPermission = "CREATE_ROLLOUT")
|
@WithUser(allSpPermissions = true, removeFromAllPermission = "CREATE_ROLLOUT")
|
||||||
public void createRolloutWithInsufficientPermissionReturnsForbidden() throws Exception {
|
void createRolloutWithInsufficientPermissionReturnsForbidden() throws Exception {
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||||
mvc.perform(post("/rest/v1/rollouts")
|
mvc.perform(post("/rest/v1/rollouts").content(
|
||||||
.content(JsonBuilder.rollout("name", "desc", 10, dsA.getId(), "name==test", null))
|
JsonBuilder.rollout("name", "desc", 10, dsA.getId(), "name==test", null))
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().is(403)).andReturn();
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().is(403))
|
||||||
|
.andReturn();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that creating rollout with not exisiting distribution set returns not found")
|
@Description("Testing that creating rollout with not existing distribution set returns not found")
|
||||||
public void createRolloutWithNotExistingDistributionSetReturnsNotFound() throws Exception {
|
void createRolloutWithNotExistingDistributionSetReturnsNotFound() throws Exception {
|
||||||
mvc.perform(post("/rest/v1/rollouts").content(JsonBuilder.rollout("name", "desc", 10, 1234, "name==test", null))
|
mvc.perform(post("/rest/v1/rollouts").content(JsonBuilder.rollout("name", "desc", 10, 1234, "name==test", null))
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()).andReturn();
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isNotFound())
|
||||||
|
.andReturn();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that creating rollout with not valid formed target filter query returns bad request")
|
@Description("Testing that creating rollout with not valid formed target filter query returns bad request")
|
||||||
public void createRolloutWithNotWellFormedFilterReturnsBadRequest() throws Exception {
|
void createRolloutWithNotWellFormedFilterReturnsBadRequest() throws Exception {
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||||
mvc.perform(post("/rest/v1/rollouts")
|
mvc.perform(post("/rest/v1/rollouts").content(
|
||||||
.content(JsonBuilder.rollout("name", "desc", 10, dsA.getId(), "name=test", null))
|
JsonBuilder.rollout("name", "desc", 10, dsA.getId(), "name=test", null))
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest())
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isBadRequest())
|
||||||
.andExpect(jsonPath("errorCode", equalTo("hawkbit.server.error.rest.param.rsqlParamSyntax")))
|
.andExpect(jsonPath("errorCode", equalTo("hawkbit.server.error.rest.param.rsqlParamSyntax")))
|
||||||
.andReturn();
|
.andReturn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
@Description("Ensures that the repository refuses to create rollout without a defined target filter set.")
|
@Description("Ensures that the repository refuses to create rollout without a defined target filter set.")
|
||||||
public void missingTargetFilterQueryInRollout() throws Exception {
|
void missingTargetFilterQueryInRollout() throws Exception {
|
||||||
|
|
||||||
final String targetFilterQuery = null;
|
final String targetFilterQuery = null;
|
||||||
|
|
||||||
@@ -127,7 +139,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that rollout can be created")
|
@Description("Testing that rollout can be created")
|
||||||
public void createRollout() throws Exception {
|
void createRollout() throws Exception {
|
||||||
testdataFactory.createTargets(20, "target", "rollout");
|
testdataFactory.createTargets(20, "target", "rollout");
|
||||||
|
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||||
@@ -136,17 +148,18 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that rollout cannot be created if too many rollout groups are specified.")
|
@Description("Verifies that rollout cannot be created if too many rollout groups are specified.")
|
||||||
public void createRolloutWithTooManyRolloutGroups() throws Exception {
|
void createRolloutWithTooManyRolloutGroups() throws Exception {
|
||||||
|
|
||||||
final int maxGroups = quotaManagement.getMaxRolloutGroupsPerRollout();
|
final int maxGroups = quotaManagement.getMaxRolloutGroupsPerRollout();
|
||||||
testdataFactory.createTargets(20, "target", "rollout");
|
testdataFactory.createTargets(20, "target", "rollout");
|
||||||
|
|
||||||
mvc.perform(post("/rest/v1/rollouts")
|
mvc.perform(post("/rest/v1/rollouts").content(JsonBuilder.rollout("rollout1", "rollout1Desc", maxGroups + 1,
|
||||||
.content(JsonBuilder.rollout("rollout1", "rollout1Desc", maxGroups + 1,
|
|
||||||
testdataFactory.createDistributionSet("ds").getId(), "id==target*",
|
testdataFactory.createDistributionSet("ds").getId(), "id==target*",
|
||||||
new RolloutGroupConditionBuilder().withDefaults().build()))
|
new RolloutGroupConditionBuilder().withDefaults().build()))
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden())
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isForbidden())
|
||||||
.andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName())))
|
.andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName())))
|
||||||
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
|
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
|
||||||
|
|
||||||
@@ -154,17 +167,18 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that rollout cannot be created if the 'max targets per rollout group' quota would be violated for one of the groups.")
|
@Description("Verifies that rollout cannot be created if the 'max targets per rollout group' quota would be violated for one of the groups.")
|
||||||
public void createRolloutFailsIfRolloutGroupQuotaIsViolated() throws Exception {
|
void createRolloutFailsIfRolloutGroupQuotaIsViolated() throws Exception {
|
||||||
|
|
||||||
final int maxTargets = quotaManagement.getMaxTargetsPerRolloutGroup();
|
final int maxTargets = quotaManagement.getMaxTargetsPerRolloutGroup();
|
||||||
testdataFactory.createTargets(maxTargets + 1, "target", "rollout");
|
testdataFactory.createTargets(maxTargets + 1, "target", "rollout");
|
||||||
|
|
||||||
mvc.perform(post("/rest/v1/rollouts")
|
mvc.perform(post("/rest/v1/rollouts").content(
|
||||||
.content(JsonBuilder.rollout("rollout1", "rollout1Desc", 1,
|
JsonBuilder.rollout("rollout1", "rollout1Desc", 1, testdataFactory.createDistributionSet("ds").getId(),
|
||||||
testdataFactory.createDistributionSet("ds").getId(), "id==target*",
|
"id==target*", new RolloutGroupConditionBuilder().withDefaults().build()))
|
||||||
new RolloutGroupConditionBuilder().withDefaults().build()))
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isForbidden())
|
||||||
.andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName())))
|
.andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName())))
|
||||||
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
|
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
|
||||||
|
|
||||||
@@ -172,7 +186,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that rollout can be created with groups")
|
@Description("Testing that rollout can be created with groups")
|
||||||
public void createRolloutWithGroupDefinitions() throws Exception {
|
void createRolloutWithGroupDefinitions() throws Exception {
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("ro");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("ro");
|
||||||
|
|
||||||
final int amountTargets = 10;
|
final int amountTargets = 10;
|
||||||
@@ -199,16 +213,22 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that no rollout with groups that have illegal percentages can be created")
|
@Description("Testing that no rollout with groups that have illegal percentages can be created")
|
||||||
public void createRolloutWithTooLowPercentage() throws Exception {
|
void createRolloutWithTooLowPercentage() throws Exception {
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("ro2");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("ro2");
|
||||||
|
|
||||||
final int amountTargets = 10;
|
final int amountTargets = 10;
|
||||||
testdataFactory.createTargets(amountTargets, "ro-target", "rollout");
|
testdataFactory.createTargets(amountTargets, "ro-target", "rollout");
|
||||||
|
|
||||||
final List<RolloutGroup> rolloutGroups = Arrays.asList(
|
final List<RolloutGroup> rolloutGroups = Arrays.asList(entityFactory.rolloutGroup()
|
||||||
entityFactory.rolloutGroup().create().name("Group1").description("Group1desc").targetPercentage(0F)
|
.create()
|
||||||
.build(),
|
.name("Group1")
|
||||||
entityFactory.rolloutGroup().create().name("Group2").description("Group2desc").targetPercentage(100F)
|
.description("Group1desc")
|
||||||
|
.targetPercentage(0F)
|
||||||
|
.build(), entityFactory.rolloutGroup()
|
||||||
|
.create()
|
||||||
|
.name("Group2")
|
||||||
|
.description("Group2desc")
|
||||||
|
.targetPercentage(100F)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
final RolloutGroupConditions rolloutGroupConditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
final RolloutGroupConditions rolloutGroupConditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
||||||
@@ -224,16 +244,22 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that no rollout with groups that have illegal percentages can be created")
|
@Description("Testing that no rollout with groups that have illegal percentages can be created")
|
||||||
public void createRolloutWithTooHighPercentage() throws Exception {
|
void createRolloutWithTooHighPercentage() throws Exception {
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("ro2");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("ro2");
|
||||||
|
|
||||||
final int amountTargets = 10;
|
final int amountTargets = 10;
|
||||||
testdataFactory.createTargets(amountTargets, "ro-target", "rollout");
|
testdataFactory.createTargets(amountTargets, "ro-target", "rollout");
|
||||||
|
|
||||||
final List<RolloutGroup> rolloutGroups = Arrays.asList(
|
final List<RolloutGroup> rolloutGroups = Arrays.asList(entityFactory.rolloutGroup()
|
||||||
entityFactory.rolloutGroup().create().name("Group1").description("Group1desc").targetPercentage(1F)
|
.create()
|
||||||
.build(),
|
.name("Group1")
|
||||||
entityFactory.rolloutGroup().create().name("Group2").description("Group2desc").targetPercentage(101F)
|
.description("Group1desc")
|
||||||
|
.targetPercentage(1F)
|
||||||
|
.build(), entityFactory.rolloutGroup()
|
||||||
|
.create()
|
||||||
|
.name("Group2")
|
||||||
|
.description("Group2desc")
|
||||||
|
.targetPercentage(101F)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
final RolloutGroupConditions rolloutGroupConditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
final RolloutGroupConditions rolloutGroupConditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
||||||
@@ -249,24 +275,29 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing the empty list is returned if no rollout exists")
|
@Description("Testing the empty list is returned if no rollout exists")
|
||||||
public void noRolloutReturnsEmptyList() throws Exception {
|
void noRolloutReturnsEmptyList() throws Exception {
|
||||||
mvc.perform(get("/rest/v1/rollouts").accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
mvc.perform(get("/rest/v1/rollouts").accept(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(jsonPath("$.content", hasSize(0))).andExpect(jsonPath("$.total", equalTo(0)));
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
|
.andExpect(jsonPath("$.content", hasSize(0)))
|
||||||
|
.andExpect(jsonPath("$.total", equalTo(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Retrieves single rollout from management API including extra data that is delivered only for single rollout access.")
|
@Description("Retrieves single rollout from management API including extra data that is delivered only for single rollout access.")
|
||||||
public void retrieveSingleRollout() throws Exception {
|
void retrieveSingleRollout() throws Exception {
|
||||||
testdataFactory.createTargets(20, "rollout", "rollout");
|
testdataFactory.createTargets(20, "rollout", "rollout");
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
// create rollout including the created targets with prefix 'rollout'
|
// create rollout including the created targets with prefix 'rollout'
|
||||||
final Rollout rollout = rolloutManagement.create(
|
final Rollout rollout = rolloutManagement.create(entityFactory.rollout()
|
||||||
entityFactory.rollout().create().name("rollout1").set(dsA.getId())
|
.create()
|
||||||
.targetFilterQuery("controllerId==rollout*"),
|
.name("rollout1")
|
||||||
4, new RolloutGroupConditionBuilder().withDefaults()
|
.set(dsA.getId())
|
||||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build());
|
.targetFilterQuery("controllerId==rollout*"), 4, new RolloutGroupConditionBuilder().withDefaults()
|
||||||
|
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100")
|
||||||
|
.build());
|
||||||
|
|
||||||
retrieveAndVerifyRolloutInCreating(dsA, rollout);
|
retrieveAndVerifyRolloutInCreating(dsA, rollout);
|
||||||
retrieveAndVerifyRolloutInReady(rollout);
|
retrieveAndVerifyRolloutInReady(rollout);
|
||||||
@@ -362,7 +393,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that rollout paged list contains rollouts")
|
@Description("Testing that rollout paged list contains rollouts")
|
||||||
public void rolloutPagedListContainsAllRollouts() throws Exception {
|
void rolloutPagedListContainsAllRollouts() throws Exception {
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
testdataFactory.createTargets(20, "target", "rollout");
|
testdataFactory.createTargets(20, "target", "rollout");
|
||||||
@@ -403,7 +434,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that rollout paged list is limited by the query param limit")
|
@Description("Testing that rollout paged list is limited by the query param limit")
|
||||||
public void rolloutPagedListIsLimitedToQueryParam() throws Exception {
|
void rolloutPagedListIsLimitedToQueryParam() throws Exception {
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
testdataFactory.createTargets(20, "target", "rollout");
|
testdataFactory.createTargets(20, "target", "rollout");
|
||||||
@@ -423,7 +454,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that rollout paged list is limited by the query param limit")
|
@Description("Testing that rollout paged list is limited by the query param limit")
|
||||||
public void retrieveRolloutGroupsForSpecificRollout() throws Exception {
|
void retrieveRolloutGroupsForSpecificRollout() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 20;
|
final int amountTargets = 20;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -446,7 +477,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that starting the rollout switches the state to starting and then to running")
|
@Description("Testing that starting the rollout switches the state to starting and then to running")
|
||||||
public void startingRolloutSwitchesIntoRunningState() throws Exception {
|
void startingRolloutSwitchesIntoRunningState() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 20;
|
final int amountTargets = 20;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -479,7 +510,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that pausing the rollout switches the state to paused")
|
@Description("Testing that pausing the rollout switches the state to paused")
|
||||||
public void pausingRolloutSwitchesIntoPausedState() throws Exception {
|
void pausingRolloutSwitchesIntoPausedState() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 20;
|
final int amountTargets = 20;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -509,7 +540,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that resuming the rollout switches the state to running")
|
@Description("Testing that resuming the rollout switches the state to running")
|
||||||
public void resumingRolloutSwitchesIntoRunningState() throws Exception {
|
void resumingRolloutSwitchesIntoRunningState() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 20;
|
final int amountTargets = 20;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -543,7 +574,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that an already started rollout cannot be started again and returns bad request")
|
@Description("Testing that an already started rollout cannot be started again and returns bad request")
|
||||||
public void startingAlreadyStartedRolloutReturnsBadRequest() throws Exception {
|
void startingAlreadyStartedRolloutReturnsBadRequest() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 20;
|
final int amountTargets = 20;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -567,7 +598,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that resuming a rollout which is not started leads to bad request")
|
@Description("Testing that resuming a rollout which is not started leads to bad request")
|
||||||
public void resumingNotStartedRolloutReturnsBadRequest() throws Exception {
|
void resumingNotStartedRolloutReturnsBadRequest() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 20;
|
final int amountTargets = 20;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -584,7 +615,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that starting rollout the first rollout group is in running state")
|
@Description("Testing that starting rollout the first rollout group is in running state")
|
||||||
public void startingRolloutFirstRolloutGroupIsInRunningState() throws Exception {
|
void startingRolloutFirstRolloutGroupIsInRunningState() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 10;
|
final int amountTargets = 10;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -612,17 +643,18 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that a single rollout group can be retrieved")
|
@Description("Testing that a single rollout group can be retrieved")
|
||||||
public void retrieveSingleRolloutGroup() throws Exception {
|
void retrieveSingleRolloutGroup() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 20;
|
final int amountTargets = 20;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
// create rollout including the created targets with prefix 'rollout'
|
// create rollout including the created targets with prefix 'rollout'
|
||||||
final Rollout rollout = rolloutManagement.create(
|
final Rollout rollout = rolloutManagement.create(entityFactory.rollout()
|
||||||
entityFactory.rollout().create().name("rollout1").set(dsA.getId())
|
.create()
|
||||||
.targetFilterQuery("controllerId==rollout*"),
|
.name("rollout1")
|
||||||
4, new RolloutGroupConditionBuilder().withDefaults()
|
.set(dsA.getId())
|
||||||
|
.targetFilterQuery("controllerId==rollout*"), 4, new RolloutGroupConditionBuilder().withDefaults()
|
||||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build());
|
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build());
|
||||||
|
|
||||||
final RolloutGroup firstGroup = rolloutGroupManagement
|
final RolloutGroup firstGroup = rolloutGroupManagement
|
||||||
@@ -711,7 +743,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that the targets of rollout group can be retrieved")
|
@Description("Testing that the targets of rollout group can be retrieved")
|
||||||
public void retrieveTargetsFromRolloutGroup() throws Exception {
|
void retrieveTargetsFromRolloutGroup() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 10;
|
final int amountTargets = 10;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -720,8 +752,8 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
// create rollout including the created targets with prefix 'rollout'
|
// create rollout including the created targets with prefix 'rollout'
|
||||||
final Rollout rollout = createRollout("rollout1", 2, dsA.getId(), "controllerId==rollout*");
|
final Rollout rollout = createRollout("rollout1", 2, dsA.getId(), "controllerId==rollout*");
|
||||||
|
|
||||||
final RolloutGroup firstGroup = rolloutGroupManagement
|
final RolloutGroup firstGroup = rolloutGroupManagement.findByRollout(PageRequest.of(0, 1, Direction.ASC, "id"),
|
||||||
.findByRollout(PageRequest.of(0, 1, Direction.ASC, "id"), rollout.getId()).getContent().get(0);
|
rollout.getId()).getContent().get(0);
|
||||||
|
|
||||||
// retrieve targets from the first rollout group with known ID
|
// retrieve targets from the first rollout group with known ID
|
||||||
mvc.perform(
|
mvc.perform(
|
||||||
@@ -734,7 +766,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that the targets of rollout group can be retrieved with rsql query param")
|
@Description("Testing that the targets of rollout group can be retrieved with rsql query param")
|
||||||
public void retrieveTargetsFromRolloutGroupWithQuery() throws Exception {
|
void retrieveTargetsFromRolloutGroupWithQuery() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 10;
|
final int amountTargets = 10;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -743,8 +775,8 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
// create rollout including the created targets with prefix 'rollout'
|
// create rollout including the created targets with prefix 'rollout'
|
||||||
final Rollout rollout = createRollout("rollout1", 2, dsA.getId(), "controllerId==rollout*");
|
final Rollout rollout = createRollout("rollout1", 2, dsA.getId(), "controllerId==rollout*");
|
||||||
|
|
||||||
final RolloutGroup firstGroup = rolloutGroupManagement
|
final RolloutGroup firstGroup = rolloutGroupManagement.findByRollout(PageRequest.of(0, 1, Direction.ASC, "id"),
|
||||||
.findByRollout(PageRequest.of(0, 1, Direction.ASC, "id"), rollout.getId()).getContent().get(0);
|
rollout.getId()).getContent().get(0);
|
||||||
|
|
||||||
final String targetInGroup = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, firstGroup.getId())
|
final String targetInGroup = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, firstGroup.getId())
|
||||||
.getContent().get(0).getControllerId();
|
.getContent().get(0).getControllerId();
|
||||||
@@ -760,7 +792,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that the targets of rollout group can be retrieved after the rollout has been started")
|
@Description("Testing that the targets of rollout group can be retrieved after the rollout has been started")
|
||||||
public void retrieveTargetsFromRolloutGroupAfterRolloutIsStarted() throws Exception {
|
void retrieveTargetsFromRolloutGroupAfterRolloutIsStarted() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 10;
|
final int amountTargets = 10;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -788,7 +820,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Start the rollout in async mode")
|
@Description("Start the rollout in async mode")
|
||||||
public void startingRolloutSwitchesIntoRunningStateAsync() throws Exception {
|
void startingRolloutSwitchesIntoRunningStateAsync() throws Exception {
|
||||||
|
|
||||||
final int amountTargets = 1000;
|
final int amountTargets = 1000;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -798,19 +830,31 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
final Rollout rollout = createRollout("rollout1", 4, dsA.getId(), "controllerId==rollout*");
|
final Rollout rollout = createRollout("rollout1", 4, dsA.getId(), "controllerId==rollout*");
|
||||||
|
|
||||||
// starting rollout
|
// starting rollout
|
||||||
mvc.perform(post("/rest/v1/rollouts/{rolloutId}/start", rollout.getId())).andDo(MockMvcResultPrinter.print())
|
mvc.perform(post("/rest/v1/rollouts/{rolloutId}/start", rollout.getId()))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
// Run here, because scheduler is disabled during tests
|
// Run here, because scheduler is disabled during tests
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
// check if running
|
// check if running
|
||||||
assertThat(doWithTimeout(() -> getRollout(rollout.getId()), this::success, 60_000, 100)).isNotNull();
|
awaitRunningState(rollout.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void awaitRunningState(final Long rolloutId) {
|
||||||
|
Awaitility.await()
|
||||||
|
.atMost(Duration.ONE_MINUTE)
|
||||||
|
.pollInterval(Duration.ONE_HUNDRED_MILLISECONDS)
|
||||||
|
.with()
|
||||||
|
.until(() -> WithSpringAuthorityRule.runAsPrivileged(
|
||||||
|
() -> rolloutManagement.get(rolloutId).orElseThrow(NoSuchElementException::new))
|
||||||
|
.getStatus()
|
||||||
|
.equals(RolloutStatus.RUNNING));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Deletion of a rollout")
|
@Description("Deletion of a rollout")
|
||||||
public void deleteRollout() throws Exception {
|
void deleteRollout() throws Exception {
|
||||||
final int amountTargets = 10;
|
final int amountTargets = 10;
|
||||||
testdataFactory.createTargets(amountTargets, "rolloutDelete", "rolloutDelete");
|
testdataFactory.createTargets(amountTargets, "rolloutDelete", "rolloutDelete");
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||||
@@ -818,26 +862,34 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
// create rollout including the created targets with prefix 'rollout'
|
// create rollout including the created targets with prefix 'rollout'
|
||||||
final Rollout rollout = createRollout("rolloutDelete", 4, dsA.getId(), "controllerId==rolloutDelete*");
|
final Rollout rollout = createRollout("rolloutDelete", 4, dsA.getId(), "controllerId==rolloutDelete*");
|
||||||
|
|
||||||
// delete rollout
|
mvc.perform(delete("/rest/v1/rollouts/{rolloutid}", rollout.getId()))
|
||||||
mvc.perform(delete("/rest/v1/rollouts/{rolloutid}", rollout.getId())).andDo(MockMvcResultPrinter.print())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
assertThat(getRollout(rollout.getId()).getStatus()).isEqualTo(RolloutStatus.DELETING);
|
assertStatusIs(rollout, RolloutStatus.DELETING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Soft deletion of a rollout: soft deletion appears when already running rollout is being deleted")
|
@Description("Soft deletion of a rollout: soft deletion appears when already running rollout is being deleted")
|
||||||
public void deleteRunningRollout() throws Exception {
|
void deleteRunningRollout() throws Exception {
|
||||||
final Rollout rollout = testdataFactory.createSoftDeletedRollout("softDeletedRollout");
|
final Rollout rollout = testdataFactory.createSoftDeletedRollout("softDeletedRollout");
|
||||||
|
|
||||||
mvc.perform(get("/rest/v1/rollouts/{rolloutid}", rollout.getId())).andDo(MockMvcResultPrinter.print())
|
mvc.perform(get("/rest/v1/rollouts/{rolloutid}", rollout.getId()))
|
||||||
.andExpect(status().isOk()).andExpect(jsonPath("$.deleted", equalTo(true)));
|
.andDo(MockMvcResultPrinter.print())
|
||||||
assertThat(getRollout(rollout.getId()).getStatus()).isEqualTo(RolloutStatus.DELETED);
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.deleted", equalTo(true)));
|
||||||
|
|
||||||
|
assertStatusIs(rollout, RolloutStatus.DELETED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertStatusIs(final Rollout rollout, RolloutStatus expected) {
|
||||||
|
final Optional<Rollout> updatedRollout = rolloutManagement.get(rollout.getId());
|
||||||
|
assertThat(updatedRollout).get().extracting(Rollout::getStatus).isEqualTo(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that rollout paged list with rsql parameter")
|
@Description("Testing that rollout paged list with rsql parameter")
|
||||||
public void getRolloutWithRSQLParam() throws Exception {
|
void getRolloutWithRSQLParam() throws Exception {
|
||||||
|
|
||||||
final int amountTargetsRollout1 = 25;
|
final int amountTargetsRollout1 = 25;
|
||||||
final int amountTargetsRollout2 = 25;
|
final int amountTargetsRollout2 = 25;
|
||||||
@@ -875,7 +927,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Testing that rolloutgroup paged list with rsql parameter")
|
@Description("Testing that rolloutgroup paged list with rsql parameter")
|
||||||
public void retrieveRolloutGroupsForSpecificRolloutWithRSQLParam() throws Exception {
|
void retrieveRolloutGroupsForSpecificRolloutWithRSQLParam() throws Exception {
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 20;
|
final int amountTargets = 20;
|
||||||
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
testdataFactory.createTargets(amountTargets, "rollout", "rollout");
|
||||||
@@ -909,7 +961,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that a DOWNLOAD_ONLY rollout is possible")
|
@Description("Verifies that a DOWNLOAD_ONLY rollout is possible")
|
||||||
public void createDownloadOnlyRollout() throws Exception {
|
void createDownloadOnlyRollout() throws Exception {
|
||||||
testdataFactory.createTargets(20, "target", "rollout");
|
testdataFactory.createTargets(20, "target", "rollout");
|
||||||
|
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||||
@@ -917,8 +969,8 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("A rollout create request containing a weight is only accepted when weight is valide and multi assignment is on.")
|
@Description("A rollout create request containing a weight is only accepted when weight is valid and multi assignment is on.")
|
||||||
public void weightValidation() throws Exception {
|
void weightValidation() throws Exception {
|
||||||
testdataFactory.createTargets(4, "rollout", "description");
|
testdataFactory.createTargets(4, "rollout", "description");
|
||||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||||
final int weight = 66;
|
final int weight = 66;
|
||||||
@@ -946,43 +998,6 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
assertThat(rollouts.get(0).getWeight()).get().isEqualTo(weight);
|
assertThat(rollouts.get(0).getWeight()).get().isEqualTo(weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T> T doWithTimeout(final Callable<T> callable, final SuccessCondition<T> successCondition,
|
|
||||||
final long timeout, final long pollInterval) throws Exception // NOPMD
|
|
||||||
{
|
|
||||||
|
|
||||||
if (pollInterval < 0) {
|
|
||||||
throw new IllegalArgumentException("pollInterval must non negative");
|
|
||||||
}
|
|
||||||
|
|
||||||
long duration = 0;
|
|
||||||
Exception exception = null;
|
|
||||||
T returnValue = null;
|
|
||||||
while (untilTimeoutReached(timeout, duration)) {
|
|
||||||
try {
|
|
||||||
returnValue = callable.call();
|
|
||||||
// clear exception
|
|
||||||
exception = null;
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
exception = ex;
|
|
||||||
}
|
|
||||||
Thread.sleep(pollInterval);
|
|
||||||
duration += pollInterval > 0 ? pollInterval : 1;
|
|
||||||
if (exception == null && successCondition.success(returnValue)) {
|
|
||||||
return returnValue;
|
|
||||||
} else {
|
|
||||||
returnValue = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (exception != null) {
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean untilTimeoutReached(final long timeout, final long duration) {
|
|
||||||
return duration <= timeout || timeout < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void postRollout(final String name, final int groupSize, final Long distributionSetId,
|
private void postRollout(final String name, final int groupSize, final Long distributionSetId,
|
||||||
final String targetFilterQuery, final int targets, final Action.ActionType type) throws Exception {
|
final String targetFilterQuery, final int targets, final Action.ActionType type) throws Exception {
|
||||||
final String actionType = MgmtRestModelMapper.convertActionType(type).getName();
|
final String actionType = MgmtRestModelMapper.convertActionType(type).getName();
|
||||||
@@ -1026,15 +1041,6 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
|||||||
// Run here, because Scheduler is disabled during tests
|
// Run here, because Scheduler is disabled during tests
|
||||||
rolloutManagement.handleRollouts();
|
rolloutManagement.handleRollouts();
|
||||||
|
|
||||||
return rolloutManagement.get(rollout.getId()).get();
|
return rolloutManagement.get(rollout.getId()).orElseThrow(NoSuchElementException::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean success(final Rollout result) {
|
|
||||||
return result != null && result.getStatus() == RolloutStatus.RUNNING;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Rollout getRollout(final Long rolloutId) throws Exception {
|
|
||||||
return rolloutManagement.get(rolloutId).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,12 @@ import java.io.InputStream;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.awaitility.Awaitility;
|
||||||
|
import org.awaitility.Duration;
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
|
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||||
@@ -72,23 +75,22 @@ import io.qameta.allure.Story;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link MgmtSoftwareModuleResource} {@link RestController}.
|
* Tests for {@link MgmtSoftwareModuleResource} {@link RestController}.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Feature("Component Tests - Management API")
|
@Feature("Component Tests - Management API")
|
||||||
@Story("Software Module Resource")
|
@Story("Software Module Resource")
|
||||||
@TestPropertySource(properties = { "hawkbit.server.security.dos.maxArtifactSize=100000",
|
@TestPropertySource(properties = { "hawkbit.server.security.dos.maxArtifactSize=100000",
|
||||||
"hawkbit.server.security.dos.maxArtifactStorage=500000" })
|
"hawkbit.server.security.dos.maxArtifactStorage=500000" })
|
||||||
public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTest {
|
class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void assertPreparationOfRepo() {
|
public void assertPreparationOfRepo() {
|
||||||
assertThat(softwareModuleManagement.findAll(PAGE)).as("no softwaremodule should be founded").hasSize(0);
|
assertThat(softwareModuleManagement.findAll(PAGE)).as("no softwaremodule should be founded").isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the update of software module metadata. It is verfied that only the selected fields for the update are really updated and the modification values are filled (i.e. updated by and at).")
|
@Description("Tests the update of software module metadata. It is verfied that only the selected fields for the update are really updated and the modification values are filled (i.e. updated by and at).")
|
||||||
@WithUser(principal = "smUpdateTester", allSpPermissions = true)
|
@WithUser(principal = "smUpdateTester", allSpPermissions = true)
|
||||||
public void updateSoftwareModuleOnlyDescriptionAndVendorNameUntouched() throws Exception {
|
void updateSoftwareModuleOnlyDescriptionAndVendorNameUntouched() throws Exception {
|
||||||
final String knownSWName = "name1";
|
final String knownSWName = "name1";
|
||||||
final String knownSWVersion = "version1";
|
final String knownSWVersion = "version1";
|
||||||
final String knownSWDescription = "description1";
|
final String knownSWDescription = "description1";
|
||||||
@@ -97,101 +99,122 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
final String updateVendor = "newVendor1";
|
final String updateVendor = "newVendor1";
|
||||||
final String updateDescription = "newDescription1";
|
final String updateDescription = "newDescription1";
|
||||||
|
|
||||||
SoftwareModule sm = softwareModuleManagement.create(entityFactory.softwareModule().create().type(osType)
|
final SoftwareModule sm = softwareModuleManagement.create(entityFactory.softwareModule()
|
||||||
.name(knownSWName).version(knownSWVersion).description(knownSWDescription).vendor(knownSWVendor));
|
.create()
|
||||||
|
.type(osType)
|
||||||
|
.name(knownSWName)
|
||||||
|
.version(knownSWVersion)
|
||||||
|
.description(knownSWDescription)
|
||||||
|
.vendor(knownSWVendor));
|
||||||
|
|
||||||
assertThat(sm.getName()).as("Wrong name of the software module").isEqualTo(knownSWName);
|
assertThat(sm.getName()).as("Wrong name of the software module").isEqualTo(knownSWName);
|
||||||
|
|
||||||
final String body = new JSONObject().put("vendor", updateVendor).put("description", updateDescription)
|
final String body = new JSONObject().put("vendor", updateVendor)
|
||||||
.put("name", "nameShouldNotBeChanged").toString();
|
.put("description", updateDescription)
|
||||||
|
.put("name", "nameShouldNotBeChanged")
|
||||||
|
.toString();
|
||||||
|
|
||||||
// ensures that we are not to fast so that last modified is not set
|
// ensures that we are not to fast so that last modified is not set correctly
|
||||||
// correctly
|
Awaitility.await()
|
||||||
Thread.sleep(1);
|
.atMost(Duration.ONE_HUNDRED_MILLISECONDS)
|
||||||
|
.pollInterval(10L, TimeUnit.MILLISECONDS)
|
||||||
|
.until(() -> sm.getLastModifiedAt() > 0L && sm.getLastModifiedBy() != null);
|
||||||
|
|
||||||
mvc.perform(put("/rest/v1/softwaremodules/{smId}", sm.getId()).content(body)
|
mvc.perform(put("/rest/v1/softwaremodules/{smId}", sm.getId()).content(body)
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.id", equalTo(sm.getId().intValue())))
|
.andExpect(jsonPath("$.id", equalTo(sm.getId().intValue())))
|
||||||
.andExpect(jsonPath("$.vendor", equalTo(updateVendor)))
|
.andExpect(jsonPath("$.vendor", equalTo(updateVendor)))
|
||||||
.andExpect(jsonPath("$.lastModifiedBy", equalTo("smUpdateTester")))
|
.andExpect(jsonPath("$.lastModifiedBy", equalTo("smUpdateTester")))
|
||||||
.andExpect(jsonPath("$.lastModifiedAt", not(equalTo(sm.getLastModifiedAt()))))
|
.andExpect(jsonPath("$.lastModifiedAt", not(equalTo(sm.getLastModifiedAt()))))
|
||||||
.andExpect(jsonPath("$.description", equalTo(updateDescription)))
|
.andExpect(jsonPath("$.description", equalTo(updateDescription)))
|
||||||
.andExpect(jsonPath("$.name", equalTo(knownSWName))).andReturn();
|
.andExpect(jsonPath("$.name", equalTo(knownSWName)))
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
sm = softwareModuleManagement.get(sm.getId()).get();
|
final SoftwareModule updatedSm = softwareModuleManagement.get(sm.getId()).get();
|
||||||
assertThat(sm.getName()).isEqualTo(knownSWName);
|
assertThat(updatedSm.getName()).isEqualTo(knownSWName);
|
||||||
assertThat(sm.getVendor()).isEqualTo(updateVendor);
|
assertThat(updatedSm.getVendor()).isEqualTo(updateVendor);
|
||||||
assertThat(sm.getLastModifiedBy()).isEqualTo("smUpdateTester");
|
assertThat(updatedSm.getLastModifiedBy()).isEqualTo("smUpdateTester");
|
||||||
assertThat(sm.getDescription()).isEqualTo(updateDescription);
|
assertThat(updatedSm.getDescription()).isEqualTo(updateDescription);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the update of the deletion flag. It is verfied that the software module can't be marked as deleted through update operation.")
|
@Description("Tests the update of the deletion flag. It is verfied that the software module can't be marked as deleted through update operation.")
|
||||||
@WithUser(principal = "smUpdateTester", allSpPermissions = true)
|
@WithUser(principal = "smUpdateTester", allSpPermissions = true)
|
||||||
public void updateSoftwareModuleDeletedFlag() throws Exception {
|
void updateSoftwareModuleDeletedFlag() throws Exception {
|
||||||
final String knownSWName = "name1";
|
final String knownSWName = "name1";
|
||||||
final String knownSWVersion = "version1";
|
final String knownSWVersion = "version1";
|
||||||
|
|
||||||
SoftwareModule sm = softwareModuleManagement
|
final SoftwareModule sm = softwareModuleManagement.create(
|
||||||
.create(entityFactory.softwareModule().create().type(osType).name(knownSWName).version(knownSWVersion));
|
entityFactory.softwareModule().create().type(osType).name(knownSWName).version(knownSWVersion));
|
||||||
|
|
||||||
assertThat(sm.isDeleted()).as("Created software module should not be deleted").isEqualTo(false);
|
assertThat(sm.isDeleted()).as("Created software module should not be deleted").isFalse();
|
||||||
|
|
||||||
final String body = new JSONObject().put("deleted", true).toString();
|
final String body = new JSONObject().put("deleted", true).toString();
|
||||||
|
|
||||||
// ensures that we are not to fast so that last modified is not set
|
// ensures that we are not to fast so that last modified is not set correctly
|
||||||
// correctly
|
Awaitility.await()
|
||||||
Thread.sleep(1);
|
.atMost(Duration.ONE_HUNDRED_MILLISECONDS)
|
||||||
|
.pollInterval(10L, TimeUnit.MILLISECONDS)
|
||||||
|
.until(() -> sm.getLastModifiedAt() > 0L && sm.getLastModifiedBy() != null);
|
||||||
|
|
||||||
mvc.perform(put("/rest/v1/softwaremodules/{smId}", sm.getId()).content(body)
|
mvc.perform(put("/rest/v1/softwaremodules/{smId}", sm.getId()).content(body)
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.id", equalTo(sm.getId().intValue())))
|
.andExpect(jsonPath("$.id", equalTo(sm.getId().intValue())))
|
||||||
.andExpect(jsonPath("$.lastModifiedBy", equalTo("smUpdateTester")))
|
.andExpect(jsonPath("$.lastModifiedBy", equalTo("smUpdateTester")))
|
||||||
.andExpect(jsonPath("$.lastModifiedAt", equalTo(sm.getLastModifiedAt())))
|
.andExpect(jsonPath("$.lastModifiedAt", equalTo(sm.getLastModifiedAt())))
|
||||||
.andExpect(jsonPath("$.deleted", equalTo(false)));
|
.andExpect(jsonPath("$.deleted", equalTo(false)));
|
||||||
|
|
||||||
sm = softwareModuleManagement.get(sm.getId()).get();
|
final SoftwareModule updatedSm = softwareModuleManagement.get(sm.getId()).get();
|
||||||
assertThat(sm.getLastModifiedBy()).isEqualTo("smUpdateTester");
|
assertThat(sm.getLastModifiedBy()).isEqualTo("smUpdateTester");
|
||||||
assertThat(sm.getLastModifiedAt()).isEqualTo(sm.getLastModifiedAt());
|
assertThat(sm.getLastModifiedAt()).isEqualTo(sm.getLastModifiedAt());
|
||||||
assertThat(sm.isDeleted()).isEqualTo(false);
|
assertThat(sm.isDeleted()).isFalse();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the upload of an artifact binary. The upload is executed and the content checked in the repository for completeness.")
|
@Description("Tests the upload of an artifact binary. The upload is executed and the content checked in the repository for completeness.")
|
||||||
public void uploadArtifact() throws Exception {
|
void uploadArtifact() throws Exception {
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
// create test file
|
// create test file
|
||||||
final byte random[] = randomBytes(5 * 1024);
|
final byte[] random = randomBytes(5 * 1024);
|
||||||
final String md5sum = HashGeneratorUtils.generateMD5(random);
|
final String md5sum = HashGeneratorUtils.generateMD5(random);
|
||||||
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
|
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
|
||||||
final String sha256sum = HashGeneratorUtils.generateSHA256(random);
|
final String sha256sum = HashGeneratorUtils.generateSHA256(random);
|
||||||
final MockMultipartFile file = new MockMultipartFile("file", "origFilename", null, random);
|
final MockMultipartFile file = new MockMultipartFile("file", "origFilename", null, random);
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
final MvcResult mvcResult = mvc
|
final MvcResult mvcResult = mvc.perform(
|
||||||
.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
|
multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isCreated())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("$.hashes.md5", equalTo(md5sum)))
|
.andExpect(jsonPath("$.hashes.md5", equalTo(md5sum)))
|
||||||
.andExpect(jsonPath("$.hashes.sha1", equalTo(sha1sum)))
|
.andExpect(jsonPath("$.hashes.sha1", equalTo(sha1sum)))
|
||||||
.andExpect(jsonPath("$.hashes.sha256", equalTo(sha256sum)))
|
.andExpect(jsonPath("$.hashes.sha256", equalTo(sha256sum)))
|
||||||
.andExpect(jsonPath("$.size", equalTo(random.length)))
|
.andExpect(jsonPath("$.size", equalTo(random.length)))
|
||||||
.andExpect(jsonPath("$.providedFilename", equalTo("origFilename"))).andReturn();
|
.andExpect(jsonPath("$.providedFilename", equalTo("origFilename")))
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
// check rest of response compared to DB
|
// check rest of response compared to DB
|
||||||
final MgmtArtifact artResult = ResourceUtility
|
final MgmtArtifact artResult = ResourceUtility.convertArtifactResponse(
|
||||||
.convertArtifactResponse(mvcResult.getResponse().getContentAsString());
|
mvcResult.getResponse().getContentAsString());
|
||||||
final Long artId = softwareModuleManagement.get(sm.getId()).get().getArtifacts().get(0).getId();
|
final Long artId = softwareModuleManagement.get(sm.getId()).get().getArtifacts().get(0).getId();
|
||||||
assertThat(artResult.getArtifactId()).as("Wrong artifact id").isEqualTo(artId);
|
assertThat(artResult.getArtifactId()).as("Wrong artifact id").isEqualTo(artId);
|
||||||
assertThat(JsonPath.compile("$._links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
assertThat(JsonPath.compile("$._links.self.href")
|
||||||
.as("Link contains no self url")
|
.read(mvcResult.getResponse().getContentAsString())
|
||||||
|
.toString()).as("Link contains no self url")
|
||||||
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artId);
|
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artId);
|
||||||
assertThat(JsonPath.compile("$._links.download.href").read(mvcResult.getResponse().getContentAsString())
|
assertThat(JsonPath.compile("$._links.download.href")
|
||||||
.toString()).as("response contains no download url ").isEqualTo(
|
.read(mvcResult.getResponse().getContentAsString())
|
||||||
|
.toString()).as("response contains no download url ")
|
||||||
|
.isEqualTo(
|
||||||
"http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artId + "/download");
|
"http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artId + "/download");
|
||||||
|
|
||||||
assertArtifact(sm, random);
|
assertArtifact(sm, random);
|
||||||
@@ -199,7 +222,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that artifacts which exceed the configured maximum size cannot be uploaded.")
|
@Description("Verifies that artifacts which exceed the configured maximum size cannot be uploaded.")
|
||||||
public void uploadArtifactFailsIfTooLarge() throws Exception {
|
void uploadArtifactFailsIfTooLarge() throws Exception {
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModule("quota", "quota", false);
|
final SoftwareModule sm = testdataFactory.createSoftwareModule("quota", "quota", false);
|
||||||
final long maxSize = quotaManagement.getMaxArtifactSize();
|
final long maxSize = quotaManagement.getMaxArtifactSize();
|
||||||
|
|
||||||
@@ -218,7 +241,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that artifact with invalid filename cannot be uploaded to prevent cross site scripting.")
|
@Description("Verifies that artifact with invalid filename cannot be uploaded to prevent cross site scripting.")
|
||||||
public void uploadArtifactFailsIfFilenameInvalide() throws Exception {
|
void uploadArtifactFailsIfFilenameInvalide() throws Exception {
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModule("quota", "quota", false);
|
final SoftwareModule sm = testdataFactory.createSoftwareModule("quota", "quota", false);
|
||||||
final String illegalFilename = "<img src=ernw onerror=alert(1)>.xml";
|
final String illegalFilename = "<img src=ernw onerror=alert(1)>.xml";
|
||||||
|
|
||||||
@@ -226,7 +249,8 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
final MockMultipartFile file = new MockMultipartFile("file", illegalFilename, null, randomBytes);
|
final MockMultipartFile file = new MockMultipartFile("file", illegalFilename, null, randomBytes);
|
||||||
|
|
||||||
mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
|
mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
|
||||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isBadRequest())
|
.andExpect(status().isBadRequest())
|
||||||
.andExpect(jsonPath("$.message", containsString("Invalid characters in string")));
|
.andExpect(jsonPath("$.message", containsString("Invalid characters in string")));
|
||||||
}
|
}
|
||||||
@@ -261,26 +285,27 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that the system does not accept empty artifact uploads. Expected response: BAD REQUEST")
|
@Description("Verifies that the system does not accept empty artifact uploads. Expected response: BAD REQUEST")
|
||||||
public void emptyUploadArtifact() throws Exception {
|
void emptyUploadArtifact() throws Exception {
|
||||||
assertThat(softwareModuleManagement.findAll(PAGE)).hasSize(0);
|
assertThat(softwareModuleManagement.findAll(PAGE)).isEmpty();
|
||||||
assertThat(artifactManagement.count()).isEqualTo(0);
|
assertThat(artifactManagement.count()).isZero();
|
||||||
|
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
final MockMultipartFile file = new MockMultipartFile("file", "orig", null, new byte[0]);
|
final MockMultipartFile file = new MockMultipartFile("file", "orig", null, new byte[0]);
|
||||||
|
|
||||||
mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
|
mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
|
||||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that the system does not accept identical artifacts uploads for the same software module. Expected response: CONFLICT")
|
@Description("Verifies that the system does not accept identical artifacts uploads for the same software module. Expected response: CONFLICT")
|
||||||
public void duplicateUploadArtifact() throws Exception {
|
void duplicateUploadArtifact() throws Exception {
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
final byte random[] = randomBytes(5 * 1024);
|
final byte[] random = randomBytes(5 * 1024);
|
||||||
final String md5sum = HashGeneratorUtils.generateMD5(random);
|
final String md5sum = HashGeneratorUtils.generateMD5(random);
|
||||||
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
|
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
|
||||||
final String sha256sum = HashGeneratorUtils.generateSHA256(random);
|
final String sha256sum = HashGeneratorUtils.generateSHA256(random);
|
||||||
@@ -299,20 +324,23 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("verfies that option to upload artifacts with a custom defined by metadata, i.e. not the file name of the binary itself.")
|
@Description("verifies that option to upload artifacts with a custom defined by metadata, i.e. not the file name of the binary itself.")
|
||||||
public void uploadArtifactWithCustomName() throws Exception {
|
void uploadArtifactWithCustomName() throws Exception {
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
assertThat(artifactManagement.count()).isEqualTo(0);
|
assertThat(artifactManagement.count()).isZero();
|
||||||
|
|
||||||
// create test file
|
// create test file
|
||||||
final byte random[] = randomBytes(5 * 1024);
|
final byte[] random = randomBytes(5 * 1024);
|
||||||
final MockMultipartFile file = new MockMultipartFile("file", "origFilename", null, random);
|
final MockMultipartFile file = new MockMultipartFile("file", "origFilename", null, random);
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file).param("filename",
|
mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
|
||||||
"customFilename")).andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
.param("filename", "customFilename"))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isCreated())
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
.andExpect(jsonPath("$.providedFilename", equalTo("customFilename"))).andExpect(status().isCreated());
|
.andExpect(jsonPath("$.providedFilename", equalTo("customFilename")))
|
||||||
|
.andExpect(status().isCreated());
|
||||||
|
|
||||||
// check result in db...
|
// check result in db...
|
||||||
// repo
|
// repo
|
||||||
@@ -323,13 +351,13 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that the system refuses upload of an artifact where the provided hash sums do not match. Expected result: BAD REQUEST")
|
@Description("Verifies that the system refuses upload of an artifact where the provided hash sums do not match. Expected result: BAD REQUEST")
|
||||||
public void uploadArtifactWithHashCheck() throws Exception {
|
void uploadArtifactWithHashCheck() throws Exception {
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
assertThat(artifactManagement.count()).isEqualTo(0);
|
assertThat(artifactManagement.count()).isZero();
|
||||||
|
|
||||||
// create test file
|
// create test file
|
||||||
final byte random[] = randomBytes(5 * 1024);
|
final byte[] random = randomBytes(5 * 1024);
|
||||||
final String md5sum = HashGeneratorUtils.generateMD5(random);
|
final String md5sum = HashGeneratorUtils.generateMD5(random);
|
||||||
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
|
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
|
||||||
final String sha256sum = HashGeneratorUtils.generateSHA256(random);
|
final String sha256sum = HashGeneratorUtils.generateSHA256(random);
|
||||||
@@ -379,13 +407,13 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that only a limited number of artifacts can be uploaded for one software module.")
|
@Description("Verifies that only a limited number of artifacts can be uploaded for one software module.")
|
||||||
public void uploadArtifactsUntilQuotaExceeded() throws Exception {
|
void uploadArtifactsUntilQuotaExceeded() throws Exception {
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
final long maxArtifacts = quotaManagement.getMaxArtifactsPerSoftwareModule();
|
final long maxArtifacts = quotaManagement.getMaxArtifactsPerSoftwareModule();
|
||||||
|
|
||||||
for (int i = 0; i < maxArtifacts; ++i) {
|
for (int i = 0; i < maxArtifacts; ++i) {
|
||||||
// create test file
|
// create test file
|
||||||
final byte random[] = randomBytes(5 * 1024);
|
final byte[] random = randomBytes(5 * 1024);
|
||||||
final String md5sum = HashGeneratorUtils.generateMD5(random);
|
final String md5sum = HashGeneratorUtils.generateMD5(random);
|
||||||
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
|
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
|
||||||
final String sha256sum = HashGeneratorUtils.generateSHA256(random);
|
final String sha256sum = HashGeneratorUtils.generateSHA256(random);
|
||||||
@@ -403,7 +431,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
// upload one more file to cause the quota to be exceeded
|
// upload one more file to cause the quota to be exceeded
|
||||||
final byte random[] = randomBytes(5 * 1024);
|
final byte[] random = randomBytes(5 * 1024);
|
||||||
final MockMultipartFile file = new MockMultipartFile("file", "origFilename_final", null, random);
|
final MockMultipartFile file = new MockMultipartFile("file", "origFilename_final", null, random);
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
@@ -417,7 +445,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that artifacts can only be added as long as the artifact storage quota is not exceeded.")
|
@Description("Verifies that artifacts can only be added as long as the artifact storage quota is not exceeded.")
|
||||||
public void uploadArtifactsUntilStorageQuotaExceeded() throws Exception {
|
void uploadArtifactsUntilStorageQuotaExceeded() throws Exception {
|
||||||
|
|
||||||
final long storageLimit = quotaManagement.getMaxArtifactStorage();
|
final long storageLimit = quotaManagement.getMaxArtifactStorage();
|
||||||
|
|
||||||
@@ -427,7 +455,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
for (int i = 0; i < numArtifacts; ++i) {
|
for (int i = 0; i < numArtifacts; ++i) {
|
||||||
// create test file
|
// create test file
|
||||||
final byte random[] = randomBytes(artifactSize);
|
final byte[] random = randomBytes(artifactSize);
|
||||||
final String md5sum = HashGeneratorUtils.generateMD5(random);
|
final String md5sum = HashGeneratorUtils.generateMD5(random);
|
||||||
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
|
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
|
||||||
final String sha256sum = HashGeneratorUtils.generateSHA256(random);
|
final String sha256sum = HashGeneratorUtils.generateSHA256(random);
|
||||||
@@ -446,7 +474,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
// upload one more file to cause the quota to be exceeded
|
// upload one more file to cause the quota to be exceeded
|
||||||
final byte random[] = randomBytes(artifactSize);
|
final byte[] random = randomBytes(artifactSize);
|
||||||
final MockMultipartFile file = new MockMultipartFile("file", "origFilename_final", null, random);
|
final MockMultipartFile file = new MockMultipartFile("file", "origFilename_final", null, random);
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
@@ -461,16 +489,16 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests binary download of an artifact including verfication that the downloaded binary is consistent and that the etag header is as expected identical to the SHA1 hash of the file.")
|
@Description("Tests binary download of an artifact including verfication that the downloaded binary is consistent and that the etag header is as expected identical to the SHA1 hash of the file.")
|
||||||
public void downloadArtifact() throws Exception {
|
void downloadArtifact() throws Exception {
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
final int artifactSize = 5 * 1024;
|
final int artifactSize = 5 * 1024;
|
||||||
final byte random[] = randomBytes(artifactSize);
|
final byte[] random = randomBytes(artifactSize);
|
||||||
|
|
||||||
final Artifact artifact = artifactManagement
|
final Artifact artifact = artifactManagement.create(
|
||||||
.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
|
new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
|
||||||
final Artifact artifact2 = artifactManagement
|
final Artifact artifact2 = artifactManagement.create(
|
||||||
.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file2", false, artifactSize));
|
new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file2", false, artifactSize));
|
||||||
|
|
||||||
downloadAndVerify(sm, random, artifact);
|
downloadAndVerify(sm, random, artifact);
|
||||||
downloadAndVerify(sm, random, artifact2);
|
downloadAndVerify(sm, random, artifact2);
|
||||||
@@ -492,19 +520,21 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies the listing of one defined artifact assigned to a given software module. That includes the artifact metadata and download links.")
|
@Description("Verifies the listing of one defined artifact assigned to a given software module. That includes the artifact metadata and download links.")
|
||||||
public void getArtifact() throws Exception {
|
void getArtifact() throws Exception {
|
||||||
// prepare data for test
|
// prepare data for test
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
final int artifactSize = 5 * 1024;
|
final int artifactSize = 5 * 1024;
|
||||||
final byte random[] = randomBytes(artifactSize);
|
final byte random[] = randomBytes(artifactSize);
|
||||||
|
|
||||||
final Artifact artifact = artifactManagement
|
final Artifact artifact = artifactManagement.create(
|
||||||
.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
|
new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
|
||||||
|
|
||||||
// perform test
|
// perform test
|
||||||
mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts/{artId}", sm.getId(), artifact.getId())
|
mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts/{artId}", sm.getId(), artifact.getId()).accept(
|
||||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("$.id", equalTo(artifact.getId().intValue())))
|
.andExpect(jsonPath("$.id", equalTo(artifact.getId().intValue())))
|
||||||
.andExpect(jsonPath("$.size", equalTo(random.length)))
|
.andExpect(jsonPath("$.size", equalTo(random.length)))
|
||||||
@@ -521,16 +551,18 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies the listing of an artifact that belongs to a soft deleted software module.")
|
@Description("Verifies the listing of an artifact that belongs to a soft deleted software module.")
|
||||||
public void getArtifactSoftDeleted() throws Exception {
|
void getArtifactSoftDeleted() throws Exception {
|
||||||
// prepare data for test
|
// prepare data for test
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs("softDeleted");
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs("softDeleted");
|
||||||
final Artifact artifact = testdataFactory.createArtifacts(sm.getId()).get(0);
|
final Artifact artifact = testdataFactory.createArtifacts(sm.getId()).get(0);
|
||||||
testdataFactory.createDistributionSet(Arrays.asList(sm));
|
testdataFactory.createDistributionSet(Collections.singletonList(sm));
|
||||||
softwareModuleManagement.delete(sm.getId());
|
softwareModuleManagement.delete(sm.getId());
|
||||||
|
|
||||||
// perform test
|
// perform test
|
||||||
mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts/{artId}", sm.getId(), artifact.getId())
|
mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts/{artId}", sm.getId(), artifact.getId()).accept(
|
||||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("$.id", equalTo(artifact.getId().intValue())))
|
.andExpect(jsonPath("$.id", equalTo(artifact.getId().intValue())))
|
||||||
.andExpect(jsonPath("$.size", equalTo((int) artifact.getSize())))
|
.andExpect(jsonPath("$.size", equalTo((int) artifact.getSize())))
|
||||||
@@ -546,19 +578,20 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies the listing of all artifacts assigned to a software module. That includes the artifact metadata and download links.")
|
@Description("Verifies the listing of all artifacts assigned to a software module. That includes the artifact metadata and download links.")
|
||||||
public void getArtifacts() throws Exception {
|
void getArtifacts() throws Exception {
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
final int artifactSize = 5 * 1024;
|
final int artifactSize = 5 * 1024;
|
||||||
final byte random[] = randomBytes(artifactSize);
|
final byte[] random = randomBytes(artifactSize);
|
||||||
|
|
||||||
final Artifact artifact = artifactManagement
|
final Artifact artifact = artifactManagement.create(
|
||||||
.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
|
new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
|
||||||
final Artifact artifact2 = artifactManagement
|
final Artifact artifact2 = artifactManagement.create(
|
||||||
.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file2", false, artifactSize));
|
new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file2", false, artifactSize));
|
||||||
|
|
||||||
mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("$.[0].id", equalTo(artifact.getId().intValue())))
|
.andExpect(jsonPath("$.[0].id", equalTo(artifact.getId().intValue())))
|
||||||
.andExpect(jsonPath("$.[0].size", equalTo(random.length)))
|
.andExpect(jsonPath("$.[0].size", equalTo(random.length)))
|
||||||
@@ -579,11 +612,11 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that the system refuses unsupported request types and answers as defined to them, e.g. NOT FOUND on a non existing resource. Or a HTTP POST for updating a resource results in METHOD NOT ALLOWED etc.")
|
@Description("Verifies that the system refuses unsupported request types and answers as defined to them, e.g. NOT FOUND on a non existing resource. Or a HTTP POST for updating a resource results in METHOD NOT ALLOWED etc.")
|
||||||
public void invalidRequestsOnArtifactResource() throws Exception {
|
void invalidRequestsOnArtifactResource() throws Exception {
|
||||||
|
|
||||||
final int artifactSize = 5 * 1024;
|
final int artifactSize = 5 * 1024;
|
||||||
final byte random[] = randomBytes(artifactSize);
|
final byte[] random = randomBytes(artifactSize);
|
||||||
final MockMultipartFile file = new MockMultipartFile("file", "orig", null, random);
|
final MockMultipartFile file = new MockMultipartFile("file", "orig", null, random);
|
||||||
|
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
@@ -626,22 +659,25 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that the system refuses unsupported request types and answers as defined to them, e.g. NOT FOUND on a non existing resource. Or a HTTP POST for updating a resource results in METHOD NOT ALLOWED etc.")
|
@Description("Verifies that the system refuses unsupported request types and answers as defined to them, e.g. NOT FOUND on a non existing resource. Or a HTTP POST for updating a resource results in METHOD NOT ALLOWED etc.")
|
||||||
public void invalidRequestsOnSoftwaremodulesResource() throws Exception {
|
void invalidRequestsOnSoftwaremodulesResource() throws Exception {
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
final List<SoftwareModule> modules = Arrays.asList(sm);
|
final List<SoftwareModule> modules = Arrays.asList(sm);
|
||||||
|
|
||||||
// SM does not exist
|
// SM does not exist
|
||||||
mvc.perform(get("/rest/v1/softwaremodules/12345678")).andDo(MockMvcResultPrinter.print())
|
mvc.perform(get("/rest/v1/softwaremodules/12345678"))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
mvc.perform(delete("/rest/v1/softwaremodules/12345678")).andDo(MockMvcResultPrinter.print())
|
mvc.perform(delete("/rest/v1/softwaremodules/12345678"))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
// bad request - no content
|
// bad request - no content
|
||||||
mvc.perform(post("/rest/v1/softwaremodules").contentType(MediaType.APPLICATION_JSON))
|
mvc.perform(post("/rest/v1/softwaremodules").contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest());
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isBadRequest());
|
||||||
|
|
||||||
// bad request - bad content
|
// bad request - bad content
|
||||||
mvc.perform(post("/rest/v1/softwaremodules").content("sdfjsdlkjfskdjf".getBytes())
|
mvc.perform(post("/rest/v1/softwaremodules").content("sdfjsdlkjfskdjf".getBytes())
|
||||||
@@ -683,10 +719,11 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test of modules retrieval without any parameters. Will return all modules in the system as defined by standard page size.")
|
@Description("Test of modules retrieval without any parameters. Will return all modules in the system as defined by standard page size.")
|
||||||
public void getSoftwareModulesWithoutAddtionalRequestParameters() throws Exception {
|
void getSoftwareModulesWithoutAddtionalRequestParameters() throws Exception {
|
||||||
final int modules = 5;
|
final int modules = 5;
|
||||||
createSoftwareModulesAlphabetical(modules);
|
createSoftwareModulesAlphabetical(modules);
|
||||||
mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING)).andDo(MockMvcResultPrinter.print())
|
mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(modules)))
|
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(modules)))
|
||||||
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(modules)))
|
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(modules)))
|
||||||
@@ -695,13 +732,14 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test of modules retrieval with paging limit parameter. Will return all modules in the system as defined by given page size.")
|
@Description("Test of modules retrieval with paging limit parameter. Will return all modules in the system as defined by given page size.")
|
||||||
public void detSoftwareModulesWithPagingLimitRequestParameter() throws Exception {
|
void detSoftwareModulesWithPagingLimitRequestParameter() throws Exception {
|
||||||
final int modules = 5;
|
final int modules = 5;
|
||||||
final int limitSize = 1;
|
final int limitSize = 1;
|
||||||
createSoftwareModulesAlphabetical(modules);
|
createSoftwareModulesAlphabetical(modules);
|
||||||
mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING)
|
mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING).param(
|
||||||
.param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize)))
|
MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize)))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(modules)))
|
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(modules)))
|
||||||
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize)))
|
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize)))
|
||||||
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(limitSize)));
|
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(limitSize)));
|
||||||
@@ -709,15 +747,16 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test of modules retrieval with paging limit offset parameters. Will return all modules in the system as defined by given page size starting from given offset.")
|
@Description("Test of modules retrieval with paging limit offset parameters. Will return all modules in the system as defined by given page size starting from given offset.")
|
||||||
public void getSoftwareModulesWithPagingLimitAndOffsetRequestParameter() throws Exception {
|
void getSoftwareModulesWithPagingLimitAndOffsetRequestParameter() throws Exception {
|
||||||
final int modules = 5;
|
final int modules = 5;
|
||||||
final int offsetParam = 2;
|
final int offsetParam = 2;
|
||||||
final int expectedSize = modules - offsetParam;
|
final int expectedSize = modules - offsetParam;
|
||||||
createSoftwareModulesAlphabetical(modules);
|
createSoftwareModulesAlphabetical(modules);
|
||||||
mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING)
|
mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING).param(
|
||||||
.param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam))
|
MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam))
|
||||||
.param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(modules)))
|
.param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(modules)))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(modules)))
|
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(modules)))
|
||||||
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize)))
|
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize)))
|
||||||
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(expectedSize)));
|
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(expectedSize)));
|
||||||
@@ -726,12 +765,13 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
@Test
|
@Test
|
||||||
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
||||||
@Description("Test retrieval of all software modules the user has access to.")
|
@Description("Test retrieval of all software modules the user has access to.")
|
||||||
public void getSoftwareModules() throws Exception {
|
void getSoftwareModules() throws Exception {
|
||||||
final SoftwareModule os = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule os = testdataFactory.createSoftwareModuleOs();
|
||||||
final SoftwareModule app = testdataFactory.createSoftwareModuleApp();
|
final SoftwareModule app = testdataFactory.createSoftwareModuleApp();
|
||||||
|
|
||||||
mvc.perform(get("/rest/v1/softwaremodules").accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get("/rest/v1/softwaremodules").accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("$.content.[?(@.id==" + os.getId() + ")].name", contains(os.getName())))
|
.andExpect(jsonPath("$.content.[?(@.id==" + os.getId() + ")].name", contains(os.getName())))
|
||||||
.andExpect(jsonPath("$.content.[?(@.id==" + os.getId() + ")].version", contains(os.getVersion())))
|
.andExpect(jsonPath("$.content.[?(@.id==" + os.getId() + ")].version", contains(os.getVersion())))
|
||||||
@@ -759,7 +799,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test the various filter parameters, e.g. filter by name or type of the module.")
|
@Description("Test the various filter parameters, e.g. filter by name or type of the module.")
|
||||||
public void getSoftwareModulesWithFilterParameters() throws Exception {
|
void getSoftwareModulesWithFilterParameters() throws Exception {
|
||||||
final SoftwareModule os1 = testdataFactory.createSoftwareModuleOs("1");
|
final SoftwareModule os1 = testdataFactory.createSoftwareModuleOs("1");
|
||||||
final SoftwareModule app1 = testdataFactory.createSoftwareModuleApp("1");
|
final SoftwareModule app1 = testdataFactory.createSoftwareModuleApp("1");
|
||||||
testdataFactory.createSoftwareModuleOs("2");
|
testdataFactory.createSoftwareModuleOs("2");
|
||||||
@@ -769,7 +809,8 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
// only by name, only one exists per name
|
// only by name, only one exists per name
|
||||||
mvc.perform(get("/rest/v1/softwaremodules?q=name==" + os1.getName()).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get("/rest/v1/softwaremodules?q=name==" + os1.getName()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("$.content.[?(@.id==" + os1.getId() + ")].name", contains(os1.getName())))
|
.andExpect(jsonPath("$.content.[?(@.id==" + os1.getId() + ")].name", contains(os1.getName())))
|
||||||
.andExpect(jsonPath("$.content.[?(@.id==" + os1.getId() + ")].version", contains(os1.getVersion())))
|
.andExpect(jsonPath("$.content.[?(@.id==" + os1.getId() + ")].version", contains(os1.getVersion())))
|
||||||
@@ -816,29 +857,32 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that the system answers as defined in case of a wrong filter parameter syntax. Expected result: BAD REQUEST with error description.")
|
@Description("Verifies that the system answers as defined in case of a wrong filter parameter syntax. Expected result: BAD REQUEST with error description.")
|
||||||
public void getSoftwareModulesWithSyntaxErrorFilterParameter() throws Exception {
|
void getSoftwareModulesWithSyntaxErrorFilterParameter() throws Exception {
|
||||||
mvc.perform(get("/rest/v1/softwaremodules?q=wrongFIQLSyntax").accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get("/rest/v1/softwaremodules?q=wrongFIQLSyntax").accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isBadRequest())
|
||||||
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.rest.param.rsqlParamSyntax")));
|
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.rest.param.rsqlParamSyntax")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that the system answers as defined in case of a non existing field used in filter. Expected result: BAD REQUEST with error description.")
|
@Description("Verifies that the system answers as defined in case of a non existing field used in filter. Expected result: BAD REQUEST with error description.")
|
||||||
public void getSoftwareModulesWithUnknownFieldErrorFilterParameter() throws Exception {
|
void getSoftwareModulesWithUnknownFieldErrorFilterParameter() throws Exception {
|
||||||
mvc.perform(get("/rest/v1/softwaremodules?q=wrongField==abc").accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get("/rest/v1/softwaremodules?q=wrongField==abc").accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isBadRequest())
|
||||||
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.rest.param.rsqlInvalidField")));
|
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.rest.param.rsqlInvalidField")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
||||||
@Description("Tests GET request on /rest/v1/softwaremodules/{smId}.")
|
@Description("Tests GET request on /rest/v1/softwaremodules/{smId}.")
|
||||||
public void getSoftwareModule() throws Exception {
|
void getSoftwareModule() throws Exception {
|
||||||
final SoftwareModule os = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule os = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
mvc.perform(get("/rest/v1/softwaremodules/{smId}", os.getId()).accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get("/rest/v1/softwaremodules/{smId}", os.getId()).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("$.name", equalTo(os.getName())))
|
.andExpect(jsonPath("$.name", equalTo(os.getName())))
|
||||||
.andExpect(jsonPath("$.version", equalTo(os.getVersion())))
|
.andExpect(jsonPath("$.version", equalTo(os.getVersion())))
|
||||||
@@ -861,26 +905,41 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
||||||
@Description("Verfies that the create request actually results in the creation of the modules in the repository.")
|
@Description("Verifies that the create request actually results in the creation of the modules in the repository.")
|
||||||
public void createSoftwareModules() throws Exception {
|
void createSoftwareModules() throws Exception {
|
||||||
final SoftwareModule os = entityFactory.softwareModule().create().name("name1").type(osType).version("version1")
|
final SoftwareModule os = entityFactory.softwareModule()
|
||||||
.vendor("vendor1").description("description1").build();
|
.create()
|
||||||
final SoftwareModule ah = entityFactory.softwareModule().create().name("name3").type(appType)
|
.name("name1")
|
||||||
.version("version3").vendor("vendor3").description("description3").build();
|
.type(osType)
|
||||||
|
.version("version1")
|
||||||
|
.vendor("vendor1")
|
||||||
|
.description("description1")
|
||||||
|
.build();
|
||||||
|
final SoftwareModule ah = entityFactory.softwareModule()
|
||||||
|
.create()
|
||||||
|
.name("name3")
|
||||||
|
.type(appType)
|
||||||
|
.version("version3")
|
||||||
|
.vendor("vendor3")
|
||||||
|
.description("description3")
|
||||||
|
.build();
|
||||||
|
|
||||||
final List<SoftwareModule> modules = Arrays.asList(os, ah);
|
final List<SoftwareModule> modules = Arrays.asList(os, ah);
|
||||||
|
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
|
|
||||||
final MvcResult mvcResult = mvc
|
final MvcResult mvcResult = mvc.perform(
|
||||||
.perform(post("/rest/v1/softwaremodules/").accept(MediaType.APPLICATION_JSON_VALUE)
|
post("/rest/v1/softwaremodules/").accept(MediaType.APPLICATION_JSON_VALUE)
|
||||||
.content(JsonBuilder.softwareModules(modules)).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.softwareModules(modules))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isCreated())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("[0].name", equalTo("name1")))
|
.andExpect(jsonPath("[0].name", equalTo("name1")))
|
||||||
.andExpect(jsonPath("[0].version", equalTo("version1")))
|
.andExpect(jsonPath("[0].version", equalTo("version1")))
|
||||||
.andExpect(jsonPath("[0].description", equalTo("description1")))
|
.andExpect(jsonPath("[0].description", equalTo("description1")))
|
||||||
.andExpect(jsonPath("[0].vendor", equalTo("vendor1"))).andExpect(jsonPath("[0].type", equalTo("os")))
|
.andExpect(jsonPath("[0].vendor", equalTo("vendor1")))
|
||||||
|
.andExpect(jsonPath("[0].type", equalTo("os")))
|
||||||
.andExpect(jsonPath("[0].createdBy", equalTo("uploadTester")))
|
.andExpect(jsonPath("[0].createdBy", equalTo("uploadTester")))
|
||||||
.andExpect(jsonPath("[1].name", equalTo("name3")))
|
.andExpect(jsonPath("[1].name", equalTo("name3")))
|
||||||
.andExpect(jsonPath("[1].version", equalTo("version3")))
|
.andExpect(jsonPath("[1].version", equalTo("version3")))
|
||||||
@@ -888,60 +947,62 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
.andExpect(jsonPath("[1].vendor", equalTo("vendor3")))
|
.andExpect(jsonPath("[1].vendor", equalTo("vendor3")))
|
||||||
.andExpect(jsonPath("[1].type", equalTo("application")))
|
.andExpect(jsonPath("[1].type", equalTo("application")))
|
||||||
.andExpect(jsonPath("[1].createdBy", equalTo("uploadTester")))
|
.andExpect(jsonPath("[1].createdBy", equalTo("uploadTester")))
|
||||||
.andExpect(jsonPath("[1].createdAt", not(equalTo(0)))).andReturn();
|
.andExpect(jsonPath("[1].createdAt", not(equalTo(0))))
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
final SoftwareModule osCreated = softwareModuleManagement
|
final SoftwareModule osCreated = softwareModuleManagement.getByNameAndVersionAndType("name1", "version1",
|
||||||
.getByNameAndVersionAndType("name1", "version1", osType.getId()).get();
|
osType.getId()).get();
|
||||||
final SoftwareModule appCreated = softwareModuleManagement
|
final SoftwareModule appCreated = softwareModuleManagement.getByNameAndVersionAndType("name3", "version3",
|
||||||
.getByNameAndVersionAndType("name3", "version3", appType.getId()).get();
|
appType.getId()).get();
|
||||||
|
|
||||||
assertThat(
|
assertThat(JsonPath.compile("[0]._links.self.href")
|
||||||
JsonPath.compile("[0]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
.read(mvcResult.getResponse().getContentAsString())
|
||||||
.as("Response contains invalid self href")
|
.toString()).as("Response contains invalid self href")
|
||||||
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + osCreated.getId());
|
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + osCreated.getId());
|
||||||
|
|
||||||
assertThat(
|
assertThat(JsonPath.compile("[1]._links.self.href")
|
||||||
JsonPath.compile("[1]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
.read(mvcResult.getResponse().getContentAsString())
|
||||||
.as("Response contains links self href")
|
.toString()).as("Response contains links self href")
|
||||||
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + appCreated.getId());
|
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + appCreated.getId());
|
||||||
|
|
||||||
assertThat(softwareModuleManagement.findAll(PAGE)).as("Wrong softwaremodule size").hasSize(2);
|
assertThat(softwareModuleManagement.findAll(PAGE)).as("Wrong softwaremodule size").hasSize(2);
|
||||||
assertThat(softwareModuleManagement.findByType(PAGE, osType.getId()).getContent().get(0).getName())
|
assertThat(softwareModuleManagement.findByType(PAGE, osType.getId()).getContent().get(0).getName()).as(
|
||||||
.as("Softwaremoudle name is wrong").isEqualTo(os.getName());
|
"Softwaremoudle name is wrong").isEqualTo(os.getName());
|
||||||
assertThat(softwareModuleManagement.findByType(PAGE, osType.getId()).getContent().get(0).getCreatedBy())
|
assertThat(softwareModuleManagement.findByType(PAGE, osType.getId()).getContent().get(0).getCreatedBy()).as(
|
||||||
.as("Softwaremoudle created by is wrong").isEqualTo("uploadTester");
|
"Softwaremoudle created by is wrong").isEqualTo("uploadTester");
|
||||||
assertThat(softwareModuleManagement.findByType(PAGE, osType.getId()).getContent().get(0).getCreatedAt())
|
assertThat(softwareModuleManagement.findByType(PAGE, osType.getId()).getContent().get(0).getCreatedAt()).as(
|
||||||
.as("Softwaremoudle created at is wrong").isGreaterThanOrEqualTo(current);
|
"Softwaremoudle created at is wrong").isGreaterThanOrEqualTo(current);
|
||||||
assertThat(softwareModuleManagement.findByType(PAGE, appType.getId()).getContent().get(0).getName())
|
assertThat(softwareModuleManagement.findByType(PAGE, appType.getId()).getContent().get(0).getName()).as(
|
||||||
.as("Softwaremoudle name is wrong").isEqualTo(ah.getName());
|
"Softwaremoudle name is wrong").isEqualTo(ah.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies successfull deletion of software modules that are not in use, i.e. assigned to a DS.")
|
@Description("Verifies successfull deletion of software modules that are not in use, i.e. assigned to a DS.")
|
||||||
public void deleteUnassignedSoftwareModule() throws Exception {
|
void deleteUnassignedSoftwareModule() throws Exception {
|
||||||
|
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
final int artifactSize = 5 * 1024;
|
final int artifactSize = 5 * 1024;
|
||||||
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
|
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
|
||||||
|
|
||||||
artifactManagement
|
artifactManagement.create(
|
||||||
.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
|
new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
|
||||||
|
|
||||||
assertThat(softwareModuleManagement.findAll(PAGE)).as("Softwaremoudle size is wrong").hasSize(1);
|
assertThat(softwareModuleManagement.findAll(PAGE)).as("Softwaremoudle size is wrong").hasSize(1);
|
||||||
assertThat(artifactManagement.count()).isEqualTo(1);
|
assertThat(artifactManagement.count()).isEqualTo(1);
|
||||||
|
|
||||||
mvc.perform(delete("/rest/v1/softwaremodules/{smId}", sm.getId())).andDo(MockMvcResultPrinter.print())
|
mvc.perform(delete("/rest/v1/softwaremodules/{smId}", sm.getId()))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
assertThat(softwareModuleManagement.findAll(PAGE)).as("After delete no softwarmodule should be available")
|
assertThat(softwareModuleManagement.findAll(PAGE)).as("After delete no softwarmodule should be available")
|
||||||
.isEmpty();
|
.isEmpty();
|
||||||
assertThat(artifactManagement.count()).isEqualTo(0);
|
assertThat(artifactManagement.count()).isZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies successfull deletion of a software module that is in use, i.e. assigned to a DS which should result in movinf the module to the archive.")
|
@Description("Verifies successfull deletion of a software module that is in use, i.e. assigned to a DS which should result in movinf the module to the archive.")
|
||||||
public void deleteAssignedSoftwareModule() throws Exception {
|
void deleteAssignedSoftwareModule() throws Exception {
|
||||||
final DistributionSet ds1 = testdataFactory.createDistributionSet("a");
|
final DistributionSet ds1 = testdataFactory.createDistributionSet("a");
|
||||||
|
|
||||||
final int artifactSize = 5 * 1024;
|
final int artifactSize = 5 * 1024;
|
||||||
@@ -969,8 +1030,8 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the deletion of an artifact including verfication that the artifact is actually erased in the repository and removed from the software module.")
|
@Description("Tests the deletion of an artifact including verification that the artifact is actually erased in the repository and removed from the software module.")
|
||||||
public void deleteArtifact() throws Exception {
|
void deleteArtifact() throws Exception {
|
||||||
// Create 1 SM
|
// Create 1 SM
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
@@ -978,10 +1039,10 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
|
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
|
||||||
|
|
||||||
// Create 2 artifacts
|
// Create 2 artifacts
|
||||||
final Artifact artifact = artifactManagement
|
final Artifact artifact = artifactManagement.create(
|
||||||
.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
|
new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
|
||||||
artifactManagement
|
artifactManagement.create(
|
||||||
.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file2", false, artifactSize));
|
new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file2", false, artifactSize));
|
||||||
|
|
||||||
// check repo before delete
|
// check repo before delete
|
||||||
assertThat(softwareModuleManagement.findAll(PAGE)).hasSize(1);
|
assertThat(softwareModuleManagement.findAll(PAGE)).hasSize(1);
|
||||||
@@ -991,7 +1052,8 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
// delete
|
// delete
|
||||||
mvc.perform(delete("/rest/v1/softwaremodules/{smId}/artifacts/{artId}", sm.getId(), artifact.getId()))
|
mvc.perform(delete("/rest/v1/softwaremodules/{smId}/artifacts/{artId}", sm.getId(), artifact.getId()))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
// check that only one artifact is still alive and still assigned
|
// check that only one artifact is still alive and still assigned
|
||||||
assertThat(softwareModuleManagement.findAll(PAGE)).as("After the sm should be marked as deleted").hasSize(1);
|
assertThat(softwareModuleManagement.findAll(PAGE)).as("After the sm should be marked as deleted").hasSize(1);
|
||||||
@@ -1002,8 +1064,8 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies the successful creation of metadata and the enforcement of the meta data quota.")
|
@Description("Verifies the successful creation of metadata and the enforcement of the meta data quota.")
|
||||||
public void createMetadata() throws Exception {
|
void createMetadata() throws Exception {
|
||||||
|
|
||||||
final String knownKey1 = "knownKey1";
|
final String knownKey1 = "knownKey1";
|
||||||
final String knownValue1 = "knownValue1";
|
final String knownValue1 = "knownValue1";
|
||||||
@@ -1020,18 +1082,17 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
.contentType(MediaType.APPLICATION_JSON).content(metaData1.toString()))
|
.contentType(MediaType.APPLICATION_JSON).content(metaData1.toString()))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("[0]key", equalTo(knownKey1))).andExpect(jsonPath("[0]value", equalTo(knownValue1)))
|
.andExpect(jsonPath("[0].key", equalTo(knownKey1)))
|
||||||
.andExpect(jsonPath("[0]targetVisible", equalTo(false)))
|
.andExpect(jsonPath("[0].value", equalTo(knownValue1)))
|
||||||
.andExpect(jsonPath("[1]key", equalTo(knownKey2))).andExpect(jsonPath("[1]value", equalTo(knownValue2)))
|
.andExpect(jsonPath("[0].targetVisible", equalTo(false)))
|
||||||
.andExpect(jsonPath("[1]targetVisible", equalTo(true)));
|
.andExpect(jsonPath("[1].key", equalTo(knownKey2)))
|
||||||
|
.andExpect(jsonPath("[1].value", equalTo(knownValue2)))
|
||||||
|
.andExpect(jsonPath("[1].targetVisible", equalTo(true)));
|
||||||
|
|
||||||
final SoftwareModuleMetadata metaKey1 = softwareModuleManagement
|
assertThat(softwareModuleManagement.getMetaDataBySoftwareModuleId(sm.getId(), knownKey1))
|
||||||
.getMetaDataBySoftwareModuleId(sm.getId(), knownKey1).get();
|
.as("Metadata key is wrong").get().extracting(SoftwareModuleMetadata::getValue).isEqualTo(knownValue1);
|
||||||
final SoftwareModuleMetadata metaKey2 = softwareModuleManagement
|
assertThat(softwareModuleManagement.getMetaDataBySoftwareModuleId(sm.getId(), knownKey2))
|
||||||
.getMetaDataBySoftwareModuleId(sm.getId(), knownKey2).get();
|
.as("Metadata key is wrong").get().extracting(SoftwareModuleMetadata::getValue).isEqualTo(knownValue2);
|
||||||
|
|
||||||
assertThat(metaKey1.getValue()).as("Metadata key is wrong").isEqualTo(knownValue1);
|
|
||||||
assertThat(metaKey2.getValue()).as("Metadata key is wrong").isEqualTo(knownValue2);
|
|
||||||
|
|
||||||
// verify quota enforcement
|
// verify quota enforcement
|
||||||
final int maxMetaData = quotaManagement.getMaxMetaDataEntriesPerSoftwareModule();
|
final int maxMetaData = quotaManagement.getMaxMetaDataEntriesPerSoftwareModule();
|
||||||
@@ -1054,8 +1115,8 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies the successfull update of metadata based on given key.")
|
@Description("Verifies the successful update of metadata based on given key.")
|
||||||
public void updateMetadata() throws Exception {
|
void updateMetadata() throws Exception {
|
||||||
// prepare and create metadata for update
|
// prepare and create metadata for update
|
||||||
final String knownKey = "knownKey";
|
final String knownKey = "knownKey";
|
||||||
final String knownValue = "knownValue";
|
final String knownValue = "knownValue";
|
||||||
@@ -1065,24 +1126,27 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
softwareModuleManagement.createMetaData(
|
softwareModuleManagement.createMetaData(
|
||||||
entityFactory.softwareModuleMetadata().create(sm.getId()).key(knownKey).value(knownValue));
|
entityFactory.softwareModuleMetadata().create(sm.getId()).key(knownKey).value(knownValue));
|
||||||
|
|
||||||
final JSONObject jsonObject = new JSONObject().put("key", knownKey).put("value", updateValue)
|
final JSONObject jsonObject = new JSONObject().put("key", knownKey)
|
||||||
|
.put("value", updateValue)
|
||||||
.put("targetVisible", true);
|
.put("targetVisible", true);
|
||||||
|
|
||||||
mvc.perform(put("/rest/v1/softwaremodules/{swId}/metadata/{key}", sm.getId(), knownKey)
|
mvc.perform(put("/rest/v1/softwaremodules/{swId}/metadata/{key}", sm.getId(), knownKey).accept(
|
||||||
.accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON)
|
MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON).content(jsonObject.toString()))
|
||||||
.content(jsonObject.toString())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("key", equalTo(knownKey))).andExpect(jsonPath("value", equalTo(updateValue)));
|
.andExpect(jsonPath("key", equalTo(knownKey)))
|
||||||
|
.andExpect(jsonPath("value", equalTo(updateValue)));
|
||||||
|
|
||||||
final SoftwareModuleMetadata assertDS = softwareModuleManagement
|
final SoftwareModuleMetadata assertDS = softwareModuleManagement.getMetaDataBySoftwareModuleId(sm.getId(),
|
||||||
.getMetaDataBySoftwareModuleId(sm.getId(), knownKey).get();
|
knownKey).get();
|
||||||
assertThat(assertDS.getValue()).as("Metadata is wrong").isEqualTo(updateValue);
|
assertThat(assertDS.getValue()).as("Metadata is wrong").isEqualTo(updateValue);
|
||||||
assertThat(assertDS.isTargetVisible()).as("target visible is wrong").isTrue();
|
assertThat(assertDS.isTargetVisible()).as("target visible is wrong").isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies the successfull deletion of metadata entry.")
|
@Description("Verifies the successful deletion of metadata entry.")
|
||||||
public void deleteMetadata() throws Exception {
|
void deleteMetadata() throws Exception {
|
||||||
// prepare and create metadata for deletion
|
// prepare and create metadata for deletion
|
||||||
final String knownKey = "knownKey";
|
final String knownKey = "knownKey";
|
||||||
final String knownValue = "knownValue";
|
final String knownValue = "knownValue";
|
||||||
@@ -1092,14 +1156,15 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
entityFactory.softwareModuleMetadata().create(sm.getId()).key(knownKey).value(knownValue));
|
entityFactory.softwareModuleMetadata().create(sm.getId()).key(knownKey).value(knownValue));
|
||||||
|
|
||||||
mvc.perform(delete("/rest/v1/softwaremodules/{swId}/metadata/{key}", sm.getId(), knownKey))
|
mvc.perform(delete("/rest/v1/softwaremodules/{swId}/metadata/{key}", sm.getId(), knownKey))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
assertThat(softwareModuleManagement.getMetaDataBySoftwareModuleId(sm.getId(), knownKey)).isNotPresent();
|
assertThat(softwareModuleManagement.getMetaDataBySoftwareModuleId(sm.getId(), knownKey)).isNotPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that module metadta deletion request to API on an entity that does not exist results in NOT_FOUND.")
|
@Description("Ensures that module metadata deletion request to API on an entity that does not exist results in NOT_FOUND.")
|
||||||
public void deleteModuleMetadataThatDoesNotExistLeadsToNotFound() throws Exception {
|
void deleteModuleMetadataThatDoesNotExistLeadsToNotFound() throws Exception {
|
||||||
// prepare and create metadata for deletion
|
// prepare and create metadata for deletion
|
||||||
final String knownKey = "knownKey";
|
final String knownKey = "knownKey";
|
||||||
final String knownValue = "knownValue";
|
final String knownValue = "knownValue";
|
||||||
@@ -1109,7 +1174,8 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
entityFactory.softwareModuleMetadata().create(sm.getId()).key(knownKey).value(knownValue));
|
entityFactory.softwareModuleMetadata().create(sm.getId()).key(knownKey).value(knownValue));
|
||||||
|
|
||||||
mvc.perform(delete("/rest/v1/softwaremodules/{swId}/metadata/XXX", sm.getId(), knownKey))
|
mvc.perform(delete("/rest/v1/softwaremodules/{swId}/metadata/XXX", sm.getId(), knownKey))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
mvc.perform(delete("/rest/v1/softwaremodules/1234/metadata/{key}", knownKey))
|
mvc.perform(delete("/rest/v1/softwaremodules/1234/metadata/{key}", knownKey))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||||
@@ -1119,22 +1185,25 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that module deletion request to API on an entity that does not exist results in NOT_FOUND.")
|
@Description("Ensures that module deletion request to API on an entity that does not exist results in NOT_FOUND.")
|
||||||
public void deleteSoftwareModuleThatDoesNotExistLeadsToNotFound() throws Exception {
|
void deleteSoftwareModuleThatDoesNotExistLeadsToNotFound() throws Exception {
|
||||||
mvc.perform(delete("/rest/v1/softwaremodules/1234")).andDo(MockMvcResultPrinter.print())
|
mvc.perform(delete("/rest/v1/softwaremodules/1234"))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies the successfull search of a metadata entry based on value.")
|
@Description("Verifies the successful search of a metadata entry based on value.")
|
||||||
public void searchSoftwareModuleMetadataRsql() throws Exception {
|
void searchSoftwareModuleMetadataRsql() throws Exception {
|
||||||
final int totalMetadata = 10;
|
final int totalMetadata = 10;
|
||||||
final String knownKeyPrefix = "knownKey";
|
final String knownKeyPrefix = "knownKey";
|
||||||
final String knownValuePrefix = "knownValue";
|
final String knownValuePrefix = "knownValue";
|
||||||
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
|
||||||
|
|
||||||
for (int index = 0; index < totalMetadata; index++) {
|
for (int index = 0; index < totalMetadata; index++) {
|
||||||
softwareModuleManagement.createMetaData(entityFactory.softwareModuleMetadata().create(sm.getId())
|
softwareModuleManagement.createMetaData(entityFactory.softwareModuleMetadata()
|
||||||
.key(knownKeyPrefix + index).value(knownValuePrefix + index));
|
.create(sm.getId())
|
||||||
|
.key(knownKeyPrefix + index)
|
||||||
|
.value(knownValuePrefix + index));
|
||||||
}
|
}
|
||||||
|
|
||||||
final String rsqlSearchValue1 = "value==knownValue1";
|
final String rsqlSearchValue1 = "value==knownValue1";
|
||||||
|
|||||||
@@ -25,25 +25,29 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.validation.ConstraintViolationException;
|
import javax.validation.ConstraintViolationException;
|
||||||
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.awaitility.Awaitility;
|
||||||
|
import org.awaitility.Duration;
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||||
import org.eclipse.hawkbit.repository.ActionFields;
|
import org.eclipse.hawkbit.repository.ActionFields;
|
||||||
|
import org.eclipse.hawkbit.repository.Identifiable;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
@@ -93,7 +97,7 @@ import io.qameta.allure.Story;
|
|||||||
*/
|
*/
|
||||||
@Feature("Component Tests - Management API")
|
@Feature("Component Tests - Management API")
|
||||||
@Story("Target Resource")
|
@Story("Target Resource")
|
||||||
public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
|
class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
|
||||||
|
|
||||||
private static final String TARGET_DESCRIPTION_TEST = "created in test";
|
private static final String TARGET_DESCRIPTION_TEST = "created in test";
|
||||||
|
|
||||||
@@ -127,8 +131,8 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
private JpaProperties jpaProperties;
|
private JpaProperties jpaProperties;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that actions list is in exptected order.")
|
@Description("Ensures that actions list is in expected order.")
|
||||||
public void getActionStatusReturnsCorrectType() throws Exception {
|
void getActionStatusReturnsCorrectType() throws Exception {
|
||||||
final int limitSize = 2;
|
final int limitSize = 2;
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
||||||
@@ -159,7 +163,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
@Description("Ensures that security token is not returned if user does not have READ_TARGET_SEC_TOKEN permission.")
|
@Description("Ensures that security token is not returned if user does not have READ_TARGET_SEC_TOKEN permission.")
|
||||||
@WithUser(allSpPermissions = false, authorities = { SpPermission.READ_TARGET, SpPermission.CREATE_TARGET })
|
@WithUser(allSpPermissions = false, authorities = { SpPermission.READ_TARGET, SpPermission.CREATE_TARGET })
|
||||||
public void securityTokenIsNotInResponseIfMissingPermission() throws Exception {
|
void securityTokenIsNotInResponseIfMissingPermission() throws Exception {
|
||||||
|
|
||||||
final String knownControllerId = "knownControllerId";
|
final String knownControllerId = "knownControllerId";
|
||||||
testdataFactory.createTarget(knownControllerId);
|
testdataFactory.createTarget(knownControllerId);
|
||||||
@@ -172,7 +176,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
@Description("Ensures that security token is returned if user does have READ_TARGET_SEC_TOKEN permission.")
|
@Description("Ensures that security token is returned if user does have READ_TARGET_SEC_TOKEN permission.")
|
||||||
@WithUser(allSpPermissions = false, authorities = { SpPermission.READ_TARGET, SpPermission.CREATE_TARGET,
|
@WithUser(allSpPermissions = false, authorities = { SpPermission.READ_TARGET, SpPermission.CREATE_TARGET,
|
||||||
SpPermission.READ_TARGET_SEC_TOKEN })
|
SpPermission.READ_TARGET_SEC_TOKEN })
|
||||||
public void securityTokenIsInResponseWithCorrectPermission() throws Exception {
|
void securityTokenIsInResponseWithCorrectPermission() throws Exception {
|
||||||
|
|
||||||
final String knownControllerId = "knownControllerId";
|
final String knownControllerId = "knownControllerId";
|
||||||
final Target createTarget = testdataFactory.createTarget(knownControllerId);
|
final Target createTarget = testdataFactory.createTarget(knownControllerId);
|
||||||
@@ -183,7 +187,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that that IP address is in result as stored in the repository.")
|
@Description("Ensures that that IP address is in result as stored in the repository.")
|
||||||
public void addressAndIpAddressInTargetResult() throws Exception {
|
void addressAndIpAddressInTargetResult() throws Exception {
|
||||||
// prepare targets with IP
|
// prepare targets with IP
|
||||||
final String knownControllerId1 = "0815";
|
final String knownControllerId1 = "0815";
|
||||||
final String knownControllerId2 = "4711";
|
final String knownControllerId2 = "4711";
|
||||||
@@ -212,13 +216,13 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that actions history is returned as defined by filter status==pending,status==finished.")
|
@Description("Ensures that actions history is returned as defined by filter status==pending,status==finished.")
|
||||||
public void searchActionsRsql() throws Exception {
|
void searchActionsRsql() throws Exception {
|
||||||
|
|
||||||
// prepare test
|
// prepare test
|
||||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||||
final Target createTarget = testdataFactory.createTarget("knownTargetId");
|
final Target createTarget = testdataFactory.createTarget("knownTargetId");
|
||||||
|
|
||||||
assignDistributionSet(dsA, Arrays.asList(createTarget));
|
assignDistributionSet(dsA, Collections.singletonList(createTarget));
|
||||||
|
|
||||||
final String rsqlPendingStatus = "status==pending";
|
final String rsqlPendingStatus = "status==pending";
|
||||||
final String rsqlFinishedStatus = "status==finished";
|
final String rsqlFinishedStatus = "status==finished";
|
||||||
@@ -243,8 +247,8 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a deletion of an active action results in cancelation triggered.")
|
@Description("Ensures that a deletion of an active action results in cancellation triggered.")
|
||||||
public void cancelActionOK() throws Exception {
|
void cancelActionOK() throws Exception {
|
||||||
// prepare test
|
// prepare test
|
||||||
final Target tA = createTargetAndStartAction();
|
final Target tA = createTargetAndStartAction();
|
||||||
|
|
||||||
@@ -269,8 +273,8 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that method not allowed is returned if cancelation is triggered on already canceled action.")
|
@Description("Ensures that method not allowed is returned if cancellation is triggered on already canceled action.")
|
||||||
public void cancelAndCancelActionIsNotAllowed() throws Exception {
|
void cancelAndCancelActionIsNotAllowed() throws Exception {
|
||||||
// prepare test
|
// prepare test
|
||||||
final Target tA = createTargetAndStartAction();
|
final Target tA = createTargetAndStartAction();
|
||||||
|
|
||||||
@@ -291,7 +295,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Force Quit an Action, which is already canceled. Expected Result is an HTTP response code 204.")
|
@Description("Force Quit an Action, which is already canceled. Expected Result is an HTTP response code 204.")
|
||||||
public void forceQuitAnCanceledActionReturnsOk() throws Exception {
|
void forceQuitAnCanceledActionReturnsOk() throws Exception {
|
||||||
|
|
||||||
final Target tA = createTargetAndStartAction();
|
final Target tA = createTargetAndStartAction();
|
||||||
|
|
||||||
@@ -305,7 +309,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
assertThat(cancelActions).hasSize(1);
|
assertThat(cancelActions).hasSize(1);
|
||||||
assertThat(cancelActions.get(0).isCancelingOrCanceled()).isTrue();
|
assertThat(cancelActions.get(0).isCancelingOrCanceled()).isTrue();
|
||||||
|
|
||||||
// test - force quit an canceled action should return 204
|
// test - force quit: Canceled actions should return 204
|
||||||
mvc.perform(delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}?force=true",
|
mvc.perform(delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}?force=true",
|
||||||
tA.getControllerId(), cancelActions.get(0).getId())).andDo(MockMvcResultPrinter.print())
|
tA.getControllerId(), cancelActions.get(0).getId())).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isNoContent());
|
.andExpect(status().isNoContent());
|
||||||
@@ -313,7 +317,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Force Quit an Action, which is not canceled. Expected Result is an HTTP response code 405.")
|
@Description("Force Quit an Action, which is not canceled. Expected Result is an HTTP response code 405.")
|
||||||
public void forceQuitAnNotCanceledActionReturnsMethodNotAllowed() throws Exception {
|
void forceQuitAnNotCanceledActionReturnsMethodNotAllowed() throws Exception {
|
||||||
|
|
||||||
final Target tA = createTargetAndStartAction();
|
final Target tA = createTargetAndStartAction();
|
||||||
|
|
||||||
@@ -327,7 +331,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that deletion is executed if permitted.")
|
@Description("Ensures that deletion is executed if permitted.")
|
||||||
public void deleteTargetReturnsOK() throws Exception {
|
void deleteTargetReturnsOK() throws Exception {
|
||||||
final String knownControllerId = "knownControllerIdDelete";
|
final String knownControllerId = "knownControllerIdDelete";
|
||||||
testdataFactory.createTarget(knownControllerId);
|
testdataFactory.createTarget(knownControllerId);
|
||||||
|
|
||||||
@@ -339,7 +343,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that deletion is refused with not found if target does not exist.")
|
@Description("Ensures that deletion is refused with not found if target does not exist.")
|
||||||
public void deleteTargetWhichDoesNotExistsLeadsToNotFound() throws Exception {
|
void deleteTargetWhichDoesNotExistsLeadsToNotFound() throws Exception {
|
||||||
final String knownControllerId = "knownControllerIdDelete";
|
final String knownControllerId = "knownControllerIdDelete";
|
||||||
|
|
||||||
mvc.perform(delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId))
|
mvc.perform(delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId))
|
||||||
@@ -348,7 +352,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that update is refused with not found if target does not exist.")
|
@Description("Ensures that update is refused with not found if target does not exist.")
|
||||||
public void updateTargetWhichDoesNotExistsLeadsToNotFound() throws Exception {
|
void updateTargetWhichDoesNotExistsLeadsToNotFound() throws Exception {
|
||||||
final String knownControllerId = "knownControllerIdUpdate";
|
final String knownControllerId = "knownControllerIdUpdate";
|
||||||
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content("{}")
|
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content("{}")
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||||
@@ -357,37 +361,37 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target update request is reflected by repository.")
|
@Description("Ensures that target update request is reflected by repository.")
|
||||||
public void updateTargetDescription() throws Exception {
|
void updateTargetDescription() throws Exception {
|
||||||
final String knownControllerId = "123";
|
final String knownControllerId = "123";
|
||||||
final String knownNewDescription = "a new desc updated over rest";
|
final String knownNewDescription = "a new desc updated over rest";
|
||||||
final String knownNameNotModiy = "nameNotModiy";
|
final String knownNameNotModify = "nameNotModify";
|
||||||
final String body = new JSONObject().put("description", knownNewDescription).toString();
|
final String body = new JSONObject().put("description", knownNewDescription).toString();
|
||||||
|
|
||||||
// prepare
|
// prepare
|
||||||
targetManagement.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModiy)
|
targetManagement.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModify)
|
||||||
.description("old description"));
|
.description("old description"));
|
||||||
|
|
||||||
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body)
|
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body)
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.controllerId", equalTo(knownControllerId)))
|
.andExpect(jsonPath("$.controllerId", equalTo(knownControllerId)))
|
||||||
.andExpect(jsonPath("$.description", equalTo(knownNewDescription)))
|
.andExpect(jsonPath("$.description", equalTo(knownNewDescription)))
|
||||||
.andExpect(jsonPath("$.name", equalTo(knownNameNotModiy)));
|
.andExpect(jsonPath("$.name", equalTo(knownNameNotModify)));
|
||||||
|
|
||||||
final Target findTargetByControllerID = targetManagement.getByControllerID(knownControllerId).get();
|
final Target findTargetByControllerID = targetManagement.getByControllerID(knownControllerId).get();
|
||||||
assertThat(findTargetByControllerID.getDescription()).isEqualTo(knownNewDescription);
|
assertThat(findTargetByControllerID.getDescription()).isEqualTo(knownNewDescription);
|
||||||
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy);
|
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModify);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target update request fails is updated value fails against a constraint.")
|
@Description("Ensures that target update request fails is updated value fails against a constraint.")
|
||||||
public void updateTargetDescriptionFailsIfInvalidLength() throws Exception {
|
void updateTargetDescriptionFailsIfInvalidLength() throws Exception {
|
||||||
final String knownControllerId = "123";
|
final String knownControllerId = "123";
|
||||||
final String knownNewDescription = RandomStringUtils.randomAlphabetic(513);
|
final String knownNewDescription = RandomStringUtils.randomAlphabetic(513);
|
||||||
final String knownNameNotModiy = "nameNotModiy";
|
final String knownNameNotModify = "nameNotModify";
|
||||||
final String body = new JSONObject().put("description", knownNewDescription).toString();
|
final String body = new JSONObject().put("description", knownNewDescription).toString();
|
||||||
|
|
||||||
// prepare
|
// prepare
|
||||||
targetManagement.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModiy)
|
targetManagement.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModify)
|
||||||
.description("old description"));
|
.description("old description"));
|
||||||
|
|
||||||
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body)
|
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body)
|
||||||
@@ -400,53 +404,53 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target update request is reflected by repository.")
|
@Description("Ensures that target update request is reflected by repository.")
|
||||||
public void updateTargetSecurityToken() throws Exception {
|
void updateTargetSecurityToken() throws Exception {
|
||||||
final String knownControllerId = "123";
|
final String knownControllerId = "123";
|
||||||
final String knownNewToken = "6567576565";
|
final String knownNewToken = "6567576565";
|
||||||
final String knownNameNotModiy = "nameNotModiy";
|
final String knownNameNotModify = "nameNotModify";
|
||||||
final String body = new JSONObject().put("securityToken", knownNewToken).toString();
|
final String body = new JSONObject().put("securityToken", knownNewToken).toString();
|
||||||
|
|
||||||
// prepare
|
// prepare
|
||||||
targetManagement
|
targetManagement
|
||||||
.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModiy));
|
.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModify));
|
||||||
|
|
||||||
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body)
|
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body)
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.controllerId", equalTo(knownControllerId)))
|
.andExpect(jsonPath("$.controllerId", equalTo(knownControllerId)))
|
||||||
.andExpect(jsonPath("$.securityToken", equalTo(knownNewToken)))
|
.andExpect(jsonPath("$.securityToken", equalTo(knownNewToken)))
|
||||||
.andExpect(jsonPath("$.name", equalTo(knownNameNotModiy)));
|
.andExpect(jsonPath("$.name", equalTo(knownNameNotModify)));
|
||||||
|
|
||||||
final Target findTargetByControllerID = targetManagement.getByControllerID(knownControllerId).get();
|
final Target findTargetByControllerID = targetManagement.getByControllerID(knownControllerId).get();
|
||||||
assertThat(findTargetByControllerID.getSecurityToken()).isEqualTo(knownNewToken);
|
assertThat(findTargetByControllerID.getSecurityToken()).isEqualTo(knownNewToken);
|
||||||
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy);
|
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModify);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target update request is reflected by repository.")
|
@Description("Ensures that target update request is reflected by repository.")
|
||||||
public void updateTargetAddress() throws Exception {
|
void updateTargetAddress() throws Exception {
|
||||||
final String knownControllerId = "123";
|
final String knownControllerId = "123";
|
||||||
final String knownNewAddress = "amqp://test123/foobar";
|
final String knownNewAddress = "amqp://test123/foobar";
|
||||||
final String knownNameNotModiy = "nameNotModiy";
|
final String knownNameNotModify = "nameNotModify";
|
||||||
final String body = new JSONObject().put("address", knownNewAddress).toString();
|
final String body = new JSONObject().put("address", knownNewAddress).toString();
|
||||||
|
|
||||||
// prepare
|
// prepare
|
||||||
targetManagement.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModiy)
|
targetManagement.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModify)
|
||||||
.address(knownNewAddress));
|
.address(knownNewAddress));
|
||||||
|
|
||||||
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body)
|
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body)
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.controllerId", equalTo(knownControllerId)))
|
.andExpect(jsonPath("$.controllerId", equalTo(knownControllerId)))
|
||||||
.andExpect(jsonPath("$.address", equalTo(knownNewAddress)))
|
.andExpect(jsonPath("$.address", equalTo(knownNewAddress)))
|
||||||
.andExpect(jsonPath("$.name", equalTo(knownNameNotModiy)));
|
.andExpect(jsonPath("$.name", equalTo(knownNameNotModify)));
|
||||||
|
|
||||||
final Target findTargetByControllerID = targetManagement.getByControllerID(knownControllerId).get();
|
final Target findTargetByControllerID = targetManagement.getByControllerID(knownControllerId).get();
|
||||||
assertThat(findTargetByControllerID.getAddress().toString()).isEqualTo(knownNewAddress);
|
assertThat(findTargetByControllerID.getAddress()).hasToString(knownNewAddress);
|
||||||
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy);
|
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModify);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target query returns list of targets in defined format.")
|
@Description("Ensures that target query returns list of targets in defined format.")
|
||||||
public void getTargetWithoutAddtionalRequestParameters() throws Exception {
|
void getTargetWithoutAdditionalRequestParameters() throws Exception {
|
||||||
final int knownTargetAmount = 3;
|
final int knownTargetAmount = 3;
|
||||||
final String idA = "a";
|
final String idA = "a";
|
||||||
final String idB = "b";
|
final String idB = "b";
|
||||||
@@ -489,7 +493,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target query returns list of targets in defined format in size reduced by given limit parameter.")
|
@Description("Ensures that target query returns list of targets in defined format in size reduced by given limit parameter.")
|
||||||
public void getTargetWithPagingLimitRequestParameter() throws Exception {
|
void getTargetWithPagingLimitRequestParameter() throws Exception {
|
||||||
final int knownTargetAmount = 3;
|
final int knownTargetAmount = 3;
|
||||||
final int limitSize = 1;
|
final int limitSize = 1;
|
||||||
createTargetsAlphabetical(knownTargetAmount);
|
createTargetsAlphabetical(knownTargetAmount);
|
||||||
@@ -514,7 +518,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target query returns list of targets in defined format in size reduced by given limit and offset parameter.")
|
@Description("Ensures that target query returns list of targets in defined format in size reduced by given limit and offset parameter.")
|
||||||
public void getTargetWithPagingLimitAndOffsetRequestParameter() throws Exception {
|
void getTargetWithPagingLimitAndOffsetRequestParameter() throws Exception {
|
||||||
final int knownTargetAmount = 5;
|
final int knownTargetAmount = 5;
|
||||||
final int offsetParam = 2;
|
final int offsetParam = 2;
|
||||||
final int expectedSize = knownTargetAmount - offsetParam;
|
final int expectedSize = knownTargetAmount - offsetParam;
|
||||||
@@ -559,7 +563,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the get request for a target works.")
|
@Description("Ensures that the get request for a target works.")
|
||||||
public void getSingleTarget() throws Exception {
|
void getSingleTarget() throws Exception {
|
||||||
// create first a target which can be retrieved by rest interface
|
// create first a target which can be retrieved by rest interface
|
||||||
final String knownControllerId = "1";
|
final String knownControllerId = "1";
|
||||||
final String knownName = "someName";
|
final String knownName = "someName";
|
||||||
@@ -583,7 +587,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target get request returns a not found if the target does not exits.")
|
@Description("Ensures that target get request returns a not found if the target does not exits.")
|
||||||
public void getSingleTargetNoExistsResponseNotFound() throws Exception {
|
void getSingleTargetNoExistsResponseNotFound() throws Exception {
|
||||||
|
|
||||||
final String targetIdNotExists = "bubu";
|
final String targetIdNotExists = "bubu";
|
||||||
|
|
||||||
@@ -600,7 +604,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that get request for asigned distribution sets returns no count if no distribution set has been assigned.")
|
@Description("Ensures that get request for asigned distribution sets returns no count if no distribution set has been assigned.")
|
||||||
public void getAssignedDistributionSetOfTargetIsEmpty() throws Exception {
|
void getAssignedDistributionSetOfTargetIsEmpty() throws Exception {
|
||||||
// create first a target which can be retrieved by rest interface
|
// create first a target which can be retrieved by rest interface
|
||||||
final String knownControllerId = "1";
|
final String knownControllerId = "1";
|
||||||
final String knownName = "someName";
|
final String knownName = "someName";
|
||||||
@@ -614,7 +618,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the get request for asigned distribution sets works.")
|
@Description("Ensures that the get request for asigned distribution sets works.")
|
||||||
public void getAssignedDistributionSetOfTarget() throws Exception {
|
void getAssignedDistributionSetOfTarget() throws Exception {
|
||||||
// create first a target which can be retrieved by rest interface
|
// create first a target which can be retrieved by rest interface
|
||||||
final String knownControllerId = "1";
|
final String knownControllerId = "1";
|
||||||
final String knownName = "someName";
|
final String knownName = "someName";
|
||||||
@@ -671,7 +675,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that get request for installed distribution sets returns no count if no distribution set has been installed.")
|
@Description("Ensures that get request for installed distribution sets returns no count if no distribution set has been installed.")
|
||||||
public void getInstalledDistributionSetOfTargetIsEmpty() throws Exception {
|
void getInstalledDistributionSetOfTargetIsEmpty() throws Exception {
|
||||||
// create first a target which can be retrieved by rest interface
|
// create first a target which can be retrieved by rest interface
|
||||||
final String knownControllerId = "1";
|
final String knownControllerId = "1";
|
||||||
final String knownName = "someName";
|
final String knownName = "someName";
|
||||||
@@ -683,12 +687,12 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a target creation with empty name and a controllerId that exceeds the name length limitation is successful and the name gets truncated.")
|
@Description("Ensures that a target creation with empty name and a controllerId that exceeds the name length limitation is successful and the name gets truncated.")
|
||||||
public void createTargetWithEmptyNameAndLongControllerId() throws Exception {
|
void createTargetWithEmptyNameAndLongControllerId() throws Exception {
|
||||||
final String randomString = RandomStringUtils.randomAlphanumeric(JpaTarget.CONTROLLER_ID_MAX_SIZE);
|
final String randomString = RandomStringUtils.randomAlphanumeric(JpaTarget.CONTROLLER_ID_MAX_SIZE);
|
||||||
|
|
||||||
final Target target = entityFactory.target().create().controllerId(randomString).build();
|
final Target target = entityFactory.target().create().controllerId(randomString).build();
|
||||||
|
|
||||||
final String targetList = JsonBuilder.targets(Arrays.asList(target), false);
|
final String targetList = JsonBuilder.targets(Collections.singletonList(target), false);
|
||||||
|
|
||||||
final String expectedTargetName = randomString.substring(0,
|
final String expectedTargetName = randomString.substring(0,
|
||||||
Math.min(JpaTarget.CONTROLLER_ID_MAX_SIZE, NamedEntity.NAME_MAX_SIZE));
|
Math.min(JpaTarget.CONTROLLER_ID_MAX_SIZE, NamedEntity.NAME_MAX_SIZE));
|
||||||
@@ -703,13 +707,13 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that post request for creating a target with no payload returns a bad request.")
|
@Description("Ensures that post request for creating a target with no payload returns a bad request.")
|
||||||
public void createTargetWithoutPayloadBadRequest() throws Exception {
|
void createTargetWithoutPayloadBadRequest() throws Exception {
|
||||||
|
|
||||||
final MvcResult mvcResult = mvc
|
final MvcResult mvcResult = mvc
|
||||||
.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING).contentType(MediaType.APPLICATION_JSON))
|
.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING).contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn();
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn();
|
||||||
|
|
||||||
assertThat(targetManagement.count()).isEqualTo(0);
|
assertThat(targetManagement.count()).isZero();
|
||||||
|
|
||||||
// verify response json exception message
|
// verify response json exception message
|
||||||
final ExceptionInfo exceptionInfo = ResourceUtility
|
final ExceptionInfo exceptionInfo = ResourceUtility
|
||||||
@@ -720,7 +724,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that post request for creating a target with invalid payload returns a bad request.")
|
@Description("Ensures that post request for creating a target with invalid payload returns a bad request.")
|
||||||
public void createTargetWithBadPayloadBadRequest() throws Exception {
|
void createTargetWithBadPayloadBadRequest() throws Exception {
|
||||||
final String notJson = "abc";
|
final String notJson = "abc";
|
||||||
|
|
||||||
final MvcResult mvcResult = mvc
|
final MvcResult mvcResult = mvc
|
||||||
@@ -728,7 +732,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn();
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn();
|
||||||
|
|
||||||
assertThat(targetManagement.count()).isEqualTo(0);
|
assertThat(targetManagement.count()).isZero();
|
||||||
|
|
||||||
// verify response json exception message
|
// verify response json exception message
|
||||||
final ExceptionInfo exceptionInfo = ResourceUtility
|
final ExceptionInfo exceptionInfo = ResourceUtility
|
||||||
@@ -738,14 +742,14 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that a mandatory properties of new targets are validated as not null.")
|
@Description("Verifies that a mandatory properties of new targets are validated as not null.")
|
||||||
public void createTargetWithMissingMandatoryPropertyBadRequest() throws Exception {
|
void createTargetWithMissingMandatoryPropertyBadRequest() throws Exception {
|
||||||
final MvcResult mvcResult = mvc
|
final MvcResult mvcResult = mvc
|
||||||
.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING).content("[{\"name\":\"id1\"}]")
|
.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING).content("[{\"name\":\"id1\"}]")
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn();
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn();
|
||||||
|
|
||||||
assertThat(targetManagement.count()).isEqualTo(0);
|
assertThat(targetManagement.count()).isZero();
|
||||||
|
|
||||||
// verify response json exception message
|
// verify response json exception message
|
||||||
final ExceptionInfo exceptionInfo = ResourceUtility
|
final ExceptionInfo exceptionInfo = ResourceUtility
|
||||||
@@ -756,15 +760,16 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that a properties of new targets are validated as in allowed size range.")
|
@Description("Verfies that a properties of new targets are validated as in allowed size range.")
|
||||||
public void createTargetWithInvalidPropertyBadRequest() throws Exception {
|
void createTargetWithInvalidPropertyBadRequest() throws Exception {
|
||||||
final Target test1 = entityFactory.target().create().controllerId("id1")
|
final Target test1 = entityFactory.target().create().controllerId("id1")
|
||||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1)).build();
|
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1)).build();
|
||||||
|
|
||||||
final MvcResult mvcResult = mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING)
|
final MvcResult mvcResult = mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING)
|
||||||
.content(JsonBuilder.targets(Arrays.asList(test1), true)).contentType(MediaType.APPLICATION_JSON))
|
.content(JsonBuilder.targets(Collections.singletonList(test1), true))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn();
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn();
|
||||||
|
|
||||||
assertThat(targetManagement.count()).isEqualTo(0);
|
assertThat(targetManagement.count()).isZero();
|
||||||
|
|
||||||
// verify response json exception message
|
// verify response json exception message
|
||||||
final ExceptionInfo exceptionInfo = ResourceUtility
|
final ExceptionInfo exceptionInfo = ResourceUtility
|
||||||
@@ -775,7 +780,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a post request for creating multiple targets works.")
|
@Description("Ensures that a post request for creating multiple targets works.")
|
||||||
public void createTargetsListReturnsSuccessful() throws Exception {
|
void createTargetsListReturnsSuccessful() throws Exception {
|
||||||
final Target test1 = entityFactory.target().create().controllerId("id1").name("testname1")
|
final Target test1 = entityFactory.target().create().controllerId("id1").name("testname1")
|
||||||
.securityToken("token").address("amqp://test123/foobar").description("testid1").build();
|
.securityToken("token").address("amqp://test123/foobar").description("testid1").build();
|
||||||
final Target test2 = entityFactory.target().create().controllerId("id2").name("testname2")
|
final Target test2 = entityFactory.target().create().controllerId("id2").name("testname2")
|
||||||
@@ -810,32 +815,35 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
.andExpect(jsonPath("[2].createdBy", equalTo("bumlux"))).andReturn();
|
.andExpect(jsonPath("[2].createdBy", equalTo("bumlux"))).andReturn();
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
JsonPath.compile("[0]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
JsonPath.compile("[0]._links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
||||||
.isEqualTo("http://localhost/rest/v1/targets/id1");
|
.isEqualTo("http://localhost/rest/v1/targets/id1");
|
||||||
assertThat(
|
assertThat(
|
||||||
JsonPath.compile("[1]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
JsonPath.compile("[1]._links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
||||||
.isEqualTo("http://localhost/rest/v1/targets/id2");
|
.isEqualTo("http://localhost/rest/v1/targets/id2");
|
||||||
assertThat(
|
assertThat(
|
||||||
JsonPath.compile("[2]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
JsonPath.compile("[2]._links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
||||||
.isEqualTo("http://localhost/rest/v1/targets/id3");
|
.isEqualTo("http://localhost/rest/v1/targets/id3");
|
||||||
|
|
||||||
assertThat(targetManagement.getByControllerID("id1")).isNotNull();
|
final Target t1 = assertTarget("id1", "testname1", "testid1");
|
||||||
assertThat(targetManagement.getByControllerID("id1").get().getName()).isEqualTo("testname1");
|
assertThat(t1.getSecurityToken()).isEqualTo("token");
|
||||||
assertThat(targetManagement.getByControllerID("id1").get().getDescription()).isEqualTo("testid1");
|
assertThat(t1.getAddress()).hasToString("amqp://test123/foobar");
|
||||||
assertThat(targetManagement.getByControllerID("id1").get().getSecurityToken()).isEqualTo("token");
|
|
||||||
assertThat(targetManagement.getByControllerID("id1").get().getAddress().toString())
|
assertTarget("id2", "testname2", "testid2");
|
||||||
.isEqualTo("amqp://test123/foobar");
|
assertTarget("id3", "testname3", "testid3");
|
||||||
assertThat(targetManagement.getByControllerID("id2")).isNotNull();
|
}
|
||||||
assertThat(targetManagement.getByControllerID("id2").get().getName()).isEqualTo("testname2");
|
|
||||||
assertThat(targetManagement.getByControllerID("id2").get().getDescription()).isEqualTo("testid2");
|
private Target assertTarget(final String controllerId, final String name, final String description) {
|
||||||
assertThat(targetManagement.getByControllerID("id3")).isNotNull();
|
final Optional<Target> target1 = targetManagement.getByControllerID(controllerId);
|
||||||
assertThat(targetManagement.getByControllerID("id3").get().getName()).isEqualTo("testname3");
|
assertThat(target1).isPresent();
|
||||||
assertThat(targetManagement.getByControllerID("id3").get().getDescription()).isEqualTo("testid3");
|
final Target t = target1.get();
|
||||||
|
assertThat(t.getName()).isEqualTo(name);
|
||||||
|
assertThat(t.getDescription()).isEqualTo(description);
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a post request for creating one target within a list works.")
|
@Description("Ensures that a post request for creating one target within a list works.")
|
||||||
public void createTargetsSingleEntryListReturnsSuccessful() throws Exception {
|
void createTargetsSingleEntryListReturnsSuccessful() throws Exception {
|
||||||
final String knownName = "someName";
|
final String knownName = "someName";
|
||||||
final String knownControllerId = "controllerId1";
|
final String knownControllerId = "controllerId1";
|
||||||
final String knownDescription = "someDescription";
|
final String knownDescription = "someDescription";
|
||||||
@@ -855,7 +863,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a post request for creating the same target again leads to a conflict response.")
|
@Description("Ensures that a post request for creating the same target again leads to a conflict response.")
|
||||||
public void createTargetsSingleEntryListDoubleReturnConflict() throws Exception {
|
void createTargetsSingleEntryListDoubleReturnConflict() throws Exception {
|
||||||
final String knownName = "someName";
|
final String knownName = "someName";
|
||||||
final String knownControllerId = "controllerId1";
|
final String knownControllerId = "controllerId1";
|
||||||
final String knownDescription = "someDescription";
|
final String knownDescription = "someDescription";
|
||||||
@@ -885,7 +893,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the get request for action of a target returns no actions if nothing has happened.")
|
@Description("Ensures that the get request for action of a target returns no actions if nothing has happened.")
|
||||||
public void getActionWithEmptyResult() throws Exception {
|
void getActionWithEmptyResult() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
testdataFactory.createTarget(knownTargetId);
|
testdataFactory.createTarget(knownTargetId);
|
||||||
|
|
||||||
@@ -897,7 +905,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the expected response is returned for update action.")
|
@Description("Ensures that the expected response is returned for update action.")
|
||||||
public void getUpdateAction() throws Exception {
|
void getUpdateAction() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
||||||
|
|
||||||
@@ -918,7 +926,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the expected response is returned for update action with maintenance window.")
|
@Description("Ensures that the expected response is returned for update action with maintenance window.")
|
||||||
public void getUpdateActionWithMaintenanceWindow() throws Exception {
|
void getUpdateActionWithMaintenanceWindow() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final String schedule = getTestSchedule(10);
|
final String schedule = getTestSchedule(10);
|
||||||
final String duration = getTestDuration(10);
|
final String duration = getTestDuration(10);
|
||||||
@@ -947,7 +955,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the expected response is returned when update action was cancelled.")
|
@Description("Ensures that the expected response is returned when update action was cancelled.")
|
||||||
public void getCancelAction() throws Exception {
|
void getCancelAction() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
||||||
|
|
||||||
@@ -968,7 +976,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the expected response is returned when update action with maintenance window was cancelled.")
|
@Description("Ensures that the expected response is returned when update action with maintenance window was cancelled.")
|
||||||
public void getCancelActionWithMaintenanceWindow() throws Exception {
|
void getCancelActionWithMaintenanceWindow() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final String schedule = getTestSchedule(10);
|
final String schedule = getTestSchedule(10);
|
||||||
final String duration = getTestDuration(10);
|
final String duration = getTestDuration(10);
|
||||||
@@ -997,7 +1005,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the expected response of geting actions of a target is returned.")
|
@Description("Ensures that the expected response of geting actions of a target is returned.")
|
||||||
public void getMultipleActions() throws Exception {
|
void getMultipleActions() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
||||||
|
|
||||||
@@ -1021,7 +1029,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the expected response of getting actions with maintenance window of a target is returned.")
|
@Description("Ensures that the expected response of getting actions with maintenance window of a target is returned.")
|
||||||
public void getMultipleActionsWithMaintenanceWindow() throws Exception {
|
void getMultipleActionsWithMaintenanceWindow() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final String schedule = getTestSchedule(10);
|
final String schedule = getTestSchedule(10);
|
||||||
final String duration = getTestDuration(10);
|
final String duration = getTestDuration(10);
|
||||||
@@ -1059,7 +1067,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that the API returns the status list with expected content.")
|
@Description("Verifies that the API returns the status list with expected content.")
|
||||||
public void getMultipleActionStatus() throws Exception {
|
void getMultipleActionStatus() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final Action action = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId).get(0);
|
final Action action = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId).get(0);
|
||||||
// retrieve list in default descending order for actionstaus entries
|
// retrieve list in default descending order for actionstaus entries
|
||||||
@@ -1087,11 +1095,11 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that the API returns the status list with expected content sorted by reportedAt field.")
|
@Description("Verifies that the API returns the status list with expected content sorted by reportedAt field.")
|
||||||
public void getMultipleActionStatusSortedByReportedAt() throws Exception {
|
void getMultipleActionStatusSortedByReportedAt() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final Action action = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId).get(0);
|
final Action action = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId).get(0);
|
||||||
final List<ActionStatus> actionStatus = deploymentManagement.findActionStatusByAction(PAGE, action.getId())
|
final List<ActionStatus> actionStatus = deploymentManagement.findActionStatusByAction(PAGE, action.getId())
|
||||||
.getContent().stream().sorted((e1, e2) -> Long.compare(e1.getId(), e2.getId()))
|
.getContent().stream().sorted(Comparator.comparingLong(Identifiable::getId))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// descending order
|
// descending order
|
||||||
@@ -1133,7 +1141,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies that the API returns the status list with expected content split into two pages.")
|
@Description("Verifies that the API returns the status list with expected content split into two pages.")
|
||||||
public void getMultipleActionStatusWithPagingLimitRequestParameter() throws Exception {
|
void getMultipleActionStatusWithPagingLimitRequestParameter() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
|
|
||||||
final Action action = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId).get(0);
|
final Action action = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId).get(0);
|
||||||
@@ -1173,7 +1181,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies getting multiple actions with the paging request parameter.")
|
@Description("Verifies getting multiple actions with the paging request parameter.")
|
||||||
public void getMultipleActionsWithPagingLimitRequestParameter() throws Exception {
|
void getMultipleActionsWithPagingLimitRequestParameter() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
||||||
|
|
||||||
@@ -1230,13 +1238,12 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
+ "?offset=0&limit=50&sort=id:DESC";
|
+ "?offset=0&limit=50&sort=id:DESC";
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId)
|
private List<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) {
|
||||||
throws InterruptedException {
|
|
||||||
return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null);
|
return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Action> generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(final String knownTargetId,
|
private List<Action> generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(final String knownTargetId,
|
||||||
final String schedule, final String duration, final String timezone) throws InterruptedException {
|
final String schedule, final String duration, final String timezone) {
|
||||||
final Target target = testdataFactory.createTarget(knownTargetId);
|
final Target target = testdataFactory.createTarget(knownTargetId);
|
||||||
|
|
||||||
final Iterator<DistributionSet> sets = testdataFactory.createDistributionSets(2).iterator();
|
final Iterator<DistributionSet> sets = testdataFactory.createDistributionSets(2).iterator();
|
||||||
@@ -1245,11 +1252,14 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
// Update
|
// Update
|
||||||
if (schedule == null) {
|
if (schedule == null) {
|
||||||
final List<Target> updatedTargets = assignDistributionSet(one, Arrays.asList(target)).getAssignedEntity()
|
final List<Target> updatedTargets = assignDistributionSet(one, Collections.singletonList(target))
|
||||||
|
.getAssignedEntity()
|
||||||
.stream().map(Action::getTarget).collect(Collectors.toList());
|
.stream().map(Action::getTarget).collect(Collectors.toList());
|
||||||
// 2nd update
|
// 2nd update
|
||||||
// sleep 10ms to ensure that we can sort by reportedAt
|
// sleep 10ms to ensure that we can sort by reportedAt
|
||||||
Thread.sleep(10);
|
Awaitility.await().atMost(Duration.ONE_HUNDRED_MILLISECONDS).atLeast(5, TimeUnit.MILLISECONDS)
|
||||||
|
.pollInterval(10, TimeUnit.MILLISECONDS)
|
||||||
|
.until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L));
|
||||||
assignDistributionSet(two, updatedTargets);
|
assignDistributionSet(two, updatedTargets);
|
||||||
} else {
|
} else {
|
||||||
final List<Target> updatedTargets = assignDistributionSetWithMaintenanceWindow(one.getId(),
|
final List<Target> updatedTargets = assignDistributionSetWithMaintenanceWindow(one.getId(),
|
||||||
@@ -1257,7 +1267,9 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
.map(Action::getTarget).collect(Collectors.toList());
|
.map(Action::getTarget).collect(Collectors.toList());
|
||||||
// 2nd update
|
// 2nd update
|
||||||
// sleep 10ms to ensure that we can sort by reportedAt
|
// sleep 10ms to ensure that we can sort by reportedAt
|
||||||
Thread.sleep(10);
|
Awaitility.await().atMost(Duration.ONE_HUNDRED_MILLISECONDS).atLeast(5, TimeUnit.MILLISECONDS)
|
||||||
|
.pollInterval(10, TimeUnit.MILLISECONDS)
|
||||||
|
.until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L));
|
||||||
assignDistributionSetWithMaintenanceWindow(two.getId(), updatedTargets.get(0).getControllerId(), schedule,
|
assignDistributionSetWithMaintenanceWindow(two.getId(), updatedTargets.get(0).getControllerId(), schedule,
|
||||||
duration, timezone);
|
duration, timezone);
|
||||||
}
|
}
|
||||||
@@ -1272,7 +1284,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that an action is switched from soft to forced if requested by management API")
|
@Description("Verfies that an action is switched from soft to forced if requested by management API")
|
||||||
public void updateAction() throws Exception {
|
void updateAction() throws Exception {
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet();
|
final DistributionSet set = testdataFactory.createDistributionSet();
|
||||||
final Long actionId = getFirstAssignedActionId(
|
final Long actionId = getFirstAssignedActionId(
|
||||||
@@ -1299,7 +1311,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verfies that a DS to target assignment is reflected by the repository and that repeating "
|
@Description("Verfies that a DS to target assignment is reflected by the repository and that repeating "
|
||||||
+ "the assignment does not change the target.")
|
+ "the assignment does not change the target.")
|
||||||
public void assignDistributionSetToTarget() throws Exception {
|
void assignDistributionSetToTarget() throws Exception {
|
||||||
|
|
||||||
Target target = testdataFactory.createTarget();
|
Target target = testdataFactory.createTarget();
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||||
@@ -1326,7 +1338,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that a DOWNLOAD_ONLY DS to target assignment is properly handled")
|
@Description("Verfies that a DOWNLOAD_ONLY DS to target assignment is properly handled")
|
||||||
public void assignDownloadOnlyDistributionSetToTarget() throws Exception {
|
void assignDownloadOnlyDistributionSetToTarget() throws Exception {
|
||||||
|
|
||||||
final Target target = testdataFactory.createTarget();
|
final Target target = testdataFactory.createTarget();
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||||
@@ -1339,15 +1351,14 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get()).isEqualTo(set);
|
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get()).isEqualTo(set);
|
||||||
final Slice<Action> actions = deploymentManagement.findActionsByTarget("targetExist", PageRequest.of(0, 100));
|
final Slice<Action> actions = deploymentManagement.findActionsByTarget("targetExist", PageRequest.of(0, 100));
|
||||||
assertThat(actions.getSize()).isGreaterThan(0);
|
assertThat(actions).isNotEmpty().filteredOn(a -> a.getDistributionSet().equals(set))
|
||||||
actions.stream().filter(a -> a.getDistributionSet().equals(set))
|
.extracting(Action::getActionType).containsOnly(ActionType.DOWNLOAD_ONLY);
|
||||||
.forEach(a -> ActionType.DOWNLOAD_ONLY.equals(a.getActionType()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that an offline DS to target assignment is reflected by the repository and that repeating "
|
@Description("Verfies that an offline DS to target assignment is reflected by the repository and that repeating "
|
||||||
+ "the assignment does not change the target.")
|
+ "the assignment does not change the target.")
|
||||||
public void offlineAssignDistributionSetToTarget() throws Exception {
|
void offlineAssignDistributionSetToTarget() throws Exception {
|
||||||
|
|
||||||
Target target = testdataFactory.createTarget();
|
Target target = testdataFactory.createTarget();
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||||
@@ -1377,7 +1388,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void assignDistributionSetToTargetWithActionTimeForcedAndTime() throws Exception {
|
void assignDistributionSetToTargetWithActionTimeForcedAndTime() throws Exception {
|
||||||
|
|
||||||
final Target target = testdataFactory.createTarget("fsdfsd");
|
final Target target = testdataFactory.createTarget("fsdfsd");
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||||
@@ -1400,7 +1411,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Assigns distribution set to target with only maintenance schedule.")
|
@Description("Assigns distribution set to target with only maintenance schedule.")
|
||||||
public void assignDistributionSetToTargetWithMaintenanceWindowStartTimeOnly() throws Exception {
|
void assignDistributionSetToTargetWithMaintenanceWindowStartTimeOnly() throws Exception {
|
||||||
|
|
||||||
final Target target = testdataFactory.createTarget("fsdfsd");
|
final Target target = testdataFactory.createTarget("fsdfsd");
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||||
@@ -1415,7 +1426,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Assigns distribution set to target with only maintenance window duration.")
|
@Description("Assigns distribution set to target with only maintenance window duration.")
|
||||||
public void assignDistributionSetToTargetWithMaintenanceWindowEndTimeOnly() throws Exception {
|
void assignDistributionSetToTargetWithMaintenanceWindowEndTimeOnly() throws Exception {
|
||||||
|
|
||||||
final Target target = testdataFactory.createTarget("fsdfsd");
|
final Target target = testdataFactory.createTarget("fsdfsd");
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||||
@@ -1430,7 +1441,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Assigns distribution set to target with valid maintenance window.")
|
@Description("Assigns distribution set to target with valid maintenance window.")
|
||||||
public void assignDistributionSetToTargetWithValidMaintenanceWindow() throws Exception {
|
void assignDistributionSetToTargetWithValidMaintenanceWindow() throws Exception {
|
||||||
|
|
||||||
final Target target = testdataFactory.createTarget("fsdfsd");
|
final Target target = testdataFactory.createTarget("fsdfsd");
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||||
@@ -1447,7 +1458,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Assigns distribution set to target with maintenance window next execution start (should be ignored, calculated automaticaly based on schedule, duration and timezone)")
|
@Description("Assigns distribution set to target with maintenance window next execution start (should be ignored, calculated automaticaly based on schedule, duration and timezone)")
|
||||||
public void assignDistributionSetToTargetWithMaintenanceWindowNextExecutionStart() throws Exception {
|
void assignDistributionSetToTargetWithMaintenanceWindowNextExecutionStart() throws Exception {
|
||||||
|
|
||||||
final Target target = testdataFactory.createTarget("fsdfsd");
|
final Target target = testdataFactory.createTarget("fsdfsd");
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||||
@@ -1469,7 +1480,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Assigns distribution set to target with last maintenance window scheduled before current time.")
|
@Description("Assigns distribution set to target with last maintenance window scheduled before current time.")
|
||||||
public void assignDistributionSetToTargetWithMaintenanceWindowEndTimeBeforeStartTime() throws Exception {
|
void assignDistributionSetToTargetWithMaintenanceWindowEndTimeBeforeStartTime() throws Exception {
|
||||||
|
|
||||||
final Target target = testdataFactory.createTarget("fsdfsd");
|
final Target target = testdataFactory.createTarget("fsdfsd");
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||||
@@ -1485,7 +1496,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void invalidRequestsOnAssignDistributionSetToTarget() throws Exception {
|
void invalidRequestsOnAssignDistributionSetToTarget() throws Exception {
|
||||||
|
|
||||||
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
final DistributionSet set = testdataFactory.createDistributionSet("one");
|
||||||
|
|
||||||
@@ -1514,7 +1525,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void invalidRequestsOnActionResource() throws Exception {
|
void invalidRequestsOnActionResource() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
|
|
||||||
// target does not exist
|
// target does not exist
|
||||||
@@ -1546,7 +1557,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void invalidRequestsOnActionStatusResource() throws Exception {
|
void invalidRequestsOnActionStatusResource() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
|
|
||||||
// target does not exist
|
// target does not exist
|
||||||
@@ -1579,7 +1590,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getControllerAttributesViaTargetResourceReturnsAttributesWithOk() throws Exception {
|
void getControllerAttributesViaTargetResourceReturnsAttributesWithOk() throws Exception {
|
||||||
// create target with attributes
|
// create target with attributes
|
||||||
final String knownTargetId = "targetIdWithAttributes";
|
final String knownTargetId = "targetIdWithAttributes";
|
||||||
final Map<String, String> knownControllerAttrs = new HashMap<>();
|
final Map<String, String> knownControllerAttrs = new HashMap<>();
|
||||||
@@ -1595,7 +1606,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getControllerEmptyAttributesReturnsNoContent() throws Exception {
|
void getControllerEmptyAttributesReturnsNoContent() throws Exception {
|
||||||
// create target with attributes
|
// create target with attributes
|
||||||
final String knownTargetId = "targetIdWithAttributes";
|
final String knownTargetId = "targetIdWithAttributes";
|
||||||
testdataFactory.createTarget(knownTargetId);
|
testdataFactory.createTarget(knownTargetId);
|
||||||
@@ -1607,7 +1618,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Request update of Controller Attributes.")
|
@Description("Request update of Controller Attributes.")
|
||||||
public void triggerControllerAttributesUpdate() throws Exception {
|
void triggerControllerAttributesUpdate() throws Exception {
|
||||||
// create target with attributes
|
// create target with attributes
|
||||||
final String knownTargetId = "targetIdNeedsUpdate";
|
final String knownTargetId = "targetIdNeedsUpdate";
|
||||||
final Map<String, String> knownControllerAttrs = new HashMap<>();
|
final Map<String, String> knownControllerAttrs = new HashMap<>();
|
||||||
@@ -1656,7 +1667,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void searchTargetsUsingRsqlQuery() throws Exception {
|
void searchTargetsUsingRsqlQuery() throws Exception {
|
||||||
final int amountTargets = 10;
|
final int amountTargets = 10;
|
||||||
createTargetsAlphabetical(amountTargets);
|
createTargetsAlphabetical(amountTargets);
|
||||||
|
|
||||||
@@ -1686,7 +1697,6 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
*
|
*
|
||||||
* @param amount
|
* @param amount
|
||||||
* The number of targets to create
|
* The number of targets to create
|
||||||
* @throws URISyntaxException
|
|
||||||
*/
|
*/
|
||||||
private void createTargetsAlphabetical(final int amount) {
|
private void createTargetsAlphabetical(final int amount) {
|
||||||
char character = 'a';
|
char character = 'a';
|
||||||
@@ -1717,7 +1727,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that the metadata creation through API is reflected by the repository.")
|
@Description("Ensures that the metadata creation through API is reflected by the repository.")
|
||||||
public void createMetadata() throws Exception {
|
void createMetadata() throws Exception {
|
||||||
final String knownControllerId = "targetIdWithMetadata";
|
final String knownControllerId = "targetIdWithMetadata";
|
||||||
testdataFactory.createTarget(knownControllerId);
|
testdataFactory.createTarget(knownControllerId);
|
||||||
|
|
||||||
@@ -1735,9 +1745,10 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
.contentType(MediaType.APPLICATION_JSON).content(metaData1.toString()))
|
.contentType(MediaType.APPLICATION_JSON).content(metaData1.toString()))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
.andExpect(jsonPath("[0]key", equalTo(knownKey1))).andExpect(jsonPath("[0]value", equalTo(knownValue1)))
|
.andExpect(jsonPath("[0].key", equalTo(knownKey1)))
|
||||||
.andExpect(jsonPath("[1]key", equalTo(knownKey2)))
|
.andExpect(jsonPath("[0].value", equalTo(knownValue1)))
|
||||||
.andExpect(jsonPath("[1]value", equalTo(knownValue2)));
|
.andExpect(jsonPath("[1].key", equalTo(knownKey2)))
|
||||||
|
.andExpect(jsonPath("[1].value", equalTo(knownValue2)));
|
||||||
|
|
||||||
final TargetMetadata metaKey1 = targetManagement.getMetaDataByControllerId(knownControllerId, knownKey1).get();
|
final TargetMetadata metaKey1 = targetManagement.getMetaDataByControllerId(knownControllerId, knownKey1).get();
|
||||||
final TargetMetadata metaKey2 = targetManagement.getMetaDataByControllerId(knownControllerId, knownKey2).get();
|
final TargetMetadata metaKey2 = targetManagement.getMetaDataByControllerId(knownControllerId, knownKey2).get();
|
||||||
@@ -1766,7 +1777,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a metadata update through API is reflected by the repository.")
|
@Description("Ensures that a metadata update through API is reflected by the repository.")
|
||||||
public void updateMetadata() throws Exception {
|
void updateMetadata() throws Exception {
|
||||||
final String knownControllerId = "targetIdWithMetadata";
|
final String knownControllerId = "targetIdWithMetadata";
|
||||||
|
|
||||||
// prepare and create metadata for update
|
// prepare and create metadata for update
|
||||||
@@ -1799,7 +1810,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a metadata entry deletion through API is reflected by the repository.")
|
@Description("Ensures that a metadata entry deletion through API is reflected by the repository.")
|
||||||
public void deleteMetadata() throws Exception {
|
void deleteMetadata() throws Exception {
|
||||||
final String knownControllerId = "targetIdWithMetadata";
|
final String knownControllerId = "targetIdWithMetadata";
|
||||||
|
|
||||||
// prepare and create metadata for deletion
|
// prepare and create metadata for deletion
|
||||||
@@ -1816,7 +1827,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target metadata deletion request to API on an entity that does not exist results in NOT_FOUND.")
|
@Description("Ensures that target metadata deletion request to API on an entity that does not exist results in NOT_FOUND.")
|
||||||
public void deleteMetadataThatDoesNotExistLeadsToNotFound() throws Exception {
|
void deleteMetadataThatDoesNotExistLeadsToNotFound() throws Exception {
|
||||||
final String knownControllerId = "targetIdWithMetadata";
|
final String knownControllerId = "targetIdWithMetadata";
|
||||||
|
|
||||||
// prepare and create metadata for deletion
|
// prepare and create metadata for deletion
|
||||||
@@ -1836,7 +1847,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a metadata entry selection through API reflectes the repository content.")
|
@Description("Ensures that a metadata entry selection through API reflectes the repository content.")
|
||||||
public void getSingleMetadata() throws Exception {
|
void getSingleMetadata() throws Exception {
|
||||||
final String knownControllerId = "targetIdWithMetadata";
|
final String knownControllerId = "targetIdWithMetadata";
|
||||||
|
|
||||||
// prepare and create metadata for deletion
|
// prepare and create metadata for deletion
|
||||||
@@ -1852,7 +1863,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a metadata entry paged list selection through API reflectes the repository content.")
|
@Description("Ensures that a metadata entry paged list selection through API reflectes the repository content.")
|
||||||
public void getPagedListOfMetadata() throws Exception {
|
void getPagedListOfMetadata() throws Exception {
|
||||||
final String knownControllerId = "targetIdWithMetadata";
|
final String knownControllerId = "targetIdWithMetadata";
|
||||||
|
|
||||||
final int totalMetadata = 10;
|
final int totalMetadata = 10;
|
||||||
@@ -1885,7 +1896,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a target metadata filtered query with value==knownValue1 parameter returns only the metadata entries with that value.")
|
@Description("Ensures that a target metadata filtered query with value==knownValue1 parameter returns only the metadata entries with that value.")
|
||||||
public void searchDistributionSetMetadataRsql() throws Exception {
|
void searchDistributionSetMetadataRsql() throws Exception {
|
||||||
final String knownControllerId = "targetIdWithMetadata";
|
final String knownControllerId = "targetIdWithMetadata";
|
||||||
|
|
||||||
final int totalMetadata = 10;
|
final int totalMetadata = 10;
|
||||||
@@ -1904,7 +1915,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("A request for assigning multiple DS to a target results in a Bad Request when multiassignment in disabled.")
|
@Description("A request for assigning multiple DS to a target results in a Bad Request when multiassignment in disabled.")
|
||||||
public void multiassignmentRequestNotAllowedIfDisabled() throws Exception {
|
void multiassignmentRequestNotAllowedIfDisabled() throws Exception {
|
||||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||||
final List<Long> dsIds = testdataFactory.createDistributionSets(2).stream().map(DistributionSet::getId)
|
final List<Long> dsIds = testdataFactory.createDistributionSets(2).stream().map(DistributionSet::getId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@@ -1919,7 +1930,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Passing an array in assignment request is allowed if multiassignment is disabled and array size in 1.")
|
@Description("Passing an array in assignment request is allowed if multiassignment is disabled and array size in 1.")
|
||||||
public void multiassignmentRequestAllowedIfDisabledButHasSizeOne() throws Exception {
|
void multiassignmentRequestAllowedIfDisabledButHasSizeOne() throws Exception {
|
||||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||||
|
|
||||||
@@ -1931,7 +1942,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Identical assignments in a single request are removed when multiassignment in disabled.")
|
@Description("Identical assignments in a single request are removed when multiassignment in disabled.")
|
||||||
public void identicalAssignmentInRequestAreRemovedIfMultiassignmentsDisabled() throws Exception {
|
void identicalAssignmentInRequestAreRemovedIfMultiassignmentsDisabled() throws Exception {
|
||||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||||
|
|
||||||
@@ -1945,7 +1956,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Assign multiple DSs to a target in one request with multiassignments enabled.")
|
@Description("Assign multiple DSs to a target in one request with multiassignments enabled.")
|
||||||
public void multiAssignment() throws Exception {
|
void multiAssignment() throws Exception {
|
||||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||||
final List<Long> dsIds = testdataFactory.createDistributionSets(2).stream().map(DistributionSet::getId)
|
final List<Long> dsIds = testdataFactory.createDistributionSets(2).stream().map(DistributionSet::getId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@@ -1960,8 +1971,8 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("An assignment request containing a weight is only accepted when weight is valide and multi assignment is on.")
|
@Description("An assignment request containing a weight is only accepted when weight is valid and multi assignment is on.")
|
||||||
public void weightValidation() throws Exception {
|
void weightValidation() throws Exception {
|
||||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||||
final int weight = 98;
|
final int weight = 98;
|
||||||
@@ -1985,7 +1996,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("An assignment request containing a valid weight when multi assignment is off.")
|
@Description("An assignment request containing a valid weight when multi assignment is off.")
|
||||||
public void weightWithSingleAssignment() throws Exception {
|
void weightWithSingleAssignment() throws Exception {
|
||||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||||
|
|
||||||
@@ -1999,7 +2010,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("An assignment request containing a valid weight when multi assignment is on.")
|
@Description("An assignment request containing a valid weight when multi assignment is on.")
|
||||||
public void weightWithMultiAssignment() throws Exception {
|
void weightWithMultiAssignment() throws Exception {
|
||||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||||
final int weight = 98;
|
final int weight = 98;
|
||||||
@@ -2018,7 +2029,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Get weight of action")
|
@Description("Get weight of action")
|
||||||
public void getActionWeight() throws Exception {
|
void getActionWeight() throws Exception {
|
||||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||||
final int customWeightHigh = 800;
|
final int customWeightHigh = 800;
|
||||||
@@ -2049,7 +2060,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("An action provides information of the rollout it was created for (if any).")
|
@Description("An action provides information of the rollout it was created for (if any).")
|
||||||
public void getActionWithRolloutInfo() throws Exception {
|
void getActionWithRolloutInfo() throws Exception {
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
final int amountTargets = 10;
|
final int amountTargets = 10;
|
||||||
@@ -2082,7 +2093,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a post request for creating targets with target type works.")
|
@Description("Ensures that a post request for creating targets with target type works.")
|
||||||
public void createTargetsWithTargetType() throws Exception {
|
void createTargetsWithTargetType() throws Exception {
|
||||||
final TargetType type1 = testdataFactory.createTargetType("typeWithDs", Collections.singletonList(standardDsType));
|
final TargetType type1 = testdataFactory.createTargetType("typeWithDs", Collections.singletonList(standardDsType));
|
||||||
final TargetType type2 = testdataFactory.createTargetType("typeWithOutDs", Collections.singletonList(standardDsType));
|
final TargetType type2 = testdataFactory.createTargetType("typeWithOutDs", Collections.singletonList(standardDsType));
|
||||||
|
|
||||||
@@ -2132,26 +2143,21 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
.andExpect(jsonPath(JSON_PATH_DESCRIPTION, equalTo("testid2")))
|
.andExpect(jsonPath(JSON_PATH_DESCRIPTION, equalTo("testid2")))
|
||||||
.andExpect(jsonPath("$._links.targetType.href", equalTo(hrefType1))).andReturn();
|
.andExpect(jsonPath("$._links.targetType.href", equalTo(hrefType1))).andReturn();
|
||||||
|
|
||||||
assertThat(targetManagement.getByControllerID("id1")).isNotNull();
|
final Target target1 = assertTarget("id1", "targetWithoutType", "testid1");
|
||||||
assertThat(targetManagement.getByControllerID("id1").get().getName()).isEqualTo("targetWithoutType");
|
assertThat(target1.getTargetType()).isNull();
|
||||||
assertThat(targetManagement.getByControllerID("id1").get().getDescription()).isEqualTo("testid1");
|
assertThat(target1.getSecurityToken()).isEqualTo("token");
|
||||||
assertThat(targetManagement.getByControllerID("id1").get().getTargetType()).isNull();
|
assertThat(target1.getAddress()).hasToString("amqp://test123/foobar");
|
||||||
assertThat(targetManagement.getByControllerID("id1").get().getSecurityToken()).isEqualTo("token");
|
|
||||||
assertThat(targetManagement.getByControllerID("id1").get().getAddress().toString())
|
final Target target2 = assertTarget("id2", "targetOfType1", "testid2");
|
||||||
.isEqualTo("amqp://test123/foobar");
|
assertThat(target2.getTargetType()).extracting(TargetType::getName).isEqualTo("typeWithDs");
|
||||||
assertThat(targetManagement.getByControllerID("id2")).isNotNull();
|
|
||||||
assertThat(targetManagement.getByControllerID("id2").get().getName()).isEqualTo("targetOfType1");
|
final Target target3 = assertTarget("id3", "targetOfType2", "testid3");
|
||||||
assertThat(targetManagement.getByControllerID("id2").get().getDescription()).isEqualTo("testid2");
|
assertThat(target3.getTargetType()).extracting(TargetType::getName).isEqualTo("typeWithOutDs");
|
||||||
assertThat(targetManagement.getByControllerID("id2").get().getTargetType().getName()).isEqualTo("typeWithDs");
|
|
||||||
assertThat(targetManagement.getByControllerID("id3")).isNotNull();
|
|
||||||
assertThat(targetManagement.getByControllerID("id3").get().getName()).isEqualTo("targetOfType2");
|
|
||||||
assertThat(targetManagement.getByControllerID("id3").get().getDescription()).isEqualTo("testid3");
|
|
||||||
assertThat(targetManagement.getByControllerID("id3").get().getTargetType().getName()).isEqualTo("typeWithOutDs");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a post request for creating target with target type works.")
|
@Description("Ensures that a post request for creating target with target type works.")
|
||||||
public void createTargetWithExistingTargetType() throws Exception {
|
void createTargetWithExistingTargetType() throws Exception {
|
||||||
// create target type
|
// create target type
|
||||||
List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype",1);
|
List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype",1);
|
||||||
assertThat(targetTypes).hasSize(1);
|
assertThat(targetTypes).hasSize(1);
|
||||||
@@ -2171,7 +2177,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a put request for updating targets with target type works.")
|
@Description("Ensures that a put request for updating targets with target type works.")
|
||||||
public void updateTargetTypeInTarget() throws Exception {
|
void updateTargetTypeInTarget() throws Exception {
|
||||||
// create target type
|
// create target type
|
||||||
List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype",2);
|
List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype",2);
|
||||||
assertThat(targetTypes).hasSize(2);
|
assertThat(targetTypes).hasSize(2);
|
||||||
@@ -2193,7 +2199,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a post request for creating targets with unknown target type fails.")
|
@Description("Ensures that a post request for creating targets with unknown target type fails.")
|
||||||
public void addingNonExistingTargetTypeInTargetShouldFail() throws Exception {
|
void addingNonExistingTargetTypeInTargetShouldFail() throws Exception {
|
||||||
long unknownTargetTypeId = 999;
|
long unknownTargetTypeId = 999;
|
||||||
String errorMsg = String.format("TargetType with given identifier {%s} does not exist.", unknownTargetTypeId);
|
String errorMsg = String.format("TargetType with given identifier {%s} does not exist.", unknownTargetTypeId);
|
||||||
|
|
||||||
@@ -2213,7 +2219,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a post request for assign target type to target works.")
|
@Description("Ensures that a post request for assign target type to target works.")
|
||||||
public void assignTargetTypeToTarget() throws Exception {
|
void assignTargetTypeToTarget() throws Exception {
|
||||||
// create target type
|
// create target type
|
||||||
TargetType targetType = testdataFactory.findOrCreateTargetType("targettype");
|
TargetType targetType = testdataFactory.findOrCreateTargetType("targettype");
|
||||||
assertThat(targetType).isNotNull();
|
assertThat(targetType).isNotNull();
|
||||||
@@ -2233,7 +2239,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a post request for assign a invalid target type to target fails.")
|
@Description("Ensures that a post request for assign a invalid target type to target fails.")
|
||||||
public void assignInvalidTargetTypeToTargetFails() throws Exception {
|
void assignInvalidTargetTypeToTargetFails() throws Exception {
|
||||||
// Invalid target type ID
|
// Invalid target type ID
|
||||||
long invalidTargetTypeId = 999;
|
long invalidTargetTypeId = 999;
|
||||||
|
|
||||||
@@ -2260,7 +2266,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that a delete request for unassign target type from target works.")
|
@Description("Ensures that a delete request for unassign target type from target works.")
|
||||||
public void unassignTargetTypeFromTarget() throws Exception {
|
void unassignTargetTypeFromTarget() throws Exception {
|
||||||
// create target type
|
// create target type
|
||||||
List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype",1);
|
List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype",1);
|
||||||
assertThat(targetTypes).hasSize(1);
|
assertThat(targetTypes).hasSize(1);
|
||||||
@@ -2279,10 +2285,10 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void invalidRequestsOnTargetTypeResource() throws Exception {
|
void invalidRequestsOnTargetTypeResource() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
final Target target = testdataFactory.createTarget(knownTargetId);
|
testdataFactory.createTarget(knownTargetId);
|
||||||
final TargetType targettype = testdataFactory.createTargetType("targettype", Collections.emptyList());
|
testdataFactory.createTargetType("targettype", Collections.emptyList());
|
||||||
|
|
||||||
// GET is not allowed
|
// GET is not allowed
|
||||||
mvc.perform(get(
|
mvc.perform(get(
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ public class RestConfiguration {
|
|||||||
* filter in the filter chain
|
* filter in the filter chain
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
FilterRegistrationBean eTagFilter() {
|
FilterRegistrationBean<ExcludePathAwareShallowETagFilter> eTagFilter() {
|
||||||
|
|
||||||
final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
|
final FilterRegistrationBean<ExcludePathAwareShallowETagFilter> filterRegBean = new FilterRegistrationBean<>();
|
||||||
// Exclude the URLs for downloading artifacts, so no eTag is generated
|
// Exclude the URLs for downloading artifacts, so no eTag is generated
|
||||||
// in the ShallowEtagHeaderFilter, just using the SH1 hash of the
|
// in the ShallowEtagHeaderFilter, just using the SH1 hash of the
|
||||||
// artifact itself as 'ETag', because otherwise the file will be copied
|
// artifact itself as 'ETag', because otherwise the file will be copied
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ public final class FileStreamingUtil {
|
|||||||
LOG.debug("range header for filename ({}) is: {}", filename, range);
|
LOG.debug("range header for filename ({}) is: {}", filename, range);
|
||||||
|
|
||||||
// Range header matches"bytes=n-n,n-n,n-n..."
|
// Range header matches"bytes=n-n,n-n,n-n..."
|
||||||
if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*$")) {
|
if (!range.matches("^bytes=\\d*-\\d*(,\\d*-\\d*)*+$")) {
|
||||||
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + length);
|
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + length);
|
||||||
LOG.debug("range header for filename ({}) is not satisfiable: ", filename);
|
LOG.debug("range header for filename ({}) is not satisfiable: ", filename);
|
||||||
return new ResponseEntity<>(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE);
|
return new ResponseEntity<>(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE);
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2022 Bosch.IO 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.rest.util;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||||
|
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import io.qameta.allure.Feature;
|
||||||
|
import io.qameta.allure.Story;
|
||||||
|
|
||||||
|
@Feature("Component Tests - Management API")
|
||||||
|
@Story("File streaming")
|
||||||
|
class FileStreamingUtilTest {
|
||||||
|
private final static String CONTENT = "This is some very long string which is intended to test";
|
||||||
|
private final static byte[] CONTENT_BYTES = CONTENT.getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
private static final DbArtifact TEST_ARTIFACT = new DbArtifact() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getArtifactId() {
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DbArtifactHash getHashes() {
|
||||||
|
return new DbArtifactHash("sha1-111", "md5-123", "sha256-123");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSize() {
|
||||||
|
return CONTENT_BYTES.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContentType() {
|
||||||
|
return "text/plain";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getFileInputStream() {
|
||||||
|
return new ByteArrayInputStream(CONTENT_BYTES);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldProcessRangeHeaderForMultipartRequests() throws IOException {
|
||||||
|
final HttpServletResponse servletResponse = Mockito.mock(HttpServletResponse.class);
|
||||||
|
final ServletOutputStream outputStream = Mockito.mock(ServletOutputStream.class);
|
||||||
|
|
||||||
|
Mockito.when(servletResponse.getOutputStream()).thenReturn(outputStream);
|
||||||
|
final HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class);
|
||||||
|
Mockito.when(servletRequest.getHeader("Range")).thenReturn("bytes=0-10,9-15,16-");
|
||||||
|
long lastModified = System.currentTimeMillis();
|
||||||
|
|
||||||
|
final ResponseEntity<InputStream> responseEntity = FileStreamingUtil.writeFileResponse(TEST_ARTIFACT,
|
||||||
|
"test.file", lastModified, servletResponse, servletRequest, null);
|
||||||
|
|
||||||
|
assertThat(responseEntity).isNotNull();
|
||||||
|
verify(servletResponse).setDateHeader(HttpHeaders.LAST_MODIFIED, lastModified);
|
||||||
|
final ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
|
final ArgumentCaptor<Integer> lenCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||||
|
|
||||||
|
verify(outputStream).print(stringCaptor.capture());
|
||||||
|
assertThat(stringCaptor.getValue()).contains("--THIS_STRING_SEPARATES_MULTIPART--");
|
||||||
|
verify(outputStream, times(3)).write(any(), anyInt(), lenCaptor.capture());
|
||||||
|
assertThat(lenCaptor.getAllValues()).containsExactly(11, 7, 39); // Range lengths
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldValidateRangeHeaderForMultipartRequests() throws IOException {
|
||||||
|
long lastModified = System.currentTimeMillis();
|
||||||
|
final HttpServletResponse servletResponse = Mockito.mock(HttpServletResponse.class);
|
||||||
|
final ServletOutputStream outputStream = Mockito.mock(ServletOutputStream.class);
|
||||||
|
Mockito.when(servletResponse.getOutputStream()).thenReturn(outputStream);
|
||||||
|
|
||||||
|
final HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class);
|
||||||
|
Mockito.when(servletRequest.getHeader("Range")).thenReturn("bytes=0-10***,9-15,16-");
|
||||||
|
|
||||||
|
final ResponseEntity<InputStream> responseEntity = FileStreamingUtil.writeFileResponse(TEST_ARTIFACT,
|
||||||
|
"test.file", lastModified, servletResponse, servletRequest, null);
|
||||||
|
|
||||||
|
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE);
|
||||||
|
verify(outputStream, times(0)).print(anyString());
|
||||||
|
verify(outputStream, times(0)).write(any(), anyInt(), anyInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.rest.util;
|
package org.eclipse.hawkbit.rest.util;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -42,24 +42,21 @@ public class SortUtilityTest {
|
|||||||
@Description("Ascending sorting based on name.")
|
@Description("Ascending sorting based on name.")
|
||||||
public void parseSortParam1() {
|
public void parseSortParam1() {
|
||||||
final List<Order> parse = SortUtility.parse(TargetFields.class, SORT_PARAM_1);
|
final List<Order> parse = SortUtility.parse(TargetFields.class, SORT_PARAM_1);
|
||||||
assertThat(1).as("Count of parsing parameter").isEqualTo(parse.size());
|
assertThat(parse).as("Count of parsing parameter").hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ascending sorting based on name and descending sorting based on description.")
|
@Description("Ascending sorting based on name and descending sorting based on description.")
|
||||||
public void parseSortParam2() {
|
public void parseSortParam2() {
|
||||||
final List<Order> parse = SortUtility.parse(TargetFields.class, SORT_PARAM_2);
|
final List<Order> parse = SortUtility.parse(TargetFields.class, SORT_PARAM_2);
|
||||||
assertThat(2).as("Count of parsing parameter").isEqualTo(parse.size());
|
assertThat(parse).as("Count of parsing parameter").hasSize(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Sorting with wrong syntax leads to SortParameterSyntaxErrorException.")
|
@Description("Sorting with wrong syntax leads to SortParameterSyntaxErrorException.")
|
||||||
public void parseWrongSyntaxParam() {
|
public void parseWrongSyntaxParam() {
|
||||||
try {
|
assertThrows(SortParameterSyntaxErrorException.class,
|
||||||
SortUtility.parse(TargetFields.class, SYNTAX_FAILURE_SORT_PARAM);
|
() -> SortUtility.parse(TargetFields.class, SYNTAX_FAILURE_SORT_PARAM));
|
||||||
fail("SortParameterSyntaxErrorException expected because of wrong syntax");
|
|
||||||
} catch (final SortParameterSyntaxErrorException e) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -72,22 +69,14 @@ public class SortUtilityTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Sorting with unknown direction order leads to SortParameterUnsupportedDirectionException.")
|
@Description("Sorting with unknown direction order leads to SortParameterUnsupportedDirectionException.")
|
||||||
public void parseWrongDirectionParam() {
|
public void parseWrongDirectionParam() {
|
||||||
try {
|
assertThrows(SortParameterUnsupportedDirectionException.class,
|
||||||
SortUtility.parse(TargetFields.class, WRONG_DIRECTION_PARAM);
|
() -> SortUtility.parse(TargetFields.class, WRONG_DIRECTION_PARAM));
|
||||||
fail("SortParameterUnsupportedDirectionException expected because of unknown direction order");
|
|
||||||
} catch (final SortParameterUnsupportedDirectionException e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Sorting with unknown field leads to SortParameterUnsupportedFieldException.")
|
@Description("Sorting with unknown field leads to SortParameterUnsupportedFieldException.")
|
||||||
public void parseWrongFieldParam() {
|
public void parseWrongFieldParam() {
|
||||||
try {
|
assertThrows(SortParameterUnsupportedFieldException.class,
|
||||||
SortUtility.parse(TargetFields.class, WRONG_FIELD_PARAM);
|
() -> SortUtility.parse(TargetFields.class, WRONG_FIELD_PARAM));
|
||||||
fail("SortParameterUnsupportedFieldException expected because of unknown field");
|
|
||||||
} catch (final SortParameterUnsupportedFieldException e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.im.authentication;
|
package org.eclipse.hawkbit.im.authentication;
|
||||||
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -22,16 +21,14 @@ import org.springframework.security.core.GrantedAuthority;
|
|||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Software provisioning permissions that are technically available as
|
* Software provisioning permissions that are technically available as
|
||||||
* {@link GrantedAuthority} based on the authenticated users identity context.
|
* {@linkplain GrantedAuthority} based on the authenticated users identity
|
||||||
|
* context.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* The Permissions cover CRUD for two data areas:
|
* The permissions cover CRUD operations for various areas within eclipse
|
||||||
*
|
* hawkBit, like targets, software-artifacts, distribution sets, config-options
|
||||||
* XX_Target_CRUD which covers the following entities: {@link Target} entities
|
* etc.
|
||||||
* including metadata, {@link TargetTag}s, {@link TargetRegistrationRule}s
|
|
||||||
* XX_Repository CRUD which covers: {@link DistributionSet}s,
|
|
||||||
* {@link SoftwareModule}s, DS Tags
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public final class SpPermission {
|
public final class SpPermission {
|
||||||
@@ -39,69 +36,50 @@ public final class SpPermission {
|
|||||||
private static final Logger LOGGER = LoggerFactory.getLogger(SpPermission.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(SpPermission.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to read the targets from the
|
* Permission to read the targets (list and filter).
|
||||||
* {@link ProvisioningTargetRepository} including their meta information,
|
|
||||||
* {@link ProvisioningTargetFilter}s and target changing entities (
|
|
||||||
* {@link DistributionSetApplier} and {@link TargetRegistrationRule}). That
|
|
||||||
* corresponds in REST API to GET.
|
|
||||||
*/
|
*/
|
||||||
public static final String READ_TARGET = "READ_TARGET";
|
public static final String READ_TARGET = "READ_TARGET";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to read the target security token. The security token is
|
* Permission to read the target security token. The security token is security
|
||||||
* security concerned and should be protected. So the combination
|
* concerned and should be protected. So the combination
|
||||||
* {@link #READ_TARGET} and {@link #READ_TARGET_SEC_TOKEN} is necessary to
|
* {@linkplain #READ_TARGET} and {@code READ_TARGET_SEC_TOKEN} is necessary to
|
||||||
* able to read the security token of an target.
|
* be able to read the security token of a target.
|
||||||
*/
|
*/
|
||||||
public static final String READ_TARGET_SEC_TOKEN = "READ_TARGET_SECURITY_TOKEN";
|
public static final String READ_TARGET_SEC_TOKEN = "READ_TARGET_SECURITY_TOKEN";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to change/edit/update targets in the
|
* Permission to change/edit/update targets and to assign updates.
|
||||||
* {@link ProvisioningTargetRepository} including their meta information and
|
|
||||||
* or/relations or {@link DistributionSet} assignment,
|
|
||||||
* {@link ProvisioningTargetFilter}s and target changing entities (
|
|
||||||
* {@link DistributionSetApplier} and {@link TargetRegistrationRule}). That
|
|
||||||
* corresponds in REST API to POST.
|
|
||||||
*/
|
*/
|
||||||
public static final String UPDATE_TARGET = "UPDATE_TARGET";
|
public static final String UPDATE_TARGET = "UPDATE_TARGET";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to add new targets to the {@link ProvisioningTargetRepository}
|
* Permission to add new targets including their meta information.
|
||||||
* including their meta information and or/relations or
|
|
||||||
* {@link DistributionSet} assignment.That corresponds in REST API to PUT.
|
|
||||||
*/
|
*/
|
||||||
public static final String CREATE_TARGET = "CREATE_TARGET";
|
public static final String CREATE_TARGET = "CREATE_TARGET";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to delete targets in the {@link ProvisioningTargetRepository},
|
* Permission to delete targets.
|
||||||
* {@link ProvisioningTargetFilter}s and target changing entities (
|
|
||||||
* {@link DistributionSetApplier} and {@link TargetRegistrationRule}). That
|
|
||||||
* corresponds in REST API to DELETE.
|
|
||||||
*/
|
*/
|
||||||
public static final String DELETE_TARGET = "DELETE_TARGET";
|
public static final String DELETE_TARGET = "DELETE_TARGET";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to read {@link DistributionSet}s and/or {@link OsPackage}s.
|
* Permission to read distributions and artifacts.
|
||||||
* That corresponds in REST API to GET.
|
|
||||||
*/
|
*/
|
||||||
public static final String READ_REPOSITORY = "READ_REPOSITORY";
|
public static final String READ_REPOSITORY = "READ_REPOSITORY";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to edit/update {@link DistributionSet}s including their
|
* Permission to edit/update distributions and artifacts.
|
||||||
* {@link OsPackage} assignment and/or {@link OsPackage}s. That corresponds
|
|
||||||
* in REST API to POST.
|
|
||||||
*/
|
*/
|
||||||
public static final String UPDATE_REPOSITORY = "UPDATE_REPOSITORY";
|
public static final String UPDATE_REPOSITORY = "UPDATE_REPOSITORY";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to add {@link DistributionSet}s and/or {@link OsPackage}s to
|
* Permission to add distributions and artifacts.
|
||||||
* the repository. That corresponds in REST API to PUT.
|
|
||||||
*/
|
*/
|
||||||
public static final String CREATE_REPOSITORY = "CREATE_REPOSITORY";
|
public static final String CREATE_REPOSITORY = "CREATE_REPOSITORY";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to delete {@link DistributionSet}s and/or {@link OsPackage}s
|
* Permission to delete distributions and artifacts.
|
||||||
* from the repository. That corresponds in REST API to DELETE.
|
|
||||||
*/
|
*/
|
||||||
public static final String DELETE_REPOSITORY = "DELETE_REPOSITORY";
|
public static final String DELETE_REPOSITORY = "DELETE_REPOSITORY";
|
||||||
|
|
||||||
@@ -112,7 +90,7 @@ public final class SpPermission {
|
|||||||
public static final String SYSTEM_ADMIN = "SYSTEM_ADMIN";
|
public static final String SYSTEM_ADMIN = "SYSTEM_ADMIN";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to download repository artifact of an software module.
|
* Permission to download repository artifacts of a software module.
|
||||||
*/
|
*/
|
||||||
public static final String DOWNLOAD_REPOSITORY_ARTIFACT = "DOWNLOAD_REPOSITORY_ARTIFACT";
|
public static final String DOWNLOAD_REPOSITORY_ARTIFACT = "DOWNLOAD_REPOSITORY_ARTIFACT";
|
||||||
|
|
||||||
@@ -157,9 +135,6 @@ public final class SpPermission {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all permission.
|
* Return all permission.
|
||||||
*
|
|
||||||
* @param exclusionRoles
|
|
||||||
* roles which will excluded
|
|
||||||
* @return all permissions
|
* @return all permissions
|
||||||
*/
|
*/
|
||||||
public static List<String> getAllAuthorities() {
|
public static List<String> getAllAuthorities() {
|
||||||
@@ -167,7 +142,6 @@ public final class SpPermission {
|
|||||||
final Field[] declaredFields = SpPermission.class.getDeclaredFields();
|
final Field[] declaredFields = SpPermission.class.getDeclaredFields();
|
||||||
for (final Field field : declaredFields) {
|
for (final Field field : declaredFields) {
|
||||||
if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) {
|
if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) {
|
||||||
field.setAccessible(true);
|
|
||||||
try {
|
try {
|
||||||
final String role = (String) field.get(null);
|
final String role = (String) field.get(null);
|
||||||
allPermissions.add(role);
|
allPermissions.add(role);
|
||||||
@@ -219,8 +193,8 @@ public final class SpPermission {
|
|||||||
public static final String CONTROLLER_ROLE = "ROLE_CONTROLLER";
|
public static final String CONTROLLER_ROLE = "ROLE_CONTROLLER";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The role which contains in the spring security context in case an
|
* The role which contained in the spring security context in case that a
|
||||||
* controller is authenticated but only as anonymous.
|
* controller is authenticated, but only as 'anonymous'.
|
||||||
*/
|
*/
|
||||||
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
|
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
|
||||||
|
|
||||||
@@ -359,7 +333,7 @@ public final class SpPermission {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring security eval hasAnyRole expression to check if the spring
|
* Spring security eval hasAnyRole expression to check if the spring
|
||||||
* context contains the anoynmous role or the controller specific role
|
* context contains the anonymous role or the controller specific role
|
||||||
* {@link SpringEvalExpressions#CONTROLLER_ROLE}.
|
* {@link SpringEvalExpressions#CONTROLLER_ROLE}.
|
||||||
*/
|
*/
|
||||||
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
|
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public class UserPrincipal extends User {
|
|||||||
*/
|
*/
|
||||||
public UserPrincipal(final String username, final String firstname, final String lastname, final String loginname,
|
public UserPrincipal(final String username, final String firstname, final String lastname, final String loginname,
|
||||||
final String email, final String tenant) {
|
final String email, final String tenant) {
|
||||||
this(username, "***", lastname, firstname, loginname, email, tenant, Collections.emptyList());
|
this(username, "***", firstname, lastname, loginname, email, tenant, Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,11 +11,13 @@ package org.eclipse.hawkbit.im.authentication;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
@@ -26,7 +28,7 @@ import io.qameta.allure.Story;
|
|||||||
*/
|
*/
|
||||||
@Feature("Unit Tests - Security")
|
@Feature("Unit Tests - Security")
|
||||||
@Story("Permission Test")
|
@Story("Permission Test")
|
||||||
public final class PermissionTest {
|
public final class SpPermissionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verify the get permission function")
|
@Description("Verify the get permission function")
|
||||||
@@ -38,6 +40,21 @@ public final class PermissionTest {
|
|||||||
assertThat(allAuthoritiesList).hasSize(allPermission);
|
assertThat(allAuthoritiesList).hasSize(allPermission);
|
||||||
assertThat(allAuthoritiesList.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList()))
|
assertThat(allAuthoritiesList.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList()))
|
||||||
.containsAll(allAuthorities);
|
.containsAll(allAuthorities);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Try to double check if all permissions works as expected")
|
||||||
|
void shouldReturnAllPermissions() {
|
||||||
|
List<String> expected = new LinkedList<>();
|
||||||
|
ReflectionUtils.doWithFields(SpPermission.class, f -> {
|
||||||
|
if (ReflectionUtils.isPublicStaticFinal(f) && String.class.equals(f.getType())) {
|
||||||
|
try {
|
||||||
|
expected.add((String) f.get(null));
|
||||||
|
} catch (IllegalAccessException | IllegalArgumentException e) {
|
||||||
|
// skip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assertThat(SpPermission.getAllAuthorities()).containsAll(expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An pre-authenticated processing filter which extracts the principal from a
|
* A pre-authenticated processing filter which extracts the principal from a
|
||||||
* request URI and the credential from a request header in a the
|
* request URI and the credential from a request header in a the
|
||||||
* {@link DmfTenantSecurityToken}.
|
* {@link DmfTenantSecurityToken}.
|
||||||
*
|
*
|
||||||
@@ -44,9 +44,8 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
|
|||||||
// X-Ssl-Issuer-Dn-1: CN=Bosch-CA-DE,CN=PKI,DC=Bosch,DC=com
|
// X-Ssl-Issuer-Dn-1: CN=Bosch-CA-DE,CN=PKI,DC=Bosch,DC=com
|
||||||
// X-Ssl-Issuer-Hash-1: ae:11:f5:6a:0a:e8:74:50:81:0e:0c:37:ec:c5:22:fc
|
// X-Ssl-Issuer-Hash-1: ae:11:f5:6a:0a:e8:74:50:81:0e:0c:37:ec:c5:22:fc
|
||||||
private final String caCommonNameHeader;
|
private final String caCommonNameHeader;
|
||||||
// the X-Ssl-Issuer-Hash basic header header which contains the x509
|
// the X-Ssl-Issuer-Hash basic header: Contains the x509 fingerprint hash, this
|
||||||
// fingerprint hash, this
|
// header exists multiple times in the request for all trusted chains.
|
||||||
// header exists multiple in the request for all trusted chain.
|
|
||||||
private final String sslIssuerHashBasicHeader;
|
private final String sslIssuerHashBasicHeader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,18 +75,18 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HeaderAuthentication getPreAuthenticatedPrincipal(final DmfTenantSecurityToken secruityToken) {
|
public HeaderAuthentication getPreAuthenticatedPrincipal(final DmfTenantSecurityToken securityToken) {
|
||||||
// retrieve the common name header and the authority name header from
|
// retrieve the common name header and the authority name header from
|
||||||
// the http request and combine them together
|
// the http request and combine them together
|
||||||
final String commonNameValue = secruityToken.getHeader(caCommonNameHeader);
|
final String commonNameValue = securityToken.getHeader(caCommonNameHeader);
|
||||||
final String knownSslIssuerConfigurationValue = tenantAware.runAsTenant(secruityToken.getTenant(),
|
final String knownSslIssuerConfigurationValue = tenantAware.runAsTenant(securityToken.getTenant(),
|
||||||
sslIssuerNameConfigTenantRunner);
|
sslIssuerNameConfigTenantRunner);
|
||||||
final String sslIssuerHashValue = getIssuerHashHeader(secruityToken, knownSslIssuerConfigurationValue);
|
final String sslIssuerHashValue = getIssuerHashHeader(securityToken, knownSslIssuerConfigurationValue);
|
||||||
if (commonNameValue != null && LOGGER.isTraceEnabled()) {
|
if (commonNameValue != null && LOGGER.isTraceEnabled()) {
|
||||||
LOGGER.trace("Found commonNameHeader {}={}, using as credentials", caCommonNameHeader, commonNameValue);
|
LOGGER.trace("Found commonNameHeader {}={}, using as credentials", caCommonNameHeader, commonNameValue);
|
||||||
}
|
}
|
||||||
if (sslIssuerHashValue != null && LOGGER.isTraceEnabled()) {
|
if (sslIssuerHashValue != null && LOGGER.isTraceEnabled()) {
|
||||||
LOGGER.trace("Found sslIssuerHash ****, using as credentials for tenant {}", secruityToken.getTenant());
|
LOGGER.trace("Found sslIssuerHash ****, using as credentials for tenant {}", securityToken.getTenant());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commonNameValue != null && sslIssuerHashValue != null) {
|
if (commonNameValue != null && sslIssuerHashValue != null) {
|
||||||
@@ -97,37 +96,36 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getPreAuthenticatedCredentials(final DmfTenantSecurityToken secruityToken) {
|
public Object getPreAuthenticatedCredentials(final DmfTenantSecurityToken securityToken) {
|
||||||
final String authorityNameConfigurationValue = tenantAware.runAsTenant(secruityToken.getTenant(),
|
final String authorityNameConfigurationValue = tenantAware.runAsTenant(securityToken.getTenant(),
|
||||||
sslIssuerNameConfigTenantRunner);
|
sslIssuerNameConfigTenantRunner);
|
||||||
String controllerId = secruityToken.getControllerId();
|
|
||||||
// in case of legacy download artifact, the controller ID is not in the
|
// in case of legacy download artifact, the controller ID is not in the
|
||||||
// URL path, so then we just use the common name header
|
// URL path, so then we just use the common name header
|
||||||
if (controllerId == null || "anonymous".equals(controllerId)) {
|
final String controllerId = //
|
||||||
controllerId = secruityToken.getHeader(caCommonNameHeader);
|
(securityToken.getControllerId() == null || "anonymous".equals(securityToken.getControllerId()) //
|
||||||
}
|
? securityToken.getHeader(caCommonNameHeader)
|
||||||
|
: securityToken.getControllerId());
|
||||||
|
|
||||||
final List<String> knownHashes = splitMultiHashBySemicolon(authorityNameConfigurationValue);
|
final List<String> knownHashes = splitMultiHashBySemicolon(authorityNameConfigurationValue);
|
||||||
|
return knownHashes.stream().map(hashItem -> new HeaderAuthentication(controllerId, hashItem))
|
||||||
final String cntlId = controllerId;
|
|
||||||
return knownHashes.stream().map(hashItem -> new HeaderAuthentication(cntlId, hashItem))
|
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterates over the {@link #sslIssuerHashBasicHeader} basic header
|
* Iterates over the {@link #sslIssuerHashBasicHeader} basic header
|
||||||
* {@code X-Ssl-Issuer-Hash-%d} and try to finds the same hash as known.
|
* {@code X-Ssl-Issuer-Hash-%d} and try to find the same hash as known. It's ok
|
||||||
* It's ok if we find the the hash in any the trusted CA chain to accept
|
* if we find the hash in any the trusted CA chain to accept this request for
|
||||||
* this request for this tenant.
|
* this tenant.
|
||||||
*/
|
*/
|
||||||
private String getIssuerHashHeader(final DmfTenantSecurityToken secruityToken, final String knownIssuerHashes) {
|
private String getIssuerHashHeader(final DmfTenantSecurityToken securityToken, final String knownIssuerHashes) {
|
||||||
// there may be several knownIssuerHashes configured for the tenant
|
// there may be several knownIssuerHashes configured for the tenant
|
||||||
final List<String> knownHashes = splitMultiHashBySemicolon(knownIssuerHashes);
|
final List<String> knownHashes = splitMultiHashBySemicolon(knownIssuerHashes);
|
||||||
|
|
||||||
// iterate over the headers until we get a null header.
|
// iterate over the headers until we get a null header.
|
||||||
int iHeader = 1;
|
int iHeader = 1;
|
||||||
String foundHash;
|
String foundHash;
|
||||||
while ((foundHash = secruityToken.getHeader(String.format(sslIssuerHashBasicHeader, iHeader))) != null) {
|
while ((foundHash = securityToken.getHeader(String.format(sslIssuerHashBasicHeader, iHeader))) != null) {
|
||||||
if (knownHashes.contains(foundHash.toLowerCase())) {
|
if (knownHashes.contains(foundHash.toLowerCase())) {
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (LOGGER.isTraceEnabled()) {
|
||||||
LOGGER.trace("Found matching ssl issuer hash at position {}", iHeader);
|
LOGGER.trace("Found matching ssl issuer hash at position {}", iHeader);
|
||||||
@@ -137,8 +135,8 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
|
|||||||
iHeader++;
|
iHeader++;
|
||||||
}
|
}
|
||||||
LOG_SECURITY_AUTH.debug(
|
LOG_SECURITY_AUTH.debug(
|
||||||
"Certifacte request but no matching hash found in headers {} for common name {} in request",
|
"Certificate request but no matching hash found in headers {} for common name {} in request",
|
||||||
sslIssuerHashBasicHeader, secruityToken.getHeader(caCommonNameHeader));
|
sslIssuerHashBasicHeader, securityToken.getHeader(caCommonNameHeader));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +154,6 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> splitMultiHashBySemicolon(final String knownIssuerHashes) {
|
private static List<String> splitMultiHashBySemicolon(final String knownIssuerHashes) {
|
||||||
return Arrays.stream(knownIssuerHashes.split(";|,")).map(String::toLowerCase).collect(Collectors.toList());
|
return Arrays.stream(knownIssuerHashes.split("[;,]")).map(String::toLowerCase).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -23,11 +22,11 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
import io.qameta.allure.Story;
|
import io.qameta.allure.Story;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
|
|
||||||
@Feature("Unit Tests - Security")
|
@Feature("Unit Tests - Security")
|
||||||
@Story("Issuer hash based authentication")
|
@Story("Issuer hash based authentication")
|
||||||
@@ -57,8 +56,6 @@ public class ControllerPreAuthenticatedSecurityHeaderFilterTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private TenantConfigurationManagement tenantConfigurationManagementMock;
|
private TenantConfigurationManagement tenantConfigurationManagementMock;
|
||||||
@Mock
|
@Mock
|
||||||
private DmfTenantSecurityToken tenantSecurityTokenMock;
|
|
||||||
@Mock
|
|
||||||
private UserAuthoritiesResolver authoritiesResolver;
|
private UserAuthoritiesResolver authoritiesResolver;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@@ -74,7 +71,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilterTest {
|
|||||||
final DmfTenantSecurityToken securityToken = prepareSecurityToken(SINGLE_HASH);
|
final DmfTenantSecurityToken securityToken = prepareSecurityToken(SINGLE_HASH);
|
||||||
// use single known hash
|
// use single known hash
|
||||||
when(tenantConfigurationManagementMock.getConfigurationValue(
|
when(tenantConfigurationManagementMock.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME), eq(String.class)))
|
TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, String.class))
|
||||||
.thenReturn(CONFIG_VALUE_SINGLE_HASH);
|
.thenReturn(CONFIG_VALUE_SINGLE_HASH);
|
||||||
assertThat(underTest.getPreAuthenticatedPrincipal(securityToken)).isNotNull();
|
assertThat(underTest.getPreAuthenticatedPrincipal(securityToken)).isNotNull();
|
||||||
}
|
}
|
||||||
@@ -84,7 +81,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilterTest {
|
|||||||
public void testIssuerHashBasedAuthenticationWithMultipleKnownHashes() {
|
public void testIssuerHashBasedAuthenticationWithMultipleKnownHashes() {
|
||||||
// use multiple known hashes
|
// use multiple known hashes
|
||||||
when(tenantConfigurationManagementMock.getConfigurationValue(
|
when(tenantConfigurationManagementMock.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME), eq(String.class)))
|
TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, String.class))
|
||||||
.thenReturn(CONFIG_VALUE_MULTI_HASH);
|
.thenReturn(CONFIG_VALUE_MULTI_HASH);
|
||||||
assertThat(underTest.getPreAuthenticatedPrincipal(prepareSecurityToken(SINGLE_HASH))).isNotNull();
|
assertThat(underTest.getPreAuthenticatedPrincipal(prepareSecurityToken(SINGLE_HASH))).isNotNull();
|
||||||
assertThat(underTest.getPreAuthenticatedPrincipal(prepareSecurityToken(SECOND_HASH))).isNotNull();
|
assertThat(underTest.getPreAuthenticatedPrincipal(prepareSecurityToken(SECOND_HASH))).isNotNull();
|
||||||
@@ -97,7 +94,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilterTest {
|
|||||||
final DmfTenantSecurityToken securityToken = prepareSecurityToken(UNKNOWN_HASH);
|
final DmfTenantSecurityToken securityToken = prepareSecurityToken(UNKNOWN_HASH);
|
||||||
// use single known hash
|
// use single known hash
|
||||||
when(tenantConfigurationManagementMock.getConfigurationValue(
|
when(tenantConfigurationManagementMock.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME), eq(String.class)))
|
TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, String.class))
|
||||||
.thenReturn(CONFIG_VALUE_MULTI_HASH);
|
.thenReturn(CONFIG_VALUE_MULTI_HASH);
|
||||||
assertThat(underTest.getPreAuthenticatedPrincipal(securityToken)).isNull();
|
assertThat(underTest.getPreAuthenticatedPrincipal(securityToken)).isNull();
|
||||||
}
|
}
|
||||||
@@ -112,7 +109,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilterTest {
|
|||||||
final HeaderAuthentication expected2 = new HeaderAuthentication(CA_COMMON_NAME_VALUE, SECOND_HASH);
|
final HeaderAuthentication expected2 = new HeaderAuthentication(CA_COMMON_NAME_VALUE, SECOND_HASH);
|
||||||
|
|
||||||
when(tenantConfigurationManagementMock.getConfigurationValue(
|
when(tenantConfigurationManagementMock.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME), eq(String.class)))
|
TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, String.class))
|
||||||
.thenReturn(CONFIG_VALUE_MULTI_HASH);
|
.thenReturn(CONFIG_VALUE_MULTI_HASH);
|
||||||
|
|
||||||
final Collection<HeaderAuthentication> credentials1 = (Collection<HeaderAuthentication>) underTest
|
final Collection<HeaderAuthentication> credentials1 = (Collection<HeaderAuthentication>) underTest
|
||||||
@@ -123,8 +120,8 @@ public class ControllerPreAuthenticatedSecurityHeaderFilterTest {
|
|||||||
final Object principal1 = underTest.getPreAuthenticatedPrincipal(securityToken1);
|
final Object principal1 = underTest.getPreAuthenticatedPrincipal(securityToken1);
|
||||||
final Object principal2 = underTest.getPreAuthenticatedPrincipal(securityToken2);
|
final Object principal2 = underTest.getPreAuthenticatedPrincipal(securityToken2);
|
||||||
|
|
||||||
assertThat(credentials1.contains(expected1)).isTrue();
|
assertThat(credentials1).contains(expected1);
|
||||||
assertThat(credentials2.contains(expected2)).isTrue();
|
assertThat(credentials2).contains(expected2);
|
||||||
|
|
||||||
assertThat(expected1).as("hash1 expected in principal!").isEqualTo(principal1);
|
assertThat(expected1).as("hash1 expected in principal!").isEqualTo(principal1);
|
||||||
assertThat(expected2).as("hash2 expected in principal!").isEqualTo(principal2);
|
assertThat(expected2).as("hash2 expected in principal!").isEqualTo(principal2);
|
||||||
|
|||||||
@@ -45,7 +45,6 @@
|
|||||||
<phase>process-classes</phase>
|
<phase>process-classes</phase>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- if you don't specify any modules, the plugin will find them -->
|
<!-- if you don't specify any modules, the plugin will find them -->
|
||||||
<!-- <modules> <module>com.vaadin.demo.mobilemail.gwt.ColorPickerWidgetSet</module> </modules> -->
|
|
||||||
</configuration>
|
</configuration>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>resources</goal>
|
<goal>resources</goal>
|
||||||
|
|||||||
@@ -91,18 +91,18 @@ public class FileTransferHandlerStreamVariable extends AbstractFileTransferHandl
|
|||||||
return ByteStreams.nullOutputStream();
|
return ByteStreams.nullOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
// we return the outputstream so we cannot close it here
|
// we return the output stream - we cannot close it here
|
||||||
@SuppressWarnings("squid:S2095")
|
@SuppressWarnings("squid:S2095")
|
||||||
final PipedOutputStream outputStream = new PipedOutputStream();
|
final PipedOutputStream outputStream = new PipedOutputStream();
|
||||||
PipedInputStream inputStream = null;
|
final PipedInputStream inputStream;
|
||||||
try {
|
try {
|
||||||
inputStream = new PipedInputStream(outputStream);
|
inputStream = new PipedInputStream(outputStream);
|
||||||
publishUploadProgressEvent(fileUploadId, 0, fileSize);
|
publishUploadProgressEvent(fileUploadId, 0, fileSize);
|
||||||
startTransferToRepositoryThread(inputStream, fileUploadId, mimeType);
|
startTransferToRepositoryThread(inputStream, fileUploadId, mimeType);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
LOG.warn("Creating piped Stream failed {}.", e);
|
LOG.warn("Creating piped Stream failed {}.", e.getMessage());
|
||||||
tryToCloseIOStream(outputStream);
|
tryToCloseIOStream(outputStream);
|
||||||
tryToCloseIOStream(inputStream);
|
// input stream is not created in case of and IOException here
|
||||||
interruptUploadDueToUploadFailed();
|
interruptUploadDueToUploadFailed();
|
||||||
publishUploadFailedAndFinishedEvent(fileUploadId);
|
publishUploadFailedAndFinishedEvent(fileUploadId);
|
||||||
return ByteStreams.nullOutputStream();
|
return ByteStreams.nullOutputStream();
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
|
|||||||
private final transient SoftwareModuleManagement softwareModuleManagement;
|
private final transient SoftwareModuleManagement softwareModuleManagement;
|
||||||
private final long maxSize;
|
private final long maxSize;
|
||||||
|
|
||||||
private volatile FileUploadId fileUploadId;
|
private FileUploadId fileUploadId;
|
||||||
|
|
||||||
FileTransferHandlerVaadinUpload(final long maxSize, final SoftwareModuleManagement softwareManagement,
|
FileTransferHandlerVaadinUpload(final long maxSize, final SoftwareModuleManagement softwareManagement,
|
||||||
final ArtifactManagement artifactManagement, final VaadinMessageSource i18n, final Lock uploadLock) {
|
final ArtifactManagement artifactManagement, final VaadinMessageSource i18n, final Lock uploadLock) {
|
||||||
@@ -64,6 +64,11 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
|
|||||||
this.softwareModuleManagement = softwareManagement;
|
this.softwareModuleManagement = softwareManagement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized FileUploadId setFileUploadId(final String fileName, final SoftwareModule softwareModule) {
|
||||||
|
this.fileUploadId = new FileUploadId(fileName, softwareModule);
|
||||||
|
return fileUploadId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload started for {@link Upload} variant.
|
* Upload started for {@link Upload} variant.
|
||||||
*
|
*
|
||||||
@@ -75,8 +80,7 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
|
|||||||
resetState();
|
resetState();
|
||||||
|
|
||||||
final SoftwareModule softwareModule = getSelectedSoftwareModule();
|
final SoftwareModule softwareModule = getSelectedSoftwareModule();
|
||||||
|
final FileUploadId fupId = setFileUploadId(event.getFilename(), softwareModule);
|
||||||
this.fileUploadId = new FileUploadId(event.getFilename(), softwareModule);
|
|
||||||
|
|
||||||
if (getUploadState().isFileInUploadState(this.fileUploadId)) {
|
if (getUploadState().isFileInUploadState(this.fileUploadId)) {
|
||||||
// actual interrupt will happen a bit late so setting the below
|
// actual interrupt will happen a bit late so setting the below
|
||||||
@@ -84,15 +88,14 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
|
|||||||
interruptUploadDueToDuplicateFile();
|
interruptUploadDueToDuplicateFile();
|
||||||
event.getUpload().interruptUpload();
|
event.getUpload().interruptUpload();
|
||||||
} else {
|
} else {
|
||||||
publishUploadStarted(fileUploadId);
|
publishUploadStarted(fupId);
|
||||||
|
|
||||||
if (RegexCharacterCollection.stringContainsCharacter(event.getFilename(), ILLEGAL_FILENAME_CHARACTERS)) {
|
if (RegexCharacterCollection.stringContainsCharacter(event.getFilename(), ILLEGAL_FILENAME_CHARACTERS)) {
|
||||||
LOG.debug("Filename contains illegal characters {} for upload {}", fileUploadId.getFilename(),
|
LOG.debug("Filename contains illegal characters {} for upload {}", fupId.getFilename(), fupId);
|
||||||
fileUploadId);
|
|
||||||
interruptUploadDueToIllegalFilename();
|
interruptUploadDueToIllegalFilename();
|
||||||
event.getUpload().interruptUpload();
|
event.getUpload().interruptUpload();
|
||||||
} else if (isFileAlreadyContainedInSoftwareModule(fileUploadId, softwareModule)) {
|
} else if (isFileAlreadyContainedInSoftwareModule(fupId, softwareModule)) {
|
||||||
LOG.debug("File {} already contained in Software Module {}", fileUploadId.getFilename(),
|
LOG.debug("File {} already contained in Software Module {}", fupId.getFilename(),
|
||||||
softwareModule);
|
softwareModule);
|
||||||
interruptUploadDueToDuplicateFile();
|
interruptUploadDueToDuplicateFile();
|
||||||
event.getUpload().interruptUpload();
|
event.getUpload().interruptUpload();
|
||||||
@@ -115,7 +118,6 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public OutputStream receiveUpload(final String fileName, final String mimeType) {
|
public OutputStream receiveUpload(final String fileName, final String mimeType) {
|
||||||
|
|
||||||
if (isUploadInterrupted()) {
|
if (isUploadInterrupted()) {
|
||||||
return ByteStreams.nullOutputStream();
|
return ByteStreams.nullOutputStream();
|
||||||
}
|
}
|
||||||
@@ -123,15 +125,14 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
|
|||||||
// we return the outputstream so we cannot close it here
|
// we return the outputstream so we cannot close it here
|
||||||
@SuppressWarnings("squid:S2095")
|
@SuppressWarnings("squid:S2095")
|
||||||
final PipedOutputStream outputStream = new PipedOutputStream();
|
final PipedOutputStream outputStream = new PipedOutputStream();
|
||||||
PipedInputStream inputStream = null;
|
|
||||||
try {
|
try {
|
||||||
inputStream = new PipedInputStream(outputStream);
|
PipedInputStream inputStream = new PipedInputStream(outputStream);
|
||||||
publishUploadProgressEvent(fileUploadId, 0, 0);
|
publishUploadProgressEvent(fileUploadId, 0, 0);
|
||||||
startTransferToRepositoryThread(inputStream, fileUploadId, mimeType);
|
startTransferToRepositoryThread(inputStream, fileUploadId, mimeType);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
LOG.warn("Creating piped Stream failed {}.", e);
|
LOG.warn("Creating piped Stream failed!", e);
|
||||||
tryToCloseIOStream(outputStream);
|
tryToCloseIOStream(outputStream);
|
||||||
tryToCloseIOStream(inputStream);
|
// input stream is not created in case of an IOException
|
||||||
interruptUploadDueToUploadFailed();
|
interruptUploadDueToUploadFailed();
|
||||||
publishUploadFailedAndFinishedEvent(fileUploadId);
|
publishUploadFailedAndFinishedEvent(fileUploadId);
|
||||||
return ByteStreams.nullOutputStream();
|
return ByteStreams.nullOutputStream();
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public abstract class AbstractAddEntityWindowController<T, E, R> extends Abstrac
|
|||||||
* @param uiDependencies
|
* @param uiDependencies
|
||||||
* {@link CommonUiDependencies}
|
* {@link CommonUiDependencies}
|
||||||
*/
|
*/
|
||||||
public AbstractAddEntityWindowController(final CommonUiDependencies uiDependencies) {
|
protected AbstractAddEntityWindowController(final CommonUiDependencies uiDependencies) {
|
||||||
super(uiDependencies);
|
super(uiDependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public abstract class AbstractAddNamedEntityWindowController<T, E extends ProxyN
|
|||||||
* @param uiDependencies
|
* @param uiDependencies
|
||||||
* {@link CommonUiDependencies}
|
* {@link CommonUiDependencies}
|
||||||
*/
|
*/
|
||||||
public AbstractAddNamedEntityWindowController(final CommonUiDependencies uiDependencies) {
|
protected AbstractAddNamedEntityWindowController(final CommonUiDependencies uiDependencies) {
|
||||||
super(uiDependencies);
|
super(uiDependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public abstract class AbstractUpdateEntityWindowController<T, E, R> extends Abst
|
|||||||
* @param uiDependencies
|
* @param uiDependencies
|
||||||
* {@link CommonUiDependencies}
|
* {@link CommonUiDependencies}
|
||||||
*/
|
*/
|
||||||
public AbstractUpdateEntityWindowController(final CommonUiDependencies uiDependencies) {
|
protected AbstractUpdateEntityWindowController(final CommonUiDependencies uiDependencies) {
|
||||||
super(uiDependencies);
|
super(uiDependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public abstract class AbstractUpdateNamedEntityWindowController<T, E extends Pro
|
|||||||
* @param uiDependencies
|
* @param uiDependencies
|
||||||
* {@link CommonUiDependencies}
|
* {@link CommonUiDependencies}
|
||||||
*/
|
*/
|
||||||
public AbstractUpdateNamedEntityWindowController(final CommonUiDependencies uiDependencies) {
|
protected AbstractUpdateNamedEntityWindowController(final CommonUiDependencies uiDependencies) {
|
||||||
super(uiDependencies);
|
super(uiDependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.common.data.proxies;
|
package org.eclipse.hawkbit.ui.common.data.proxies;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.Identifiable;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.Identifiable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Proxy entity representing the {@link Identifiable} entity, fetched from
|
* Proxy entity representing the {@link Identifiable} entity, fetched from
|
||||||
@@ -23,7 +25,7 @@ public abstract class ProxyIdentifiableEntity implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Constructor to initialize the id with null
|
* Constructor to initialize the id with null
|
||||||
*/
|
*/
|
||||||
public ProxyIdentifiableEntity() {
|
protected ProxyIdentifiableEntity() {
|
||||||
this.id = null;
|
this.id = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +34,7 @@ public abstract class ProxyIdentifiableEntity implements Serializable {
|
|||||||
* @param id
|
* @param id
|
||||||
* Id of entity
|
* Id of entity
|
||||||
*/
|
*/
|
||||||
public ProxyIdentifiableEntity(final Long id) {
|
protected ProxyIdentifiableEntity(final Long id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,25 +66,13 @@ public abstract class ProxyIdentifiableEntity implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public boolean equals(final Object o) {
|
||||||
if (this == obj) {
|
if (this == o)
|
||||||
return true;
|
return true;
|
||||||
}
|
if (o == null || getClass() != o.getClass())
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
final ProxyIdentifiableEntity that = (ProxyIdentifiableEntity) o;
|
||||||
if (getClass() != obj.getClass()) {
|
return Objects.equals(id, that.id);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final ProxyIdentifiableEntity other = (ProxyIdentifiableEntity) obj;
|
|
||||||
if (id == null) {
|
|
||||||
if (other.id != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!id.equals(other.id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public abstract class ProxyNamedEntity extends ProxyIdentifiableEntity implement
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
public ProxyNamedEntity() {
|
protected ProxyNamedEntity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +41,7 @@ public abstract class ProxyNamedEntity extends ProxyIdentifiableEntity implement
|
|||||||
* @param id
|
* @param id
|
||||||
* Id of named entity
|
* Id of named entity
|
||||||
*/
|
*/
|
||||||
public ProxyNamedEntity(final Long id) {
|
protected ProxyNamedEntity(final Long id) {
|
||||||
super(id);
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public abstract class AbstractGridDetailsLayout<T extends ProxyNamedEntity> exte
|
|||||||
* @param i18n
|
* @param i18n
|
||||||
* VaadinMessageSource
|
* VaadinMessageSource
|
||||||
*/
|
*/
|
||||||
public AbstractGridDetailsLayout(final VaadinMessageSource i18n) {
|
protected AbstractGridDetailsLayout(final VaadinMessageSource i18n) {
|
||||||
this.i18n = i18n;
|
this.i18n = i18n;
|
||||||
|
|
||||||
this.binder = new Binder<>();
|
this.binder = new Binder<>();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import com.vaadin.server.Sizeable.Unit;
|
|||||||
import com.vaadin.ui.Window;
|
import com.vaadin.ui.Window;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract builder for Meta data window
|
* Abstract builder for metadata window
|
||||||
*
|
*
|
||||||
* @param <F>
|
* @param <F>
|
||||||
* Generic type
|
* Generic type
|
||||||
@@ -31,7 +31,7 @@ public abstract class AbstractMetaDataWindowBuilder<F> extends AbstractEntityWin
|
|||||||
* @param uiDependencies
|
* @param uiDependencies
|
||||||
* {@link CommonUiDependencies}
|
* {@link CommonUiDependencies}
|
||||||
*/
|
*/
|
||||||
public AbstractMetaDataWindowBuilder(final CommonUiDependencies uiDependencies) {
|
protected AbstractMetaDataWindowBuilder(final CommonUiDependencies uiDependencies) {
|
||||||
super(uiDependencies);
|
super(uiDependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public abstract class AbstractMetaDataWindowLayout<F> extends HorizontalLayout {
|
|||||||
* @param uiDependencies
|
* @param uiDependencies
|
||||||
* {@link CommonUiDependencies}
|
* {@link CommonUiDependencies}
|
||||||
*/
|
*/
|
||||||
public AbstractMetaDataWindowLayout(final CommonUiDependencies uiDependencies) {
|
protected AbstractMetaDataWindowLayout(final CommonUiDependencies uiDependencies) {
|
||||||
this.uiDependencies = uiDependencies;
|
this.uiDependencies = uiDependencies;
|
||||||
this.i18n = uiDependencies.getI18n();
|
this.i18n = uiDependencies.getI18n();
|
||||||
this.eventBus = uiDependencies.getEventBus();
|
this.eventBus = uiDependencies.getEventBus();
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public abstract class AbstractBreadcrumbGridHeader extends AbstractGridHeader {
|
|||||||
* @param eventBus
|
* @param eventBus
|
||||||
* UIEventBus
|
* UIEventBus
|
||||||
*/
|
*/
|
||||||
public AbstractBreadcrumbGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
protected AbstractBreadcrumbGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
||||||
final UIEventBus eventBus) {
|
final UIEventBus eventBus) {
|
||||||
super(i18n, permChecker, eventBus);
|
super(i18n, permChecker, eventBus);
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public abstract class AbstractDetailsHeader<T> extends AbstractMasterAwareGridHe
|
|||||||
* @param uiNotification
|
* @param uiNotification
|
||||||
* UINotification
|
* UINotification
|
||||||
*/
|
*/
|
||||||
public AbstractDetailsHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
protected AbstractDetailsHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
||||||
final UIEventBus eventBus, final UINotification uiNotification) {
|
final UIEventBus eventBus, final UINotification uiNotification) {
|
||||||
super(i18n, permChecker, eventBus);
|
super(i18n, permChecker, eventBus);
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ public abstract class AbstractDetailsHeader<T> extends AbstractMasterAwareGridHe
|
|||||||
addHeaderSupports(Arrays.asList(editDetailsHeaderSupport, metaDataDetailsHeaderSupport));
|
addHeaderSupports(Arrays.asList(editDetailsHeaderSupport, metaDataDetailsHeaderSupport));
|
||||||
}
|
}
|
||||||
|
|
||||||
// can be overriden in child classes for entity-specific permission
|
// can be overridden in child classes for entity-specific permission
|
||||||
protected boolean hasEditPermission() {
|
protected boolean hasEditPermission() {
|
||||||
return permChecker.hasUpdateRepositoryPermission();
|
return permChecker.hasUpdateRepositoryPermission();
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ public abstract class AbstractDetailsHeader<T> extends AbstractMasterAwareGridHe
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// can be overriden in child classes for entity-specific permission
|
// can be overridden in child classes for entity-specific permission
|
||||||
protected boolean hasMetadataReadPermission() {
|
protected boolean hasMetadataReadPermission() {
|
||||||
return permChecker.hasReadRepositoryPermission();
|
return permChecker.hasReadRepositoryPermission();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ public abstract class AbstractEntityGridHeader extends AbstractGridHeader {
|
|||||||
* @param view
|
* @param view
|
||||||
* EventView
|
* EventView
|
||||||
*/
|
*/
|
||||||
public AbstractEntityGridHeader(final CommonUiDependencies uiDependencies, final HidableLayoutUiState filterLayoutUiState,
|
protected AbstractEntityGridHeader(final CommonUiDependencies uiDependencies,
|
||||||
|
final HidableLayoutUiState filterLayoutUiState,
|
||||||
final GridLayoutUiState gridLayoutUiState, final EventLayout filterLayout, final EventView view) {
|
final GridLayoutUiState gridLayoutUiState, final EventLayout filterLayout, final EventView view) {
|
||||||
super(uiDependencies.getI18n(), uiDependencies.getPermChecker(), uiDependencies.getEventBus());
|
super(uiDependencies.getI18n(), uiDependencies.getPermChecker(), uiDependencies.getEventBus());
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public abstract class AbstractFilterHeader extends AbstractGridHeader {
|
|||||||
* @param eventBus
|
* @param eventBus
|
||||||
* UIEventBus
|
* UIEventBus
|
||||||
*/
|
*/
|
||||||
public AbstractFilterHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
protected AbstractFilterHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
||||||
final UIEventBus eventBus) {
|
final UIEventBus eventBus) {
|
||||||
super(i18n, permChecker, eventBus);
|
super(i18n, permChecker, eventBus);
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public abstract class AbstractGridHeader extends VerticalLayout {
|
|||||||
* @param eventBus
|
* @param eventBus
|
||||||
* UIEventBus
|
* UIEventBus
|
||||||
*/
|
*/
|
||||||
public AbstractGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
protected AbstractGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
||||||
final UIEventBus eventBus) {
|
final UIEventBus eventBus) {
|
||||||
this.i18n = i18n;
|
this.i18n = i18n;
|
||||||
this.permChecker = permChecker;
|
this.permChecker = permChecker;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public abstract class AbstractMasterAwareGridHeader<T> extends AbstractGridHeade
|
|||||||
* @param eventBus
|
* @param eventBus
|
||||||
* UIEventBus
|
* UIEventBus
|
||||||
*/
|
*/
|
||||||
public AbstractMasterAwareGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
protected AbstractMasterAwareGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
||||||
final UIEventBus eventBus) {
|
final UIEventBus eventBus) {
|
||||||
super(i18n, permChecker, eventBus);
|
super(i18n, permChecker, eventBus);
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class TargetFilterAddUpdateLayout extends AbstractEntityWindowLayout<Prox
|
|||||||
* @param rsqlValidationOracle
|
* @param rsqlValidationOracle
|
||||||
* RsqlValidationOracle
|
* RsqlValidationOracle
|
||||||
*/
|
*/
|
||||||
public TargetFilterAddUpdateLayout(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
protected TargetFilterAddUpdateLayout(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
|
||||||
final UiProperties uiProperties, final TargetFilterDetailsLayoutUiState uiState, final UIEventBus eventBus,
|
final UiProperties uiProperties, final TargetFilterDetailsLayoutUiState uiState, final UIEventBus eventBus,
|
||||||
final RsqlValidationOracle rsqlValidationOracle) {
|
final RsqlValidationOracle rsqlValidationOracle) {
|
||||||
super();
|
super();
|
||||||
@@ -140,7 +140,8 @@ public class TargetFilterAddUpdateLayout extends AbstractEntityWindowLayout<Prox
|
|||||||
autoCompleteComponent.addValidationListener((valid, message) -> searchButton.setEnabled(valid));
|
autoCompleteComponent.addValidationListener((valid, message) -> searchButton.setEnabled(valid));
|
||||||
autoCompleteComponent.addTextfieldChangedListener(this::onFilterQueryTextfieldChanged);
|
autoCompleteComponent.addTextfieldChangedListener(this::onFilterQueryTextfieldChanged);
|
||||||
autoCompleteComponent
|
autoCompleteComponent
|
||||||
.addShortcutListener(new ShortcutListener("List Filtered Targets", ShortcutAction.KeyCode.ENTER, null) {
|
.addShortcutListener(
|
||||||
|
new ShortcutListener("List Filtered Targets", ShortcutAction.KeyCode.ENTER, (int[]) null) {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -200,13 +201,6 @@ public class TargetFilterAddUpdateLayout extends AbstractEntityWindowLayout<Prox
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable search button
|
|
||||||
*/
|
|
||||||
public void disableSearchButton() {
|
|
||||||
searchButton.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check validity of target filter query.
|
* Check validity of target filter query.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public class DeploymentAssignmentWindowController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the given distribution sets to targets assignments
|
* Save the given distribution sets to target assignments
|
||||||
*
|
*
|
||||||
* @param proxyTargets
|
* @param proxyTargets
|
||||||
* to assign the given distribution sets to
|
* to assign the given distribution sets to
|
||||||
@@ -140,7 +140,7 @@ public class DeploymentAssignmentWindowController {
|
|||||||
EntityModifiedEventType.ENTITY_UPDATED, ProxyTarget.class, assignedTargetIds));
|
EntityModifiedEventType.ENTITY_UPDATED, ProxyTarget.class, assignedTargetIds));
|
||||||
} catch (final MultiAssignmentIsNotEnabledException e) {
|
} catch (final MultiAssignmentIsNotEnabledException e) {
|
||||||
notification.displayValidationError(i18n.getMessage("message.target.ds.multiassign.error"));
|
notification.displayValidationError(i18n.getMessage("message.target.ds.multiassign.error"));
|
||||||
LOG.error("UI allowed multiassignment although it is not enabled: {}", e);
|
LOG.error("UI allowed multi-assignment although it is not enabled", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,13 +12,14 @@ import java.io.Serializable;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.vaadin.data.Binder;
|
|
||||||
import com.vaadin.ui.CustomComponent;
|
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxySystemConfigWindow;
|
import org.eclipse.hawkbit.ui.common.data.proxies.ProxySystemConfigWindow;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import com.vaadin.data.Binder;
|
||||||
|
import com.vaadin.ui.CustomComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all configuration views. This class implements the logic for
|
* Base class for all configuration views. This class implements the logic for
|
||||||
* the handling of the configurations in a consistent way.
|
* the handling of the configurations in a consistent way.
|
||||||
@@ -33,7 +34,7 @@ public abstract class BaseConfigurationView<B extends ProxySystemConfigWindow> e
|
|||||||
private final transient TenantConfigurationManagement tenantConfigurationManagement;
|
private final transient TenantConfigurationManagement tenantConfigurationManagement;
|
||||||
private final Binder<B> binder;
|
private final Binder<B> binder;
|
||||||
|
|
||||||
public BaseConfigurationView(final TenantConfigurationManagement tenantConfigurationManagement) {
|
protected BaseConfigurationView(final TenantConfigurationManagement tenantConfigurationManagement) {
|
||||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
||||||
binder = new Binder<>();
|
binder = new Binder<>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import java.util.TimeZone;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.time.DurationFormatUtils;
|
import org.apache.commons.lang3.time.DurationFormatUtils;
|
||||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyNamedEntity;
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
@@ -99,10 +98,10 @@ public final class SPDateTimeUtil {
|
|||||||
*
|
*
|
||||||
* @param lastQueryDate
|
* @param lastQueryDate
|
||||||
* Last query date
|
* Last query date
|
||||||
* @return String formatted date
|
* @return String formatted date or {@code null} when the provided {@code lastQueryDate} was {@code null}
|
||||||
*/
|
*/
|
||||||
public static String getFormattedDate(final Long lastQueryDate) {
|
public static String getFormattedDate(final Long lastQueryDate) {
|
||||||
return formatDate(lastQueryDate, null);
|
return getFormattedDate(lastQueryDate, SPUIDefinitions.LAST_QUERY_DATE_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,67 +111,15 @@ public final class SPDateTimeUtil {
|
|||||||
* Last query date
|
* Last query date
|
||||||
* @param datePattern
|
* @param datePattern
|
||||||
* pattern how to format the date (cp. {@code SimpleDateFormat})
|
* pattern how to format the date (cp. {@code SimpleDateFormat})
|
||||||
* @return String formatted date
|
* @return String formatted date or {@code null} when the provided {@code lastQueryDate} was {@code null}
|
||||||
*/
|
*/
|
||||||
public static String getFormattedDate(final Long lastQueryDate, final String datePattern) {
|
public static String getFormattedDate(final Long lastQueryDate, final String datePattern) {
|
||||||
return formatDate(lastQueryDate, null, datePattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get formatted date 'created at' by entity.
|
|
||||||
*
|
|
||||||
* @param baseEntity
|
|
||||||
* the entity
|
|
||||||
* @return String formatted date
|
|
||||||
*/
|
|
||||||
public static String formatCreatedAt(final ProxyNamedEntity baseEntity) {
|
|
||||||
if (baseEntity == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return formatDate(baseEntity.getCreatedAt(), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get formatted date 'last modified at' by entity.
|
|
||||||
*
|
|
||||||
* @param baseEntity
|
|
||||||
* the entity
|
|
||||||
* @return String formatted date
|
|
||||||
*/
|
|
||||||
public static String formatLastModifiedAt(final ProxyNamedEntity baseEntity) {
|
|
||||||
if (baseEntity == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return formatDate(baseEntity.getLastModifiedAt(), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get formatted date 'last modified at' by entity.
|
|
||||||
*
|
|
||||||
* @param baseEntity
|
|
||||||
* the entity
|
|
||||||
* @param datePattern
|
|
||||||
* pattern how to format the date (cp. {@code SimpleDateFormat})
|
|
||||||
* @return String formatted date
|
|
||||||
*/
|
|
||||||
public static String formatLastModifiedAt(final ProxyNamedEntity baseEntity, final String datePattern) {
|
|
||||||
if (baseEntity == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return formatDate(baseEntity.getLastModifiedAt(), "", datePattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String formatDate(final Long lastQueryDate, final String defaultString, final String datePattern) {
|
|
||||||
if (lastQueryDate != null) {
|
if (lastQueryDate != null) {
|
||||||
final SimpleDateFormat format = new SimpleDateFormat(datePattern);
|
final SimpleDateFormat format = new SimpleDateFormat(datePattern);
|
||||||
format.setTimeZone(getBrowserTimeZone());
|
format.setTimeZone(getBrowserTimeZone());
|
||||||
return format.format(new Date(lastQueryDate));
|
return format.format(new Date(lastQueryDate));
|
||||||
}
|
}
|
||||||
return defaultString;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
private static String formatDate(final Long lastQueryDate, final String defaultString) {
|
|
||||||
return formatDate(lastQueryDate, defaultString, SPUIDefinitions.LAST_QUERY_DATE_FORMAT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,10 +173,10 @@ public final class SPDateTimeUtil {
|
|||||||
* Get time zone of the browser client to be used as default.
|
* Get time zone of the browser client to be used as default.
|
||||||
*/
|
*/
|
||||||
public static String getClientTimeZoneOffsetId() {
|
public static String getClientTimeZoneOffsetId() {
|
||||||
return getCurentZonedDateTime().getOffset().getId().replaceAll("Z", "+00:00");
|
return getCurrentZonedDateTime().getOffset().getId().replace("Z", "+00:00");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ZonedDateTime getCurentZonedDateTime() {
|
private static ZonedDateTime getCurrentZonedDateTime() {
|
||||||
return ZonedDateTime.now(getBrowserTimeZoneId());
|
return ZonedDateTime.now(getBrowserTimeZoneId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +190,7 @@ public final class SPDateTimeUtil {
|
|||||||
* @return Two weeks from current date and time in epoc milliseconds
|
* @return Two weeks from current date and time in epoc milliseconds
|
||||||
*/
|
*/
|
||||||
public static Long twoWeeksFromNowEpochMilli() {
|
public static Long twoWeeksFromNowEpochMilli() {
|
||||||
return getCurentZonedDateTime().plusWeeks(2).toInstant().toEpochMilli();
|
return getCurrentZonedDateTime().plusWeeks(2).toInstant().toEpochMilli();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -252,7 +199,7 @@ public final class SPDateTimeUtil {
|
|||||||
* @return Half an hour from current date and time in epoc milliseconds
|
* @return Half an hour from current date and time in epoc milliseconds
|
||||||
*/
|
*/
|
||||||
public static Long halfAnHourFromNowEpochMilli() {
|
public static Long halfAnHourFromNowEpochMilli() {
|
||||||
return getCurentZonedDateTime().plusMinutes(30).toInstant().toEpochMilli();
|
return getCurrentZonedDateTime().plusMinutes(30).toInstant().toEpochMilli();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ public class HawkbitCommonUtilTest {
|
|||||||
// WHEN
|
// WHEN
|
||||||
final Locale currentLocale2 = HawkbitCommonUtil.getCurrentLocale();
|
final Locale currentLocale2 = HawkbitCommonUtil.getCurrentLocale();
|
||||||
// THEN
|
// THEN
|
||||||
assertThat(Locale.GERMAN).isEqualTo(currentLocale2);
|
assertThat(currentLocale2).isEqualTo(Locale.GERMAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("If a default locale is set in the environment, then it should take perceedence over requested browser locale")
|
@Description("If a default locale is set in the environment, then it should take precedence over requested browser locale")
|
||||||
public void getLocaleToBeUsedShouldReturnDefaultLocalIfSet() {
|
public void getLocaleToBeUsedShouldReturnDefaultLocalIfSet() {
|
||||||
final UiProperties.Localization localizationProperties = Mockito.mock(UiProperties.Localization.class);
|
final UiProperties.Localization localizationProperties = Mockito.mock(UiProperties.Localization.class);
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ public class HawkbitCommonUtilTest {
|
|||||||
// WHEN
|
// WHEN
|
||||||
final Locale localeToBeUsed = HawkbitCommonUtil.getLocaleToBeUsed(localizationProperties, Locale.CHINESE);
|
final Locale localeToBeUsed = HawkbitCommonUtil.getLocaleToBeUsed(localizationProperties, Locale.CHINESE);
|
||||||
// THEN
|
// THEN
|
||||||
assertThat(Locale.GERMAN).isEqualTo(localeToBeUsed);
|
assertThat(localeToBeUsed).isEqualTo(Locale.GERMAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -74,7 +74,7 @@ public class HawkbitCommonUtilTest {
|
|||||||
// WHEN
|
// WHEN
|
||||||
final Locale localeToBeUsed = HawkbitCommonUtil.getLocaleToBeUsed(localizationProperties, Locale.GERMAN);
|
final Locale localeToBeUsed = HawkbitCommonUtil.getLocaleToBeUsed(localizationProperties, Locale.GERMAN);
|
||||||
// THEN
|
// THEN
|
||||||
assertThat(Locale.GERMAN).isEqualTo(localeToBeUsed);
|
assertThat(localeToBeUsed).isEqualTo(Locale.GERMAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
3
pom.xml
3
pom.xml
@@ -129,8 +129,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
|
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<!-- Developer preview -->
|
<!-- Developer preview: java.version = 11 -->
|
||||||
<!-- <java.version>11</java.version> -->
|
|
||||||
|
|
||||||
<spring.boot.version>2.3.7.RELEASE</spring.boot.version>
|
<spring.boot.version>2.3.7.RELEASE</spring.boot.version>
|
||||||
<spring.cloud.version>Hoxton.SR7</spring.cloud.version>
|
<spring.cloud.version>Hoxton.SR7</spring.cloud.version>
|
||||||
|
|||||||
Reference in New Issue
Block a user