From 10a19da69b3061488d450ad0ac9afd692f819f5f Mon Sep 17 00:00:00 2001 From: Andrey Dyachkov Date: Fri, 4 May 2018 10:07:00 +0200 Subject: [PATCH 1/3] aruha-1636: unlimited retention time by Nakadi admin --- .../nakadi/config/ValidatorConfig.java | 2 +- .../controller/EventTypeController.java | 14 +++--- .../EventTypeOptionsValidationException.java | 8 ++++ .../zalando/nakadi/service/AdminService.java | 7 +-- .../nakadi/service/EventTypeService.java | 32 ++++++++++--- .../validation/EventTypeOptionsValidator.java | 34 ++++++++++++++ .../validation/EventTypeOptionsValidator.java | 47 ------------------- .../EventTypeAuthorizationTest.java | 30 ++++++++++++ .../EventTypeControllerTestCase.java | 13 +++-- .../nakadi/service/EventTypeServiceTest.java | 8 +++- .../EventTypeOptionsValidatorTest.java | 41 ++++++++-------- 11 files changed, 141 insertions(+), 95 deletions(-) create mode 100644 src/main/java/org/zalando/nakadi/exceptions/runtime/EventTypeOptionsValidationException.java create mode 100644 src/main/java/org/zalando/nakadi/service/validation/EventTypeOptionsValidator.java delete mode 100644 src/main/java/org/zalando/nakadi/validation/EventTypeOptionsValidator.java diff --git a/src/main/java/org/zalando/nakadi/config/ValidatorConfig.java b/src/main/java/org/zalando/nakadi/config/ValidatorConfig.java index 49f9c9ece6..6be53ef4f2 100644 --- a/src/main/java/org/zalando/nakadi/config/ValidatorConfig.java +++ b/src/main/java/org/zalando/nakadi/config/ValidatorConfig.java @@ -11,7 +11,7 @@ import org.springframework.context.annotation.Configuration; import org.zalando.nakadi.domain.SchemaChange; import org.zalando.nakadi.domain.Version; -import org.zalando.nakadi.validation.EventTypeOptionsValidator; +import org.zalando.nakadi.service.validation.EventTypeOptionsValidator; import org.zalando.nakadi.validation.SchemaEvolutionService; import org.zalando.nakadi.validation.schema.CategoryChangeConstraint; import org.zalando.nakadi.validation.schema.CompatibilityModeChangeConstraint; diff --git a/src/main/java/org/zalando/nakadi/controller/EventTypeController.java b/src/main/java/org/zalando/nakadi/controller/EventTypeController.java index 13e1db2b2e..cfb5605520 100644 --- a/src/main/java/org/zalando/nakadi/controller/EventTypeController.java +++ b/src/main/java/org/zalando/nakadi/controller/EventTypeController.java @@ -7,7 +7,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.Errors; -import org.springframework.validation.ValidationUtils; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -34,6 +33,7 @@ import org.zalando.nakadi.exceptions.runtime.NoEventTypeException; import org.zalando.nakadi.exceptions.runtime.ServiceTemporarilyUnavailableException; import org.zalando.nakadi.exceptions.runtime.TopicConfigException; +import org.zalando.nakadi.exceptions.runtime.EventTypeOptionsValidationException; import org.zalando.nakadi.plugin.api.ApplicationService; import org.zalando.nakadi.plugin.api.authz.AuthorizationService; import org.zalando.nakadi.problem.ValidationProblem; @@ -41,7 +41,6 @@ import org.zalando.nakadi.service.EventTypeService; import org.zalando.nakadi.service.FeatureToggleService; import org.zalando.nakadi.service.Result; -import org.zalando.nakadi.validation.EventTypeOptionsValidator; import org.zalando.problem.MoreStatus; import org.zalando.problem.Problem; import org.zalando.problem.spring.web.advice.Responses; @@ -63,7 +62,6 @@ public class EventTypeController { private final EventTypeService eventTypeService; private final FeatureToggleService featureToggleService; - private final EventTypeOptionsValidator eventTypeOptionsValidator; private final ApplicationService applicationService; private final AdminService adminService; private final NakadiSettings nakadiSettings; @@ -71,13 +69,11 @@ public class EventTypeController { @Autowired public EventTypeController(final EventTypeService eventTypeService, final FeatureToggleService featureToggleService, - final EventTypeOptionsValidator eventTypeOptionsValidator, final ApplicationService applicationService, final AdminService adminService, final NakadiSettings nakadiSettings) { this.eventTypeService = eventTypeService; this.featureToggleService = featureToggleService; - this.eventTypeOptionsValidator = eventTypeOptionsValidator; this.applicationService = applicationService; this.adminService = adminService; this.nakadiSettings = nakadiSettings; @@ -100,7 +96,6 @@ public ResponseEntity create(@Valid @RequestBody final EventTypeBase eventTyp return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); } - ValidationUtils.invokeValidator(eventTypeOptionsValidator, eventType.getOptions(), errors); if (featureToggleService.isFeatureEnabled(CHECK_OWNING_APPLICATION) && !applicationService.exists(eventType.getOwningApplication())) { return Responses.create(Problem.valueOf(MoreStatus.UNPROCESSABLE_ENTITY, @@ -144,7 +139,6 @@ public ResponseEntity update( NakadiRuntimeException, ServiceTemporarilyUnavailableException, UnableProcessException { - ValidationUtils.invokeValidator(eventTypeOptionsValidator, eventType.getOptions(), errors); if (errors.hasErrors()) { return Responses.create(new ValidationProblem(errors), request); } @@ -234,4 +228,10 @@ public ResponseEntity invalidEventTypeException(final InvalidEventTypeE return Responses.create(exception.asProblem(), request); } + @ExceptionHandler(EventTypeOptionsValidationException.class) + public ResponseEntity unableProcess(final EventTypeOptionsValidationException exception, + final NativeWebRequest request) { + LOG.debug(exception.getMessage(), exception); + return Responses.create(MoreStatus.UNPROCESSABLE_ENTITY, exception.getMessage(), request); + } } diff --git a/src/main/java/org/zalando/nakadi/exceptions/runtime/EventTypeOptionsValidationException.java b/src/main/java/org/zalando/nakadi/exceptions/runtime/EventTypeOptionsValidationException.java new file mode 100644 index 0000000000..2aa4c90c41 --- /dev/null +++ b/src/main/java/org/zalando/nakadi/exceptions/runtime/EventTypeOptionsValidationException.java @@ -0,0 +1,8 @@ +package org.zalando.nakadi.exceptions.runtime; + +public class EventTypeOptionsValidationException extends MyNakadiRuntimeException1 { + + public EventTypeOptionsValidationException(String message) { + super(message); + } +} diff --git a/src/main/java/org/zalando/nakadi/service/AdminService.java b/src/main/java/org/zalando/nakadi/service/AdminService.java index 270cef96a4..c471617ad5 100644 --- a/src/main/java/org/zalando/nakadi/service/AdminService.java +++ b/src/main/java/org/zalando/nakadi/service/AdminService.java @@ -13,6 +13,7 @@ import org.zalando.nakadi.domain.ResourceAuthorization; import org.zalando.nakadi.exceptions.UnableProcessException; import org.zalando.nakadi.exceptions.runtime.DbWriteOperationsBlockedException; +import org.zalando.nakadi.plugin.api.PluginException; import org.zalando.nakadi.plugin.api.authz.AuthorizationService; import org.zalando.nakadi.plugin.api.authz.Resource; import org.zalando.nakadi.repository.db.AuthorizationDbRepository; @@ -67,14 +68,14 @@ public void updateAdmins(final List newAdmins) throws DbWriteOperati authorizationDbRepository.update(add, delete); } - public boolean isAdmin(final AuthorizationService.Operation operation) { + public boolean isAdmin(final AuthorizationService.Operation operation) throws PluginException { final List permissions = getAdmins(); final Resource resource = new AdminResource(ADMIN_RESOURCE, ResourceAuthorization.fromPermissionsList(permissions)); return authorizationService.isAuthorized(operation, resource); } - public boolean hasAllDataAccess(final AuthorizationService.Operation operation) { + public boolean hasAllDataAccess(final AuthorizationService.Operation operation) throws PluginException { try { final List permissions = resourceCache.get(ALL_DATA_ACCESS_RESOURCE, () -> authorizationDbRepository.listAllDataAccess()); @@ -100,7 +101,7 @@ private List removeDefaultAdmin(final List permissions) .collect(Collectors.toList()); } - private void validateAllAdmins(final List admins) throws UnableProcessException { + private void validateAllAdmins(final List admins) throws UnableProcessException, PluginException { final List invalid = admins.stream().filter(permission -> !authorizationService.isAuthorizationAttributeValid(permission.getAuthorizationAttribute())) .collect(Collectors.toList()); diff --git a/src/main/java/org/zalando/nakadi/service/EventTypeService.java b/src/main/java/org/zalando/nakadi/service/EventTypeService.java index 8cd1eab638..31e960970c 100644 --- a/src/main/java/org/zalando/nakadi/service/EventTypeService.java +++ b/src/main/java/org/zalando/nakadi/service/EventTypeService.java @@ -39,18 +39,21 @@ import org.zalando.nakadi.exceptions.runtime.AccessDeniedException; import org.zalando.nakadi.exceptions.runtime.DbWriteOperationsBlockedException; import org.zalando.nakadi.exceptions.runtime.EventTypeDeletionException; +import org.zalando.nakadi.exceptions.runtime.EventTypeOptionsValidationException; import org.zalando.nakadi.exceptions.runtime.EventTypeUnavailableException; import org.zalando.nakadi.exceptions.runtime.InconsistentStateException; import org.zalando.nakadi.exceptions.runtime.NoEventTypeException; import org.zalando.nakadi.exceptions.runtime.ServiceTemporarilyUnavailableException; import org.zalando.nakadi.exceptions.runtime.TopicConfigException; import org.zalando.nakadi.partitioning.PartitionResolver; +import org.zalando.nakadi.plugin.api.authz.AuthorizationService; import org.zalando.nakadi.repository.EventTypeRepository; import org.zalando.nakadi.repository.TopicRepository; import org.zalando.nakadi.repository.db.SubscriptionDbRepository; import org.zalando.nakadi.repository.kafka.PartitionsCalculator; import org.zalando.nakadi.service.timeline.TimelineService; import org.zalando.nakadi.service.timeline.TimelineSync; +import org.zalando.nakadi.service.validation.EventTypeOptionsValidator; import org.zalando.nakadi.util.JsonUtils; import org.zalando.nakadi.validation.SchemaEvolutionService; import org.zalando.nakadi.validation.SchemaIncompatibility; @@ -85,6 +88,8 @@ public class EventTypeService { private final TransactionTemplate transactionTemplate; private final NakadiKpiPublisher nakadiKpiPublisher; private final String etLogEventType; + private final EventTypeOptionsValidator eventTypeOptionsValidator; + private final AdminService adminService; @Autowired public EventTypeService(final EventTypeRepository eventTypeRepository, @@ -100,7 +105,9 @@ public EventTypeService(final EventTypeRepository eventTypeRepository, final TransactionTemplate transactionTemplate, final NakadiSettings nakadiSettings, final NakadiKpiPublisher nakadiKpiPublisher, - @Value("${nakadi.kpi.event-types.nakadiEventTypeLog}") final String etLogEventType) { + @Value("${nakadi.kpi.event-types.nakadiEventTypeLog}") final String etLogEventType, + final EventTypeOptionsValidator eventTypeOptionsValidator, + final AdminService adminService) { this.eventTypeRepository = eventTypeRepository; this.timelineService = timelineService; this.partitionResolver = partitionResolver; @@ -115,19 +122,27 @@ public EventTypeService(final EventTypeRepository eventTypeRepository, this.nakadiSettings = nakadiSettings; this.nakadiKpiPublisher = nakadiKpiPublisher; this.etLogEventType = etLogEventType; + this.eventTypeOptionsValidator = eventTypeOptionsValidator; + this.adminService = adminService; } public List list() { return eventTypeRepository.list(); } - public void create(final EventTypeBase eventType) throws TopicCreationException, InternalNakadiException, - NoSuchPartitionStrategyException, DuplicatedEventTypeNameException, InvalidEventTypeException, - DbWriteOperationsBlockedException { + public void create(final EventTypeBase eventType) + throws TopicCreationException, + InternalNakadiException, + NoSuchPartitionStrategyException, + DuplicatedEventTypeNameException, + InvalidEventTypeException, + DbWriteOperationsBlockedException, + EventTypeOptionsValidationException { if (featureToggleService.isFeatureEnabled(FeatureToggleService.Feature.DISABLE_DB_WRITE_OPERATIONS)) { throw new DbWriteOperationsBlockedException("Cannot create event type: write operations on DB " + "are blocked by feature flag."); } + eventTypeOptionsValidator.checkRetentionTime(eventType.getOptions()); setDefaultEventTypeOptions(eventType); validateSchema(eventType); enrichment.validate(eventType); @@ -250,7 +265,8 @@ public void update(final String eventTypeName, NakadiRuntimeException, ServiceTemporarilyUnavailableException, UnableProcessException, - DbWriteOperationsBlockedException { + DbWriteOperationsBlockedException, + EventTypeOptionsValidationException { if (featureToggleService.isFeatureEnabled(FeatureToggleService.Feature.DISABLE_DB_WRITE_OPERATIONS)) { throw new DbWriteOperationsBlockedException("Cannot update event type: write operations on DB " + "are blocked by feature flag."); @@ -258,10 +274,12 @@ public void update(final String eventTypeName, Closeable updatingCloser = null; try { updatingCloser = timelineSync.workWithEventType(eventTypeName, nakadiSettings.getTimelineWaitTimeoutMs()); - final EventType original = eventTypeRepository.findByName(eventTypeName); - authorizationValidator.authorizeEventTypeAdmin(original); + if (!adminService.isAdmin(AuthorizationService.Operation.WRITE)) { + eventTypeOptionsValidator.checkRetentionTime(eventTypeBase.getOptions()); + authorizationValidator.authorizeEventTypeAdmin(original); + } authorizationValidator.validateAuthorization(original, eventTypeBase); validateName(eventTypeName, eventTypeBase); validateSchema(eventTypeBase); diff --git a/src/main/java/org/zalando/nakadi/service/validation/EventTypeOptionsValidator.java b/src/main/java/org/zalando/nakadi/service/validation/EventTypeOptionsValidator.java new file mode 100644 index 0000000000..aa7894d438 --- /dev/null +++ b/src/main/java/org/zalando/nakadi/service/validation/EventTypeOptionsValidator.java @@ -0,0 +1,34 @@ +package org.zalando.nakadi.service.validation; + +import org.zalando.nakadi.domain.EventTypeOptions; +import org.zalando.nakadi.exceptions.runtime.EventTypeOptionsValidationException; + +public final class EventTypeOptionsValidator { + + private final long minTopicRetentionMs; + private final long maxTopicRetentionMs; + + public EventTypeOptionsValidator(final long minTopicRetentionMs, + final long maxTopicRetentionMs) { + this.minTopicRetentionMs = minTopicRetentionMs; + this.maxTopicRetentionMs = maxTopicRetentionMs; + } + + public void checkRetentionTime(final EventTypeOptions options) throws EventTypeOptionsValidationException { + if (options == null) { + return; + } + + final Long retentionTime = options.getRetentionTime(); + if (retentionTime != null) { + if (retentionTime > maxTopicRetentionMs) { + throw new EventTypeOptionsValidationException( + "Field \"options.retention_time\" can not be more than " + maxTopicRetentionMs); + } else if (retentionTime < minTopicRetentionMs) { + throw new EventTypeOptionsValidationException( + "Field \"options.retention_time\" can not be less than " + minTopicRetentionMs); + } + } + } + +} diff --git a/src/main/java/org/zalando/nakadi/validation/EventTypeOptionsValidator.java b/src/main/java/org/zalando/nakadi/validation/EventTypeOptionsValidator.java deleted file mode 100644 index ff6c5663df..0000000000 --- a/src/main/java/org/zalando/nakadi/validation/EventTypeOptionsValidator.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.zalando.nakadi.validation; - -import org.springframework.validation.Errors; -import org.springframework.validation.Validator; -import org.zalando.nakadi.domain.EventTypeOptions; - -public final class EventTypeOptionsValidator implements Validator { - - private final long minTopicRetentionMs; - private final long maxTopicRetentionMs; - - public EventTypeOptionsValidator(final long minTopicRetentionMs, - final long maxTopicRetentionMs) { - this.minTopicRetentionMs = minTopicRetentionMs; - this.maxTopicRetentionMs = maxTopicRetentionMs; - } - - @Override - public boolean supports(final Class clazz) { - return EventTypeOptions.class.equals(clazz); - } - - @Override - public void validate(final Object target, final Errors errors) { - final EventTypeOptions options = (EventTypeOptions) target; - checkRetentionTime(errors, options); - } - - private void checkRetentionTime(final Errors errors, final EventTypeOptions options) { - if (options == null) { - return; - } - - final Long retentionTime = options.getRetentionTime(); - if (retentionTime != null) { - if (retentionTime > maxTopicRetentionMs) { - createError(errors, "can not be more than " + maxTopicRetentionMs); - } else if (retentionTime < minTopicRetentionMs) { - createError(errors, "can not be less than " + minTopicRetentionMs); - } - } - } - - private void createError(final Errors errors, final String message) { - errors.rejectValue("options.retentionTime", null, message); - } -} diff --git a/src/test/java/org/zalando/nakadi/controller/EventTypeAuthorizationTest.java b/src/test/java/org/zalando/nakadi/controller/EventTypeAuthorizationTest.java index d4cb06f968..20ed9c2e14 100644 --- a/src/test/java/org/zalando/nakadi/controller/EventTypeAuthorizationTest.java +++ b/src/test/java/org/zalando/nakadi/controller/EventTypeAuthorizationTest.java @@ -2,6 +2,7 @@ import org.junit.Test; import org.zalando.nakadi.domain.EventType; +import org.zalando.nakadi.domain.EventTypeOptions; import org.zalando.nakadi.domain.EventTypeResource; import org.zalando.nakadi.exceptions.UnableProcessException; import org.zalando.nakadi.exceptions.runtime.AccessDeniedException; @@ -18,6 +19,7 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -51,6 +53,34 @@ public void whenPUTNotAuthorizedThen403() throws Exception { "Access on ADMIN event-type:"+ eventType.getName() + " denied")))); } + @Test + public void whenPUTUnlimitedRetentionTimeByAdminThen200() throws Exception { + final EventTypeOptions eto = new EventTypeOptions(); + eto.setRetentionTime(Long.MAX_VALUE); + final EventType eventType = EventTypeTestBuilder.builder().options(eto).build(); + + doReturn(eventType).when(eventTypeRepository).findByName(any()); + when(adminService.isAdmin(AuthorizationService.Operation.WRITE)).thenReturn(true); + + putEventType(eventType, eventType.getName()) + .andExpect(status().isOk()); + } + + @Test + public void whenPUTUnlimitedRetentionTimeByUserThen422() throws Exception { + final EventTypeOptions eto = new EventTypeOptions(); + eto.setRetentionTime(Long.MAX_VALUE); + final EventType eventType = EventTypeTestBuilder.builder().options(eto).build(); + + doReturn(eventType).when(eventTypeRepository).findByName(any()); + when(adminService.isAdmin(AuthorizationService.Operation.WRITE)).thenReturn(false); + + putEventType(eventType, eventType.getName()) + .andExpect(status().isUnprocessableEntity()) + .andExpect(content().string(matchesProblem(Problem.valueOf(MoreStatus.UNPROCESSABLE_ENTITY, + "Field \"options.retention_time\" can not be more than 345600000")))); + } + @Test public void whenPUTNullAuthorizationForExistingAuthorization() throws Exception { final EventType newEventType = EventTypeTestBuilder.builder().build(); diff --git a/src/test/java/org/zalando/nakadi/controller/EventTypeControllerTestCase.java b/src/test/java/org/zalando/nakadi/controller/EventTypeControllerTestCase.java index b2f2d8be21..cc09983bba 100644 --- a/src/test/java/org/zalando/nakadi/controller/EventTypeControllerTestCase.java +++ b/src/test/java/org/zalando/nakadi/controller/EventTypeControllerTestCase.java @@ -32,7 +32,7 @@ import org.zalando.nakadi.service.timeline.TimelineSync; import org.zalando.nakadi.util.UUIDGenerator; import org.zalando.nakadi.utils.TestUtils; -import org.zalando.nakadi.validation.EventTypeOptionsValidator; +import org.zalando.nakadi.service.validation.EventTypeOptionsValidator; import org.zalando.nakadi.validation.SchemaEvolutionService; import org.zalando.problem.Problem; import uk.co.datumedge.hamcrest.json.SameJSONAs; @@ -103,15 +103,14 @@ public void init() throws Exception { return callback.doInTransaction(null); }); + final EventTypeOptionsValidator eventTypeOptionsValidator = + new EventTypeOptionsValidator(TOPIC_RETENTION_MIN_MS, TOPIC_RETENTION_MAX_MS); final EventTypeService eventTypeService = new EventTypeService(eventTypeRepository, timelineService, partitionResolver, enrichment, subscriptionRepository, schemaEvolutionService, partitionsCalculator, featureToggleService, authorizationValidator, timelineSync, transactionTemplate, nakadiSettings, - nakadiKpiPublisher, "et-log-event-type"); - - final EventTypeOptionsValidator eventTypeOptionsValidator = - new EventTypeOptionsValidator(TOPIC_RETENTION_MIN_MS, TOPIC_RETENTION_MAX_MS); - final EventTypeController controller = new EventTypeController(eventTypeService, - featureToggleService, eventTypeOptionsValidator, applicationService, adminService, nakadiSettings); + nakadiKpiPublisher, "et-log-event-type", eventTypeOptionsValidator, adminService); + final EventTypeController controller = new EventTypeController(eventTypeService,featureToggleService, + applicationService, adminService, nakadiSettings); doReturn(randomUUID).when(uuid).randomUUID(); doReturn(true).when(applicationService).exists(any()); diff --git a/src/test/java/org/zalando/nakadi/service/EventTypeServiceTest.java b/src/test/java/org/zalando/nakadi/service/EventTypeServiceTest.java index 5352ea6e09..94283046c0 100644 --- a/src/test/java/org/zalando/nakadi/service/EventTypeServiceTest.java +++ b/src/test/java/org/zalando/nakadi/service/EventTypeServiceTest.java @@ -21,6 +21,7 @@ import org.zalando.nakadi.repository.kafka.PartitionsCalculator; import org.zalando.nakadi.service.timeline.TimelineService; import org.zalando.nakadi.service.timeline.TimelineSync; +import org.zalando.nakadi.service.validation.EventTypeOptionsValidator; import org.zalando.nakadi.validation.SchemaEvolutionService; import java.util.ArrayList; @@ -44,6 +45,8 @@ public class EventTypeServiceTest { private static final String KPI_ET_LOG_EVENT_TYPE = "et-log"; + protected static final long TOPIC_RETENTION_MIN_MS = 86400000; + protected static final long TOPIC_RETENTION_MAX_MS = 345600000; private final Enrichment enrichment = mock(Enrichment.class); private final EventTypeRepository eventTypeRepository = mock(EventTypeRepository.class); @@ -58,14 +61,17 @@ public class EventTypeServiceTest { private final TransactionTemplate transactionTemplate = mock(TransactionTemplate.class); private final AuthorizationValidator authorizationValidator = mock(AuthorizationValidator.class); private final NakadiKpiPublisher nakadiKpiPublisher = mock(NakadiKpiPublisher.class); + private final AdminService adminService = mock(AdminService.class); private EventTypeService eventTypeService; @Before public void setUp() { + final EventTypeOptionsValidator eventTypeOptionsValidator = + new EventTypeOptionsValidator(TOPIC_RETENTION_MIN_MS, TOPIC_RETENTION_MAX_MS); eventTypeService = new EventTypeService(eventTypeRepository, timelineService, partitionResolver, enrichment, subscriptionDbRepository, schemaEvolutionService, partitionsCalculator, featureToggleService, authorizationValidator, timelineSync, transactionTemplate, nakadiSettings, nakadiKpiPublisher, - KPI_ET_LOG_EVENT_TYPE); + KPI_ET_LOG_EVENT_TYPE, eventTypeOptionsValidator, adminService); when(transactionTemplate.execute(any())).thenAnswer(invocation -> { final TransactionCallback callback = (TransactionCallback) invocation.getArguments()[0]; return callback.doInTransaction(null); diff --git a/src/test/java/org/zalando/nakadi/validation/EventTypeOptionsValidatorTest.java b/src/test/java/org/zalando/nakadi/validation/EventTypeOptionsValidatorTest.java index 78d59f0368..03c4389eaf 100644 --- a/src/test/java/org/zalando/nakadi/validation/EventTypeOptionsValidatorTest.java +++ b/src/test/java/org/zalando/nakadi/validation/EventTypeOptionsValidatorTest.java @@ -1,51 +1,48 @@ package org.zalando.nakadi.validation; -import org.junit.Before; +import org.junit.Assert; import org.junit.Test; -import org.mockito.Matchers; -import org.mockito.Mockito; -import org.springframework.validation.Errors; import org.zalando.nakadi.domain.EventTypeOptions; +import org.zalando.nakadi.exceptions.runtime.EventTypeOptionsValidationException; +import org.zalando.nakadi.service.validation.EventTypeOptionsValidator; public class EventTypeOptionsValidatorTest { private static final Long TOPIC_RETENTION_MIN = 1L; private static final Long TOPIC_RETENTION_MAX = 3L; - private final Errors mockedErrors = Mockito.mock(Errors.class); private final EventTypeOptionsValidator validator = new EventTypeOptionsValidator( TOPIC_RETENTION_MIN, TOPIC_RETENTION_MAX ); - @Before - public void setUp() throws Exception { - Mockito.reset(mockedErrors); - } @Test public void testValidation() { final EventTypeOptions eventTypeOptions = new EventTypeOptions(); - validator.validate(eventTypeOptions, mockedErrors); - - Mockito.verify(mockedErrors, Mockito.times(0)).rejectValue(Matchers.any(), Matchers.any(), - Matchers.any()); + validator.checkRetentionTime(eventTypeOptions); } @Test public void testValidationMin() { - validator.validate(createEventTypeOptions(0L), mockedErrors); - - Mockito.verify(mockedErrors, Mockito.times(1)) - .rejectValue("options.retentionTime", null, "can not be less than " + TOPIC_RETENTION_MIN); + try { + validator.checkRetentionTime(createEventTypeOptions(0L)); + Assert.fail("EventTypeOptionsValidationException is expected here"); + } catch (EventTypeOptionsValidationException e) { + Assert.assertEquals( + "Field \"options.retention_time\" can not be less than " + TOPIC_RETENTION_MIN, e.getMessage()); + } } @Test public void testValidationMax() { - validator.validate(createEventTypeOptions(4L), mockedErrors); - - Mockito.verify(mockedErrors, Mockito.times(1)) - .rejectValue("options.retentionTime", null, "can not be more than " + TOPIC_RETENTION_MAX); + try { + validator.checkRetentionTime(createEventTypeOptions(4L)); + Assert.fail("EventTypeOptionsValidationException is expected here"); + } catch (EventTypeOptionsValidationException e) { + Assert.assertEquals( + "Field \"options.retention_time\" can not be more than " + TOPIC_RETENTION_MAX, e.getMessage()); + } } private EventTypeOptions createEventTypeOptions(final long retentionTime) { @@ -54,4 +51,4 @@ private EventTypeOptions createEventTypeOptions(final long retentionTime) { return eventTypeOptions; } -} \ No newline at end of file +} From 9a89c55e20c9debadde74aa6a754b8b075e7acce Mon Sep 17 00:00:00 2001 From: Andrey Dyachkov Date: Fri, 4 May 2018 10:20:58 +0200 Subject: [PATCH 2/3] aruha-1636: fixed checkstyle --- .../exceptions/runtime/EventTypeOptionsValidationException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/zalando/nakadi/exceptions/runtime/EventTypeOptionsValidationException.java b/src/main/java/org/zalando/nakadi/exceptions/runtime/EventTypeOptionsValidationException.java index 2aa4c90c41..47288f648a 100644 --- a/src/main/java/org/zalando/nakadi/exceptions/runtime/EventTypeOptionsValidationException.java +++ b/src/main/java/org/zalando/nakadi/exceptions/runtime/EventTypeOptionsValidationException.java @@ -2,7 +2,7 @@ public class EventTypeOptionsValidationException extends MyNakadiRuntimeException1 { - public EventTypeOptionsValidationException(String message) { + public EventTypeOptionsValidationException(final String message) { super(message); } } From 128296155ffefd216c521e5a9f362694c3319518 Mon Sep 17 00:00:00 2001 From: Andrey Dyachkov Date: Fri, 4 May 2018 10:24:51 +0200 Subject: [PATCH 3/3] aruha-1636: removed test --- .../nakadi/validation/EventTypeOptionsValidatorTest.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/test/java/org/zalando/nakadi/validation/EventTypeOptionsValidatorTest.java b/src/test/java/org/zalando/nakadi/validation/EventTypeOptionsValidatorTest.java index 03c4389eaf..8f176b421b 100644 --- a/src/test/java/org/zalando/nakadi/validation/EventTypeOptionsValidatorTest.java +++ b/src/test/java/org/zalando/nakadi/validation/EventTypeOptionsValidatorTest.java @@ -16,13 +16,6 @@ public class EventTypeOptionsValidatorTest { TOPIC_RETENTION_MAX ); - - @Test - public void testValidation() { - final EventTypeOptions eventTypeOptions = new EventTypeOptions(); - validator.checkRetentionTime(eventTypeOptions); - } - @Test public void testValidationMin() { try {