<commit_before>/*
 * Hibernate OGM, Domain model persistence for NoSQL datastores
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.ogm.datastore.infinispanremote.utils;

import static org.jboss.as.controller.client.helpers.ClientConstants.CONTROLLER_PROCESS_STATE_STARTING;
import static org.jboss.as.controller.client.helpers.ClientConstants.CONTROLLER_PROCESS_STATE_STOPPING;
import static org.jboss.as.controller.client.helpers.ClientConstants.OP;
import static org.jboss.as.controller.client.helpers.ClientConstants.OP_ADDR;
import static org.jboss.as.controller.client.helpers.ClientConstants.OUTCOME;
import static org.jboss.as.controller.client.helpers.ClientConstants.READ_ATTRIBUTE_OPERATION;
import static org.jboss.as.controller.client.helpers.ClientConstants.RESULT;
import static org.jboss.as.controller.client.helpers.ClientConstants.SUCCESS;
import static org.jboss.as.controller.client.helpers.ClientConstants.NAME;
import static org.jboss.as.controller.client.helpers.ClientConstants.SUBSYSTEM;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;

import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.dmr.ModelNode;
import org.wildfly.core.launcher.Launcher;
import org.wildfly.core.launcher.StandaloneCommandBuilder;

/**
 * A JUnit rule which starts the Hot Rod server, and finally closes it.
 *
 * @author <NAME>
 */
public final class RemoteHotRodServerRule extends org.junit.rules.ExternalResource {

	private static final int MAX_WAIT_MILLISECONDS = 120 * 1000;
	private static final int STATE_REFRESH_MILLISECONDS = 50;
	private static final int MAX_STATE_REFRESH_ATTEMPTS =  MAX_WAIT_MILLISECONDS / STATE_REFRESH_MILLISECONDS;
	private static final String DEFAULT_CONFIG_PATH = "wildfly-trimmed-config.xml";

	/**
	 * An atomic static flag to make it possible to reuse this class both as a global JUnit listener and as a Rule, and
	 * avoid starting the server twice.
	 */
	private static final AtomicBoolean running = new AtomicBoolean();

	private final int portOffset;

	/**
	 * Reference to the Hot Rod Server process. Access protected by synchronization on the static field "running".
	 */
	private Process hotRodServer;

	public RemoteHotRodServerRule() {
		this.portOffset = 0;
	}

	/**
	 * @param portOffset Allows to specify a port offset, equivalent to: -Djboss.socket.binding.port-offset=X
	 * This is needed when running multiple instances, or to run it in parallel with WildFly for integration tests.
	 */
	public RemoteHotRodServerRule(int portOffset) {
		this.portOffset = portOffset;
	}

	@Override
	public void before() throws Exception {
		// Synchronize on the static field to defend against concurrent launches,
		// e.g. the usage as JUnit Rule concurrently with the usage as global test listener in Surefire.
		synchronized ( running ) {
			if ( running.compareAndSet( false, true ) ) {
				StandaloneCommandBuilder builder = StandaloneCommandBuilder
						.of( "target/infinispan-server" );
				builder
					.setServerReadOnlyConfiguration( DEFAULT_CONFIG_PATH );
				if ( portOffset != 0 ) {
					builder.addJavaOption( "-Djboss.socket.binding.port-offset=" + portOffset );
				}
				Launcher launcher = Launcher.of( builder );
				hotRodServer = launcher.inherit().launch();
				waitForRunning();
			}
		}
	}

	@Override
	public void after() {
		synchronized ( running ) {
			if ( hotRodServer != null ) {
				running.set( false );
				hotRodServer.destroyForcibly();
				messageOut( "Server Killed" );
			}
		}
	}

	public void waitForRunning() throws Exception {
		try ( ModelControllerClient client = ModelControllerClient.Factory.create( "localhost", 9990 + portOffset ) ) {
			waitForServerBoot( client );
			waitForCacheManagerBoot( client );
		}
	}

	private void waitForServerBoot(ModelControllerClient client) {
		for ( int attempts = 0; attempts < MAX_STATE_REFRESH_ATTEMPTS; attempts++ ) {
			if ( isServerInRunningState( client ) ) {
				messageOut( "Server is now running" );
				return;
			}
			waitOrAbort();
		}
		timedOut();
	}

	private void waitForCacheManagerBoot(ModelControllerClient client) {
		for ( int attempts = 0; attempts < MAX_STATE_REFRESH_ATTEMPTS; attempts++ ) {
			if ( isCacheExists( client ) ) {
				messageOut( "CacheManager is now running" );
				return;
			}
			waitOrAbort();
		}
		timedOut();
	}

	private void waitOrAbort() {
		try {
			Thread.sleep( STATE_REFRESH_MILLISECONDS );
		}
		catch (InterruptedException e) {
			throw new RuntimeException( "Interrupted while waiting for Hot Rod server to have booted successfully" );
		}
	}

	private void timedOut() {
		throw new RuntimeException( "Timed out while waiting for Hot Rod server to have booted successfully" );
	}

	private boolean isServerInRunningState(ModelControllerClient client) {
		try {
			ModelNode op = new ModelNode();
			op.get( OP ).set( READ_ATTRIBUTE_OPERATION );
			op.get( OP_ADDR ).setEmptyList();
			op.get( NAME ).set( "server-state" );

			ModelNode rsp = client.execute( op );
			return SUCCESS.equals( rsp.get( OUTCOME ).asString() )
					&& !CONTROLLER_PROCESS_STATE_STARTING.equals( rsp.get( RESULT ).asString() )
					&& !CONTROLLER_PROCESS_STATE_STOPPING.equals( rsp.get( RESULT ).asString() );
		}
		catch (RuntimeException rte) {
			throw rte;
		}
		catch (IOException ex) {
			return false;
		}
	}

	private boolean isCacheExists(ModelControllerClient client) {
		try {
			PathAddress pathAddress = PathAddress.pathAddress( SUBSYSTEM, "datagrid-infinispan" )
					.append( "cache-container", "clustered" );

			ModelNode op = new ModelNode();
			op.get( OP ).set( READ_ATTRIBUTE_OPERATION );
			op.get( OP_ADDR ).set( pathAddress.toModelNode() );
			op.get( NAME ).set( "cache-manager-status" );

			ModelNode resp = client.execute( op );
			return SUCCESS.equals( resp.get( OUTCOME ).asString() ) && "RUNNING".equals( resp.get( RESULT ).asString() );
		}
		catch (RuntimeException rte) {
			throw rte;
		}
		catch (IOException ex) {
			return false;
		}
	}

	public static void main(String[] args) throws Exception {
		RemoteHotRodServerRule rule = new RemoteHotRodServerRule();
		rule.before();
		rule.after();
	}

	private static void messageOut(String msg) {
		System.out.println( "\n***\tTest client helper: " + msg + "\t***\n" );
	}

}
<commit_msg>OGM-1461 Avoid RemoteHotRodServerRule to corrupt Maven's STDOUT by directly writing to native stream<commit_after>/*
 * Hibernate OGM, Domain model persistence for NoSQL datastores
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.ogm.datastore.infinispanremote.utils;

import static org.jboss.as.controller.client.helpers.ClientConstants.CONTROLLER_PROCESS_STATE_STARTING;
import static org.jboss.as.controller.client.helpers.ClientConstants.CONTROLLER_PROCESS_STATE_STOPPING;
import static org.jboss.as.controller.client.helpers.ClientConstants.OP;
import static org.jboss.as.controller.client.helpers.ClientConstants.OP_ADDR;
import static org.jboss.as.controller.client.helpers.ClientConstants.OUTCOME;
import static org.jboss.as.controller.client.helpers.ClientConstants.READ_ATTRIBUTE_OPERATION;
import static org.jboss.as.controller.client.helpers.ClientConstants.RESULT;
import static org.jboss.as.controller.client.helpers.ClientConstants.SUCCESS;
import static org.jboss.as.controller.client.helpers.ClientConstants.NAME;
import static org.jboss.as.controller.client.helpers.ClientConstants.SUBSYSTEM;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;

import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.dmr.ModelNode;
import org.wildfly.core.launcher.Launcher;
import org.wildfly.core.launcher.StandaloneCommandBuilder;

/**
 * A JUnit rule which starts the Hot Rod server, and finally closes it.
 *
 * @author <NAME>
 */
public final class RemoteHotRodServerRule extends org.junit.rules.ExternalResource {

	private static final int MAX_WAIT_MILLISECONDS = 120 * 1000;
	private static final int STATE_REFRESH_MILLISECONDS = 50;
	private static final int MAX_STATE_REFRESH_ATTEMPTS =  MAX_WAIT_MILLISECONDS / STATE_REFRESH_MILLISECONDS;
	private static final String DEFAULT_CONFIG_PATH = "wildfly-trimmed-config.xml";

	/**
	 * An atomic static flag to make it possible to reuse this class both as a global JUnit listener and as a Rule, and
	 * avoid starting the server twice.
	 */
	private static final AtomicBoolean running = new AtomicBoolean();

	private final int portOffset;

	/**
	 * Reference to the Hot Rod Server process. Access protected by synchronization on the static field "running".
	 */
	private Process hotRodServer;

	public RemoteHotRodServerRule() {
		this.portOffset = 0;
	}

	/**
	 * @param portOffset Allows to specify a port offset, equivalent to: -Djboss.socket.binding.port-offset=X
	 * This is needed when running multiple instances, or to run it in parallel with WildFly for integration tests.
	 */
	public RemoteHotRodServerRule(int portOffset) {
		this.portOffset = portOffset;
	}

	@Override
	public void before() throws Exception {
		// Synchronize on the static field to defend against concurrent launches,
		// e.g. the usage as JUnit Rule concurrently with the usage as global test listener in Surefire.
		synchronized ( running ) {
			if ( running.compareAndSet( false, true ) ) {
				StandaloneCommandBuilder builder = StandaloneCommandBuilder
						.of( "target/infinispan-server" );
				builder
					.setServerReadOnlyConfiguration( DEFAULT_CONFIG_PATH );
				if ( portOffset != 0 ) {
					builder.addJavaOption( "-Djboss.socket.binding.port-offset=" + portOffset );
				}
				Launcher launcher = Launcher.of( builder );
				//This will launch the server w/o redirecting stdin and stdout, as that would corrupt Surefire's own streams when running via Maven.
				//Might want to use launcher.inherit().launch instead if you need to debug server bootstrap.
				hotRodServer = launcher.launch();
				waitForRunning();
			}
		}
	}

	@Override
	public void after() {
		synchronized ( running ) {
			if ( hotRodServer != null ) {
				running.set( false );
				hotRodServer.destroyForcibly();
				messageOut( "Server Killed" );
			}
		}
	}

	public void waitForRunning() throws Exception {
		try ( ModelControllerClient client = ModelControllerClient.Factory.create( "localhost", 9990 + portOffset ) ) {
			waitForServerBoot( client );
			waitForCacheManagerBoot( client );
		}
	}

	private void waitForServerBoot(ModelControllerClient client) {
		for ( int attempts = 0; attempts < MAX_STATE_REFRESH_ATTEMPTS; attempts++ ) {
			if ( isServerInRunningState( client ) ) {
				messageOut( "Server is now running" );
				return;
			}
			waitOrAbort();
		}
		timedOut();
	}

	private void waitForCacheManagerBoot(ModelControllerClient client) {
		for ( int attempts = 0; attempts < MAX_STATE_REFRESH_ATTEMPTS; attempts++ ) {
			if ( isCacheExists( client ) ) {
				messageOut( "CacheManager is now running" );
				return;
			}
			waitOrAbort();
		}
		timedOut();
	}

	private void waitOrAbort() {
		try {
			Thread.sleep( STATE_REFRESH_MILLISECONDS );
		}
		catch (InterruptedException e) {
			throw new RuntimeException( "Interrupted while waiting for Hot Rod server to have booted successfully" );
		}
	}

	private void timedOut() {
		throw new RuntimeException( "Timed out while waiting for Hot Rod server to have booted successfully" );
	}

	private boolean isServerInRunningState(ModelControllerClient client) {
		try {
			ModelNode op = new ModelNode();
			op.get( OP ).set( READ_ATTRIBUTE_OPERATION );
			op.get( OP_ADDR ).setEmptyList();
			op.get( NAME ).set( "server-state" );

			ModelNode rsp = client.execute( op );
			return SUCCESS.equals( rsp.get( OUTCOME ).asString() )
					&& !CONTROLLER_PROCESS_STATE_STARTING.equals( rsp.get( RESULT ).asString() )
					&& !CONTROLLER_PROCESS_STATE_STOPPING.equals( rsp.get( RESULT ).asString() );
		}
		catch (RuntimeException rte) {
			throw rte;
		}
		catch (IOException ex) {
			return false;
		}
	}

	private boolean isCacheExists(ModelControllerClient client) {
		try {
			PathAddress pathAddress = PathAddress.pathAddress( SUBSYSTEM, "datagrid-infinispan" )
					.append( "cache-container", "clustered" );

			ModelNode op = new ModelNode();
			op.get( OP ).set( READ_ATTRIBUTE_OPERATION );
			op.get( OP_ADDR ).set( pathAddress.toModelNode() );
			op.get( NAME ).set( "cache-manager-status" );

			ModelNode resp = client.execute( op );
			return SUCCESS.equals( resp.get( OUTCOME ).asString() ) && "RUNNING".equals( resp.get( RESULT ).asString() );
		}
		catch (RuntimeException rte) {
			throw rte;
		}
		catch (IOException ex) {
			return false;
		}
	}

	public static void main(String[] args) throws Exception {
		RemoteHotRodServerRule rule = new RemoteHotRodServerRule();
		rule.before();
		rule.after();
	}

	private static void messageOut(String msg) {
		System.out.println( "\n***\tTest client helper: " + msg + "\t***\n" );
	}

}

{'fraction_non_alphanumeric': 0.10291569351314699, 'fraction_numerical': 0.0034656822120093423, 'mean_word_length': 4.197337509788567, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3878926', 'n_tokens_mistral': 4565, 'n_tokens_neox': 4059, 'n_words': 1080}