override fun render()

in plugins-verifier-service/src/main/kotlin/org/jetbrains/plugins/verifier/service/server/views/StatusPage.kt [34:152]


  override fun render(model: MutableMap<String, *>?, request: HttpServletRequest, response: HttpServletResponse) {
    response.outputStream.buildHtml {
      head {
        title("Server status")
        style {
          +"""table, th, td {
            border: 1px solid black;
            border-collapse: collapse;
          }"""
        }
      }
      body {
        div {
          h1 {
            +("Plugin Verifier Service ${serverContext.appVersion}")
          }

          h2 {
            +"Status:"
          }
          ul {
            val (totalMemory, freeMemory, usedMemory, maxMemory) = MemoryInfo.getRuntimeMemoryInfo()
            li { +"Total memory: $totalMemory" }
            li { +"Free memory: $freeMemory" }
            li { +"Used memory: $usedMemory" }
            li { +"Max memory: $maxMemory" }

            val totalIdeFilesSize = serverContext.ideFilesBank.getAvailableIdeFiles()
              .map { it.fileInfo.fileSize }
              .fold(SpaceAmount.ZERO_SPACE) { acc, v -> acc + v }

            val totalPluginsSize = serverContext.pluginFilesBank.getAvailablePluginFiles()
              .map { it.fileInfo.fileSize }
              .fold(SpaceAmount.ZERO_SPACE) { acc, v -> acc + v }

            li { +"IDEs disk usage: $totalIdeFilesSize" }
            li { +"Plugins disk usage: $totalPluginsSize" }
          }

          h2 {
            +"Services:"
          }
          ul {
            serverContext.allServices.forEach { service ->
              val serviceName = service.serviceName
              li {
                +(serviceName + " - ${service.getState()}")
                form("control-$serviceName", "display: inline;", "/control-service", method = "post") {
                  input("submit", "command", "start")
                  input("submit", "command", "resume")
                  input("submit", "command", "pause")
                  input("hidden", "service-name", serviceName)
                  +"Admin password: "
                  input("password", "admin-password")
                }
              }
            }
          }

          h2 {
            +"Available IDEs: "
          }
          ul {
            serverContext.ideFilesBank.getAvailableIdeVersions().sorted().forEach {
              li {
                +it.toString()
              }
            }
          }

          val failedAttempts = serverContext.verificationResultsFilter.failedAttempts
          if (failedAttempts.isNotEmpty()) {
            h2 {
              +"Failed verifications"
            }
            table("width: 100%") {
              tr {
                th(style = "width: 30%") { +"Plugin" }
                th(style = "width: 70%") { +"Reason" }
              }
              for ((updateInfo, attempts) in failedAttempts) {
                tr {
                  td { +updateInfo.toString() }
                  td {
                    pre {
                      +buildString {
                        appendLine("We have tried to verify $updateInfo " + "time".pluralizeWithNumber(attempts.size))
                        for (attempt in attempts.sortedByDescending { it.verificationEndTime }) {
                          appendLine("    ${attempt.verificationResult.verificationTarget} on ${DATE_FORMAT.format(attempt.verificationEndTime)}")
                          appendLine("        ${attempt.failureReason.reason}")
                        }
                      }
                    }
                  }
                }
              }
            }
          }

          val activeTasks = taskManager.activeTasks
          val lastFinishedTasks = taskManager.lastFinishedTasks

          buildTaskTable("Finished tasks (20 latest)", lastFinishedTasks.sortedByDescending { it.endTime }.take(20))

          /**
           * Task types that must have even empty tables displayed.
           */
          val nonEmptyTablesTaskTypes = listOf("VerifyPlugin", "ExtractFeatures", "SendIdes")
          val allTaskTypes = activeTasks.keys + nonEmptyTablesTaskTypes

          for (taskType in allTaskTypes) {
            val tasks = activeTasks[taskType].orEmpty()
            buildTaskTable("Running $taskType tasks", tasks.filter { it.state == TaskDescriptor.State.RUNNING })
            buildTaskTable("Waiting $taskType tasks (${tasks.size} total) (20 latest shown)", tasks.filter { it.state == TaskDescriptor.State.WAITING }.take(20))
          }
        }
      }
    }
  }