Fix sonar findings (#3015)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2026-04-15 13:14:31 +03:00
committed by GitHub
parent 0a0ab18fa2
commit a00374f455
32 changed files with 168 additions and 234 deletions

View File

@@ -1,49 +0,0 @@
/**
* Copyright (c) 2021 Bosch.IO GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.amqp;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.support.ListenerExecutionFailedException;
/**
* Class that composes a meaningful error message and enhances it with properties from failed message
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class AmqpErrorMessageComposer {
/**
* Constructs an error message based on failed message content
*
* @param throwable the throwable containing failed message content
* @return meaningful error message
*/
public static String constructErrorMessage(final Throwable throwable) {
final String mainErrorMsg = throwable.getCause().getMessage();
if (throwable instanceof ListenerExecutionFailedException listenerExecutionFailedException) {
Collection<Message> failedMessages = listenerExecutionFailedException.getFailedMessages();
// 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 byte[] amqpFailedMsgBody = failedMessage.getBody();
final Map<String, Object> amqpFailedMsgHeaders = failedMessage.getMessageProperties().getHeaders();
final String amqpFailedMsgConcatenatedHeaders = amqpFailedMsgHeaders.keySet().stream()
.map(key -> key + "=" + amqpFailedMsgHeaders.get(key))
.collect(Collectors.joining(", ", "{", "}"));
return mainErrorMsg + new String(amqpFailedMsgBody) + amqpFailedMsgConcatenatedHeaders;
}
return mainErrorMsg;
}
}

View File

@@ -182,6 +182,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
updateAttributesEvent.getTargetAddress());
}
@SuppressWarnings("java:S4449") // false positive - setCorrelationId param is @Nullable - but in spring - can't annotate it
protected void sendPingResponseToDmfReceiver(final Message ping, final String tenant, final String virtualHost) {
final Message message = MessageBuilder
.withBody(String.valueOf(System.currentTimeMillis()).getBytes())
@@ -200,10 +201,8 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
return;
}
final DmfActionRequest actionRequest = new DmfActionRequest(actionId);
final Message message = getMessageConverter().toMessage(
actionRequest,
createConnectorMessagePropertiesEvent(tenant, controllerId, EventTopic.CANCEL_DOWNLOAD));
new DmfActionRequest(actionId), createConnectorMessagePropertiesEvent(tenant, controllerId, EventTopic.CANCEL_DOWNLOAD));
amqpSenderService.sendMessage(message, address);
}

View File

@@ -18,7 +18,7 @@ import org.springframework.amqp.AmqpRejectAndDontRequeueException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
import org.springframework.amqp.support.converter.DefaultJacksonJavaTypeMapper;
import org.springframework.amqp.support.converter.MessageConversionException;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.util.ObjectUtils;
@@ -50,16 +50,17 @@ public class BaseAmqpService {
@SuppressWarnings("unchecked")
public <T> T convertMessage(@NotNull final Message message, final Class<T> clazz) {
checkMessageBody(message);
message.getMessageProperties().getHeaders().put(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME, clazz.getName());
message.getMessageProperties().getHeaders().put(DefaultJacksonJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME, clazz.getName());
return (T) rabbitTemplate.getMessageConverter().fromMessage(message);
}
@SuppressWarnings("java:S2589") // messageProperties.getContentType() could be null via setContentType
protected static void checkContentTypeJson(final Message message) {
final MessageProperties messageProperties = message.getMessageProperties();
if (messageProperties.getContentType() != null && messageProperties.getContentType().contains("json")) {
return;
final String contentType = messageProperties.getContentType();
if (contentType == null || !contentType.contains("json")) {
throw new AmqpRejectAndDontRequeueException("Content-Type is not JSON compatible");
}
throw new AmqpRejectAndDontRequeueException("Content-Type is not JSON compatible");
}
protected static boolean isMessageBodyEmpty(final Message message) {
@@ -101,6 +102,6 @@ public class BaseAmqpService {
* @param message the message to cleaned up
*/
protected void cleanMessageHeaderProperties(final Message message) {
message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME);
message.getMessageProperties().getHeaders().remove(DefaultJacksonJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME);
}
}

View File

@@ -90,7 +90,7 @@ public class DmfApiConfiguration {
}
/**
* @return {@link RabbitTemplate} with automatic retry, published confirms and {@link Jackson2JsonMessageConverter}.
* @return {@link RabbitTemplate} with automatic retry, published confirms and {@link JacksonJsonMessageConverter}.
*/
@Bean
public RabbitTemplate rabbitTemplate(final JsonMapper jsonMapper) {

View File

@@ -32,7 +32,6 @@ import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
import org.eclipse.hawkbit.dmf.json.model.DmfActionRequest;
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadAndUpdateRequest;
import org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule;
import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.TargetManagement.Create;
import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent;
@@ -60,9 +59,8 @@ import org.mockito.Mockito;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.amqp.support.converter.DefaultJacksonJavaTypeMapper;
import org.springframework.amqp.support.converter.JacksonJsonMessageConverter;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
@@ -96,7 +94,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
Create.builder().controllerId(CONTROLLER_ID).securityToken(TEST_TOKEN).address(AMQP_URI.toString()).build());
this.rabbitTemplate = Mockito.mock(RabbitTemplate.class);
when(rabbitTemplate.getMessageConverter()).thenReturn(new Jackson2JsonMessageConverter());
when(rabbitTemplate.getMessageConverter()).thenReturn(new JacksonJsonMessageConverter());
senderService = Mockito.mock(DefaultAmqpMessageSenderService.class);
@@ -112,7 +110,8 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
when(systemManagement.getTenantMetadata()).thenReturn(tenantMetaData);
when(systemManagement.getTenantMetadataWithoutDetails()).thenReturn(tenantMetaData);
amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate, senderService,
amqpMessageDispatcherService = new AmqpMessageDispatcherService(
rabbitTemplate, senderService,
artifactUrlHandlerMock, systemManagement, targetManagement,
softwareModuleManagement, distributionSetManagement, deploymentManagement);
@@ -129,8 +128,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
*/
@Test
void testSendDownloadRequestWithSoftwareModulesAndNoArtifacts() {
final DistributionSet createDistributionSet = testdataFactory
.createDistributionSet(UUID.randomUUID().toString());
final DistributionSet createDistributionSet = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
testdataFactory.addSoftwareModuleMetadata(createDistributionSet);
final Action action = createAction(createDistributionSet);
@@ -377,8 +375,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
@SuppressWarnings("unchecked")
private <T> T convertMessage(final Message message, final Class<T> clazz) {
message.getMessageProperties().getHeaders().put(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME,
clazz.getTypeName());
message.getMessageProperties().getHeaders().put(DefaultJacksonJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME, clazz.getTypeName());
return (T) rabbitTemplate.getMessageConverter().fromMessage(message);
}
}

View File

@@ -28,7 +28,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.JacksonJsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConversionException;
/**
@@ -54,7 +54,7 @@ class BaseAmqpServiceTest {
@Test
void convertMessageTest() {
final DmfActionUpdateStatus actionUpdateStatus = createActionStatus();
when(rabbitTemplate.getMessageConverter()).thenReturn(new Jackson2JsonMessageConverter());
when(rabbitTemplate.getMessageConverter()).thenReturn(new JacksonJsonMessageConverter());
final Message message = rabbitTemplate.getMessageConverter().toMessage(actionUpdateStatus, createJsonProperties());
final DmfActionUpdateStatus convertedActionUpdateStatus = baseAmqpService.convertMessage(message, DmfActionUpdateStatus.class);
@@ -91,7 +91,7 @@ class BaseAmqpServiceTest {
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
void updateActionStatusWithInvalidJsonContent() {
final Message message = createMessage("Invalid Json".getBytes());
when(rabbitTemplate.getMessageConverter()).thenReturn(new Jackson2JsonMessageConverter());
when(rabbitTemplate.getMessageConverter()).thenReturn(new JacksonJsonMessageConverter());
assertThatExceptionOfType(MessageConversionException.class)
.as("Expected MessageConversionException for invalid JSON")

View File

@@ -25,7 +25,7 @@ import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.junit.RabbitAvailable;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.JacksonJsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
@@ -88,7 +88,7 @@ public abstract class AbstractAmqpIntegrationTest extends AbstractIntegrationTes
private RabbitTemplate createDmfClient() {
final RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(new Jackson2JsonMessageConverter());
template.setMessageConverter(new JacksonJsonMessageConverter());
template.setReceiveTimeout(TimeUnit.SECONDS.toMillis(3));
template.setReplyTimeout(TimeUnit.SECONDS.toMillis(3));
template.setExchange(getExchange());

View File

@@ -16,7 +16,7 @@ import java.util.concurrent.TimeUnit;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.JacksonJsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@@ -32,7 +32,7 @@ public class AmqpTestConfiguration {
@Primary
public RabbitTemplate rabbitTemplateForTest(final ConnectionFactory connectionFactory) {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
rabbitTemplate.setMessageConverter(new JacksonJsonMessageConverter());
rabbitTemplate.setReplyTimeout(TimeUnit.SECONDS.toMillis(3));
rabbitTemplate.setReceiveTimeout(TimeUnit.SECONDS.toMillis(3));
return rabbitTemplate;