blob: 152051e824eefe0759c7e4a102e092ee6a31b21c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
namespace Apache.Ignite.Core.Tests
{
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Apache.Ignite.Core.Client;
using Apache.Ignite.Core.Impl.Common;
using Apache.Ignite.Core.Impl.Unmanaged;
using Apache.Ignite.Core.Tests.Process;
/// <summary>
/// Starts Java server nodes.
/// Uses Maven project in JavaServer folder to download and run arbitrary release
/// (Maven is the fastest way to download a release (we only need the core jar, bare minimum).
/// Server node sets thin client port to 10890.
/// </summary>
public static class JavaServer
{
/** Client port. */
public const int ClientPort = 10890;
/** Apache Ignite artifact group ID. */
public const string GroupIdIgnite = "org.apache.ignite";
/** Maven command to execute the main class. */
private const string MavenCommandExec = "compile exec:java -D\"exec.mainClass\"=\"Runner\"";
/** Java server sources path. */
private static readonly string JavaServerSourcePath = Path.Combine(
TestUtils.GetDotNetSourceDir().FullName,
"Apache.Ignite.Core.Tests",
"JavaServer");
/** Full path to Maven binary. */
private static readonly string MavenPath = GetMaven();
/// <summary>
/// Starts a server node with a given version.
/// </summary>
/// <param name="groupId">Maven artifact group id.</param>
/// <param name="version">Product version.</param>
/// <returns>Disposable object to stop the server.</returns>
public static IDisposable Start(string groupId, string version)
{
IgniteArgumentCheck.NotNullOrEmpty(version, "version");
var pomWrapper =
ReplaceIgniteVersionInPomFile(groupId, version, Path.Combine(JavaServerSourcePath, "pom.xml"));
var process = new System.Diagnostics.Process
{
StartInfo = new ProcessStartInfo
{
FileName = Os.IsWindows ? "cmd.exe" : "/bin/bash",
Arguments = Os.IsWindows
? string.Format("/c \"{0} {1}\"", MavenPath, MavenCommandExec)
: string.Format("-c \"{0} {1}\"", MavenPath, MavenCommandExec.Replace("\"", "\\\"")),
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = JavaServerSourcePath,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};
process.Start();
var processWrapper = new DisposeAction(() =>
{
process.KillProcessTree();
pomWrapper.Dispose();
});
try
{
var listDataReader = new ListDataReader();
process.AttachProcessConsoleReader(listDataReader, new IgniteProcessConsoleOutputReader());
// Wait for node to come up with a thin client connection.
if (WaitForStart(listDataReader))
{
return processWrapper;
}
throw new Exception("Failed to start Java node: " + string.Join(",", listDataReader.GetOutput()));
}
catch (Exception)
{
processWrapper.Dispose();
throw;
}
}
/// <summary>
/// Updates pom.xml with given Ignite version.
/// </summary>
private static IDisposable ReplaceIgniteVersionInPomFile(string groupId, string version, string pomFile)
{
var pomContent = File.ReadAllText(pomFile);
var originalPomContent = pomContent;
pomContent = Regex.Replace(pomContent,
@"<version>\d+\.\d+\.\d+</version>",
string.Format("<version>{0}</version>", version));
pomContent = Regex.Replace(pomContent,
@"<groupId>org.*?</groupId>",
string.Format("<groupId>{0}</groupId>", groupId));
File.WriteAllText(pomFile, pomContent);
return new DisposeAction(() => File.WriteAllText(pomFile, originalPomContent));
}
/// <summary>
/// Gets client configuration to connect to the Java server.
/// </summary>
public static IgniteClientConfiguration GetClientConfiguration()
{
return new IgniteClientConfiguration("127.0.0.1:" + ClientPort);
}
/// <summary>
/// Waits for server node to fully start.
/// </summary>
private static bool WaitForStart(ListDataReader reader)
{
return TestUtils.WaitForCondition(
() => reader.GetOutput().Any(m => m.Contains("Ignite node started OK")),
60 * 3 * 1000);
}
/// <summary>
/// Gets maven path.
/// </summary>
private static string GetMaven()
{
var extensions = Os.IsWindows ? new[] {".cmd", ".bat"} : new[] {string.Empty};
return new[] {"MAVEN_HOME", "M2_HOME", "M3_HOME", "MVN_HOME"}
.Select(Environment.GetEnvironmentVariable)
.Where(x => !string.IsNullOrEmpty(x))
.Select(x => Path.Combine(x, "bin", "mvn"))
.SelectMany(x => extensions.Select(ext => x + ext))
.Where(File.Exists)
.FirstOrDefault() ?? "mvn";
}
}
}