Skip to content
This repository has been archived by the owner on Jun 7, 2024. It is now read-only.

Bump zalando problem libs #946

Merged
merged 26 commits into from
Oct 18, 2018
Merged

Bump zalando problem libs #946

merged 26 commits into from
Oct 18, 2018

Conversation

lmontrieux
Copy link
Contributor

@lmontrieux lmontrieux commented Aug 30, 2018

Upgrade zalando problems libraries

Zalando ticket : ARUHA-1695

Description

This PR:

  • upgrades all zalando-problem libraries to the latest version
  • upgrades gradle to 4.10.2
  • removes anything deprecated from build.gradle
  • refactors exception handlers

Review

  • Tests
  • Documentation
  • CHANGELOG

Lionel Montrieux added 5 commits August 30, 2018 16:08
Update the following libraries:
- jackson-datatype-problem to 0.21.0
- problem to 0.21.0
- problem-spring-web to 0.23.0

Code fixes and refactoring of exception handling
@lmontrieux lmontrieux requested a review from a team as a code owner August 30, 2018 15:49
@codecov-io
Copy link

codecov-io commented Aug 30, 2018

Codecov Report

Merging #946 into master will increase coverage by 0.05%.
The diff coverage is 52.17%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #946      +/-   ##
============================================
+ Coverage     54.13%   54.18%   +0.05%     
- Complexity     1760     1775      +15     
============================================
  Files           318      335      +17     
  Lines          9589     9572      -17     
  Branches        872      874       +2     
============================================
- Hits           5191     5187       -4     
+ Misses         4083     4067      -16     
- Partials        315      318       +3
Impacted Files Coverage Δ Complexity Δ
...lando/nakadi/controller/HealthCheckController.java 100% <ø> (ø) 2 <0> (ø) ⬇️
.../nakadi/controller/CursorOperationsController.java 12.06% <ø> (+2.06%) 2 <0> (ø) ⬇️
...rg/zalando/nakadi/controller/SchemaController.java 100% <ø> (+13.33%) 5 <0> (ø) ⬇️
...g/zalando/nakadi/controller/VersionController.java 0% <ø> (ø) 0 <0> (ø) ⬇️
...zalando/nakadi/controller/TimelinesController.java 100% <ø> (+55%) 3 <0> (-1) ⬇️
...akadi/controller/SubscriptionStreamController.java 12.5% <ø> (-0.41%) 2 <0> (ø)
...org/zalando/nakadi/util/GzipBodyRequestFilter.java 13.95% <0%> (ø) 4 <0> (ø) ⬇️
.../zalando/nakadi/controller/SettingsController.java 15.62% <0%> (-3.3%) 1 <0> (-1)
...lando/nakadi/controller/EventStreamController.java 85.71% <0%> (ø) 20 <0> (ø) ⬇️
...do/nakadi/exceptions/runtime/BlockedException.java 0% <0%> (ø) 0 <0> (?)
... and 45 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3f65fd8...3921ea7. Read the comment docs.

Lionel Montrieux added 2 commits September 4, 2018 15:37
# Conflicts:
#	src/main/java/org/zalando/nakadi/config/SecurityConfiguration.java
Copy link
Member

@adyach adyach left a comment

Choose a reason for hiding this comment

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

Good work @lmontrieux, thank you! It makes sense for us to fully understand Zalando problem approach

@@ -89,48 +72,4 @@ public SubscriptionController(final FeatureToggleService featureToggleService,
final StatsMode statsMode = showTimeLag ? StatsMode.TIMELAG : StatsMode.NORMAL;
return subscriptionService.getSubscriptionStat(subscriptionId, statsMode);
}

@ExceptionHandler(FeatureNotAvailableException.class)
Copy link
Member

Choose a reason for hiding this comment

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

The same as for previous PR, maybe we should exceptions related to this particular controller in the controller


@RestController
public class PartitionsController {
public class PartitionsController extends NakadiProblemControllerAdvice {
Copy link
Member

Choose a reason for hiding this comment

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

why does every controller extend NakadiProblemControllerAdvice? I thought once NakadiProblemControllerAdvice is @ControllerAdvice it should work transparently.

Copy link
Contributor

Choose a reason for hiding this comment

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

@adyach I think @lmontrieux extended this class because it defines the method create used to generate the Problem response.

We would have to write some "catch/rethrow" here if we are not extending such class. What do you think? I prefer catch/rethrow instead of inheritance.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think spring wants you to use runtime exceptions everywhere, keep controller code linear without error handling and catch all in the controller advisor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now I have a global @ControllerAdvice for the handlers that relate to all controllers, and a few @ControllerAdvice with higher priority, for those controller-specific cases. Once we merge the previous PR on this work (moving problem creation to controller), some more controller-specific handlers will also more to the specific @ControllerAdvice classes (such as StorageNotFoundException)

import static org.zalando.problem.Status.UNPROCESSABLE_ENTITY;


public interface NakadiProblemHandling extends ProblemHandling {
Copy link
Member

Choose a reason for hiding this comment

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

why do we have this interface? it could be moved to NakadiProblemControllerAdvice

Copy link
Member

Choose a reason for hiding this comment

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

why should we extend ProblemHandling? do we use everything from there? for example I see validation trait there, I remember ValidationProblem.java in EventTypeController.create(), which we create by ourselves, but in case we have validation trait I expect to be created for us.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a good point. I changed the approach, I think it is cleaner and more spring boot-like now.

Lionel Montrieux added 2 commits October 8, 2018 16:55
Copy link
Member

@adyach adyach left a comment

Choose a reason for hiding this comment

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

Good job, you have made controllers super lean !

return status;
}
}
return null;
Copy link
Member

Choose a reason for hiding this comment

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

probably this is an exceptional situation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can we use 418 I'm a teapot? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I mean, it should never happen that the status code is not a real status code.

Copy link
Member

Choose a reason for hiding this comment

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

I would through runtime exception here, and if it happens we will have 500 at the end, which should be correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -110,16 +110,13 @@ private ResponseEntity postEventInternal(final String eventTypeName,
return response(result);
} catch (final JSONException e) {
Copy link
Member

Choose a reason for hiding this comment

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

I see that catch blocks here are only for logging purposes, we do logging in top level controller, do you think we can remove them?

if (featureToggleService.isFeatureEnabled(DISABLE_EVENT_TYPE_CREATION)) {
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}

if (errors.hasErrors()) {
return Responses.create(new ValidationProblem(errors), request);
throw new ValidationException(errors);
Copy link
Member

Choose a reason for hiding this comment

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

I suggest to follow common approach (no matter which one you choose), because a couple of lines above I see you return response entity in exceptional situation, and here you throw an exception

Copy link
Member

Choose a reason for hiding this comment

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

it looks like it does not make much sense to throw exception from where you can already form proper response

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, actually I was trying to avoid creating Problem in the controllers, and delegate that to ControllerAdvice classes instead. I agree with the first comment however, that the strategy should be consistent.

Copy link
Member

Choose a reason for hiding this comment

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

it is not necessarily to create Problem here, you can create ResponseEntity
?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we should create Problems for every error

if (errors.hasErrors()) {
return Responses.create(new ValidationProblem(errors), request);
throw new ValidationException(errors);
Copy link
Member

Choose a reason for hiding this comment

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

same here

if (!adminService.isAdmin(AuthorizationService.Operation.ADMIN)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
if (errors.hasErrors()) {
throw new ValidationException(errors);
Copy link
Member

Choose a reason for hiding this comment

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

same here


@Priority(10)
@ControllerAdvice(assignableTypes = CursorOperationsController.class)
public class CursorOperationsHandler implements AdviceTrait {
Copy link
Member

Choose a reason for hiding this comment

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

why does it implement AdviceTrait?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

to use AdviceTrait.create(..)

Lionel Montrieux added 11 commits October 10, 2018 16:38
# Conflicts:
#	src/main/java/org/zalando/nakadi/controller/CursorOperationsController.java
#	src/main/java/org/zalando/nakadi/controller/CursorsController.java
#	src/main/java/org/zalando/nakadi/controller/EventPublishingController.java
#	src/main/java/org/zalando/nakadi/controller/EventTypeController.java
#	src/main/java/org/zalando/nakadi/controller/ExceptionHandling.java
#	src/main/java/org/zalando/nakadi/controller/PostSubscriptionController.java
#	src/main/java/org/zalando/nakadi/controller/StoragesController.java
#	src/main/java/org/zalando/nakadi/controller/SubscriptionController.java
#	src/main/java/org/zalando/nakadi/controller/SubscriptionStreamController.java
#	src/main/java/org/zalando/nakadi/controller/TimelinesController.java
#	src/test/java/org/zalando/nakadi/controller/NakadiProblemHandlingTest.java
Copy link
Member

@adyach adyach left a comment

Choose a reason for hiding this comment

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

LGTM, though I would call *Handlers as *ExceptionHandlers

build.gradle Outdated
@@ -188,8 +190,9 @@ dependencies {
// end::dependencies[]

// tag::wrapper[]
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
wrapper {
Copy link
Member

Choose a reason for hiding this comment

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

do we really need this section ? we have defined it in gradle-wrapper.properties

}

private String generateErrorTraceId() {
public String generateErrorTraceId() {
Copy link
Member

Choose a reason for hiding this comment

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

private ?


@ExceptionHandler(NotFoundException.class)
public ResponseEntity<Problem> notFound(final NotFoundException ex, final NativeWebRequest request) {
LOG.error(ex.getMessage(), ex);
Copy link
Member

Choose a reason for hiding this comment

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

debug ?

@ExceptionHandler(UnableProcessException.class)
public ResponseEntity<Problem> handleUnableProcessException(final RuntimeException exception,
final NativeWebRequest request) {
LOG.error(exception.getMessage(), exception);
Copy link
Member

Choose a reason for hiding this comment

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

debug ?

@lmontrieux
Copy link
Contributor Author

@adyach I've addressed all comments. As we discussed offline, I went through all exception handlers, with the following guideline:

  • 5xx -> log.error and log exception (sometimes it's just log.warn when it makes more sense)
  • 4xx -> log.debug and only log exception.getMessage()

@adyach
Copy link
Member

adyach commented Oct 12, 2018

👍

@lmontrieux
Copy link
Contributor Author

deploy validation please

@lmontrieux
Copy link
Contributor Author

👍

@lmontrieux
Copy link
Contributor Author

👍

Lionel Montrieux added 2 commits October 16, 2018 13:29
# Conflicts:
#	src/main/java/org/zalando/nakadi/controller/SubscriptionController.java
#	src/main/java/org/zalando/nakadi/controller/advice/NakadiProblemExceptionHandler.java
@lmontrieux
Copy link
Contributor Author

👍

1 similar comment
@adyach
Copy link
Member

adyach commented Oct 18, 2018

👍

@lmontrieux lmontrieux merged commit f3d01f6 into master Oct 18, 2018
@lmontrieux lmontrieux deleted the bump-zalando-problem-libs branch October 18, 2018 11:39
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants