/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.communication.common;
import org.apache.commons.logging.LogFactory;
import de.rcenvironment.core.communication.api.NodeIdentifierService;
import de.rcenvironment.core.communication.common.impl.NodeIdentifierServiceImpl;
import de.rcenvironment.toolkit.utils.common.IdGenerator;
import de.rcenvironment.toolkit.utils.common.IdGeneratorType;
/**
* Utility/factory class to encapsulate the creation of test node identifiers.
*
* @author Robert Mischke
*/
public final class NodeIdentifierTestUtils {
private static NodeIdentifierService sharedTestNodeIdentifierService;
private static boolean allowImplicitNodeIdServiceCreation = true;
private NodeIdentifierTestUtils() {}
/**
* @return a random instance id string as used in {@link InstanceNodeId} instances; for unit testing only
*/
public static String createTestInstanceNodeIdString() {
return IdGenerator.fastRandomHexString(CommonIdBase.INSTANCE_PART_LENGTH);
}
/**
* @return an {@link InstanceNodeId} with a randomly generated instance id and a "null" session id part
*/
public static InstanceNodeId createTestInstanceNodeId() {
return getTestNodeIdentifierService().generateInstanceNodeId();
}
/**
* @return an {@link InstanceNodeId} with a randomly generated instance id; additionally, the given display name is associated with this
* instance id using an internal singleton map (which only makes this appropriate for unit/integration tests that do not rely on
* accurate multi-instance name data propagation)
*
* @param displayName the display name to associate with this instance id
*/
public static InstanceNodeId createTestInstanceNodeIdWithDisplayName(String displayName) {
final InstanceNodeId id = createTestInstanceNodeId();
getTestNodeIdentifierService().associateDisplayName(id, displayName);
return id;
}
/**
* @return a random instance session id string as used in {@link InstanceNodeSessionId} instances; for unit testing only
*/
public static String createTestInstanceNodeSessionIdString() {
return createTestInstanceNodeSessionId().getInstanceNodeSessionIdString();
}
/**
* @return a {@link InstanceNodeSessionId} with a randomly generated instance id and a randomly generated session id part
*/
public static InstanceNodeSessionId createTestInstanceNodeSessionId() {
return getTestNodeIdentifierService()
.generateInstanceNodeSessionId(getTestNodeIdentifierService().generateInstanceNodeId());
}
/**
* @param instanceId the instance id to use
* @return a {@link InstanceNodeSessionId} with the given instance id and a randomly generated session id part
*/
public static InstanceNodeSessionId createTestInstanceNodeSessionId(String instanceId) {
try {
return getTestNodeIdentifierService().generateInstanceNodeSessionId(
getTestNodeIdentifierService().parseInstanceNodeIdString(instanceId));
} catch (IdentifierException e) {
throw new RuntimeException("Error creating test instance session id", e);
}
}
/**
* @return a {@link InstanceNodeSessionId} with a randomly generated instance id and a randomly generated session id part; additionally,
* the given display name is associated with this instance id using an internal singleton map (which only makes this appropriate
* for unit/integration tests that do not rely on accurate multi-instance name data propagation)
*
* @param displayName the display name to associate with this instance id
*/
public static InstanceNodeSessionId createTestInstanceNodeSessionIdWithDisplayName(String displayName) {
final InstanceNodeSessionId id = createTestInstanceNodeSessionId();
getTestNodeIdentifierService().associateDisplayName(id, displayName);
return id;
}
/**
* @return a {@link InstanceNodeSessionId} with a randomly generated instance id and a randomly generated session id part; additionally,
* the given display name is associated with this instance id using an internal singleton map (which only makes this appropriate
* for unit/integration tests that do not rely on accurate multi-instance name data propagation)
*
* @param instanceId the instance id to generate the session for
* @param displayName the display name to associate with this instance id
*/
public static InstanceNodeSessionId createTestInstanceNodeSessionIdWithDisplayName(InstanceNodeId instanceId, String displayName) {
final InstanceNodeSessionId id = getTestNodeIdentifierService().generateInstanceNodeSessionId(instanceId);
getTestNodeIdentifierService().associateDisplayName(id, displayName);
return id;
}
/**
* @return a {@link LogicalNodeId} with a random instance part and the default logical node part.
*/
public static LogicalNodeId createTestDefaultLogicalNodeId() {
final LogicalNodeId id = getTestNodeIdentifierService().generateInstanceNodeId().convertToDefaultLogicalNodeId();
return id;
}
/**
* @return a {@link LogicalNodeId} with a random instance part and the default logical node part; additionally, the given display name
* is associated with this id
* @param displayName the display name to associate with this logical node id
*/
public static LogicalNodeId createTestDefaultLogicalNodeIdWithDisplayName(String displayName) {
final LogicalNodeId id = getTestNodeIdentifierService().generateInstanceNodeId().convertToDefaultLogicalNodeId();
getTestNodeIdentifierService().associateDisplayName(id, displayName);
return id;
}
/**
* @return a {@link InstanceNodeSessionId} with all id parts being randomly generated
*
* @param useDefaultLogicalNode if a default logical node should be generated
*/
public static LogicalNodeSessionId createTestLogicalNodeSessionId(boolean useDefaultLogicalNode) {
if (!useDefaultLogicalNode) {
throw new IllegalArgumentException("Not supported yet");
} else {
LogicalNodeSessionId id = createTestInstanceNodeSessionId().convertToDefaultLogicalNodeSessionId();
return id;
}
}
/**
* @return a {@link InstanceNodeSessionId} with all id parts being randomly generated; additionally, the given display name is
* associated with this id
*
* @param displayName the display name to associate with this instance id
* @param useDefaultLogicalNode if a default logical node should be generated
*/
public static LogicalNodeSessionId createTestLogicalNodeSessionIdWithDisplayName(String displayName,
boolean useDefaultLogicalNode) {
if (!useDefaultLogicalNode) {
throw new IllegalArgumentException("Not supported yet");
} else {
LogicalNodeSessionId id = createTestInstanceNodeSessionId().convertToDefaultLogicalNodeSessionId();
getTestNodeIdentifierService().associateDisplayName(id, displayName);
return id;
}
}
/**
* Getter for unit tests that need a direct reference to the implicitly created {@link NodeIdentifierService}.
*
* @return the {@link NodeIdentifierService} singleton instance
*/
public static synchronized NodeIdentifierService getTestNodeIdentifierService() {
if (sharedTestNodeIdentifierService == null) {
if (!allowImplicitNodeIdServiceCreation) {
throw new RuntimeException("Received a method call that requires a NodeIdentifierService, "
+ "but implicit instance creation was forbidden");
}
LogFactory.getLog(NodeIdentifierTestUtils.class).debug(
"Creating implicit NodeIdentifierService; this message should only apppear during test execution");
sharedTestNodeIdentifierService = new NodeIdentifierServiceImpl(IdGeneratorType.FAST);
}
return sharedTestNodeIdentifierService;
}
/**
* Utility method for unit/integration tests to ensure that no previous service instance is used.
*
* @param allowImplicitCreation true to allow normal usage of {@link NodeIdentifierTestUtils} by unit tests; false to make accidental
* calls to it throw an exception
*/
public static synchronized void resetTestNodeIdentifierService(boolean allowImplicitCreation) {
sharedTestNodeIdentifierService = null;
allowImplicitNodeIdServiceCreation = allowImplicitCreation;
}
/**
* Test convenience method; when using this, {@link #removeTestNodeIdentifierServiceFromCurrentThread()} should typically be used as
* well.
*/
public static void attachTestNodeIdentifierServiceToCurrentThread() {
NodeIdentifierService current = NodeIdentifierContextHolder.getRawDeserializationServiceForCurrentThread();
if (current != null) {
if (current != getTestNodeIdentifierService()) {
throw new IllegalStateException("There is already another " + NodeIdentifierService.class.getSimpleName()
+ " attached to the current test thread");
} else {
throw new IllegalStateException("The shared test " + NodeIdentifierService.class.getSimpleName()
+ " has already been attached to the current test thread; "
+ "most likely, a previous test did not call the clean up method after setting it");
}
}
NodeIdentifierContextHolder.setDeserializationServiceForCurrentThread(getTestNodeIdentifierService());
}
/**
* Test convenience method; should be called whenever {@link #attachTestNodeIdentifierServiceToCurrentThread()} was used, for example in
* a test teardown method, to avoid accidentally polluting other tests.
*/
public static void removeTestNodeIdentifierServiceFromCurrentThread() {
NodeIdentifierService current = NodeIdentifierContextHolder.getRawDeserializationServiceForCurrentThread();
if (current != null && current != getTestNodeIdentifierService()) {
throw new IllegalStateException("Unexpected " + NodeIdentifierService.class.getSimpleName()
+ " found attached to the current test thread");
}
NodeIdentifierContextHolder.setDeserializationServiceForCurrentThread(null);
}
}