Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[*.{kt,kts}]
indent_size = 4
[*.{kt, kts}]
indent_size = 4
insert_final_newline = true
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import java.time.temporal.ChronoUnit
internal class Iostat : OsMetric {
companion object {
private val DELAY: Duration = Duration.ofSeconds(2)
private val LOG_PATH: String = "~/jpt-iostat.log"
private val LOG_PATH: String = "./jpt-iostat.log"

private val TIME = "date -u \"+%d-%m-%Y %H:%M:%S UTC\""
private val ADD_TIME =
Expand All @@ -32,4 +32,4 @@ internal class Iostat : OsMetric {
val process = connection.startProcess("iostat -d $seconds -x | $ADD_TIME > $LOG_PATH")
return MonitoringProcess(process, LOG_PATH)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.atlassian.performance.tools.infrastructure.api.database

import com.atlassian.performance.tools.infrastructure.api.Sed
import com.atlassian.performance.tools.infrastructure.api.jira.flow.JiraNodeFlow
import com.atlassian.performance.tools.infrastructure.api.jira.flow.install.InstalledJira
import com.atlassian.performance.tools.infrastructure.api.jira.flow.install.InstalledJiraHook
import com.atlassian.performance.tools.ssh.api.SshConnection

class DatabaseIpConfig(
private val databaseIp: String
) : InstalledJiraHook {

override fun run(
ssh: SshConnection,
jira: InstalledJira,
flow: JiraNodeFlow
) {
Sed().replace(
connection = ssh,
expression = "(<url>.*(@(//)?|//))" + "([^:/]+)" + "(.*</url>)",
output = """\1$databaseIp\5""",
file = "${jira.home}/dbconfig.xml"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ class MySqlDatabase(
Thread.sleep(Duration.ofSeconds(10).toMillis())
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.atlassian.performance.tools.infrastructure.api.database

import com.atlassian.performance.tools.infrastructure.api.jira.flow.JiraNodeFlow
import com.atlassian.performance.tools.infrastructure.api.jira.flow.install.InstalledJira
import com.atlassian.performance.tools.infrastructure.api.jira.flow.install.InstalledJiraHook
import com.atlassian.performance.tools.jvmtasks.api.Backoff
import com.atlassian.performance.tools.jvmtasks.api.IdempotentAction
import com.atlassian.performance.tools.ssh.api.SshConnection
import java.time.Duration

class MysqlConnector : InstalledJiraHook {

override fun run(
ssh: SshConnection,
jira: InstalledJira,
flow: JiraNodeFlow
) {
val connector = "https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.40.tar.gz"
IdempotentAction(
description = "Download MySQL connector",
action = { ssh.execute("wget -q $connector") }
).retry(
maxAttempts = 3,
backoff = StaticBackoff(Duration.ofSeconds(5))
)
ssh.execute("tar -xzf mysql-connector-java-5.1.40.tar.gz")
ssh.execute("cp mysql-connector-java-5.1.40/mysql-connector-java-5.1.40-bin.jar ${jira.installation}/lib")
}
}

private class StaticBackoff(
private val backOff: Duration
) : Backoff {
override fun backOff(attempt: Int): Duration = backOff
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.atlassian.performance.tools.infrastructure.api.jira

import com.atlassian.performance.tools.ssh.api.SshConnection

class EmptyJiraHome : JiraHomeSource {
override fun download(ssh: SshConnection): String {
val jiraHome = "jira-home"
ssh.execute("mkdir $jiraHome")
return jiraHome
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package com.atlassian.performance.tools.infrastructure.api.jira

import com.atlassian.performance.tools.infrastructure.api.jvm.DisabledJvmDebug
import com.atlassian.performance.tools.infrastructure.api.jvm.JavaDevelopmentKit
import com.atlassian.performance.tools.infrastructure.api.jvm.VersionedJavaDevelopmentKit
import com.atlassian.performance.tools.infrastructure.api.jvm.JvmDebug
import com.atlassian.performance.tools.infrastructure.api.jvm.OracleJDK
import com.atlassian.performance.tools.infrastructure.api.jvm.*
import com.atlassian.performance.tools.infrastructure.api.jvm.jmx.DisabledRemoteJmx
import com.atlassian.performance.tools.infrastructure.api.jvm.jmx.RemoteJmx
import com.atlassian.performance.tools.infrastructure.api.profiler.Profiler
Expand Down Expand Up @@ -157,4 +153,4 @@ class JiraNodeConfig private constructor(
JiraNodeConfig::class.java.getResource("/collectd/conf/jira-default.conf").toURI()
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.atlassian.performance.tools.infrastructure.api.jira.flow

import com.atlassian.performance.tools.infrastructure.api.jira.flow.install.InstalledJiraHook
import com.atlassian.performance.tools.infrastructure.api.jira.flow.report.Report
import com.atlassian.performance.tools.infrastructure.api.jira.flow.server.TcpServerHook
import com.atlassian.performance.tools.infrastructure.api.jira.flow.start.StartedJiraHook
import com.atlassian.performance.tools.ssh.api.SshConnection
import net.jcip.annotations.ThreadSafe
import java.util.*
import java.util.concurrent.ConcurrentLinkedQueue

@ThreadSafe
class JiraNodeFlow {

private val preInstallHooks: Queue<TcpServerHook> = ConcurrentLinkedQueue()
private val postInstallHooks: Queue<InstalledJiraHook> = ConcurrentLinkedQueue()
private val preStartHooks: Queue<InstalledJiraHook> = ConcurrentLinkedQueue()
private val postStartHooks: Queue<StartedJiraHook> = ConcurrentLinkedQueue()
val reports: Queue<Report> = ConcurrentLinkedQueue()

fun hookPreInstall(
hook: TcpServerHook
) {
preInstallHooks.add(hook)
}

internal fun runPreInstallHooks(
ssh: SshConnection,
server: TcpServer
) {
while (true) {
preInstallHooks
.poll()
?.run(ssh, server, this)
?: break
}
}

fun hookPostInstall(
hook: InstalledJiraHook
) {
postInstallHooks.add(hook)
}

internal fun listPostInstallHooks(): Iterable<InstalledJiraHook> = postInstallHooks

fun hookPreStart(
hook: InstalledJiraHook
) {
preStartHooks.add(hook)
}

internal fun listPreStartHooks(): Iterable<InstalledJiraHook> = preStartHooks

fun hookPostStart(
hook: StartedJiraHook
) {
postStartHooks.add(hook)
}

internal fun listPostStartHooks(): Iterable<StartedJiraHook> = postStartHooks
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.atlassian.performance.tools.infrastructure.api.jira.flow

class TcpServer(
val ip: String,
val publicPort: Int,
val privatePort: Int,
val name: String
) {
constructor(
ip: String,
port: Int,
name: String
) : this(
ip,
port,
port,
name
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.atlassian.performance.tools.infrastructure.api.jira.flow.install

import com.atlassian.performance.tools.infrastructure.api.jira.SharedHome
import com.atlassian.performance.tools.infrastructure.api.jira.flow.JiraNodeFlow
import com.atlassian.performance.tools.ssh.api.SshConnection

class DataCenterHook(
private val nodeId: String,
private val sharedHome: SharedHome
) : InstalledJiraHook {

override fun run(
ssh: SshConnection,
jira: InstalledJira,
flow: JiraNodeFlow
) {
val localSharedHome = sharedHome.localSharedHome
sharedHome.mount(ssh)
val jiraHome = jira.home // TODO what's the difference between localSharedHome and jiraHome? should both be hookable?
ssh.execute("echo ehcache.object.port = 40011 >> $jiraHome/cluster.properties")
ssh.execute("echo jira.node.id = $nodeId >> $jiraHome/cluster.properties")
ssh.execute("echo jira.shared.home = `realpath $localSharedHome` >> $jiraHome/cluster.properties")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.atlassian.performance.tools.infrastructure.api.jira.flow.install

import com.atlassian.performance.tools.infrastructure.api.jira.JiraNodeConfig
import com.atlassian.performance.tools.infrastructure.api.jira.flow.JiraNodeFlow
import com.atlassian.performance.tools.infrastructure.api.jira.flow.server.LateUbuntuSysstat
import com.atlassian.performance.tools.infrastructure.jira.flow.install.ProfilerHook
import com.atlassian.performance.tools.infrastructure.jira.flow.install.SplunkForwarderHook
import com.atlassian.performance.tools.ssh.api.SshConnection

class DefaultPostInstallHook(
private val config: JiraNodeConfig
) : InstalledJiraHook {

override fun run(
ssh: SshConnection,
jira: InstalledJira,
flow: JiraNodeFlow
) {
listOf(
JiraHomeProperty(),
DisabledAutoBackup(),
JvmConfig(config),
ProfilerHook(config.profiler),
SplunkForwarderHook(config.splunkForwarder),
LateUbuntuSysstat()
).forEach { it.run(ssh, jira, flow) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.atlassian.performance.tools.infrastructure.api.jira.flow.install

import com.atlassian.performance.tools.infrastructure.api.jira.flow.JiraNodeFlow
import com.atlassian.performance.tools.ssh.api.SshConnection

class DisabledAutoBackup : InstalledJiraHook {

override fun run(
ssh: SshConnection,
jira: InstalledJira,
flow: JiraNodeFlow
) {
ssh.execute("echo jira.autoexport=false > ${jira.home}/jira-config.properties")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.atlassian.performance.tools.infrastructure.api.jira.flow.install

import com.atlassian.performance.tools.infrastructure.api.jira.flow.JiraNodeFlow
import com.atlassian.performance.tools.infrastructure.api.jira.flow.TcpServer
import com.atlassian.performance.tools.ssh.api.SshConnection

class HookedJiraInstallation(
private val installation: JiraInstallation
) : JiraInstallation {

override fun install(
ssh: SshConnection,
server: TcpServer,
flow: JiraNodeFlow
): InstalledJira {
flow.runPreInstallHooks(ssh, server)
val installed = installation.install(ssh, server, flow)
flow.listPostInstallHooks().forEach { it.run(ssh, installed, flow) }
return installed
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.atlassian.performance.tools.infrastructure.api.jira.flow.install

import com.atlassian.performance.tools.infrastructure.api.jira.flow.TcpServer
import com.atlassian.performance.tools.infrastructure.api.jvm.JavaDevelopmentKit

class InstalledJira(
/**
* E.g. it contains `./dbconfig.xml`
*/
val home: String,
/**
* E.g. it contains `./conf/server.xml`
*/
val installation: String,
val jdk: JavaDevelopmentKit,
val server: TcpServer
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.atlassian.performance.tools.infrastructure.api.jira.flow.install

import com.atlassian.performance.tools.infrastructure.api.jira.flow.JiraNodeFlow
import com.atlassian.performance.tools.infrastructure.api.jira.flow.server.StartedJira
import com.atlassian.performance.tools.infrastructure.api.jira.flow.start.StartedJiraHook
import com.atlassian.performance.tools.ssh.api.SshConnection

interface InstalledJiraHook : StartedJiraHook {

fun run(
ssh: SshConnection,
jira: InstalledJira,
flow: JiraNodeFlow
)

override fun run(
ssh: SshConnection,
jira: StartedJira,
flow: JiraNodeFlow
) {
run(ssh, jira.installed, flow)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.atlassian.performance.tools.infrastructure.api.jira.flow.install

import com.atlassian.performance.tools.infrastructure.api.jira.flow.JiraNodeFlow
import com.atlassian.performance.tools.ssh.api.SshConnection

class JiraHomeProperty : InstalledJiraHook {

override fun run(
ssh: SshConnection,
jira: InstalledJira,
flow: JiraNodeFlow
) {
val properties = "${jira.installation}/atlassian-jira/WEB-INF/classes/jira-application.properties"
ssh.execute("echo jira.home=`realpath ${jira.home}` > $properties")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.atlassian.performance.tools.infrastructure.api.jira.flow.install

import com.atlassian.performance.tools.infrastructure.api.jira.flow.JiraNodeFlow
import com.atlassian.performance.tools.infrastructure.api.jira.flow.TcpServer
import com.atlassian.performance.tools.ssh.api.SshConnection
import net.jcip.annotations.ThreadSafe

@ThreadSafe
interface JiraInstallation {

fun install(
ssh: SshConnection,
server: TcpServer,
flow: JiraNodeFlow
): InstalledJira
}
Loading