/* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * 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.jbpm.executor.impl.mem; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; import org.kie.api.executor.ErrorInfo; import org.kie.api.executor.RequestInfo; import org.kie.api.executor.STATUS; import org.kie.api.runtime.query.QueryContext; import org.kie.internal.executor.api.ExecutorQueryService; @SuppressWarnings("unchecked") public class InMemoryExecutorQueryServiceImpl implements ExecutorQueryService { private InMemoryExecutorStoreService storeService; public void setStoreService(InMemoryExecutorStoreService storeService) { this.storeService = storeService; } public InMemoryExecutorQueryServiceImpl(boolean active) { } @Override public List<RequestInfo> getPendingRequests() { Map<Long, RequestInfo> requests = storeService.getRequests(); return (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByStatus(STATUS.QUEUED, STATUS.RETRYING)); } @Override public List<RequestInfo> getPendingRequestById(Long id) { List<RequestInfo> requests = new ArrayList<RequestInfo>(); RequestInfo request = storeService.findRequest(id); if (request != null && request.getStatus() == STATUS.QUEUED) { requests.add(request); } return requests; } @Override public RequestInfo getRequestById(Long id) { return storeService.findRequest(id); } @Override public List<RequestInfo> getRequestByBusinessKey(String businessKey, QueryContext queryContext) { Map<Long, RequestInfo> requests = storeService.getRequests(); List<RequestInfo> requestsByBusinessKey = (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByKey(businessKey)); return applyPaginition(requestsByBusinessKey, queryContext); } @Override public List<RequestInfo> getRequestByCommand(String command, QueryContext queryContext) { Map<Long, RequestInfo> requests = storeService.getRequests(); List<RequestInfo> requestsByCommand = (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByCommand(command)); return applyPaginition(requestsByCommand, queryContext); } @Override public List<ErrorInfo> getErrorsByRequestId(Long id) { return (List<ErrorInfo>) storeService.findRequest(id).getErrorInfo(); } @Override public List<RequestInfo> getQueuedRequests() { Map<Long, RequestInfo> requests = storeService.getRequests(); return (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByStatus(STATUS.QUEUED)); } @Override public List<RequestInfo> getCompletedRequests() { Map<Long, RequestInfo> requests = storeService.getProcessedRequests(); return (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByStatus(STATUS.DONE)); } @Override public List<RequestInfo> getInErrorRequests() { Map<Long, RequestInfo> requests = storeService.getProcessedRequests(); return (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsWitError()); } @Override public List<RequestInfo> getCancelledRequests() { Map<Long, RequestInfo> requests = storeService.getProcessedRequests(); return (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByStatus(STATUS.CANCELLED)); } @Override public List<ErrorInfo> getAllErrors() { return new ArrayList<ErrorInfo>(storeService.getErrors().values()); } @Override public List<RequestInfo> getAllRequests() { Map<Long, RequestInfo> requests = new HashMap<Long, RequestInfo>(storeService.getRequests()); requests.putAll(storeService.getProcessedRequests()); return new ArrayList<RequestInfo>(requests.values()); } @Override public List<RequestInfo> getRunningRequests() { Map<Long, RequestInfo> requests = storeService.getRequests(); return (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByStatus(STATUS.RUNNING)); } @Override public List<RequestInfo> getFutureQueuedRequests() { return getQueuedRequests(); } @Override public List<RequestInfo> getRequestsByStatus(List<STATUS> statuses) { Map<Long, RequestInfo> requests = new HashMap<Long, RequestInfo>(storeService.getRequests()); requests.putAll(storeService.getProcessedRequests()); return (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByStatus(statuses)); } @Override public RequestInfo getRequestForProcessing() { return storeService.getAndLockFirst(); } private class GetRequestsByStatus implements Predicate { private List<STATUS> statuses; GetRequestsByStatus(STATUS... status) { this.statuses = Arrays.asList(status); } GetRequestsByStatus(List<STATUS> statuses) { this.statuses = statuses; } @Override public boolean evaluate(Object object) { if (object instanceof RequestInfo) { if (statuses.contains(((RequestInfo)object).getStatus())) { return true; } } return false; } } private class GetRequestsByKey implements Predicate { private String key; GetRequestsByKey(String key) { this.key = key; } @Override public boolean evaluate(Object object) { if (object instanceof RequestInfo) { if (key.equals(((RequestInfo)object).getKey())) { return true; } } return false; } } private class GetRequestsWitError implements Predicate { GetRequestsWitError() { } @Override public boolean evaluate(Object object) { if (object instanceof RequestInfo) { if (!((RequestInfo)object).getErrorInfo().isEmpty()) { return true; } } return false; } } private class GetRequestsByCommand implements Predicate { private String command; GetRequestsByCommand(String command) { this.command = command; } @Override public boolean evaluate(Object object) { if (object instanceof RequestInfo) { if (command.equals(((RequestInfo)object).getCommandName())) { return true; } } return false; } } private class GetRequestsByDeploymentId implements Predicate { private String deploymentId; GetRequestsByDeploymentId(String deploymentId) { this.deploymentId = deploymentId; } @Override public boolean evaluate(Object object) { if (object instanceof RequestInfo) { if (deploymentId.equals(((RequestInfo)object).getDeploymentId())) { return true; } } return false; } } private class GetRequestsByProcessInstanceId implements Predicate { private Long processInstanceId; GetRequestsByProcessInstanceId(Long processInstanceId) { this.processInstanceId = processInstanceId; } @Override public boolean evaluate(Object object) { if (object instanceof RequestInfo) { if (processInstanceId.equals(((RequestInfo)object).getProcessInstanceId())) { return true; } } return false; } } @Override public List<RequestInfo> getPendingRequests(QueryContext queryContext) { return applyPaginition(getPendingRequests(), queryContext); } @Override public List<RequestInfo> getQueuedRequests(QueryContext queryContext) { return applyPaginition(getQueuedRequests(), queryContext); } @Override public List<RequestInfo> getCompletedRequests(QueryContext queryContext) { return applyPaginition(getCompletedRequests(), queryContext); } @Override public List<RequestInfo> getInErrorRequests(QueryContext queryContext) { return applyPaginition(getInErrorRequests(), queryContext); } @Override public List<RequestInfo> getCancelledRequests(QueryContext queryContext) { return applyPaginition(getCancelledRequests(), queryContext); } @Override public List<ErrorInfo> getAllErrors(QueryContext queryContext) { return applyPaginition(getAllErrors(), queryContext); } @Override public List<RequestInfo> getAllRequests(QueryContext queryContext) { return applyPaginition(getAllRequests(), queryContext); } @Override public List<RequestInfo> getRunningRequests(QueryContext queryContext) { return applyPaginition(getRunningRequests(), queryContext); } @Override public List<RequestInfo> getFutureQueuedRequests(QueryContext queryContext) { return applyPaginition(getFutureQueuedRequests(), queryContext); } @Override public List<RequestInfo> getRequestsByStatus(List<STATUS> statuses, QueryContext queryContext) { return applyPaginition(getRequestsByStatus(statuses), queryContext); } protected <T> List<T> applyPaginition(List<T> input, QueryContext queryContext) { int end = queryContext.getOffset() + queryContext.getCount(); if (input.size() < queryContext.getOffset()) { // no elements in given range return new ArrayList<T>(); } else if (input.size() >= end) { return Collections.unmodifiableList(new ArrayList<T>(input.subList(queryContext.getOffset(), end))); } else if (input.size() < end) { return Collections.unmodifiableList(new ArrayList<T>(input.subList(queryContext.getOffset(), input.size()))); } else { return Collections.unmodifiableList(input); } } @Override public RequestInfo getRequestForProcessing(Long requestId) { return storeService.removeRequest(requestId); } @Override public List<RequestInfo> getRequestsByBusinessKey(String businessKey, List<STATUS> statuses, QueryContext queryContext) { Map<Long, RequestInfo> requests = storeService.getRequests(); List<RequestInfo> requestsByKey = (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByKey(businessKey)); requestsByKey = (List<RequestInfo>) CollectionUtils.select(requestsByKey, new GetRequestsByStatus(statuses)); return applyPaginition(requestsByKey, queryContext); } @Override public List<RequestInfo> getRequestsByCommand(String command, List<STATUS> statuses, QueryContext queryContext) { Map<Long, RequestInfo> requests = storeService.getRequests(); List<RequestInfo> requestsByCommand = (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByCommand(command)); requestsByCommand = (List<RequestInfo>) CollectionUtils.select(requestsByCommand, new GetRequestsByStatus(statuses)); return applyPaginition(requestsByCommand, queryContext); } @Override public List<RequestInfo> getRequestsByDeployment(String deploymentId, List<STATUS> statuses, QueryContext queryContext) { Map<Long, RequestInfo> requests = storeService.getRequests(); List<RequestInfo> requestsByDeployment = (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByDeploymentId(deploymentId)); requestsByDeployment = (List<RequestInfo>) CollectionUtils.select(requestsByDeployment, new GetRequestsByStatus(statuses)); return applyPaginition(requestsByDeployment, queryContext); } @Override public List<RequestInfo> getRequestsByProcessInstance(Long processInstanceId, List<STATUS> statuses, QueryContext queryContext) { Map<Long, RequestInfo> requests = storeService.getRequests(); List<RequestInfo> requestsByProcessInstance = (List<RequestInfo>) CollectionUtils.select(requests.values(), new GetRequestsByProcessInstanceId(processInstanceId)); requestsByProcessInstance = (List<RequestInfo>) CollectionUtils.select(requestsByProcessInstance, new GetRequestsByStatus(statuses)); return applyPaginition(requestsByProcessInstance, queryContext); } }