/* * Copyright 2016 JBoss by Red Hat. * * 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.kie.server.integrationtests.shared; import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.concurrent.TimeoutException; import java.util.function.BooleanSupplier; import org.kie.api.command.Command; import org.kie.api.executor.STATUS; import org.kie.api.runtime.ExecutionResults; import org.kie.server.api.model.KieContainerResource; import org.kie.server.api.model.KieContainerResourceFilter; import org.kie.server.api.model.KieContainerResourceList; import org.kie.server.api.model.KieContainerStatus; import org.kie.server.api.model.KieScannerResource; import org.kie.server.api.model.KieScannerStatus; import org.kie.server.api.model.ReleaseId; import org.kie.server.api.model.ReleaseIdFilter; import org.kie.server.api.model.ServiceResponse; import org.kie.server.api.model.definition.QueryDefinition; import org.kie.server.api.model.instance.ProcessInstance; import org.kie.server.api.model.instance.RequestInfoInstance; import org.kie.server.api.model.instance.SolverInstance; import org.kie.server.api.model.instance.TaskInstance; import org.kie.server.client.JobServicesClient; import org.kie.server.client.KieServicesClient; import org.kie.server.api.exception.KieServicesException; import org.kie.server.client.ProcessServicesClient; import org.kie.server.client.QueryServicesClient; import org.kie.server.client.RuleServicesClient; import org.kie.server.client.SolverServicesClient; import org.kie.server.client.UserTaskServicesClient; public class KieServerSynchronization { private static final long SERVICE_TIMEOUT = 30000; private static final long TIMEOUT_BETWEEN_CALLS = 200; public static void waitForJobToFinish(final JobServicesClient jobServicesClient, final Long jobId) throws Exception { waitForCondition(() -> { RequestInfoInstance result = jobServicesClient.getRequestById(jobId, false, false); // If job finished (to one of final states) then return. if (STATUS.CANCELLED.toString().equals(result.getStatus()) || STATUS.DONE.toString().equals(result.getStatus()) || STATUS.ERROR.toString().equals(result.getStatus())) { return true; } return false; }); } public static void waitForKieServerSynchronization(final KieServicesClient client, final int numberOfExpectedContainers) throws Exception { waitForCondition(() -> { ServiceResponse<KieContainerResourceList> containersList = client.listContainers(); // If synchronization finished (number of containers same as expected) then return. if (containersList.getResult().getContainers() == null) { if (numberOfExpectedContainers == 0) { return true; } } else if (numberOfExpectedContainers == containersList.getResult().getContainers().size()) { // Check that all containers are created or disposed. boolean containersInitializing = false; for (KieContainerResource container : containersList.getResult().getContainers()) { if (KieContainerStatus.CREATING.equals(container.getStatus()) || KieContainerStatus.DISPOSING.equals(container.getStatus())) { containersInitializing = true; } } if (!containersInitializing) { return true; } } return false; }); } public static void waitForProcessInstanceToFinish(final ProcessServicesClient processClient, final String containerId, final long processInstanceId) throws Exception { waitForCondition(() -> { ProcessInstance processInstance = processClient.getProcessInstance(containerId, processInstanceId); // If process instance is finished (to one of final states) then return. if (((Integer) org.kie.api.runtime.process.ProcessInstance.STATE_COMPLETED).equals(processInstance.getState()) || ((Integer) org.kie.api.runtime.process.ProcessInstance.STATE_ABORTED).equals(processInstance.getState())) { return true; } return false; }); } public static void waitForProcessInstanceStart(final QueryServicesClient queryClient, final String containerId) throws Exception { waitForProcessInstanceStart(queryClient, containerId, 1, Arrays.asList(1)); } public static void waitForProcessInstanceStart(final QueryServicesClient queryClient, final String containerId, int expectedInstances, List<Integer> statuses) throws Exception { waitForCondition(() -> { List<ProcessInstance> processInstances = queryClient.findProcessInstancesByContainerId(containerId, statuses, 0, 100); if (processInstances.size() == expectedInstances) { return true; } return false; }); } public static void waitForContainerWithReleaseId(final KieServicesClient client, final ReleaseId releaseId) throws Exception { waitForCondition(() -> { ReleaseIdFilter releaseIdFilter = new ReleaseIdFilter(releaseId); KieContainerResourceFilter resourceFilter = new KieContainerResourceFilter(releaseIdFilter); ServiceResponse<KieContainerResourceList> containersList = client.listContainers(resourceFilter); List<KieContainerResource> containers = containersList.getResult().getContainers(); return containers != null && !containers.isEmpty(); }); } public static void waitForContainerWithScannerStatus(final KieServicesClient client, final KieScannerStatus scannerStatus) throws Exception { waitForCondition(() -> { ServiceResponse<KieContainerResourceList> containersList = client.listContainers(); List<KieContainerResource> containers = containersList.getResult().getContainers(); if (containers != null) { for (KieContainerResource container : containers) { KieScannerResource scanner = container.getScanner(); if (scanner != null && scannerStatus.equals(scanner.getStatus())) { return true; } } } return false; }); } public static void waitForSolver(final SolverServicesClient client, final String containerId, final String solverId) throws Exception { waitForCondition(() -> { List<SolverInstance> solverInstanceList = client.getSolvers(containerId); for (SolverInstance solver : solverInstanceList) { if (solverId.equals(solver.getSolverId())) { return true; } } return false; }); } public static void waitForSolverDispose(final SolverServicesClient client, final String containerId, final String solverId) throws Exception { waitForCondition(() -> { List<SolverInstance> solverInstanceList = client.getSolvers(containerId); for (SolverInstance solver : solverInstanceList) { if (solverId.equals(solver.getSolverId())) { return false; } } return true; }); } public static void waitForSolverStatus(final SolverServicesClient client, final String containerId, final String solverId, final SolverInstance.SolverStatus status) throws Exception { waitForCondition(() -> { SolverInstance solverInstance = client.getSolver(containerId, solverId); return status.equals(solverInstance.getStatus()); }); } public static void waitForCommandResult(final RuleServicesClient client, final String containerId, final Command command, final String identifier, final Object value) throws Exception { waitForCondition(() -> { ServiceResponse<ExecutionResults> response = client.executeCommandsWithResults(containerId, command); ExecutionResults result = response.getResult(); return value.equals(result.getValue(identifier)); }); } public static void waitForTaskStatus(final UserTaskServicesClient client, final Long taskId, final String status) throws Exception { waitForCondition(() -> { TaskInstance task = client.findTaskById(taskId); return status.equals(task.getStatus()); }); } public static void waitForQuery(final QueryServicesClient client, final QueryDefinition query) throws Exception { waitForCondition(() -> { try { QueryDefinition q = client.getQuery(query.getName()); return query.getExpression().equals(q.getExpression()); } catch (KieServicesException e) { // Query isn't created yet return false; } }); } public static void waitForQueryRemoval(final QueryServicesClient client, final QueryDefinition query) throws Exception { waitForCondition(() -> { try { client.getQuery(query.getName()); return false; } catch (KieServicesException e) { // Query doesn't exist any more return true; } }); } /** * @param condition Condition result supplier. If returns true then condition is met. * @throws Exception */ private static void waitForCondition(BooleanSupplier condition) throws Exception { long timeoutTime = Calendar.getInstance().getTimeInMillis() + SERVICE_TIMEOUT; while (Calendar.getInstance().getTimeInMillis() < timeoutTime) { if (condition.getAsBoolean()) { return; } Thread.sleep(TIMEOUT_BETWEEN_CALLS); } throw new TimeoutException("Synchronization failed for defined timeout: " + SERVICE_TIMEOUT + " milliseconds."); } }