<commit_before>/*
 * JBoss, Home of Professional Open Source
 * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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.jboss.as.arquillian.container.domain.managed;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;

import org.jboss.arquillian.container.spi.client.container.LifecycleException;
import org.jboss.as.arquillian.container.domain.CommonDomainDeployableContainer;
import org.jboss.as.arquillian.container.domain.Domain;
import org.jboss.as.arquillian.container.domain.Domain.Server;
import org.jboss.dmr.ModelNode;
import org.jboss.as.arquillian.container.domain.ManagementClient;
import org.jboss.as.protocol.StreamUtils;
import org.jboss.as.server.ServerMessages;

/**
 * @author <a href="mailto:<EMAIL>.com"><NAME></a>
 * @version $Revision: $
 */
public class ManagedDomainDeployableContainer extends CommonDomainDeployableContainer<ManagedDomainContainerConfiguration> {

    static final String TEMP_CONTAINER_DIRECTORY = "arquillian-temp-container";

    static final String SERVER_BASE_DIR = "domain";
    static final String CONFIG_DIR = "configuration";
    static final String LOG_DIR = "log";
    static final String DATA_DIR = "data";
    static final String SERVERS_DIR = "servers";

    private final Logger log = Logger.getLogger(ManagedDomainDeployableContainer.class.getName());

    private Thread shutdownThread;
    private Process process;

    @Override
    public Class<ManagedDomainContainerConfiguration> getConfigurationClass() {
        return ManagedDomainContainerConfiguration.class;
    }

    @Override
    protected void startInternal() throws LifecycleException {
        ManagedDomainContainerConfiguration config = getContainerConfiguration();

        if (isServerRunning()) {
            if (config.isAllowConnectingToRunningServer()) {
                return;
            } else {
                failDueToRunning();
            }
        }

        try {
            List<String> additionalJavaOptsCmd = createAdditionalJavaOptsCmd(config);
            final String jbossHomeDir = config.getJbossHome();
            String serverBaseDir = getSystemPropertyValue(additionalJavaOptsCmd, "jboss.server.base.dir", jbossHomeDir + File.separatorChar + SERVER_BASE_DIR);

            if (config.isSetupCleanServerBaseDir() || config.getCleanServerBaseDir() != null) {
                final File cleanServerDirectories = setupCleanServerDirectories(serverBaseDir, jbossHomeDir, config.getCleanServerBaseDir());
                replaceSystemPropertyValue(additionalJavaOptsCmd, "jboss.server.base.dir", cleanServerDirectories.toString());
            }

            List<String> loggingOptsCmd = createLoggingOptsCmd(additionalJavaOptsCmd, jbossHomeDir, serverBaseDir);
            List<String> cmd = createCommandLine(config, additionalJavaOptsCmd, loggingOptsCmd);

            log.info("Starting container with: " + cmd.toString());
            ProcessBuilder processBuilder = new ProcessBuilder(cmd);
            processBuilder.redirectErrorStream(true);
            process = processBuilder.start();
            new Thread(new ConsoleConsumer()).start();
            final Process proc = process;
            shutdownThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    if (proc != null) {
                        proc.destroy();
                        try {
                            proc.waitFor();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            });
            Runtime.getRuntime().addShutdownHook(shutdownThread);

            long startupTimeout = getContainerConfiguration().getStartupTimeoutInSeconds();
            long timeout = startupTimeout * 1000;
            boolean serverAvailable = false;
            long sleep = 1000;
            while (timeout > 0 && serverAvailable == false) {
                serverAvailable = getManagementClient().isDomainInRunningState();
                if (!serverAvailable) {
                    if (processHasDied(proc))
                        break;
                    Thread.sleep(sleep);
                    timeout -= sleep;
                    sleep = Math.max(sleep / 2, 100);
                }
            }
            if (!serverAvailable) {
                destroyProcess();
                throw new TimeoutException(String.format("Managed Domain server was not started within [%d] s",
                        config.getStartupTimeoutInSeconds()));
            }
        } catch (Exception e) {
            throw new LifecycleException("Could not start container", e);
        }
    }

    private List<String> createLoggingOptsCmd(List<String> additionalJavaOptsCmd, String jbossHomeDir, String serverBaseDir) {<commit_msg>[WFLY-1458] handle the managed domain container startup timeout properly<commit_after>/*
 * JBoss, Home of Professional Open Source
 * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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.jboss.as.arquillian.container.domain.managed;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;

import org.jboss.arquillian.container.spi.client.container.LifecycleException;
import org.jboss.as.arquillian.container.domain.CommonDomainDeployableContainer;
import org.jboss.as.arquillian.container.domain.Domain;
import org.jboss.as.arquillian.container.domain.Domain.Server;
import org.jboss.dmr.ModelNode;
import org.jboss.as.arquillian.container.domain.ManagementClient;
import org.jboss.as.protocol.StreamUtils;
import org.jboss.as.server.ServerMessages;

/**
 * @author <a href="mailto:<EMAIL>"><NAME></a>
 * @version $Revision: $
 */
public class ManagedDomainDeployableContainer extends CommonDomainDeployableContainer<ManagedDomainContainerConfiguration> {

    static final String TEMP_CONTAINER_DIRECTORY = "arquillian-temp-container";

    static final String SERVER_BASE_DIR = "domain";
    static final String CONFIG_DIR = "configuration";
    static final String LOG_DIR = "log";
    static final String DATA_DIR = "data";
    static final String SERVERS_DIR = "servers";

    private final Logger log = Logger.getLogger(ManagedDomainDeployableContainer.class.getName());

    private Thread shutdownThread;
    private Process process;

    @Override
    public Class<ManagedDomainContainerConfiguration> getConfigurationClass() {
        return ManagedDomainContainerConfiguration.class;
    }

    @Override
    protected void startInternal() throws LifecycleException {
        ManagedDomainContainerConfiguration config = getContainerConfiguration();

        if (isServerRunning()) {
            if (config.isAllowConnectingToRunningServer()) {
                return;
            } else {
                failDueToRunning();
            }
        }

        try {
            List<String> additionalJavaOptsCmd = createAdditionalJavaOptsCmd(config);
            final String jbossHomeDir = config.getJbossHome();
            String serverBaseDir = getSystemPropertyValue(additionalJavaOptsCmd, "jboss.server.base.dir", jbossHomeDir + File.separatorChar + SERVER_BASE_DIR);

            if (config.isSetupCleanServerBaseDir() || config.getCleanServerBaseDir() != null) {
                final File cleanServerDirectories = setupCleanServerDirectories(serverBaseDir, jbossHomeDir, config.getCleanServerBaseDir());
                replaceSystemPropertyValue(additionalJavaOptsCmd, "jboss.server.base.dir", cleanServerDirectories.toString());
            }

            List<String> loggingOptsCmd = createLoggingOptsCmd(additionalJavaOptsCmd, jbossHomeDir, serverBaseDir);
            List<String> cmd = createCommandLine(config, additionalJavaOptsCmd, loggingOptsCmd);

            log.info("Starting container with: " + cmd.toString());
            ProcessBuilder processBuilder = new ProcessBuilder(cmd);
            processBuilder.redirectErrorStream(true);
            process = processBuilder.start();
            new Thread(new ConsoleConsumer()).start();
            final Process proc = process;
            shutdownThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    if (proc != null) {
                        proc.destroy();
                        try {
                            proc.waitFor();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            });
            Runtime.getRuntime().addShutdownHook(shutdownThread);

            long startupTimeout = getContainerConfiguration().getStartupTimeoutInSeconds();
            long timeout = startupTimeout * 1000;
            boolean serverAvailable = false;
            long sleep = 1000;
            while (timeout > 0 && serverAvailable == false) {
                long before = System.currentTimeMillis();
                serverAvailable = getManagementClient().isDomainInRunningState();
                timeout -= (System.currentTimeMillis() - before);
                if (!serverAvailable) {
                    if (processHasDied(proc))
                        break;
                    Thread.sleep(sleep);
                    timeout -= sleep;
                    sleep = Math.max(sleep / 2, 100);
                }
            }
            if (!serverAvailable) {
                destroyProcess();
                throw new TimeoutException(String.format("Managed Domain server was not started within [%d] s",
                        config.getStartupTimeoutInSeconds()));
            }
        } catch (Exception e) {
            throw new LifecycleException("Could not start container", e);
        }
    }

    private List<String> createLoggingOptsCmd(List<String> additionalJavaOptsCmd, String jbossHomeDir, String serverBaseDir) {
{'fraction_non_alphanumeric': 0.08591768267735865, 'fraction_numerical': 0.003764012764912855, 'mean_word_length': 2.710382513661202, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, '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': '6993797', 'n_tokens_mistral': 3108, 'n_tokens_neox': 2950, 'n_words': 780}