/* * Copyright 2014 the original author or authors. * * 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.springframework.xd.dirt.test; import java.util.Arrays; import java.util.List; import org.springframework.xd.dirt.core.BaseDefinition; import org.springframework.xd.dirt.core.DeploymentStatusRepository; import org.springframework.xd.dirt.core.DeploymentUnitStatus; import org.springframework.xd.dirt.core.DeploymentUnitStatus.State; import org.springframework.xd.store.DomainRepository; /** * Verifies the state of resources (job or stream) by polling repository state until the * resource is in the expected state or the operation times out. For use with * {@link org.springframework.xd.dirt.server.singlenode.SingleNodeApplication} testing. * * @see org.springframework.xd.dirt.test.SingleNodeIntegrationTestSupport * @author David Turanski * @since 1.0 */ public class ResourceStateVerifier { private static final long STATE_CHANGE_WAIT_TIME = 50; private static final long STATE_CHANGE_TIMEOUT = 35000; private final DeploymentStatusRepository<?, String> deploymentStatusRepository; private final DomainRepository<? extends BaseDefinition, String> domainRepository; /** * * @param deploymentStatusRepository the repository that tracks deployment status * @param domainRepository the resource definition repository */ public ResourceStateVerifier(DeploymentStatusRepository<?, String> deploymentStatusRepository, DomainRepository<? extends BaseDefinition, String> domainRepository) { this.deploymentStatusRepository = deploymentStatusRepository; this.domainRepository = domainRepository; } /** * Wait for a named resource to be completely deployed. * @param resourceName the name of the resource being deployed * @return the deployment status, either State.deployed or the current State * when this operation timed out. */ public State waitForDeploy(String resourceName) { return waitForDeploy(resourceName, false); } /** * Wait for a named resource to be deployed. * @param resourceName the name of the resource being deployed * @param allowIncomplete if true, will return on State.incomplete or State.deployed * @return one of the expected States or the current State when this operation timed out. */ public State waitForDeploy(String resourceName, boolean allowIncomplete) { if (allowIncomplete) { return waitForDeployState(resourceName, State.deployed, State.incomplete); } return waitForDeployState(resourceName, State.deployed); } /** * Wait for a named resource to be undeployed. * @param resourceName the name of the resource being undeployed * @return either State.undeployed or the current state when the operation timed out. */ public State waitForUndeploy(String resourceName) { return waitForDeployState(resourceName, State.undeployed); } /** * Wait for a resource definition to be created. * @param resourceName the name of the resource being created. * @return true if the resource exists; false otherwise. */ public boolean waitForCreate(String resourceName) { long waitTime = 0; boolean exists; while (!(exists = domainRepository.exists(resourceName)) && waitTime < STATE_CHANGE_TIMEOUT) { try { Thread.sleep(STATE_CHANGE_WAIT_TIME); waitTime += STATE_CHANGE_WAIT_TIME; } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } return exists; } /** * Wait for a resource definition to be destroyed. * @param resourceName the name of the resource being destroyed. * @return true if the resource does not exist; false otherwise. */ public boolean waitForDestroy(String resourceName) { long waitTime = 0; boolean exists; while ((exists = domainRepository.exists(resourceName)) && waitTime < STATE_CHANGE_TIMEOUT) { try { Thread.sleep(STATE_CHANGE_WAIT_TIME); waitTime += STATE_CHANGE_WAIT_TIME; } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } return exists; } /** * Wait for the State to change to one or more expected target states. */ State waitForDeployState(String resourceName, State... targetStates) { DeploymentUnitStatus.State currentState = deploymentStatusRepository.getDeploymentStatus(resourceName).getState(); long waitTime = 0; List<State> targetStateList = Arrays.asList(targetStates); while (!targetStateList.contains(currentState) && waitTime < STATE_CHANGE_TIMEOUT) { try { Thread.sleep(STATE_CHANGE_WAIT_TIME); currentState = deploymentStatusRepository.getDeploymentStatus(resourceName).getState(); waitTime += STATE_CHANGE_WAIT_TIME; } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } return currentState; } }