Fix SonarQube issues (2) (#2205)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-01-20 16:29:45 +02:00
committed by GitHub
parent 385023d8b6
commit 5dabe9117a
33 changed files with 162 additions and 185 deletions

View File

@@ -18,12 +18,14 @@ import java.util.Objects;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.EqualsAndHashCode;
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;
/** /**
* {@link AbstractDbArtifact} implementation which dynamically creates a {@link FileInputStream} on calling {@link #getFileInputStream()}. * {@link AbstractDbArtifact} implementation which dynamically creates a {@link FileInputStream} on calling {@link #getFileInputStream()}.
*/ */
@EqualsAndHashCode(callSuper = true)
public class ArtifactFilesystem extends AbstractDbArtifact { public class ArtifactFilesystem extends AbstractDbArtifact {
private final File file; private final File file;

View File

@@ -49,6 +49,6 @@ class ArtifactFilesystemTest {
final ArtifactFilesystem underTest = new ArtifactFilesystem( final ArtifactFilesystem underTest = new ArtifactFilesystem(
createTempFile, ArtifactFilesystemTest.class.getSimpleName(), new DbArtifactHash("1", "2", "3"), 0L, null); createTempFile, ArtifactFilesystemTest.class.getSimpleName(), new DbArtifactHash("1", "2", "3"), 0L, null);
final byte[] buffer = new byte[1024]; final byte[] buffer = new byte[1024];
assertThat(IOUtils.read(underTest.getFileInputStream(), buffer)).isEqualTo(0); assertThat(IOUtils.read(underTest.getFileInputStream(), buffer)).isZero();
} }
} }

View File

@@ -20,7 +20,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.time.Instant;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@@ -33,7 +32,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory; import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
import com.fasterxml.jackson.dataformat.cbor.CBORGenerator; import com.fasterxml.jackson.dataformat.cbor.CBORGenerator;
import com.fasterxml.jackson.dataformat.cbor.CBORParser; import com.fasterxml.jackson.dataformat.cbor.CBORParser;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.hawkbit.ddi.json.model.DdiActionFeedback; import org.eclipse.hawkbit.ddi.json.model.DdiActionFeedback;
import org.eclipse.hawkbit.ddi.json.model.DdiAssignedVersion; import org.eclipse.hawkbit.ddi.json.model.DdiAssignedVersion;
import org.eclipse.hawkbit.ddi.json.model.DdiConfirmationFeedback; import org.eclipse.hawkbit.ddi.json.model.DdiConfirmationFeedback;
@@ -288,7 +286,7 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
protected String getJsonActionFeedback( protected String getJsonActionFeedback(
final DdiStatus.ExecutionStatus executionStatus, final DdiResult.FinalResult finalResult) throws JsonProcessingException { final DdiStatus.ExecutionStatus executionStatus, final DdiResult.FinalResult finalResult) throws JsonProcessingException {
return getJsonActionFeedback( return getJsonActionFeedback(
executionStatus, finalResult, Collections.singletonList(RandomStringUtils.randomAlphanumeric(1000))); executionStatus, finalResult, Collections.singletonList(randomString(1000)));
} }
protected String getJsonActionFeedback( protected String getJsonActionFeedback(

View File

@@ -24,25 +24,25 @@ import org.springframework.test.context.TestPropertySource;
"hawkbit.server.security.httpFirewallIgnoredPaths=/index.html" }) "hawkbit.server.security.httpFirewallIgnoredPaths=/index.html" })
@Feature("Integration Test - Security") @Feature("Integration Test - Security")
@Story("Allowed Host Names") @Story("Allowed Host Names")
public class AllowedHostNamesTest extends AbstractSecurityTest { class AllowedHostNamesTest extends AbstractSecurityTest {
@Test @Test
@Description("Tests whether a RequestRejectedException is thrown when not allowed host is used") @Description("Tests whether a RequestRejectedException is thrown when not allowed host is used")
public void allowedHostNameWithNotAllowedHost() throws Exception { void allowedHostNameWithNotAllowedHost() throws Exception {
mvc.perform(get("/").header(HttpHeaders.HOST, "www.google.com")) mvc.perform(get("/").header(HttpHeaders.HOST, "www.google.com"))
.andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());
} }
@Test @Test
@Description("Tests whether request is redirected when allowed host is used") @Description("Tests whether request is redirected when allowed host is used")
public void allowedHostNameWithAllowedHost() throws Exception { void allowedHostNameWithAllowedHost() throws Exception {
mvc.perform(get("/").header(HttpHeaders.HOST, "localhost")) mvc.perform(get("/").header(HttpHeaders.HOST, "localhost"))
.andExpect(status().is3xxRedirection()); .andExpect(status().is3xxRedirection());
} }
@Test @Test
@Description("Tests whether request without allowed host name and with ignored path end up with a client error") @Description("Tests whether request without allowed host name and with ignored path end up with a client error")
public void notAllowedHostnameWithIgnoredPath() throws Exception { void notAllowedHostnameWithIgnoredPath() throws Exception {
mvc.perform(get("/index.html").header(HttpHeaders.HOST, "www.google.com")) mvc.perform(get("/index.html").header(HttpHeaders.HOST, "www.google.com"))
.andExpect(status().is4xxClientError()); .andExpect(status().is4xxClientError());
} }

View File

@@ -32,8 +32,8 @@ public final class AmqpErrorMessageComposer {
*/ */
public static String constructErrorMessage(final Throwable throwable) { public static String constructErrorMessage(final Throwable throwable) {
final String mainErrorMsg = throwable.getCause().getMessage(); final String mainErrorMsg = throwable.getCause().getMessage();
if (throwable instanceof ListenerExecutionFailedException) { if (throwable instanceof ListenerExecutionFailedException listenerExecutionFailedException) {
Collection<Message> failedMessages = ((ListenerExecutionFailedException) throwable).getFailedMessages(); Collection<Message> failedMessages = listenerExecutionFailedException.getFailedMessages();
// since the intended message content is always on top of the collection, we only extract the first one // since the intended message content is always on top of the collection, we only extract the first one
final Message failedMessage = failedMessages.iterator().next(); final Message failedMessage = failedMessages.iterator().next();
final byte[] amqpFailedMsgBody = failedMessage.getBody(); final byte[] amqpFailedMsgBody = failedMessage.getBody();

View File

@@ -370,7 +370,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
// Handling remote request in parallel streams // Handling remote request in parallel streams
return StreamSupport.stream(partitions.spliterator(), true) // return StreamSupport.stream(partitions.spliterator(), true) //
.flatMap(partition -> withSecurityContext(() -> loadingFunction.apply(partition), context).stream()) .flatMap(partition -> withSecurityContext(() -> loadingFunction.apply(partition), context).stream())
.collect(Collectors.toList()); .toList();
} }
return loadingFunction.apply(controllerIds); return loadingFunction.apply(controllerIds);
} }
@@ -436,7 +436,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
return false; return false;
} }
return true; return true;
}).collect(Collectors.toList())); }).toList());
} }
private void sendUpdateMessageToTargets( private void sendUpdateMessageToTargets(
@@ -570,7 +570,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
} }
private List<DmfMetadata> convertMetadata(final List<SoftwareModuleMetadata> metadata) { private List<DmfMetadata> convertMetadata(final List<SoftwareModuleMetadata> metadata) {
return metadata.stream().map(md -> new DmfMetadata(md.getKey(), md.getValue())).collect(Collectors.toList()); return metadata.stream().map(md -> new DmfMetadata(md.getKey(), md.getValue())).toList();
} }
private List<DmfArtifact> convertArtifacts(final Target target, final List<Artifact> localArtifacts) { private List<DmfArtifact> convertArtifacts(final Target target, final List<Artifact> localArtifacts) {
@@ -579,7 +579,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
} }
return localArtifacts.stream().map(localArtifact -> convertArtifact(target, localArtifact)) return localArtifacts.stream().map(localArtifact -> convertArtifact(target, localArtifact))
.collect(Collectors.toList()); .toList();
} }
private DmfArtifact convertArtifact(final Target target, final Artifact localArtifact) { private DmfArtifact convertArtifact(final Target target, final Artifact localArtifact) {
@@ -619,7 +619,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
final List<DmfTarget> dmfTargets = targets.stream() final List<DmfTarget> dmfTargets = targets.stream()
.filter(target -> IpUtil.isAmqpUri(target.getAddress())) .filter(target -> IpUtil.isAmqpUri(target.getAddress()))
.map(t -> convertToDmfTarget(t, actions.get(t.getControllerId()).getId())) .map(t -> convertToDmfTarget(t, actions.get(t.getControllerId()).getId()))
.collect(Collectors.toList()); .toList();
final DmfBatchDownloadAndUpdateRequest batchRequest = new DmfBatchDownloadAndUpdateRequest(); final DmfBatchDownloadAndUpdateRequest batchRequest = new DmfBatchDownloadAndUpdateRequest();
batchRequest.setTimestamp(System.currentTimeMillis()); batchRequest.setTimestamp(System.currentTimeMillis());

View File

@@ -23,6 +23,8 @@ import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic; import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey; import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
@@ -215,7 +217,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
// Exception squid:MethodCyclomaticComplexity - false positive, is a simple mapping // Exception squid:MethodCyclomaticComplexity - false positive, is a simple mapping
@SuppressWarnings("squid:MethodCyclomaticComplexity") @SuppressWarnings("squid:MethodCyclomaticComplexity")
private static Status mapStatus(final Message message, final DmfActionUpdateStatus actionUpdateStatus, final Action action) { private static @NotNull Status mapStatus(final Message message, final DmfActionUpdateStatus actionUpdateStatus, final Action action) {
Status status = null; Status status = null;
switch (actionUpdateStatus.getActionStatus()) { switch (actionUpdateStatus.getActionStatus()) {
case DOWNLOAD: { case DOWNLOAD: {
@@ -226,8 +228,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
status = Status.RETRIEVED; status = Status.RETRIEVED;
break; break;
} }
case RUNNING: case RUNNING, CONFIRMED: {
case CONFIRMED: {
status = Status.RUNNING; status = Status.RUNNING;
break; break;
} }
@@ -373,7 +374,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
} }
private Map<SoftwareModule, List<SoftwareModuleMetadata>> getSoftwareModulesWithMetadata(final DistributionSet distributionSet) { private Map<SoftwareModule, List<SoftwareModuleMetadata>> getSoftwareModulesWithMetadata(final DistributionSet distributionSet) {
final List<Long> smIds = distributionSet.getModules().stream().map(SoftwareModule::getId).collect(Collectors.toList()); final List<Long> smIds = distributionSet.getModules().stream().map(SoftwareModule::getId).toList();
final Map<Long, List<SoftwareModuleMetadata>> metadata = controllerManagement.findTargetVisibleMetaDataBySoftwareModuleId(smIds); final Map<Long, List<SoftwareModuleMetadata>> metadata = controllerManagement.findTargetVisibleMetaDataBySoftwareModuleId(smIds);
return distributionSet.getModules().stream().collect(Collectors.toMap( return distributionSet.getModules().stream().collect(Collectors.toMap(
Function.identity(), sm -> metadata.getOrDefault(sm.getId(), Collections.emptyList()))); Function.identity(), sm -> metadata.getOrDefault(sm.getId(), Collections.emptyList())));

View File

@@ -83,7 +83,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
private Target testTarget; private Target testTarget;
@BeforeEach @BeforeEach
public void beforeEach() throws Exception { public void beforeEach() {
testTarget = targetManagement.create(entityFactory.target().create().controllerId(CONTROLLER_ID) testTarget = targetManagement.create(entityFactory.target().create().controllerId(CONTROLLER_ID)
.securityToken(TEST_TOKEN).address(AMQP_URI.toString())); .securityToken(TEST_TOKEN).address(AMQP_URI.toString()));
@@ -135,8 +135,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
assertThat(downloadAndUpdateRequest.getTargetSecurityToken()).isEqualTo(TEST_TOKEN); assertThat(downloadAndUpdateRequest.getTargetSecurityToken()).isEqualTo(TEST_TOKEN);
for (final org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule softwareModule : downloadAndUpdateRequest for (final org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule softwareModule : downloadAndUpdateRequest
.getSoftwareModules()) { .getSoftwareModules()) {
assertThat(softwareModule.getArtifacts().isEmpty()).as("Artifact list for softwaremodule should be empty") assertThat(softwareModule.getArtifacts()).as("Artifact list for softwaremodule should be empty").isEmpty();
.isTrue();
assertThat(softwareModule.getMetadata()).allSatisfy(metadata -> { assertThat(softwareModule.getMetadata()).allSatisfy(metadata -> {
assertThat(metadata.getKey()).isEqualTo(TestdataFactory.VISIBLE_SM_MD_KEY); assertThat(metadata.getKey()).isEqualTo(TestdataFactory.VISIBLE_SM_MD_KEY);
@@ -202,7 +201,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
assertThat(found.get().getSize()).isEqualTo(dbArtifact.getSize()); assertThat(found.get().getSize()).isEqualTo(dbArtifact.getSize());
assertThat(found.get().getHashes().getMd5()).isEqualTo(dbArtifact.getMd5Hash()); assertThat(found.get().getHashes().getMd5()).isEqualTo(dbArtifact.getMd5Hash());
assertThat(found.get().getHashes().getSha1()).isEqualTo(dbArtifact.getSha1Hash()); assertThat(found.get().getHashes().getSha1()).isEqualTo(dbArtifact.getSha1Hash());
assertThat(found.get().getLastModified()).isGreaterThan(0L); assertThat(found.get().getLastModified()).isPositive();
}); });
} }
} }

View File

@@ -78,7 +78,7 @@ import org.springframework.amqp.support.converter.MessageConverter;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
@Feature("Component Tests - Device Management Federation API") @Feature("Component Tests - Device Management Federation API")
@Story("AmqpMessage Handler Service Test") @Story("AmqpMessage Handler Service Test")
public class AmqpMessageHandlerServiceTest { class AmqpMessageHandlerServiceTest {
private static final String FAIL_MESSAGE_AMQP_REJECT_REASON = AmqpRejectAndDontRequeueException.class private static final String FAIL_MESSAGE_AMQP_REJECT_REASON = AmqpRejectAndDontRequeueException.class
.getSimpleName() + " was expected, "; .getSimpleName() + " was expected, ";
@@ -128,7 +128,7 @@ public class AmqpMessageHandlerServiceTest {
@BeforeEach @BeforeEach
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
public void before() { void before() {
messageConverter = new Jackson2JsonMessageConverter(); messageConverter = new Jackson2JsonMessageConverter();
lenient().when(rabbitTemplate.getMessageConverter()).thenReturn(messageConverter); lenient().when(rabbitTemplate.getMessageConverter()).thenReturn(messageConverter);
final TenantConfigurationValue multiAssignmentConfig = TenantConfigurationValue.builder().value(Boolean.FALSE) final TenantConfigurationValue multiAssignmentConfig = TenantConfigurationValue.builder().value(Boolean.FALSE)
@@ -146,19 +146,20 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Tests not allowed content-type in message") @Description("Tests not allowed content-type in message")
public void wrongContentType() { void wrongContentType() {
final MessageProperties messageProperties = new MessageProperties(); final MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentType("xml"); messageProperties.setContentType("xml");
final Message message = new Message(new byte[0], messageProperties); final Message message = new Message(new byte[0], messageProperties);
final String type = MessageType.THING_CREATED.name();
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to wrong content type") .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to wrong content type")
.isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT,
VIRTUAL_HOST)); VIRTUAL_HOST));
} }
@Test @Test
@Description("Tests the creation of a target/thing by calling the same method that incoming RabbitMQ messages would access.") @Description("Tests the creation of a target/thing by calling the same method that incoming RabbitMQ messages would access.")
public void createThing() { void createThing() {
final String knownThingId = "1"; final String knownThingId = "1";
processThingCreatedMessage(knownThingId, null); processThingCreatedMessage(knownThingId, null);
@@ -169,7 +170,7 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Tests the creation of a target/thing with specified name by calling the same method that incoming RabbitMQ messages would access.") @Description("Tests the creation of a target/thing with specified name by calling the same method that incoming RabbitMQ messages would access.")
public void createThingWithName() { void createThingWithName() {
final String knownThingId = "2"; final String knownThingId = "2";
final String knownThingName = "NonDefaultTargetName"; final String knownThingName = "NonDefaultTargetName";
@@ -185,7 +186,7 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Tests the creation of a target/thing with specified type name by calling the same method that incoming RabbitMQ messages would access.") @Description("Tests the creation of a target/thing with specified type name by calling the same method that incoming RabbitMQ messages would access.")
public void createThingWithType() { void createThingWithType() {
final String knownThingId = "2"; final String knownThingId = "2";
final String knownThingTypeName = "TargetTypeName"; final String knownThingTypeName = "TargetTypeName";
@@ -201,19 +202,17 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Tests not allowed body in message") @Description("Tests not allowed body in message")
public void createThingWithWrongBody() { void createThingWithWrongBody() {
final String knownThingId = "3"; final Message message = createMessage("Not allowed Body".getBytes(), getThingCreatedMessageProperties("3"));
final String type = MessageType.THING_CREATED.name();
assertThatExceptionOfType(MessageConversionException.class) assertThatExceptionOfType(MessageConversionException.class)
.as("MessageConversionException was excepeted due to wrong body") .as("MessageConversionException was excepeted due to wrong body")
.isThrownBy(() -> amqpMessageHandlerService.onMessage( .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT, VIRTUAL_HOST));
createMessage("Not allowed Body".getBytes(), getThingCreatedMessageProperties(knownThingId)),
MessageType.THING_CREATED.name(), TENANT, VIRTUAL_HOST));
} }
@Test @Test
@Description("Tests the creation of a target/thing with specified attributes by calling the same method that incoming RabbitMQ messages would access.") @Description("Tests the creation of a target/thing with specified attributes by calling the same method that incoming RabbitMQ messages would access.")
public void createThingWithAttributes() { void createThingWithAttributes() {
final String knownThingId = "4"; final String knownThingId = "4";
final DmfAttributeUpdate attributeUpdate = new DmfAttributeUpdate(); final DmfAttributeUpdate attributeUpdate = new DmfAttributeUpdate();
@@ -232,7 +231,7 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Tests the creation of a target/thing with specified name and attributes by calling the same method that incoming RabbitMQ messages would access.") @Description("Tests the creation of a target/thing with specified name and attributes by calling the same method that incoming RabbitMQ messages would access.")
public void createThingWithNameAndAttributes() { void createThingWithNameAndAttributes() {
final String knownThingId = "5"; final String knownThingId = "5";
final String knownThingName = "NonDefaultTargetName"; final String knownThingName = "NonDefaultTargetName";
@@ -255,7 +254,7 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Tests the target attribute update by calling the same method that incoming RabbitMQ messages would access.") @Description("Tests the target attribute update by calling the same method that incoming RabbitMQ messages would access.")
public void updateAttributes() { void updateAttributes() {
final String knownThingId = "1"; final String knownThingId = "1";
final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT);
messageProperties.setHeader(MessageHeaderKey.THING_ID, knownThingId); messageProperties.setHeader(MessageHeaderKey.THING_ID, knownThingId);
@@ -277,7 +276,7 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Verifies that the update mode is retrieved from the UPDATE_ATTRIBUTES message and passed to the controller management.") @Description("Verifies that the update mode is retrieved from the UPDATE_ATTRIBUTES message and passed to the controller management.")
public void attributeUpdateModes() { void attributeUpdateModes() {
final String knownThingId = "1"; final String knownThingId = "1";
final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT);
messageProperties.setHeader(MessageHeaderKey.THING_ID, knownThingId); messageProperties.setHeader(MessageHeaderKey.THING_ID, knownThingId);
@@ -320,32 +319,30 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Tests the creation of a thing without a 'reply to' header in message.") @Description("Tests the creation of a thing without a 'reply to' header in message.")
public void createThingWithoutReplyTo() { void createThingWithoutReplyTo() {
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED, null); final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED, null);
messageProperties.setHeader(MessageHeaderKey.THING_ID, "1"); messageProperties.setHeader(MessageHeaderKey.THING_ID, "1");
final Message message = createMessage("", messageProperties); final Message message = createMessage("", messageProperties);
final String type = MessageType.THING_CREATED.name();
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no replyTo header was set") .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no replyTo header was set")
.isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT, VIRTUAL_HOST));
VIRTUAL_HOST));
} }
@Test @Test
@Description("Tests the creation of a target/thing without a thingID by calling the same method that incoming RabbitMQ messages would access.") @Description("Tests the creation of a target/thing without a thingID by calling the same method that incoming RabbitMQ messages would access.")
public void createThingWithoutID() { void createThingWithoutID() {
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED); final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED);
final Message message = createMessage(new byte[0], messageProperties); final Message message = createMessage(new byte[0], messageProperties);
final String type = MessageType.THING_CREATED.name();
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no thingId was set") .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no thingId was set")
.isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT, VIRTUAL_HOST));
VIRTUAL_HOST));
} }
@Test @Test
@Description("Tests the call of the same method that incoming RabbitMQ messages would access with an unknown message type.") @Description("Tests the call of the same method that incoming RabbitMQ messages would access with an unknown message type.")
public void unknownMessageType() { void unknownMessageType() {
final String type = "bumlux"; final String type = "bumlux";
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED); final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED);
messageProperties.setHeader(MessageHeaderKey.THING_ID, ""); messageProperties.setHeader(MessageHeaderKey.THING_ID, "");
@@ -358,7 +355,7 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Tests a invalid message without event topic") @Description("Tests a invalid message without event topic")
public void invalidEventTopic() { void invalidEventTopic() {
final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT);
final Message message = new Message(new byte[0], messageProperties); final Message message = new Message(new byte[0], messageProperties);
@@ -366,52 +363,51 @@ public class AmqpMessageHandlerServiceTest {
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown message type").isThrownBy( .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown message type").isThrownBy(
() -> amqpMessageHandlerService.onMessage(message, "unknownMessageType", TENANT, VIRTUAL_HOST)); () -> amqpMessageHandlerService.onMessage(message, "unknownMessageType", TENANT, VIRTUAL_HOST));
final String type = MessageType.EVENT.name();
messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic"); messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic");
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown topic").isThrownBy(() -> amqpMessageHandlerService .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown topic")
.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST)); .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT, VIRTUAL_HOST));
messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name()); messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name());
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "because there was no event topic") .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "because there was no event topic")
.isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT, VIRTUAL_HOST));
VIRTUAL_HOST));
} }
@Test @Test
@Description("Tests the update of an action of a target without a exist action id") @Description("Tests the update of an action of a target without a exist action id")
public void updateActionStatusWithoutActionId() { void updateActionStatusWithoutActionId() {
when(controllerManagementMock.findActionWithDetails(anyLong())).thenReturn(Optional.empty()); when(controllerManagementMock.findActionWithDetails(anyLong())).thenReturn(Optional.empty());
final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT);
messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name()); messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name());
final DmfActionUpdateStatus actionUpdateStatus = new DmfActionUpdateStatus(1L, DmfActionStatus.DOWNLOAD); final DmfActionUpdateStatus actionUpdateStatus = new DmfActionUpdateStatus(1L, DmfActionStatus.DOWNLOAD);
final Message message = createMessage(actionUpdateStatus, messageProperties); final Message message = createMessage(actionUpdateStatus, messageProperties);
final String type = MessageType.EVENT.name();
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no action id was set") .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no action id was set")
.isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT, VIRTUAL_HOST));
VIRTUAL_HOST));
} }
@Test @Test
@Description("Tests the update of an action of a target without a exist action id") @Description("Tests the update of an action of a target without a exist action id")
public void updateActionStatusWithoutExistActionId() { void updateActionStatusWithoutExistActionId() {
final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT);
messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name()); messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name());
when(controllerManagementMock.findActionWithDetails(anyLong())).thenReturn(Optional.empty()); when(controllerManagementMock.findActionWithDetails(anyLong())).thenReturn(Optional.empty());
final DmfActionUpdateStatus actionUpdateStatus = createActionUpdateStatus(DmfActionStatus.DOWNLOAD); final DmfActionUpdateStatus actionUpdateStatus = createActionUpdateStatus(DmfActionStatus.DOWNLOAD);
final Message message = createMessage(actionUpdateStatus, messageProperties); final Message message = createMessage(actionUpdateStatus, messageProperties);
final String type = MessageType.EVENT.name();
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no action id was set") .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no action id was set")
.isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT,
VIRTUAL_HOST)); VIRTUAL_HOST));
} }
@Test @Test
@Description("Tests that messages which cause quota violations are not re-added to message queue so they would block other communication.") @Description("Tests that messages which cause quota violations are not re-added to message queue so they would block other communication.")
public void quotaExceeded() { void quotaExceeded() {
final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT);
messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name()); messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name());
@@ -429,14 +425,14 @@ public class AmqpMessageHandlerServiceTest {
when(controllerManagementMock.findActionWithDetails(anyLong())).thenReturn(Optional.of(action)); when(controllerManagementMock.findActionWithDetails(anyLong())).thenReturn(Optional.of(action));
when(controllerManagementMock.addUpdateActionStatus(any())).thenThrow(new AssignmentQuotaExceededException()); when(controllerManagementMock.addUpdateActionStatus(any())).thenThrow(new AssignmentQuotaExceededException());
final String type = MessageType.EVENT.name();
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
.isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT, VIRTUAL_HOST));
VIRTUAL_HOST));
} }
@Test @Test
@Description("Test next update is provided on finished action") @Description("Test next update is provided on finished action")
public void lookupNextUpdateActionAfterFinished() throws IllegalAccessException { void lookupNextUpdateActionAfterFinished() throws IllegalAccessException {
// Mock // Mock
final Action action = createActionWithTarget(22L); final Action action = createActionWithTarget(22L);
@@ -473,7 +469,7 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Test feedback code is persisted in messages when provided with DmfActionUpdateStatus") @Description("Test feedback code is persisted in messages when provided with DmfActionUpdateStatus")
public void feedBackCodeIsPersistedInMessages() throws IllegalAccessException { void feedBackCodeIsPersistedInMessages() throws IllegalAccessException {
// Mock // Mock
final Action action = createActionWithTarget(22L); final Action action = createActionWithTarget(22L);
@@ -509,7 +505,7 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Tests the deletion of a target/thing, requested by the target itself.") @Description("Tests the deletion of a target/thing, requested by the target itself.")
public void deleteThing() { void deleteThing() {
// prepare valid message // prepare valid message
final String knownThingId = "1"; final String knownThingId = "1";
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_REMOVED); final MessageProperties messageProperties = createMessageProperties(MessageType.THING_REMOVED);
@@ -525,15 +521,15 @@ public class AmqpMessageHandlerServiceTest {
@Test @Test
@Description("Tests the deletion of a target/thing with missing thingId") @Description("Tests the deletion of a target/thing with missing thingId")
public void deleteThingWithoutThingId() { void deleteThingWithoutThingId() {
// prepare invalid message // prepare invalid message
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_REMOVED); final MessageProperties messageProperties = createMessageProperties(MessageType.THING_REMOVED);
final Message message = createMessage(new byte[0], messageProperties); final Message message = createMessage(new byte[0], messageProperties);
final String type = MessageType.THING_REMOVED.name();
assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class)
.as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no thingId was set") .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no thingId was set")
.isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.THING_REMOVED.name(), TENANT, .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT, VIRTUAL_HOST));
VIRTUAL_HOST));
} }
@Test @Test

View File

@@ -382,9 +382,9 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
createConditionFactory().untilAsserted(() -> { createConditionFactory().untilAsserted(() -> {
try { try {
final Map<String, String> controllerAttributes = SecurityContextSwitch final Map<String, String> controllerAttributes = SecurityContextSwitch.runAsPrivileged(
.runAsPrivileged(() -> targetManagement.getControllerAttributes(controllerId)); () -> targetManagement.getControllerAttributes(controllerId));
assertThat(controllerAttributes.size()).isEqualTo(attributes.size()); assertThat(controllerAttributes).hasSameSizeAs(attributes);
assertThat(controllerAttributes).containsAllEntriesOf(attributes); assertThat(controllerAttributes).containsAllEntriesOf(attributes);
} catch (final Exception e) { } catch (final Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);

View File

@@ -227,12 +227,12 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
registerAndAssertTargetWithExistingTenant(controllerId); registerAndAssertTargetWithExistingTenant(controllerId);
final Long actionId1 = assignNewDsToTarget(controllerId, 450); final Long actionId1 = assignNewDsToTarget(controllerId, 450);
final Entry<Long, EventTopic> action1Install = new SimpleEntry<>(actionId1, EventTopic.DOWNLOAD_AND_INSTALL); final SimpleEntry<Long, EventTopic> action1Install = new SimpleEntry<>(actionId1, EventTopic.DOWNLOAD_AND_INSTALL);
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION);
assertLatestMultiActionMessage(controllerId, Collections.singletonList(action1Install)); assertLatestMultiActionMessage(controllerId, Collections.singletonList(action1Install));
final Long actionId2 = assignNewDsToTarget(controllerId, 111); final Long actionId2 = assignNewDsToTarget(controllerId, 111);
final Entry<Long, EventTopic> action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL); final SimpleEntry<Long, EventTopic> action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL);
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION);
assertLatestMultiActionMessage(controllerId, Arrays.asList(action1Install, action2Install)); assertLatestMultiActionMessage(controllerId, Arrays.asList(action1Install, action2Install));
} }
@@ -315,8 +315,8 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
deploymentManagement.cancelAction(actionId1); deploymentManagement.cancelAction(actionId1);
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION);
final Entry<Long, EventTopic> action1Cancel = new SimpleEntry<>(actionId1, EventTopic.CANCEL_DOWNLOAD); final SimpleEntry<Long, EventTopic> action1Cancel = new SimpleEntry<>(actionId1, EventTopic.CANCEL_DOWNLOAD);
final Entry<Long, EventTopic> action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL); final SimpleEntry<Long, EventTopic> action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL);
assertLatestMultiActionMessage(controllerId, Arrays.asList(action1Cancel, action2Install)); assertLatestMultiActionMessage(controllerId, Arrays.asList(action1Cancel, action2Install));
updateActionViaDmfClient(controllerId, actionId1, DmfActionStatus.CANCELED); updateActionViaDmfClient(controllerId, actionId1, DmfActionStatus.CANCELED);
@@ -349,7 +349,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
final long actionId1 = assignNewDsToTarget(controllerId, 66); final long actionId1 = assignNewDsToTarget(controllerId, 66);
final long actionId2 = assignNewDsToTarget(controllerId, 767); final long actionId2 = assignNewDsToTarget(controllerId, 767);
final Entry<Long, EventTopic> action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL); final SimpleEntry<Long, EventTopic> action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL);
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION, EventTopic.MULTI_ACTION); waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION, EventTopic.MULTI_ACTION);
updateActionViaDmfClient(controllerId, actionId1, DmfActionStatus.FINISHED); updateActionViaDmfClient(controllerId, actionId1, DmfActionStatus.FINISHED);
@@ -385,8 +385,8 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
final Long actionId2 = getFirstAssignedAction(assignDistributionSet(dsId, controllerId, 775)).getId(); final Long actionId2 = getFirstAssignedAction(assignDistributionSet(dsId, controllerId, 775)).getId();
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION);
final Entry<Long, EventTopic> action1Install = new SimpleEntry<>(actionId1, EventTopic.DOWNLOAD_AND_INSTALL); final SimpleEntry<Long, EventTopic> action1Install = new SimpleEntry<>(actionId1, EventTopic.DOWNLOAD_AND_INSTALL);
final Entry<Long, EventTopic> action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL); final SimpleEntry<Long, EventTopic> action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL);
assertLatestMultiActionMessage(controllerId, Arrays.asList(action1Install, action2Install)); assertLatestMultiActionMessage(controllerId, Arrays.asList(action1Install, action2Install));
} }
@@ -567,9 +567,10 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
assertThat(message).isNotNull(); assertThat(message).isNotNull();
final Map<String, Object> headers = message.getMessageProperties().getHeaders(); final Map<String, Object> headers = message.getMessageProperties().getHeaders();
assertThat(headers).containsEntry("thingId", controllerId); assertThat(headers)
assertThat(headers).containsEntry("type", EVENT.toString()); .containsEntry("thingId", controllerId)
assertThat(headers).containsEntry("topic", DOWNLOAD.toString()); .containsEntry("type", EVENT.toString())
.containsEntry("topic", DOWNLOAD.toString());
final Optional<Target> target = controllerManagement.getByControllerId(controllerId); final Optional<Target> target = controllerManagement.getByControllerId(controllerId);
assertThat(target).isPresent(); assertThat(target).isPresent();
@@ -596,11 +597,11 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
final List<String> controllerIds) { final List<String> controllerIds) {
assertSoftwareModules(softwareModules, request.getSoftwareModules()); assertSoftwareModules(softwareModules, request.getSoftwareModules());
final List<Object> tokens = controllerIds.stream().map(controllerId -> { final List<String> tokens = controllerIds.stream().map(controllerId -> {
final Optional<Target> target = controllerManagement.getByControllerId(controllerId); final Optional<Target> target = controllerManagement.getByControllerId(controllerId);
assertThat(target).isPresent(); assertThat(target).isPresent();
return target.get().getSecurityToken(); return target.get().getSecurityToken();
}).collect(Collectors.toList()); }).toList();
final List<DmfTarget> requestTargets = request.getTargets(); final List<DmfTarget> requestTargets = request.getTargets();
@@ -700,7 +701,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
private static List<DmfDownloadAndUpdateRequest> getDownloadAndUpdateRequests(final DmfMultiActionRequest request) { private static List<DmfDownloadAndUpdateRequest> getDownloadAndUpdateRequests(final DmfMultiActionRequest request) {
return request.getElements().stream() return request.getElements().stream()
.filter(AmqpMessageDispatcherServiceIntegrationTest::isDownloadAndUpdateRequest) .filter(AmqpMessageDispatcherServiceIntegrationTest::isDownloadAndUpdateRequest)
.map(multiAction -> (DmfDownloadAndUpdateRequest) multiAction.getAction()).collect(Collectors.toList()); .map(multiAction -> (DmfDownloadAndUpdateRequest) multiAction.getAction()).toList();
} }
private static boolean isDownloadAndUpdateRequest(final DmfMultiActionElement multiActionElement) { private static boolean isDownloadAndUpdateRequest(final DmfMultiActionElement multiActionElement) {
@@ -767,20 +768,20 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
.fromMessage(multiactionMessage); .fromMessage(multiactionMessage);
final List<Set<Long>> smIdsOfActionsFound = getDownloadAndUpdateRequests(multiActionRequest).stream() final List<Set<Long>> smIdsOfActionsFound = getDownloadAndUpdateRequests(multiActionRequest).stream()
.map(AmqpMessageDispatcherServiceIntegrationTest::getSmIds).collect(Collectors.toList()); .map(AmqpMessageDispatcherServiceIntegrationTest::getSmIds).toList();
assertThat(smIdsOfActionsFound).containsExactlyInAnyOrderElementsOf(smIdsOfActionsExpected); assertThat(smIdsOfActionsFound).containsExactlyInAnyOrderElementsOf(smIdsOfActionsExpected);
} }
private void assertLatestMultiActionMessage(final String controllerId, private void assertLatestMultiActionMessage(final String controllerId,
final List<Entry<Long, EventTopic>> actionsExpected) { final List<SimpleEntry<Long, EventTopic>> actionsExpected) {
final List<Entry<Long, EventTopic>> actionsFromMessage = getLatestMultiActionMessageActions(controllerId); final List<SimpleEntry<Long, EventTopic>> actionsFromMessage = getLatestMultiActionMessageActions(controllerId);
assertThat(actionsFromMessage).containsExactlyInAnyOrderElementsOf(actionsExpected); assertThat(actionsFromMessage).containsExactlyInAnyOrderElementsOf(actionsExpected);
} }
private List<Entry<Long, EventTopic>> getLatestMultiActionMessageActions(final String expectedControllerId) { private List<SimpleEntry<Long, EventTopic>> getLatestMultiActionMessageActions(final String expectedControllerId) {
final List<DmfMultiActionElement> multiActionRequest = getLatestMultiActionMessages(expectedControllerId); final List<DmfMultiActionElement> multiActionRequest = getLatestMultiActionMessages(expectedControllerId);
return multiActionRequest.stream() return multiActionRequest.stream()
.map(request -> new SimpleEntry<>(request.getAction().getActionId(), request.getTopic())) .map(request -> new SimpleEntry<>(request.getAction().getActionId(), request.getTopic()))
.collect(Collectors.toList()); .toList();
} }
} }

View File

@@ -24,7 +24,6 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -32,7 +31,6 @@ 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.apache.commons.lang3.RandomStringUtils;
import org.eclipse.hawkbit.amqp.AmqpMessageHandlerService; import org.eclipse.hawkbit.amqp.AmqpMessageHandlerService;
import org.eclipse.hawkbit.amqp.AmqpProperties; import org.eclipse.hawkbit.amqp.AmqpProperties;
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic; import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
@@ -199,7 +197,7 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
@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) }) @ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
void registerInvalidTargetWithTooLongControllerId() { void registerInvalidTargetWithTooLongControllerId() {
createAndSendThingCreated(RandomStringUtils.randomAlphabetic(Target.CONTROLLER_ID_MAX_SIZE + 1)); createAndSendThingCreated(randomString(Target.CONTROLLER_ID_MAX_SIZE + 1));
assertAllTargetsCount(0); assertAllTargetsCount(0);
verifyOneDeadLetterMessage(); verifyOneDeadLetterMessage();
} }
@@ -1171,13 +1169,13 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(message -> message .filter(message -> message
.startsWith(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message")) .startsWith(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message"))
.collect(Collectors.toList()); .toList();
assertThat(messagesFromServer).hasSize(messages) assertThat(messagesFromServer).hasSize(messages)
.allMatch(message -> message.endsWith(CORRELATION_ID)); .allMatch(message -> message.endsWith(CORRELATION_ID));
final List<Status> status = actionStatusList.stream().map(ActionStatus::getStatus) final List<Status> status = actionStatusList.stream().map(ActionStatus::getStatus)
.collect(Collectors.toList()); .toList();
assertThat(status).containsOnly(expectedActionStates); assertThat(status).containsOnly(expectedActionStates);
return null; return null;
@@ -1204,7 +1202,7 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
assertThat(actionStatusList).hasSize(statusListCount); assertThat(actionStatusList).hasSize(statusListCount);
final List<Status> status = actionStatusList.stream().map(ActionStatus::getStatus) final List<Status> status = actionStatusList.stream().map(ActionStatus::getStatus)
.collect(Collectors.toList()); .toList();
assertThat(status).containsOnly(expectedActionStates); assertThat(status).containsOnly(expectedActionStates);
return null; return null;

View File

@@ -20,10 +20,10 @@ import org.junit.jupiter.api.Test;
@Feature("Unit Tests - Management API") @Feature("Unit Tests - Management API")
@Story("Serialization") @Story("Serialization")
public class AuditFieldSerializationTest { class AuditFieldSerializationTest {
@Test @Test
public void assertAuditingFields() throws JsonProcessingException { void assertAuditingFields() throws JsonProcessingException {
final MgmtTarget mgmtTarget = new MgmtTarget(); final MgmtTarget mgmtTarget = new MgmtTarget();
mgmtTarget.setCreatedBy("user"); mgmtTarget.setCreatedBy("user");
mgmtTarget.setCreatedAt(System.currentTimeMillis() - 1_000_000); mgmtTarget.setCreatedAt(System.currentTimeMillis() - 1_000_000);

View File

@@ -43,7 +43,6 @@ 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.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
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;
@@ -142,12 +141,11 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
public void getArtifactsWithParameters() throws Exception { public void getArtifactsWithParameters() throws Exception {
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs(); final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
final byte[] random = RandomStringUtils.random(5).getBytes(); final byte[] random = randomBytes(5);
artifactManagement.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, 0)); artifactManagement.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, 0));
mvc.perform( mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts", sm.getId())
get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts", sm.getId())
.param("representation", MgmtRepresentationMode.FULL.toString()) .param("representation", MgmtRepresentationMode.FULL.toString())
.param("useartifacturlhandler", Boolean.TRUE.toString())) .param("useartifacturlhandler", Boolean.TRUE.toString()))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
@@ -933,7 +931,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
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 = randomBytes(artifactSize);
// Create 2 artifacts // Create 2 artifacts
final Artifact artifact = artifactManagement.create( final Artifact artifact = artifactManagement.create(
@@ -994,7 +992,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
.andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());
final SoftwareModule toLongName = entityFactory.softwareModule().create().type(osType) final SoftwareModule toLongName = entityFactory.softwareModule().create().type(osType)
.name(RandomStringUtils.randomAlphanumeric(80)).build(); .name(randomString(80)).build();
mvc.perform(post("/rest/v1/softwaremodules").content(JsonBuilder.softwareModules(Collections.singletonList(toLongName))) mvc.perform(post("/rest/v1/softwaremodules").content(JsonBuilder.softwareModules(Collections.singletonList(toLongName)))
.contentType(MediaType.APPLICATION_JSON)) .contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
@@ -1298,7 +1296,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
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 = randomBytes(artifactSize);
artifactManagement.create( artifactManagement.create(
new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize)); new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize));
@@ -1321,7 +1319,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
final DistributionSet ds1 = testdataFactory.createDistributionSet("a"); final DistributionSet ds1 = testdataFactory.createDistributionSet("a");
final int artifactSize = 5 * 1024; final int artifactSize = 5 * 1024;
final byte[] random = RandomStringUtils.random(artifactSize).getBytes(); final byte[] random = randomBytes(artifactSize);
final Long appTypeSmId = ds1.findFirstModuleByType(appType).get().getId(); final Long appTypeSmId = ds1.findFirstModuleByType(appType).get().getId();
@@ -1506,10 +1504,6 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
.andExpect(jsonPath("content[0].value", equalTo("knownValue1"))); .andExpect(jsonPath("content[0].value", equalTo("knownValue1")));
} }
private static byte[] randomBytes(final int len) {
return RandomStringUtils.randomAlphanumeric(len).getBytes();
}
private void assertArtifact(final SoftwareModule sm, final byte[] random) throws IOException { private void assertArtifact(final SoftwareModule sm, final byte[] random) throws IOException {
// check result in db... // check result in db...
// repo // repo

View File

@@ -19,27 +19,28 @@ import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
@TestPropertySource(properties = { "hawkbit.server.security.allowedHostNames=localhost", @TestPropertySource(properties = {
"hawkbit.server.security.allowedHostNames=localhost",
"hawkbit.server.security.httpFirewallIgnoredPaths=/index.html" }) "hawkbit.server.security.httpFirewallIgnoredPaths=/index.html" })
@Feature("Integration Test - Security") @Feature("Integration Test - Security")
@Story("Allowed Host Names") @Story("Allowed Host Names")
public class AllowedHostNamesTest extends AbstractSecurityTest { class AllowedHostNamesTest extends AbstractSecurityTest {
@Test @Test
@Description("Tests whether a RequestRejectedException is thrown when not allowed host is used") @Description("Tests whether a RequestRejectedException is thrown when not allowed host is used")
public void allowedHostNameWithNotAllowedHost() throws Exception { void allowedHostNameWithNotAllowedHost() throws Exception {
mvc.perform(get("/").header(HttpHeaders.HOST, "www.google.com")).andExpect(status().isBadRequest()); mvc.perform(get("/").header(HttpHeaders.HOST, "www.google.com")).andExpect(status().isBadRequest());
} }
@Test @Test
@Description("Tests whether request is redirected when allowed host is used") @Description("Tests whether request is redirected when allowed host is used")
public void allowedHostNameWithAllowedHost() throws Exception { void allowedHostNameWithAllowedHost() throws Exception {
mvc.perform(get("/").header(HttpHeaders.HOST, "localhost")).andExpect(status().is3xxRedirection()); mvc.perform(get("/").header(HttpHeaders.HOST, "localhost")).andExpect(status().is3xxRedirection());
} }
@Test @Test
@Description("Tests whether request without allowed host name and with ignored path end up with a client error") @Description("Tests whether request without allowed host name and with ignored path end up with a client error")
public void notAllowedHostnameWithIgnoredPath() throws Exception { void notAllowedHostnameWithIgnoredPath() throws Exception {
mvc.perform(get("/index.html").header(HttpHeaders.HOST, "www.google.com")) mvc.perform(get("/index.html").header(HttpHeaders.HOST, "www.google.com"))
.andExpect(status().is4xxClientError()); .andExpect(status().is4xxClientError());
} }

View File

@@ -11,18 +11,21 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial; import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.eclipse.hawkbit.exception.AbstractServerRtException; import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerError;
/** /**
* Exception being thrown in case of error while generating encryption secrets, * Exception being thrown in case of error while generating encryption secrets, encrypting or decrypting artifacts.
* encrypting or decrypting artifacts.
*/ */
@EqualsAndHashCode(callSuper = true)
public final class ArtifactEncryptionFailedException extends AbstractServerRtException { public final class ArtifactEncryptionFailedException extends AbstractServerRtException {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Getter
private final EncryptionOperation encryptionOperation; private final EncryptionOperation encryptionOperation;
public ArtifactEncryptionFailedException(final EncryptionOperation encryptionOperation) { public ArtifactEncryptionFailedException(final EncryptionOperation encryptionOperation) {
@@ -33,21 +36,15 @@ public final class ArtifactEncryptionFailedException extends AbstractServerRtExc
this(encryptionOperation, message, null); this(encryptionOperation, message, null);
} }
public ArtifactEncryptionFailedException(final EncryptionOperation encryptionOperation, final String message, public ArtifactEncryptionFailedException(final EncryptionOperation encryptionOperation, final String message, final Throwable cause) {
final Throwable cause) {
super(message, SpServerError.SP_ARTIFACT_ENCRYPTION_FAILED, cause); super(message, SpServerError.SP_ARTIFACT_ENCRYPTION_FAILED, cause);
this.encryptionOperation = encryptionOperation; this.encryptionOperation = encryptionOperation;
} }
public EncryptionOperation getEncryptionOperation() {
return encryptionOperation;
}
/** /**
* Encryption operation that caused the exception. * Encryption operation that caused the exception.
*/ */
public enum EncryptionOperation { public enum EncryptionOperation {
GENERATE_SECRETS, ENCRYPT, DECRYPT; GENERATE_SECRETS, ENCRYPT, DECRYPT;
} }
} }

View File

@@ -19,4 +19,8 @@ public abstract class AbstractBaseEntityBuilder implements Identifiable<Long> {
public Long getId() { public Long getId() {
return id; return id;
} }
static String strip(final String value) {
return value == null ? null : value.strip();
}
} }

View File

@@ -12,8 +12,8 @@ package org.eclipse.hawkbit.repository.builder;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import lombok.Getter;
import org.eclipse.hawkbit.repository.ValidString; import org.eclipse.hawkbit.repository.ValidString;
import org.springframework.util.StringUtils;
/** /**
* Create and update builder DTO. * Create and update builder DTO.
@@ -25,6 +25,7 @@ public abstract class AbstractDistributionSetUpdateCreate<T> extends AbstractNam
@ValidString @ValidString
protected String version; protected String version;
protected Boolean requiredMigrationStep; protected Boolean requiredMigrationStep;
@Getter
protected Collection<Long> modules; protected Collection<Long> modules;
public T modules(final Collection<Long> modules) { public T modules(final Collection<Long> modules) {
@@ -32,10 +33,6 @@ public abstract class AbstractDistributionSetUpdateCreate<T> extends AbstractNam
return (T) this; return (T) this;
} }
public Collection<Long> getModules() {
return modules;
}
public T requiredMigrationStep(final Boolean requiredMigrationStep) { public T requiredMigrationStep(final Boolean requiredMigrationStep) {
this.requiredMigrationStep = requiredMigrationStep; this.requiredMigrationStep = requiredMigrationStep;
return (T) this; return (T) this;
@@ -46,7 +43,7 @@ public abstract class AbstractDistributionSetUpdateCreate<T> extends AbstractNam
} }
public T version(final String version) { public T version(final String version) {
this.version = StringUtils.trimWhitespace(version); this.version = strip(version);
return (T) this; return (T) this;
} }

View File

@@ -13,7 +13,6 @@ import java.util.Optional;
import lombok.Getter; import lombok.Getter;
import org.eclipse.hawkbit.repository.ValidString; import org.eclipse.hawkbit.repository.ValidString;
import org.springframework.util.StringUtils;
/** /**
* Create and update builder DTO. * Create and update builder DTO.
@@ -29,12 +28,12 @@ public abstract class AbstractMetadataUpdateCreate<T> {
protected String value; protected String value;
public T key(final String key) { public T key(final String key) {
this.key = StringUtils.trimWhitespace(key); this.key = AbstractBaseEntityBuilder.strip(key);
return (T) this; return (T) this;
} }
public T value(final String value) { public T value(final String value) {
this.value = StringUtils.trimWhitespace(value); this.value = AbstractBaseEntityBuilder.strip(value);
return (T) this; return (T) this;
} }

View File

@@ -12,7 +12,6 @@ package org.eclipse.hawkbit.repository.builder;
import java.util.Optional; import java.util.Optional;
import org.eclipse.hawkbit.repository.ValidString; import org.eclipse.hawkbit.repository.ValidString;
import org.springframework.util.StringUtils;
public abstract class AbstractNamedEntityBuilder<T> extends AbstractBaseEntityBuilder { public abstract class AbstractNamedEntityBuilder<T> extends AbstractBaseEntityBuilder {
@@ -22,12 +21,12 @@ public abstract class AbstractNamedEntityBuilder<T> extends AbstractBaseEntityBu
protected String description; protected String description;
public T name(final String name) { public T name(final String name) {
this.name = StringUtils.trimWhitespace(name); this.name = AbstractBaseEntityBuilder.strip(name);
return (T) this; return (T) this;
} }
public T description(final String description) { public T description(final String description) {
this.description = StringUtils.trimWhitespace(description); this.description = AbstractBaseEntityBuilder.strip(description);
return (T) this; return (T) this;
} }

View File

@@ -11,7 +11,6 @@ package org.eclipse.hawkbit.repository.builder;
import org.eclipse.hawkbit.repository.ValidString; import org.eclipse.hawkbit.repository.ValidString;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions; import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import org.springframework.util.StringUtils;
/** /**
* Create builder DTO. * Create builder DTO.
@@ -27,7 +26,7 @@ public abstract class AbstractRolloutGroupCreate<T> extends AbstractNamedEntityB
protected boolean confirmationRequired; protected boolean confirmationRequired;
public T targetFilterQuery(final String targetFilterQuery) { public T targetFilterQuery(final String targetFilterQuery) {
this.targetFilterQuery = StringUtils.trimWhitespace(targetFilterQuery); this.targetFilterQuery = AbstractBaseEntityBuilder.strip(targetFilterQuery);
return (T) this; return (T) this;
} }

View File

@@ -12,7 +12,6 @@ package org.eclipse.hawkbit.repository.builder;
import java.util.Optional; import java.util.Optional;
import org.eclipse.hawkbit.repository.ValidString; import org.eclipse.hawkbit.repository.ValidString;
import org.springframework.util.StringUtils;
/** /**
* Create and update builder DTO. * Create and update builder DTO.
@@ -29,7 +28,7 @@ public abstract class AbstractSoftwareModuleUpdateCreate<T> extends AbstractName
protected String type; protected String type;
public T type(final String type) { public T type(final String type) {
this.type = StringUtils.trimWhitespace(type); this.type = AbstractBaseEntityBuilder.strip(type);
return (T) this; return (T) this;
} }
@@ -38,7 +37,7 @@ public abstract class AbstractSoftwareModuleUpdateCreate<T> extends AbstractName
} }
public T vendor(final String vendor) { public T vendor(final String vendor) {
this.vendor = StringUtils.trimWhitespace(vendor); this.vendor = AbstractBaseEntityBuilder.strip(vendor);
return (T) this; return (T) this;
} }
@@ -47,7 +46,7 @@ public abstract class AbstractSoftwareModuleUpdateCreate<T> extends AbstractName
} }
public T version(final String version) { public T version(final String version) {
this.version = StringUtils.trimWhitespace(version); this.version = AbstractBaseEntityBuilder.strip(version);
return (T) this; return (T) this;
} }

View File

@@ -25,7 +25,7 @@ public class AbstractTagUpdateCreate<T> extends AbstractNamedEntityBuilder<T> {
protected String colour; protected String colour;
public T colour(final String colour) { public T colour(final String colour) {
this.colour = StringUtils.trimWhitespace(colour); this.colour = AbstractBaseEntityBuilder.strip(colour);
return (T) this; return (T) this;
} }

View File

@@ -18,7 +18,6 @@ import org.eclipse.hawkbit.repository.ValidString;
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.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.springframework.util.StringUtils;
/** /**
* Create and update builder DTO. * Create and update builder DTO.
@@ -91,7 +90,7 @@ public abstract class AbstractTargetFilterQueryUpdateCreate<T> extends AbstractB
* @return this builder * @return this builder
*/ */
public T name(final String name) { public T name(final String name) {
this.name = StringUtils.trimWhitespace(name); this.name = AbstractBaseEntityBuilder.strip(name);
return (T) this; return (T) this;
} }
@@ -106,7 +105,7 @@ public abstract class AbstractTargetFilterQueryUpdateCreate<T> extends AbstractB
* @return this builder * @return this builder
*/ */
public T query(final String query) { public T query(final String query) {
this.query = StringUtils.trimWhitespace(query); this.query = AbstractBaseEntityBuilder.strip(query);
return (T) this; return (T) this;
} }

View File

@@ -16,7 +16,6 @@ import lombok.ToString;
import org.eclipse.hawkbit.repository.ValidString; import org.eclipse.hawkbit.repository.ValidString;
import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.springframework.util.StringUtils;
/** /**
* Create and update builder DTO. * Create and update builder DTO.
@@ -37,7 +36,7 @@ public class AbstractTargetUpdateCreate<T> extends AbstractNamedEntityBuilder<T>
protected Long targetTypeId; protected Long targetTypeId;
protected AbstractTargetUpdateCreate(final String controllerId) { protected AbstractTargetUpdateCreate(final String controllerId) {
this.controllerId = StringUtils.trimWhitespace(controllerId); this.controllerId = AbstractBaseEntityBuilder.strip(controllerId);
} }
public T status(final TargetUpdateStatus status) { public T status(final TargetUpdateStatus status) {
@@ -49,7 +48,7 @@ public class AbstractTargetUpdateCreate<T> extends AbstractNamedEntityBuilder<T>
// check if this is a real URI // check if this is a real URI
if (address != null) { if (address != null) {
try { try {
URI.create(StringUtils.trimWhitespace(address)); URI.create(AbstractBaseEntityBuilder.strip(address));
} catch (final IllegalArgumentException e) { } catch (final IllegalArgumentException e) {
throw new InvalidTargetAddressException( throw new InvalidTargetAddressException(
"The given address " + address + " violates the RFC-2396 specification", e); "The given address " + address + " violates the RFC-2396 specification", e);
@@ -60,7 +59,7 @@ public class AbstractTargetUpdateCreate<T> extends AbstractNamedEntityBuilder<T>
} }
public T securityToken(final String securityToken) { public T securityToken(final String securityToken) {
this.securityToken = StringUtils.trimWhitespace(securityToken); this.securityToken = AbstractBaseEntityBuilder.strip(securityToken);
return (T) this; return (T) this;
} }
@@ -75,7 +74,7 @@ public class AbstractTargetUpdateCreate<T> extends AbstractNamedEntityBuilder<T>
} }
public TargetCreate controllerId(final String controllerId) { public TargetCreate controllerId(final String controllerId) {
this.controllerId = StringUtils.trimWhitespace(controllerId); this.controllerId = AbstractBaseEntityBuilder.strip(controllerId);
return (TargetCreate) this; return (TargetCreate) this;
} }

View File

@@ -12,7 +12,6 @@ package org.eclipse.hawkbit.repository.builder;
import java.util.Optional; import java.util.Optional;
import org.eclipse.hawkbit.repository.ValidString; import org.eclipse.hawkbit.repository.ValidString;
import org.springframework.util.StringUtils;
/** /**
* Create and update builder DTO. * Create and update builder DTO.
@@ -27,7 +26,7 @@ public abstract class AbstractTypeUpdateCreate<T> extends AbstractNamedEntityBui
protected String key; protected String key;
public T colour(final String colour) { public T colour(final String colour) {
this.colour = StringUtils.trimWhitespace(colour); this.colour = AbstractBaseEntityBuilder.strip(colour);
return (T) this; return (T) this;
} }
@@ -36,7 +35,7 @@ public abstract class AbstractTypeUpdateCreate<T> extends AbstractNamedEntityBui
} }
public T key(final String key) { public T key(final String key) {
this.key = StringUtils.trimWhitespace(key); this.key = AbstractBaseEntityBuilder.strip(key);
return (T) this; return (T) this;
} }

View File

@@ -85,8 +85,6 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
protected static final String NOT_EXIST_ID = "12345678990"; protected static final String NOT_EXIST_ID = "12345678990";
protected static final long NOT_EXIST_IDL = Long.parseLong(NOT_EXIST_ID); protected static final long NOT_EXIST_IDL = Long.parseLong(NOT_EXIST_ID);
protected static final RandomStringUtils RANDOM_STRING_UTILS = RandomStringUtils.insecure();
private static final List<String> REPOSITORY_AND_TARGET_PERMISSIONS = List.of(SpPermission.READ_REPOSITORY, SpPermission.CREATE_REPOSITORY, SpPermission.UPDATE_REPOSITORY, SpPermission.DELETE_REPOSITORY, SpPermission.READ_TARGET, SpPermission.CREATE_TARGET, SpPermission.UPDATE_TARGET, SpPermission.DELETE_TARGET); private static final List<String> REPOSITORY_AND_TARGET_PERMISSIONS = List.of(SpPermission.READ_REPOSITORY, SpPermission.CREATE_REPOSITORY, SpPermission.UPDATE_REPOSITORY, SpPermission.DELETE_REPOSITORY, SpPermission.READ_TARGET, SpPermission.CREATE_TARGET, SpPermission.UPDATE_TARGET, SpPermission.DELETE_TARGET);
@PersistenceContext @PersistenceContext
@@ -177,14 +175,6 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
((JpaSoftwareModule) module).setOptLockRevision(module.getOptLockRevision() + 1); ((JpaSoftwareModule) module).setOptLockRevision(module.getOptLockRevision() + 1);
} }
protected static String randomString(final int len) {
return RANDOM_STRING_UTILS.next(len, true, false);
}
protected static byte[] randomBytes(final int len) {
return randomString(len).getBytes();
}
protected Database getDatabase() { protected Database getDatabase() {
return jpaProperties.getDatabase(); return jpaProperties.getDatabase();
} }

View File

@@ -25,6 +25,7 @@ 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.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.builder.AutoAssignDistributionSetUpdate;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException; import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.jpa.specifications.ActionSpecifications; import org.eclipse.hawkbit.repository.jpa.specifications.ActionSpecifications;
@@ -248,15 +249,13 @@ class AutoAssignCheckerIntTest extends AbstractJpaIntegrationTest {
final String targetDsAIdPref = "targA"; final String targetDsAIdPref = "targA";
final String targetDsFIdPref = "targB"; final String targetDsFIdPref = "targB";
// target filter query that matches first bunch of targets, that should
// fail
assertThatExceptionOfType(IncompleteDistributionSetException.class).isThrownBy(() -> {
final Long filterId = targetFilterQueryManagement.create( final Long filterId = targetFilterQueryManagement.create(
entityFactory.targetFilterQuery().create().name("filterA").query("id==" + targetDsFIdPref + "*")) entityFactory.targetFilterQuery().create().name("filterA").query("id==" + targetDsFIdPref + "*"))
.getId(); .getId();
targetFilterQueryManagement final AutoAssignDistributionSetUpdate targetFilterQuery = entityFactory.targetFilterQuery().updateAutoAssign(filterId).ds(setF.getId());
.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(filterId).ds(setF.getId())); // target filter query that matches first bunch of targets, that should fail
}); assertThatExceptionOfType(IncompleteDistributionSetException.class).isThrownBy(
() -> targetFilterQueryManagement.updateAutoAssignDS(targetFilterQuery));
// target filter query that matches failed bunch of targets // target filter query that matches failed bunch of targets
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("filterB") targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("filterB")
.query("id==" + targetDsAIdPref + "*").autoAssignDistributionSet(setA.getId())); .query("id==" + targetDsAIdPref + "*").autoAssignDistributionSet(setA.getId()));

View File

@@ -30,7 +30,6 @@ 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.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact; import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash; import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpPermission;

View File

@@ -116,6 +116,8 @@ public abstract class AbstractIntegrationTest {
protected static final URI LOCALHOST = URI.create("http://127.0.0.1"); protected static final URI LOCALHOST = URI.create("http://127.0.0.1");
protected static final int DEFAULT_TEST_WEIGHT = 500; protected static final int DEFAULT_TEST_WEIGHT = 500;
protected static final RandomStringUtils RANDOM_STRING_UTILS = RandomStringUtils.secure();
/** /**
* Number of {@link DistributionSetType}s that exist in every test case. One * Number of {@link DistributionSetType}s that exist in every test case. One
* generated by using * generated by using
@@ -292,6 +294,14 @@ public abstract class AbstractIntegrationTest {
return Comparator.comparing(Target::getControllerId); return Comparator.comparing(Target::getControllerId);
} }
protected static String randomString(final int len) {
return RANDOM_STRING_UTILS.next(len, true, false);
}
protected static byte[] randomBytes(final int len) {
return randomString(len).getBytes();
}
protected DistributionSetAssignmentResult assignDistributionSet(final long dsID, final String controllerId) { protected DistributionSetAssignmentResult assignDistributionSet(final long dsID, final String controllerId) {
return assignDistributionSet(dsID, controllerId, ActionType.FORCED); return assignDistributionSet(dsID, controllerId, ActionType.FORCED);
} }
@@ -477,7 +487,7 @@ public abstract class AbstractIntegrationTest {
private static String createTempDir() { private static String createTempDir() {
try { try {
return Files.createTempDirectory(null).toString() + "/" + RandomStringUtils.randomAlphanumeric(20); return Files.createTempDirectory(null).toString() + "/" + randomString(20);
} catch (final IOException e) { } catch (final IOException e) {
throw new IllegalStateException("Failed to create temp directory"); throw new IllegalStateException("Failed to create temp directory");
} }

View File

@@ -31,7 +31,7 @@ public abstract class AbstractSqlTestDatabase extends AbstractTestExecutionListe
protected final DatasourceContext context; protected final DatasourceContext context;
public AbstractSqlTestDatabase(final DatasourceContext context) { protected AbstractSqlTestDatabase(final DatasourceContext context) {
this.context = context; this.context = context;
} }

View File

@@ -44,7 +44,7 @@ public abstract class AbstractRestIntegrationTest extends AbstractIntegrationTes
private CharacterEncodingFilter characterEncodingFilter; private CharacterEncodingFilter characterEncodingFilter;
@BeforeEach @BeforeEach
public void before() throws Exception { public void before() {
mvc = createMvcWebAppContext(webApplicationContext).build(); mvc = createMvcWebAppContext(webApplicationContext).build();
} }

View File

@@ -58,11 +58,9 @@ public class Amqp {
} }
} }
connectionFactory.setUsername( connectionFactory.setUsername(
dmf == null || ObjectUtils.isEmpty(dmf.getUsername()) ? dmf == null || ObjectUtils.isEmpty(dmf.getUsername()) ? rabbitProperties.getUsername() : dmf.getUsername());
rabbitProperties.getUsername() : dmf.getUsername());
connectionFactory.setPassword( connectionFactory.setPassword(
dmf == null || ObjectUtils.isEmpty(dmf.getPassword()) ? dmf == null || ObjectUtils.isEmpty(dmf.getPassword()) ? rabbitProperties.getPassword() : dmf.getPassword());
rabbitProperties.getPassword() : dmf.getPassword());
connectionFactory.setVirtualHost(vHost); connectionFactory.setVirtualHost(vHost);
return connectionFactory; return connectionFactory;
} }