Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#311: dependency updates (spring-boot 2.4.0, spring-cloud to 2020.0.0, cxf to 3.4.1, etc.) #310

Merged
merged 8 commits into from
Jan 15, 2021
7 changes: 1 addition & 6 deletions boms/bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@
<inceptionYear>2014</inceptionYear>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<cxf.version>3.3.6</cxf.version>
<mmm.util.version>8.7.0</mmm.util.version>
<slf4j.version>1.7.28</slf4j.version>
<flatten.mode>bom</flatten.mode>
</properties>

Expand Down Expand Up @@ -73,7 +68,7 @@
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- JSR 250 for common annotations (component-bean lifecycle, security,
<!-- JSR 250 for common annotations (component-bean lifecycle, security,
etc.) -->
<dependency>
<groupId>javax.annotation</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package com.devonfw.module.cxf.common.impl.client.rest;

import java.lang.reflect.Method;
import java.net.URI;
import java.util.Map;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;

import org.apache.cxf.jaxrs.client.ResponseExceptionMapper;
import org.apache.cxf.jaxrs.impl.ResponseImpl;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
import org.apache.cxf.message.Message;
import org.apache.cxf.transport.Conduit;
import org.apache.cxf.ws.addressing.AttributedURIType;
import org.apache.cxf.ws.addressing.EndpointReferenceType;

import com.devonfw.module.service.common.api.client.ServiceClientErrorFactory;
import com.devonfw.module.service.common.api.client.context.ServiceContext;
Expand Down Expand Up @@ -45,13 +53,83 @@ public Throwable fromResponse(Response response) {
String data = response.readEntity(String.class);
if ((data != null) && !data.isEmpty()) {
MediaType mediaType = response.getMediaType();
URI url = response.getLocation();
String operation = null;
String serviceDetails = this.context.getServiceDescription(operation, url.toString());
String url = getUrl(response);
String operation = getOperation(response);
String serviceDetails = this.context.getServiceDescription(operation, url);
return this.errorUnmarshaller.unmarshall(data, mediaType.toString(), response.getStatus(), serviceDetails);
}
}
return null;
}

private String getOperation(Response response) {

if (response instanceof ResponseImpl) {
Message message = ((ResponseImpl) response).getOutMessage();
if (message != null) {
Object invocationContext = message.get(Message.INVOCATION_CONTEXT);
Object requestContext = getFromMap(invocationContext, "RequestContext");
OperationResourceInfo operation = getFromMap(requestContext, OperationResourceInfo.class);
if (operation != null) {
Method method = operation.getAnnotatedMethod();
if (method != null) {
return method.getName();
}
}
}
}
return null;
}

@SuppressWarnings("rawtypes")
private static Object getFromMap(Object map, Object key) {

if (map instanceof Map) {
return ((Map) map).get(key);
}
return null;
}

@SuppressWarnings("rawtypes")
private static <T> T getFromMap(Object map, Class<T> key) {

if (map instanceof Map) {
Object value = ((Map) map).get(key.getName());
if (value != null) {
try {
return key.cast(value);
} catch (Exception e) {
}
}
}
return null;
}

private String getUrl(Response response) {

URI url = response.getLocation();
if (url != null) {
return url.toString();
} else if (response instanceof ResponseImpl) {
Message message = ((ResponseImpl) response).getOutMessage();
if (message != null) {
Object uri = message.get(Message.REQUEST_URI);
if (uri instanceof String) {
return (String) uri;
}
Conduit conduit = message.get(Conduit.class);
if (conduit != null) {
EndpointReferenceType target = conduit.getTarget();
if (target != null) {
AttributedURIType address = target.getAddress();
if (address != null) {
return address.getValue();
}
}
}
}
}
return "url-not-available-in-cxf-response";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should return null instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hopefully we should never get here either...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe return "" is even safer to avoid NPE.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its a private method that is only used in a single place to pass it to getServiceDescription here:

String serviceDetails = this.context.getServiceDescription(operation, url);

That method honors null but not the empty String as the idea was that null means not available:
default String getServiceDescription(String operation, String url) {

However, we could also return "" and also change getServiceDescription to treat "" just like null.

}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.devonfw.module.kafka.common.messaging.logging.impl;

import static brave.internal.HexCodec.toLowerHex;
import static brave.internal.codec.HexCodec.toLowerHex;

import java.lang.reflect.Method;
import java.time.Instant;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.devonfw.module.kafka.common.messaging.logging.impl;

import java.util.Optional;

import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -12,8 +11,6 @@
*
* @param <K> The key type
* @param <V> The value type
*
*
*/
public class ProducerLoggingListener<K, V> implements ProducerListener<K, V> {

Expand All @@ -32,23 +29,27 @@ public ProducerLoggingListener(MessageLoggingSupport loggingSupport) {
}

@Override
public void onSuccess(String topic, Integer partition, Object key, Object value, RecordMetadata recordMetadata) {
public void onSuccess(ProducerRecord<K, V> record, RecordMetadata recordMetadata) {

String messageKey = (String) Optional.ofNullable(key).orElse("<no message key>");
String messageKey = "<no message key>";
K key = record.key();
if (key != null) {
messageKey = key.toString();
}

if (recordMetadata != null) {
this.loggingSupport.logMessageSent(LOG, messageKey, recordMetadata.topic(), recordMetadata.partition(),
recordMetadata.offset());

} else {
this.loggingSupport.logMessageSent(LOG, messageKey, topic, partition, null);
this.loggingSupport.logMessageSent(LOG, messageKey, record.topic(), record.partition(), null);
}
}

@Override
public void onError(String topic, Integer partition, Object key, Object value, Exception exception) {
public void onError(ProducerRecord<K, V> record, RecordMetadata recordMetadata, Exception exception) {

this.loggingSupport.logMessageNotSent(LOG, topic, partition,
this.loggingSupport.logMessageNotSent(LOG, record.topic(), record.partition(),
(exception != null ? exception.getLocalizedMessage() : "unknown"));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.devonfw.module.kafka.common.messaging.trace.impl;

import static brave.internal.HexCodec.lowerHexToUnsignedLong;
import static brave.internal.codec.HexCodec.lowerHexToUnsignedLong;
import static com.devonfw.module.kafka.common.messaging.util.MessageUtil.getHeaderValue;

import java.util.Optional;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.devonfw.module.kafka.common.messaging.trace.impl;

import static brave.internal.HexCodec.toLowerHex;
import static brave.internal.codec.HexCodec.toLowerHex;
import static com.devonfw.module.kafka.common.messaging.util.MessageUtil.addHeaderValue;

import java.util.Optional;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.devonfw.example.module;

import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

import org.apache.commons.codec.Charsets;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.header.Headers;
Expand Down Expand Up @@ -40,10 +40,11 @@ public class MessageRetryOperationsTest extends AbstractKafkaBaseTest {
@Override
protected void doSetUp() {

this.consumerRecord = new ConsumerRecord<>(AbstractKafkaBaseTest.RETRY_TEST_TOPIC, 0, 0, AbstractKafkaBaseTest.RETRY_TEST_TOPIC, "message");
this.consumerRecord = new ConsumerRecord<>(AbstractKafkaBaseTest.RETRY_TEST_TOPIC, 0, 0,
AbstractKafkaBaseTest.RETRY_TEST_TOPIC, "message");
Headers headers = this.consumerRecord.headers();
headers.add(MessageRetryContext.RETRY_COUNT, "0".getBytes(Charsets.UTF_8));
headers.add(MessageRetryContext.RETRY_STATE, "Pending".getBytes(Charsets.UTF_8));
headers.add(MessageRetryContext.RETRY_COUNT, "0".getBytes(StandardCharsets.UTF_8));
headers.add(MessageRetryContext.RETRY_STATE, "Pending".getBytes(StandardCharsets.UTF_8));
headers.add(MessageRetryContext.RETRY_NEXT, Instant.now().plus(1, ChronoUnit.MINUTES).toString().getBytes());
headers.add(MessageRetryContext.RETRY_UNTIL, Instant.now().toString().getBytes());

Expand Down
12 changes: 7 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@
<changelist>-SNAPSHOT</changelist>
<github.repository>devon4j</github.repository>
<devon4j.version>${revision}${changelist}</devon4j.version>
<spring.boot.version>2.3.3.RELEASE</spring.boot.version>
<spring.boot.version>2.4.0</spring.boot.version>
<!-- Spring boot and spring cloud version has to match -->
<spring.cloud.dependencies.version>Greenwich.SR6</spring.cloud.dependencies.version>
<spring.cloud.dependencies.version>2020.0.0</spring.cloud.dependencies.version>
<jackson.version>2.11.2</jackson.version> <!-- Overriding Jackson for fixing vulnerabilities -->
<guava.version>28.1-jre</guava.version>
<junit.version>5.6.1</junit.version>

<guava.version>30.0-jre</guava.version>
<junit.version>5.7.0</junit.version>
<cxf.version>3.4.1</cxf.version>
<mmm.util.version>8.7.0</mmm.util.version>
<slf4j.version>1.7.30</slf4j.version>
</properties>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void testBusinessError() {
failBecauseExceptionWasNotThrown(ServiceInvocationFailedException.class);
} catch (ServiceInvocationFailedException e) {
assertThat(e.getNlsMessage().getMessage()).matches(
"While invoking the service com\\.devonfw\\.test\\.app\\.myexample\\.service\\.api\\.rest\\.MyExampleRestService\\[http://localhost:[0-9]+/app/services/rest/my-example/v1/business-error\\] the following error occurred: Test of business error.* Probably the service is temporary unavailable\\. Please try again later\\. If the problem persists contact your system administrator\\.");
"While invoking the service com\\.devonfw\\.test\\.app\\.myexample\\.service\\.api\\.rest\\.MyExampleRestService#businessError\\[http://localhost:[0-9]+/app/services/rest/my-example/v1/business-error\\] the following error occurred: Test of business error.* Probably the service is temporary unavailable\\. Please try again later\\. If the problem persists contact your system administrator\\.");
assertThat(e.getCode()).isEqualTo(MyBusinessException.CODE);
assertThat(e.isForUser()).isTrue();
assertThat(e.isTechnical()).isTrue();
Expand All @@ -82,7 +82,7 @@ public void testTechnicalError() {
failBecauseExceptionWasNotThrown(ServiceInvocationFailedException.class);
} catch (ServiceInvocationFailedException e) {
assertThat(e.getNlsMessage().getMessage()).matches(
"While invoking the service com\\.devonfw\\.test\\.app\\.myexample\\.service\\.api\\.rest\\.MyExampleRestService\\[http://localhost:[0-9]+/app/services/rest/my-example/v1/technical-error\\] the following error occurred: An unexpected error has occurred! We apologize any inconvenience\\. Please try again later\\..* Probably the service is temporary unavailable\\. Please try again later\\. If the problem persists contact your system administrator\\.");
"While invoking the service com\\.devonfw\\.test\\.app\\.myexample\\.service\\.api\\.rest\\.MyExampleRestService#technicalError\\[http://localhost:[0-9]+/app/services/rest/my-example/v1/technical-error\\] the following error occurred: An unexpected error has occurred! We apologize any inconvenience\\. Please try again later\\..* Probably the service is temporary unavailable\\. Please try again later\\. If the problem persists contact your system administrator\\.");
assertThat(e.getCode()).isEqualTo(TechnicalErrorUserException.CODE);
assertThat(e.isForUser()).isTrue();
assertThat(e.isTechnical()).isTrue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ public class WebConfig {
* with their duration and status code.
*/
@Bean
public FilterRegistrationBean performanceLogFilter() {
public FilterRegistrationBean<PerformanceLogFilter> performanceLogFilter() {

FilterRegistrationBean registration = new FilterRegistrationBean();
Filter performanceLogFilter = new PerformanceLogFilter();
FilterRegistrationBean<PerformanceLogFilter> registration = new FilterRegistrationBean<>();
PerformanceLogFilter performanceLogFilter = new PerformanceLogFilter();
this.beanFactory.autowireBean(performanceLogFilter);
registration.setFilter(performanceLogFilter);
registration.addUrlPatterns("/*");
Expand All @@ -52,10 +52,10 @@ public DiagnosticContextFacade diagnosticContextFacade() {
* correlation id as MDC so it will be included in all associated logs.
*/
@Bean
public FilterRegistrationBean diagnosticContextFilter() {
public FilterRegistrationBean<DiagnosticContextFilter> diagnosticContextFilter() {

FilterRegistrationBean registration = new FilterRegistrationBean();
Filter diagnosticContextFilter = new DiagnosticContextFilter();
FilterRegistrationBean<DiagnosticContextFilter> registration = new FilterRegistrationBean<>();
DiagnosticContextFilter diagnosticContextFilter = new DiagnosticContextFilter();
this.beanFactory.autowireBean(diagnosticContextFilter);
registration.setFilter(diagnosticContextFilter);
registration.addUrlPatterns(ServiceConstants.URL_PATH_SERVICES + "/*");
Expand All @@ -66,9 +66,9 @@ public FilterRegistrationBean diagnosticContextFilter() {
* @return the {@link FilterRegistrationBean} to register the {@link CharacterEncodingFilter} to set the encoding.
*/
@Bean
public FilterRegistrationBean setCharacterEncodingFilter() {
public FilterRegistrationBean<CharacterEncodingFilter> setCharacterEncodingFilter() {

FilterRegistrationBean registration = new FilterRegistrationBean();
FilterRegistrationBean<CharacterEncodingFilter> registration = new FilterRegistrationBean<>();
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(false);
Expand Down