From 9c145c58ebc7153fd99b02acd76d1e3cfa9c64d8 Mon Sep 17 00:00:00 2001 From: garima Date: Mon, 20 Apr 2020 11:55:50 +0200 Subject: [PATCH] feat(engine-rest): add event subscription endpoint Related to CAM-11792 Closes PR #790 --- .../rest/EventSubscriptionRestService.java | 62 ++++ .../runtime/EventSubscriptionQueryDto.java | 196 +++++++++++ .../AbstractProcessEngineRestServiceImpl.java | 8 + .../DefaultProcessEngineRestServiceImpl.java | 7 +- .../EventSubscriptionRestServiceImpl.java | 93 +++++ .../NamedProcessEngineRestServiceImpl.java | 9 +- ...EventSubscriptionRestServiceQueryTest.java | 331 ++++++++++++++++++ .../bpm/engine/rest/helper/MockProvider.java | 6 +- 8 files changed, 709 insertions(+), 3 deletions(-) create mode 100644 engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/EventSubscriptionRestService.java create mode 100644 engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/runtime/EventSubscriptionQueryDto.java create mode 100644 engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/EventSubscriptionRestServiceImpl.java create mode 100644 engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/EventSubscriptionRestServiceQueryTest.java diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/EventSubscriptionRestService.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/EventSubscriptionRestService.java new file mode 100644 index 00000000000..a43ca0eab3c --- /dev/null +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/EventSubscriptionRestService.java @@ -0,0 +1,62 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.rest; + +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; + +import org.camunda.bpm.engine.rest.dto.CountResultDto; +import org.camunda.bpm.engine.rest.dto.runtime.EventSubscriptionDto; +import org.camunda.bpm.engine.runtime.EventSubscriptionQuery; + +@Produces(MediaType.APPLICATION_JSON) +public interface EventSubscriptionRestService { + + public static final String PATH = "/event-subscription"; + + /** + * Exposes the {@link EventSubscriptionQuery} interface as a REST service. + * + * @param uriInfo + * @param firstResult + * @param maxResults + * @return + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + List getEventSubscriptions(@Context UriInfo uriInfo, + @QueryParam("firstResult") Integer firstResult, + @QueryParam("maxResults") Integer maxResults); + + /** + * Number of event subscriptions + * + * @return + */ + @GET + @Path("/count") + @Produces(MediaType.APPLICATION_JSON) + CountResultDto getEventSubscriptionsCount(@Context UriInfo uriInfo); + +} diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/runtime/EventSubscriptionQueryDto.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/runtime/EventSubscriptionQueryDto.java new file mode 100644 index 00000000000..30ed0343d2c --- /dev/null +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/runtime/EventSubscriptionQueryDto.java @@ -0,0 +1,196 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.rest.dto.runtime; + +import static java.lang.Boolean.TRUE; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.MultivaluedMap; + +import org.camunda.bpm.engine.ProcessEngine; +import org.camunda.bpm.engine.rest.dto.AbstractQueryDto; +import org.camunda.bpm.engine.rest.dto.CamundaQueryParam; +import org.camunda.bpm.engine.rest.dto.converter.BooleanConverter; +import org.camunda.bpm.engine.rest.dto.converter.StringListConverter; +import org.camunda.bpm.engine.runtime.EventSubscriptionQuery; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class EventSubscriptionQueryDto extends AbstractQueryDto { + + private static final String SORT_BY_TENANT_ID = "tenantId"; + private static final String SORT_BY_CREATED = "created"; + + private static final List VALID_SORT_BY_VALUES; + static { + VALID_SORT_BY_VALUES = new ArrayList(); + VALID_SORT_BY_VALUES.add(SORT_BY_TENANT_ID); + VALID_SORT_BY_VALUES.add(SORT_BY_CREATED); + } + + private String eventSubscriptionId; + private String eventName; + private String eventType; + private String executionId; + private String processInstanceId; + private String activityId; + private List tenantIdIn; + private Boolean withoutTenantId; + private Boolean includeEventSubscriptionsWithoutTenantId; + + public EventSubscriptionQueryDto() { + + } + + public EventSubscriptionQueryDto(ObjectMapper objectMapper, MultivaluedMap queryParameters) { + super(objectMapper, queryParameters); + } + + public String getEventSubscriptionId() { + return eventSubscriptionId; + } + + @CamundaQueryParam("eventSubscriptionId") + public void setEventSubscriptionId(String eventSubscriptionId) { + this.eventSubscriptionId = eventSubscriptionId; + } + + public String getEventName() { + return eventName; + } + + @CamundaQueryParam("eventName") + public void setEventName(String eventName) { + this.eventName = eventName; + } + + public String getEventType() { + return eventType; + } + + @CamundaQueryParam("eventType") + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public String getExecutionId() { + return executionId; + } + + @CamundaQueryParam("executionId") + public void setExecutionId(String executionId) { + this.executionId = executionId; + } + + public String getProcessInstanceId() { + return processInstanceId; + } + + @CamundaQueryParam("processInstanceId") + public void setProcessInstanceId(String processInstanceId) { + this.processInstanceId = processInstanceId; + } + + public String getActivityId() { + return activityId; + } + + @CamundaQueryParam("activityId") + public void setActivityId(String activityId) { + this.activityId = activityId; + } + + public List getTenantIdIn() { + return tenantIdIn; + } + + @CamundaQueryParam(value = "tenantIdIn", converter = StringListConverter.class) + public void setTenantIdIn(List tenantIdIn) { + this.tenantIdIn = tenantIdIn; + } + + public Boolean getWithoutTenantId() { + return withoutTenantId; + } + + @CamundaQueryParam(value = "withoutTenantId", converter = BooleanConverter.class) + public void setWithoutTenantId(Boolean withoutTenantId) { + this.withoutTenantId = withoutTenantId; + } + + public Boolean getIncludeEventSubscriptionsWithoutTenantId() { + return includeEventSubscriptionsWithoutTenantId; + } + + @CamundaQueryParam(value = "includeEventSubscriptionsWithoutTenantId", converter = BooleanConverter.class) + public void setIncludeEventSubscriptionsWithoutTenantId(Boolean includeEventSubscriptionsWithoutTenantId) { + this.includeEventSubscriptionsWithoutTenantId = includeEventSubscriptionsWithoutTenantId; + } + + @Override + protected boolean isValidSortByValue(String value) { + return VALID_SORT_BY_VALUES.contains(value); + } + + @Override + protected EventSubscriptionQuery createNewQuery(ProcessEngine engine) { + return engine.getRuntimeService().createEventSubscriptionQuery(); + } + + @Override + protected void applyFilters(EventSubscriptionQuery query) { + if (eventSubscriptionId != null) { + query.eventSubscriptionId(eventSubscriptionId); + } + if (eventName != null) { + query.eventName(eventName); + } + if (eventType != null) { + query.eventType(eventType); + } + if (executionId != null) { + query.executionId(executionId); + } + if (processInstanceId != null) { + query.processInstanceId(processInstanceId); + } + if (activityId != null) { + query.activityId(activityId); + } + if (tenantIdIn != null && !tenantIdIn.isEmpty()) { + query.tenantIdIn(tenantIdIn.toArray(new String[tenantIdIn.size()])); + } + if (TRUE.equals(withoutTenantId)) { + query.withoutTenantId(); + } + if (TRUE.equals(includeEventSubscriptionsWithoutTenantId)) { + query.includeEventSubscriptionsWithoutTenantId(); + } + } + + @Override + protected void applySortBy(EventSubscriptionQuery query, String sortBy, Map parameters, ProcessEngine engine) { + if (sortBy.equals(SORT_BY_CREATED)) { + query.orderByCreated(); + } else if (sortBy.equals(SORT_BY_TENANT_ID)) { + query.orderByTenantId(); + } + } +} diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/AbstractProcessEngineRestServiceImpl.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/AbstractProcessEngineRestServiceImpl.java index 698b11e1ddc..f6c2bb37817 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/AbstractProcessEngineRestServiceImpl.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/AbstractProcessEngineRestServiceImpl.java @@ -31,6 +31,7 @@ import org.camunda.bpm.engine.rest.DecisionDefinitionRestService; import org.camunda.bpm.engine.rest.DecisionRequirementsDefinitionRestService; import org.camunda.bpm.engine.rest.DeploymentRestService; +import org.camunda.bpm.engine.rest.EventSubscriptionRestService; import org.camunda.bpm.engine.rest.ExecutionRestService; import org.camunda.bpm.engine.rest.ExternalTaskRestService; import org.camunda.bpm.engine.rest.FilterRestService; @@ -298,6 +299,13 @@ public SchemaLogRestService getSchemaLogRestService(String engineName) { return subResource; } + public EventSubscriptionRestService getEventSubscriptionRestService(String engineName) { + String rootResourcePath = getRelativeEngineUri(engineName).toASCIIString(); + EventSubscriptionRestServiceImpl subResource = new EventSubscriptionRestServiceImpl(engineName, getObjectMapper()); + subResource.setRelativeRootResourceUri(rootResourcePath); + return subResource; + } + protected abstract URI getRelativeEngineUri(String engineName); protected ObjectMapper getObjectMapper() { diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/DefaultProcessEngineRestServiceImpl.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/DefaultProcessEngineRestServiceImpl.java index 489440ab96b..f7760ffc3f3 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/DefaultProcessEngineRestServiceImpl.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/DefaultProcessEngineRestServiceImpl.java @@ -29,6 +29,7 @@ import org.camunda.bpm.engine.rest.DecisionDefinitionRestService; import org.camunda.bpm.engine.rest.DecisionRequirementsDefinitionRestService; import org.camunda.bpm.engine.rest.DeploymentRestService; +import org.camunda.bpm.engine.rest.EventSubscriptionRestService; import org.camunda.bpm.engine.rest.ExecutionRestService; import org.camunda.bpm.engine.rest.ExternalTaskRestService; import org.camunda.bpm.engine.rest.FilterRestService; @@ -182,7 +183,6 @@ public ModificationRestService getModificationRestService() { return super.getModificationRestService(null); } - @Path(BatchRestService.PATH) public BatchRestService getBatchRestService() { return super.getBatchRestService(null); @@ -218,6 +218,11 @@ public SchemaLogRestService getSchemaLogRestService() { return super.getSchemaLogRestService(null); } + @Path(EventSubscriptionRestService.PATH) + public EventSubscriptionRestService getEventSubscriptionRestService() { + return super.getEventSubscriptionRestService(null); + } + @Override protected URI getRelativeEngineUri(String engineName) { // the default engine diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/EventSubscriptionRestServiceImpl.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/EventSubscriptionRestServiceImpl.java new file mode 100644 index 00000000000..4effde91c91 --- /dev/null +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/EventSubscriptionRestServiceImpl.java @@ -0,0 +1,93 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.rest.impl; + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.core.UriInfo; + +import org.camunda.bpm.engine.ProcessEngine; +import org.camunda.bpm.engine.rest.EventSubscriptionRestService; +import org.camunda.bpm.engine.rest.dto.CountResultDto; +import org.camunda.bpm.engine.rest.dto.runtime.EventSubscriptionDto; +import org.camunda.bpm.engine.rest.dto.runtime.EventSubscriptionQueryDto; +import org.camunda.bpm.engine.runtime.EventSubscription; +import org.camunda.bpm.engine.runtime.EventSubscriptionQuery; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class EventSubscriptionRestServiceImpl extends AbstractRestProcessEngineAware implements EventSubscriptionRestService { + + public EventSubscriptionRestServiceImpl(String engineName, ObjectMapper objectMapper) { + super(engineName, objectMapper); + } + + @Override + public List getEventSubscriptions(UriInfo uriInfo, Integer firstResult, Integer maxResults) { + EventSubscriptionQueryDto queryDto = new EventSubscriptionQueryDto(getObjectMapper(), uriInfo.getQueryParameters()); + return queryEventSubscriptions(queryDto, firstResult, maxResults); + } + + public List queryEventSubscriptions(EventSubscriptionQueryDto queryDto, Integer firstResult, Integer maxResults) { + ProcessEngine engine = getProcessEngine(); + queryDto.setObjectMapper(getObjectMapper()); + EventSubscriptionQuery query = queryDto.toQuery(engine); + + List matchingEventSubscriptions; + if (firstResult != null || maxResults != null) { + matchingEventSubscriptions = executePaginatedQuery(query, firstResult, maxResults); + } else { + matchingEventSubscriptions = query.list(); + } + + List eventSubscriptionResults = new ArrayList(); + for (EventSubscription eventSubscription : matchingEventSubscriptions) { + EventSubscriptionDto resultEventSubscription = EventSubscriptionDto.fromEventSubscription(eventSubscription); + eventSubscriptionResults.add(resultEventSubscription); + } + return eventSubscriptionResults; + } + + private List executePaginatedQuery(EventSubscriptionQuery query, Integer firstResult, Integer maxResults) { + if (firstResult == null) { + firstResult = 0; + } + if (maxResults == null) { + maxResults = Integer.MAX_VALUE; + } + return query.listPage(firstResult, maxResults); + } + + @Override + public CountResultDto getEventSubscriptionsCount(UriInfo uriInfo) { + EventSubscriptionQueryDto queryDto = new EventSubscriptionQueryDto(getObjectMapper(), uriInfo.getQueryParameters()); + return queryEventSubscriptionsCount(queryDto); + } + + public CountResultDto queryEventSubscriptionsCount(EventSubscriptionQueryDto queryDto) { + ProcessEngine engine = getProcessEngine(); + queryDto.setObjectMapper(getObjectMapper()); + EventSubscriptionQuery query = queryDto.toQuery(engine); + + long count = query.count(); + CountResultDto result = new CountResultDto(); + result.setCount(count); + + return result; + } +} diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/NamedProcessEngineRestServiceImpl.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/NamedProcessEngineRestServiceImpl.java index faa63797e72..955fedb2266 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/NamedProcessEngineRestServiceImpl.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/NamedProcessEngineRestServiceImpl.java @@ -40,6 +40,7 @@ import org.camunda.bpm.engine.rest.DecisionDefinitionRestService; import org.camunda.bpm.engine.rest.DecisionRequirementsDefinitionRestService; import org.camunda.bpm.engine.rest.DeploymentRestService; +import org.camunda.bpm.engine.rest.EventSubscriptionRestService; import org.camunda.bpm.engine.rest.ExecutionRestService; import org.camunda.bpm.engine.rest.ExternalTaskRestService; import org.camunda.bpm.engine.rest.FilterRestService; @@ -260,6 +261,12 @@ public SchemaLogRestService getSchemaLogRestService(@PathParam("name") String en return super.getSchemaLogRestService(engineName); } + @Override + @Path("/{name}" + EventSubscriptionRestService.PATH) + public EventSubscriptionRestService getEventSubscriptionRestService(@PathParam("name") String engineName) { + return super.getEventSubscriptionRestService(engineName); + } + @GET @Produces(MediaType.APPLICATION_JSON) public List getProcessEngineNames() { @@ -285,7 +292,7 @@ protected ProcessEngineProvider getProcessEngineProvider() { ServiceLoader serviceLoader = ServiceLoader.load(ProcessEngineProvider.class); Iterator iterator = serviceLoader.iterator(); - if(iterator.hasNext()) { + if (iterator.hasNext()) { ProcessEngineProvider provider = iterator.next(); return provider; } else { diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/EventSubscriptionRestServiceQueryTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/EventSubscriptionRestServiceQueryTest.java new file mode 100644 index 00000000000..91761f399e7 --- /dev/null +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/EventSubscriptionRestServiceQueryTest.java @@ -0,0 +1,331 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.camunda.bpm.engine.rest; + +import static io.restassured.RestAssured.expect; +import static io.restassured.RestAssured.given; +import static io.restassured.path.json.JsonPath.from; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.Response.Status; + +import org.camunda.bpm.engine.rest.helper.MockProvider; +import org.camunda.bpm.engine.rest.util.container.TestContainerRule; +import org.camunda.bpm.engine.runtime.EventSubscription; +import org.camunda.bpm.engine.runtime.EventSubscriptionQuery; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.mockito.InOrder; +import org.mockito.Mockito; + +import io.restassured.response.Response; + +public class EventSubscriptionRestServiceQueryTest extends AbstractRestServiceTest { + + @ClassRule + public static TestContainerRule rule = new TestContainerRule(); + + protected static final String EVENT_SUBSCRIPTION_URL = TEST_RESOURCE_ROOT_PATH + "/event-subscription"; + protected static final String EVENT_SUBSCRIPTION_COUNT_QUERY_URL = EVENT_SUBSCRIPTION_URL + "/count"; + + private EventSubscriptionQuery mockedEventSubscriptionQuery; + + @Before + public void setUpRuntimeData() { + mockedEventSubscriptionQuery = setUpMockEventSubscriptionQuery(createMockEventSubscriptionList()); + } + + private EventSubscriptionQuery setUpMockEventSubscriptionQuery(List mockedInstances) { + EventSubscriptionQuery sampleEventSubscriptionsQuery = mock(EventSubscriptionQuery.class); + when(sampleEventSubscriptionsQuery.list()).thenReturn(mockedInstances); + when(sampleEventSubscriptionsQuery.count()).thenReturn((long) mockedInstances.size()); + when(processEngine.getRuntimeService().createEventSubscriptionQuery()).thenReturn(sampleEventSubscriptionsQuery); + return sampleEventSubscriptionsQuery; + } + + private List createMockEventSubscriptionList() { + List mocks = new ArrayList(); + + mocks.add(MockProvider.createMockEventSubscription()); + return mocks; + } + + @Test + public void testEmptyQuery() { + given() + .then().expect() + .statusCode(Status.OK.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + } + + @Test + public void testEventSubscriptionRetrieval() { + Response response = + given() + .then().expect() + .statusCode(Status.OK.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + + // assert query invocation + InOrder inOrder = Mockito.inOrder(mockedEventSubscriptionQuery); + inOrder.verify(mockedEventSubscriptionQuery).list(); + + String content = response.asString(); + List instances = from(content).getList(""); + Assert.assertEquals("There should be one event subscription returned.", 1, instances.size()); + Assert.assertNotNull("There should be one event subscription returned", instances.get(0)); + + String returnedEventSubscriptionId = from(content).getString("[0].id"); + String returnedEventType = from(content).getString("[0].eventType"); + String returnedEventName = from(content).getString("[0].eventName"); + String returnedExecutionId = from(content).getString("[0].executionId"); + String returnedProcessInstanceId = from(content).getString("[0].processInstanceId"); + String returnedActivityId = from(content).getString("[0].activityId"); + String returnedCreatedDate = from(content).getString("[0].createdDate"); + String returnedTenantId = from(content).getString("[0].tenantId"); + + Assert.assertEquals(MockProvider.EXAMPLE_EVENT_SUBSCRIPTION_ID, returnedEventSubscriptionId); + Assert.assertEquals(MockProvider.EXAMPLE_EVENT_SUBSCRIPTION_TYPE, returnedEventType); + Assert.assertEquals(MockProvider.EXAMPLE_EVENT_SUBSCRIPTION_NAME, returnedEventName); + Assert.assertEquals(MockProvider.EXAMPLE_EXECUTION_ID, returnedExecutionId); + Assert.assertEquals(MockProvider.EXAMPLE_PROCESS_INSTANCE_ID, returnedProcessInstanceId); + Assert.assertEquals(MockProvider.EXAMPLE_ACTIVITY_ID, returnedActivityId); + Assert.assertEquals(MockProvider.EXAMPLE_EVENT_SUBSCRIPTION_CREATION_DATE, returnedCreatedDate); + Assert.assertEquals(MockProvider.EXAMPLE_TENANT_ID, returnedTenantId); + } + + @Test + public void testInvalidSortingOptions() { + executeAndVerifySorting("anInvalidSortByOption", "asc", Status.BAD_REQUEST); + executeAndVerifySorting("definitionId", "anInvalidSortOrderOption", Status.BAD_REQUEST); + } + + @Test + public void testSortByParameterOnly() { + given() + .queryParam("sortBy", "created") + .then().expect() + .statusCode(Status.BAD_REQUEST.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + } + + @Test + public void testSortOrderParameterOnly() { + given() + .queryParam("sortOrder", "asc") + .then().expect() + .statusCode(Status.BAD_REQUEST.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + } + + @Test + public void testNoParametersQuery() { + expect().statusCode(Status.OK.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + + verify(mockedEventSubscriptionQuery).list(); + verifyNoMoreInteractions(mockedEventSubscriptionQuery); + } + + @Test + public void testQueryParameters() { + Map queryParameters = getCompleteQueryParameters(); + + given() + .queryParams(queryParameters) + .expect().statusCode(Status.OK.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + + verify(mockedEventSubscriptionQuery).eventSubscriptionId(queryParameters.get("eventSubscriptionId")); + verify(mockedEventSubscriptionQuery).eventType(queryParameters.get("eventType")); + verify(mockedEventSubscriptionQuery).eventName(queryParameters.get("eventName")); + verify(mockedEventSubscriptionQuery).executionId(queryParameters.get("executionId")); + verify(mockedEventSubscriptionQuery).processInstanceId(queryParameters.get("processInstanceId")); + verify(mockedEventSubscriptionQuery).activityId(queryParameters.get("activityId")); + verify(mockedEventSubscriptionQuery).list(); + } + + @Test + public void testTenantIdListParameter() { + mockedEventSubscriptionQuery = setUpMockEventSubscriptionQuery(createMockEventSubscriptionTwoTenants()); + + Response response = + given() + .queryParam("tenantIdIn", MockProvider.EXAMPLE_TENANT_ID_LIST) + .then().expect() + .statusCode(Status.OK.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + + verify(mockedEventSubscriptionQuery).tenantIdIn(MockProvider.EXAMPLE_TENANT_ID, MockProvider.ANOTHER_EXAMPLE_TENANT_ID); + verify(mockedEventSubscriptionQuery).list(); + + String content = response.asString(); + List instances = from(content).getList(""); + assertThat(instances).hasSize(2); + + String returnedTenantId1 = from(content).getString("[0].tenantId"); + String returnedTenantId2 = from(content).getString("[1].tenantId"); + + assertThat(returnedTenantId1).isEqualTo(MockProvider.EXAMPLE_TENANT_ID); + assertThat(returnedTenantId2).isEqualTo(MockProvider.ANOTHER_EXAMPLE_TENANT_ID); + } + + + @Test + public void testWithoutTenantIdParameter() { + mockedEventSubscriptionQuery = setUpMockEventSubscriptionQuery(Arrays.asList(MockProvider.createMockEventSubscription(null))); + + Response response = + given() + .queryParam("withoutTenantId", true) + .then().expect() + .statusCode(Status.OK.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + + verify(mockedEventSubscriptionQuery).withoutTenantId(); + verify(mockedEventSubscriptionQuery).list(); + + String content = response.asString(); + List definitions = from(content).getList(""); + assertThat(definitions).hasSize(1); + + String returnedTenantId1 = from(content).getString("[0].tenantId"); + assertThat(returnedTenantId1).isEqualTo(null); + } + + @Test + public void testSortingParameters() { + InOrder inOrder = Mockito.inOrder(mockedEventSubscriptionQuery); + executeAndVerifySorting("created", "asc", Status.OK); + inOrder.verify(mockedEventSubscriptionQuery).orderByCreated(); + inOrder.verify(mockedEventSubscriptionQuery).asc(); + + inOrder = Mockito.inOrder(mockedEventSubscriptionQuery); + executeAndVerifySorting("created", "desc", Status.OK); + inOrder.verify(mockedEventSubscriptionQuery).orderByCreated(); + inOrder.verify(mockedEventSubscriptionQuery).desc(); + + inOrder = Mockito.inOrder(mockedEventSubscriptionQuery); + executeAndVerifySorting("tenantId", "asc", Status.OK); + inOrder.verify(mockedEventSubscriptionQuery).orderByTenantId(); + inOrder.verify(mockedEventSubscriptionQuery).asc(); + + inOrder = Mockito.inOrder(mockedEventSubscriptionQuery); + executeAndVerifySorting("tenantId", "desc", Status.OK); + inOrder.verify(mockedEventSubscriptionQuery).orderByTenantId(); + inOrder.verify(mockedEventSubscriptionQuery).desc(); + + } + + @Test + public void testSuccessfulPagination() { + + int firstResult = 0; + int maxResults = 10; + given() + .queryParam("firstResult", firstResult) + .queryParam("maxResults", maxResults) + .then().expect() + .statusCode(Status.OK.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + + verify(mockedEventSubscriptionQuery).listPage(firstResult, maxResults); + } + + /** + * If parameter "firstResult" is missing, we expect 0 as default. + */ + @Test + public void testMissingFirstResultParameter() { + int maxResults = 10; + given() + .queryParam("maxResults", maxResults) + .then().expect() + .statusCode(Status.OK.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + + verify(mockedEventSubscriptionQuery).listPage(0, maxResults); + } + + /** + * If parameter "maxResults" is missing, we expect Integer.MAX_VALUE as + * default. + */ + @Test + public void testMissingMaxResultsParameter() { + int firstResult = 10; + given() + .queryParam("firstResult", firstResult) + .then() + .expect() + .statusCode(Status.OK.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + + verify(mockedEventSubscriptionQuery).listPage(firstResult, Integer.MAX_VALUE); + } + + @Test + public void testQueryCount() { + expect() + .statusCode(Status.OK.getStatusCode()).body("count", equalTo(1)) + .when().get(EVENT_SUBSCRIPTION_COUNT_QUERY_URL); + + verify(mockedEventSubscriptionQuery).count(); + } + + protected void executeAndVerifySorting(String sortBy, String sortOrder, Status expectedStatus) { + given() + .queryParam("sortBy", sortBy) + .queryParam("sortOrder", sortOrder) + .then().expect() + .statusCode(expectedStatus.getStatusCode()) + .when().get(EVENT_SUBSCRIPTION_URL); + } + + private Map getCompleteQueryParameters() { + Map parameters = new HashMap(); + + parameters.put("eventSubscriptionId", "anEventSubscriptionId"); + parameters.put("eventType", "aEventType"); + parameters.put("eventName", "aEventName"); + parameters.put("executionId", "aExecutionId"); + parameters.put("processInstanceId", "aProcessInstanceId"); + parameters.put("activityId", "aActivityId"); + + return parameters; + } + + private List createMockEventSubscriptionTwoTenants() { + return Arrays.asList( + MockProvider.createMockEventSubscription(MockProvider.EXAMPLE_TENANT_ID), + MockProvider.createMockEventSubscription(MockProvider.ANOTHER_EXAMPLE_TENANT_ID) + ); + } +} diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/helper/MockProvider.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/helper/MockProvider.java index b382fa78b9c..ec5b19d771d 100644 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/helper/MockProvider.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/helper/MockProvider.java @@ -1245,6 +1245,10 @@ public static Execution createMockExecution(String tenantId) { } public static EventSubscription createMockEventSubscription() { + return createMockEventSubscription(EXAMPLE_TENANT_ID); + } + + public static EventSubscription createMockEventSubscription(String tenantId) { EventSubscription mock = mock(EventSubscription.class); when(mock.getId()).thenReturn(EXAMPLE_EVENT_SUBSCRIPTION_ID); @@ -1254,7 +1258,7 @@ public static EventSubscription createMockEventSubscription() { when(mock.getProcessInstanceId()).thenReturn(EXAMPLE_PROCESS_INSTANCE_ID); when(mock.getActivityId()).thenReturn(EXAMPLE_ACTIVITY_ID); when(mock.getCreated()).thenReturn(DateTimeUtil.parseDate(EXAMPLE_EVENT_SUBSCRIPTION_CREATION_DATE)); - when(mock.getTenantId()).thenReturn(EXAMPLE_TENANT_ID); + when(mock.getTenantId()).thenReturn(tenantId); return mock; }