Commit 5044470e by Tomasz Ciesielczyk

node util handler nullpointer fix

parent 9b59da7a
No preview for this file type
......@@ -28,9 +28,9 @@ abstract class RTMWorker : Runnable {
}
protected fun notify(actions: PowerSettings) {
if (Keys.PCM.notification_endpoint.getNullable() != null) {
if (Keys.RTM.notification_endpoint.getNullable() != null) {
try {
Keys.PCM.notification_endpoint.getNullable()?.let { endpoint ->
Keys.RTM.notification_endpoint.getNullable()?.let { endpoint ->
logInfo("Action notify: $endpoint")
Jsoup.connect(endpoint).method(Connection.Method.POST).requestBody(actions.getSettings().toJson()).execute()
......
......@@ -7,11 +7,13 @@ import psnc.m2dc.rtm.CurrentState
import psnc.m2dc.rtm.PowerSettings
import psnc.m2dc.rtm.StorageKeys
import psnc.m2dc.rtm.dao.DAO
import psnc.m2dc.rtm.dao.LightStorage
import psnc.m2dc.rtm.model.rest.*
import psnc.m2dc.rtm.model.rpm.Resource
import psnc.m2dc.rtm.properties.keys.Keys
import psnc.m2dc.rtm.rpm.RPMApi
import psnc.m2dc.rtm.utils.Timer
import psnc.m2dc.rtm.utils.printConsole
import psnc.m2dc.rtm.utils.sum
class PCMApi() {
......@@ -184,6 +186,7 @@ class PCMApi() {
*/
fun getPowerOverLimit(getSparePower: Boolean = false): Pair<Double, Double> {
printConsole("limit details:" + LightStorage.instance.getValue("PCM_POWER_LIMIT")?.type() + " : " + LightStorage.instance.getValue("PCM_POWER_LIMIT")?.get())
var totalLimit = StorageKeys.POWER_LIMIT
val map: HashMap<String, Double> = if (this.getPowerCappingStrategy() == PowerCappingStrategy.LAZY) {
......
......@@ -4,6 +4,7 @@ import psnc.m2dc.rtm.ActionCache
import psnc.m2dc.rtm.CurrentState
import psnc.m2dc.rtm.RTMWorker
import psnc.m2dc.rtm.esm.ESMWorker
import psnc.m2dc.rtm.model.rest.PCMState
import psnc.m2dc.rtm.properties.keys.Keys
import psnc.m2dc.rtm.utils.Timer
import psnc.m2dc.rtm.utils.logInfo
......@@ -48,9 +49,14 @@ class PCMWorker(var state: CurrentState) : RTMWorker() {
}
}
fun getCurrentState(): CurrentState? {
fun getCurrentState(): PCMState? {
synchronized(lock) {
return currentWorker?.state
return currentWorker?.state?.let {
it->
// PCMApi.instance().getPowerLimit()
PCMState(it.currentPowerOverLimit>0,-it.currentPowerOverLimit,it.powerUsage)
}
// return currentWorker?.state
}
}
......
......@@ -31,11 +31,18 @@ class RTMApi private constructor() {
fun start() {
log.info("Start REST service!")
ServerInitializer.init()
log.info("Initialize PCM Api")
}
fun initConf() {
log.info("Start service INIT!")
ServerConfInitializer.init()
}
}
fun main(args: Array<String>) {
JCommandAgent.instance(args).execute()
......
package psnc.m2dc.rtm
import psnc.m2dc.rtm.commands.java.APP_VERSION
import psnc.m2dc.rtm.dao.DAO
import psnc.m2dc.rtm.dao.LightStorage
import psnc.m2dc.rtm.model.rpm.ModelMap
import psnc.m2dc.rtm.properties.keys.Keys
import psnc.m2dc.rtm.utils.Timer
import psnc.m2dc.rtm.utils.logError
import psnc.m2dc.rtm.utils.logInfo
import psnc.m2dc.rtm.utils.setWatch
/**
* Server's initialization methods
*/
object ServerConfInitializer {
fun init() {
try {
logInfo("version: $APP_VERSION")
loadConfig()
loadResources()
// setDefaultPriorities()
LightStorage.instance.save(null)
} catch (e: Exception) {
e.printStackTrace()
logError("Server initialization failed: ${e.message}")
System.exit(-1)
}
}
private fun loadConfig() {
Timer.start()
DAO.Settings.loadComponentPowerModel()
ModelMap.load()
Timer.stop()
}
// private fun setDefaultPriorities() {
// try {
// val currentMap = PCMApi.instance().getNodePrioritiesAsMap()
// val defaultMap = Keys.PCM.default_node_priority_map
// val defaultPriority = Keys.PCM.default_node_priority.getNullable()
// val priorities = ArrayList<NodePriority>()
// DAO.Resource.getNodes().values.forEach { node ->
// if (!currentMap.contains(node.id)) {
// (defaultMap.getNullable(node.id) ?: defaultPriority?.let {
// NodePriority(node.id, it.powerCapabilities, it.weight, it.validIn)
// })?.let { priority ->
// priorities.add(priority)
// }
// }
// }
// PCMApi.instance().setNodePriorities(priorities)
// } catch (e: Exception) {
// logError(e, "Default priorities not loaded: ${e.message}")
// }
//
// }
private fun loadResources() {
val t = setWatch()
if (Keys.RTM.resources_src_list.get().contains("RECS"))
DAO.ResourcesManagerApi.getRecsHosts(true)
DAO.ResourcesManagerApi.loadResources()
DAO.ResourcesManagerApi.saveResourcesToFile(listOf())
setWatch(t)
}
}
\ No newline at end of file
......@@ -21,6 +21,7 @@ import spark.Spark
*/
object ServerInitializer {
fun init() {
try {
logInfo("version: $APP_VERSION")
......
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package psnc.m2dc.rtm.commands.java;
import com.beust.jcommander.Parameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import psnc.m2dc.rtm.ICommandLine;
import psnc.m2dc.rtm.RTMApi;
/**
* @author Tomek
*/
@Parameters(commandNames = "init", commandDescription = " Init server conf")
public class InitCommand extends ICommandLine {
private static final Logger log = LoggerFactory.getLogger(InitCommand.class);
@Override
public void execute() {
RTMApi.Companion.instance().initConf();
}
}
......@@ -3,6 +3,7 @@ package psnc.m2dc.rtm.rest
import com.google.gson.JsonObject
import com.google.gson.reflect.TypeToken
import org.slf4j.LoggerFactory
import psnc.m2dc.rtm.RTMApi
import psnc.m2dc.rtm.model.rest.*
import psnc.m2dc.rtm.properties.RTMProperties
import psnc.m2dc.rtm.rest.handlers.EnergySaverHandler
......@@ -195,6 +196,13 @@ abstract class Handlers {
RTMProperties.log.debug(result)
}
fun spark.Request.getJson():JsonObject?{
if (this.contentLength()<=0 || !this.body().isEmpty() ){
return null
}
return RTMApi.getJsonObj(this.body())
}
}
// val map = RTMApi.INSTANCE().storage.get<HashMap<String, NodeSettings>>(StorageKeys.temperature_limits)
......
......@@ -37,7 +37,9 @@ object HandlersMap {
const val pcm_powerLimit = "/pcm/powerlimit"
const val reset_pcm_powerLimit = "/pcm/powerlimit/reset"
//TODO:deprecated
const val pcm_priorityList = "/pcm/prioritylist"
const val pcm_priority = "/pcm/priority"
const val pcm_check_state = "/pcm/state"
const val pcm_current_state = "/pcm/current_state"
//#endregion
......
......@@ -42,6 +42,12 @@ class PCMHandler : Handlers() {
get(HandlersMap.pcm_priorityList) { req, res ->
instance.getPCMPriorityList(req, res)
}
post(HandlersMap.pcm_priority) { req, res ->
instance.setPCMPriorityList(req, res)
}
get(HandlersMap.pcm_priority) { req, res ->
instance.getPCMPriorityList(req, res)
}
get(HandlersMap.pcm_current_state) { req, res ->
instance.getPCMCurrentState(req, res)
}
......
......@@ -4,6 +4,7 @@ import org.slf4j.LoggerFactory
import psnc.m2dc.rtm.ActionCache
import psnc.m2dc.rtm.RTMApi
import psnc.m2dc.rtm.dao.DAO
import psnc.m2dc.rtm.dao.LightStorage
import psnc.m2dc.rtm.model.rpm.ManagementMethodType
import psnc.m2dc.rtm.model.rpm.Resource
import psnc.m2dc.rtm.pcm.PCMApi
......@@ -304,22 +305,21 @@ class ResourceHandler : Handlers() {
return try {
req.logDebug()
val nodeId = req.params("node_id")
val resource = DAO.Resource.getResource(nodeId)
// val resource = DAO.Resource.getResource(nodeId)
val metadataKey = req.params("metadata_key")
val metadataValue = req.params("metadata_value")
if (metadataKey != null && metadataValue != null) {
resource.put(metadataKey, metadataValue)
} else {
DAO.Resource.setProperty(nodeId, metadataKey, metadataValue)
} else {
val jo = RTMApi.getJsonObj(req.body())
jo.entrySet().forEach({
val propertyName = it.key
val propertyValue = it.value.asString
resource.put(propertyName, propertyValue)
DAO.Resource.setProperty(nodeId, propertyName, propertyValue)
})
}
DAO.ResourcesManagerApi.saveOrUpdate(hashMapOf(resource.id to resource))
LightStorage.instance.save(null)
RESTExamples.OK_RESPONSE
} catch (e: Exception) {
res.status(400)
......@@ -441,7 +441,7 @@ class ResourceHandler : Handlers() {
req.logDebug()
val jo = RTMApi.getJsonObj(req.body())
val rcu = getRCUUtil(jo)!!
val ttl = rcu.timeInterval.ttl() - 300 //5 min
// val ttl = rcu.timeInterval.ttl() - 300 //5 min
DAO.Chassis.addRCUUtil(rcu)
// RTMProperties.storage.put("RCU_UTIL", rcu, ttl * 1000)
// RTMProperties.storage.save()
......@@ -471,8 +471,7 @@ class ResourceHandler : Handlers() {
fun getNodeUtil(req: Request, res: Response): String {
return try {
req.logDebug()
val jo = RTMApi.getJsonObj(req.body())
val timeInterval = this.getTimeInterval(jo)
val timeInterval =req.getJson()?.let { jo -> this.getTimeInterval(jo) }
val nodeUtil = if (timeInterval != null) {
DAO.Chassis.getNodeUtil(timeInterval)
} else
......
......@@ -53,13 +53,13 @@ class PriorityCommand : Runnable {
}
list
})
return RTMRestClient.instance.connect(HandlersMap.pcm_priorityList, Connection.Method.POST, jb.toJson())
return RTMRestClient.instance.connect(HandlersMap.pcm_priority, Connection.Method.POST, jb.toJson())
.get(Handlers.RESTKeys.result.name, RTMRestClient.instance.debug)
}
private fun getPriority(): List<NodePriority>? {
debugConsole("get nodePriorities")
return RTMRestClient.instance.connect(HandlersMap.pcm_priorityList,
return RTMRestClient.instance.connect(HandlersMap.pcm_priority,
Connection.Method.GET).get(Handlers.RESTKeys.nodePriorities.name,
RTMRestClient.instance.debug)
}
......
package psnc.m2dc.rtm.dao
import com.casstomdev.lightstorage.impl.TreeStorage
import com.casstomdev.lightstorage.impl.tree.TreeUtils
import org.slf4j.LoggerFactory
import psnc.m2dc.rtm.model.rpm.*
import psnc.m2dc.rtm.properties.keys.Keys
......@@ -56,7 +57,7 @@ class ResourceDAO(val storage: TreeStorage) {
fun getMaximumPowerUsage() =
try {
var accumulator = 0.0
var accumulator = 0.0
this.getNodes().values.forEach { node ->
accumulator += ModelMap.get(node.typeId).getMax(100.0)
}
......@@ -109,14 +110,23 @@ class ResourceDAO(val storage: TreeStorage) {
}
// private fun getResourceManagementMethodApi(res: Resource,
// managementMethodType: ManagementMethodType): ManagementApi {
// DAO.Settings.getSensorMap()!!.getApiTypes(managementMethodType).keys.forEach { typeName ->
// DAO.ResourcesManagerApi.getResourceType(res).apiMap[typeName]?.firstOrNull()?.api?.let { return it }
// }
// throw NoSuchResourceException("getResourceManagementMethodApi :${res.id}")
//
// }
fun getProperty(resourceId: String, property: String) = storage.get<String>("resources", resourceId, "properties", property)
fun setProperty(resourceId: String, property: String, value: Any) =
storage.put(listOf("resources", resourceId, "properties", property), value)
fun getParentId(childId: String) = storage.get<String>("resources", childId, "parentId")
fun addChild(resourceId: String, childId: String) {
val key = TreeUtils.makeKey(arrayListOf("resources", resourceId, "childResources"))
try {
storage.lockObject(key)
val size = storage.getObject(key)?.size() ?: 0
storage.put(arrayListOf("resources", resourceId, "childResources", "[$size]", "id"), childId)
} finally {
storage.unLockObject(key)
}
}
// fun setParentId(resourceId: String, property: String, value: Any) =
// storage.put(listOf("resources", resourceId, "properties", property), value)
fun getType(resourceId: String): String? = storage.get("resources", resourceId, "typeId")
......
......@@ -53,49 +53,6 @@ class ResourceManager : DataDAO() {
fun saveOrUpdate(resources: HashMap<String, Resource>) {
synchronized(this) {
val current = /*this.getResources() ?:*/ HashMap<String, Resource>()
resources.forEach { id, resource ->
if (current.containsKey(id)) {
val updatedResource = update(resource, current[id]!!)
current[id] = updatedResource
} else {
current[id] = resource
}
}
}
}
private fun update(resource: Resource, old: Resource): Resource {
// resourceMap: HashMap<String, Resource>, overwrite: Boolean = true
var r = resource
// r = Resource(r.id, r.typeId, r.parentResource ?: old.parentResource,
// r.childResources ?: old.childResources, r.properties ?: old.properties ?: HashMap(),
// r.resourceType ?: old.resourceType )
r = Resource(r.id, r.typeId, r.parentResource ?: old.parentResource,
r.childResources ?: old.childResources, r.properties,
r.resourceType ?: old.resourceType)
// else {
// r = Resource(temp.id, temp.typeId, temp.parentResource ?: r.parentResource,
// temp.childResources ?: r.childResources, temp.properties ?: r.properties ?: HashMap(),
// temp.resourceType ?: r.resourceType ?: null)
// }
// if (old.properties != null) {
old.properties.entries.forEach({
// if (overwrite) {
// r.properties!!.put(it.key, it.value)
// } else {
r.properties.putIfAbsent(it.key, it.value)
// }
})
// }
return r
}
fun getResourceType(r: Resource): ResourceType {
return Keys.RTM.resource_type_map.getNullable(r.typeId) ?: throw NullPointerException(
......@@ -128,27 +85,29 @@ class ResourceManager : DataDAO() {
fun loadResources() {
val srcList = Keys.RTM.resources_src_list.get()
// val orderedSourceList = listOf("FILE", "RECS")
val orderedSourceList = listOf("RECS", "FILE")
val resources = HashMap<String, Resource>()
// val resources = HashMap<String, Resource>()
orderedSourceList.forEach { src ->
if (srcList.contains(src)) {
loadResources(src).forEach { loaded ->
loaded.value.get(Resource.Property.is_node, true)
loaded.value.saveIndex(nodeIndex, "resources", loaded.key)
//child resources
if (Keys.RTM.load_node_children.get() && !resources.containsKey(loaded.key)) {
if (Keys.RTM.load_node_children.get()) {
logInfo("Load child resources for${loaded.key}")
this.loadChildResources(loaded.value).forEach { child ->
resources[child.key]?.let {
if ((DAO.Resource.getParentId(child.value.id)?.equals(loaded.value.id)) == false) {
throw IllegalStateException(
"Duplicate child for: ${loaded.value.id} -> child:${child.value.id}!")
} ?: { resources[child.key] = child.value }.invoke()
"Duplicate child for: ${loaded.value.id} -> child:${child.value.id}:${child.value.parentId}!")
}
loaded.value.get(Resource.Property.is_node, true)
loaded.value.saveIndex(nodeIndex, "resources", loaded.key)
DAO.Resource.addChild(loaded.value.id, child.value.id)
}
}
resources[loaded.key] = resources[loaded.key]?.extend(loaded.value) ?: loaded.value
// resources[loaded.key] = resources[loaded.key]?.extend(loaded.value) ?: loaded.value
}
logInfo("resources loaded: ${resources.size}")
// logInfo("resources loaded: ${resources.size}")
}
}
// this.save(resources)
......@@ -186,7 +145,6 @@ class ResourceManager : DataDAO() {
throw IllegalArgumentException("src:$src not found")
}
}
setParentNodeId(res)
logInfo("resources loaded from $src(${res.keys.size})")
logDebug("loaded resources: ${RTMProperties.JSONParser.toJson(res.keys.toList().subList(0, Math.min(res.size, 1600)))}")
......@@ -199,7 +157,7 @@ class ResourceManager : DataDAO() {
}
private fun loadChildResources(resource: Resource): HashMap<String, Resource> {
logDebug("Loading child resources ${resource.id}")
logDebug("Loading child resources for: ${resource.id}")
val res = HashMap<String, Resource>()
try {
if (resource.childResources == null) {
......@@ -212,12 +170,12 @@ class ResourceManager : DataDAO() {
it.forEach { child ->
child.put(Resource.Property.is_node, false)
child.put(Resource.Property.node_id, resource.id)
val currentChild = resource.childResources?.find { it.id == child.id }
if (currentChild == null) {
resource.childResources?.add(child)
} else {
currentChild.extend(child)
}
// val currentChild = resource.childResources?.find { it.id == child.id }
// if (currentChild == null) {
// resource.childResources?.add(child)
// } else {
// currentChild.extend(child)
// }
}
it
}.forEach { child ->
......@@ -277,7 +235,7 @@ class ResourceManager : DataDAO() {
m.forEach {
if ((it.value.get<String>(Resource.Property.ssh_host) != null ||
it.value.get<String>(Resource.Property.recs_host) != null) &&
it.value.parentResource == null &&
it.value.parentId == null &&
it.value.get(Resource.Property.is_node, true)) {
it.value.put(Resource.Property.is_node, true)
it.value.put(Resource.Property.node_id, it.value.id)
......@@ -324,8 +282,8 @@ class ResourceManager : DataDAO() {
} else {
var parent = resource
//find root root
while (parent.parentResource != null) {
parent = parent.parentResource!!
while (parent.parentId != null) {
parent = DAO.Resource.getResource(parent.parentId!!)
}
if (parent.get(Resource.Property.is_node, false)) {
resource.put(Resource.Property.node_id, parent.id)
......@@ -363,8 +321,6 @@ class ResourceManager : DataDAO() {
}
//#region private
......@@ -472,16 +428,30 @@ class ResourceManager : DataDAO() {
}
/**
// * calculate utilization from power usage is not available
// */
// private fun calculateUtilization(resourceId: String): Double? {
// fun saveOrUpdate(resources: HashMap<String, Resource>) {
// synchronized(this) {
// val current = /*this.getResources() ?:*/ HashMap<String, Resource>()
// resources.forEach { id, resource ->
// if (current.containsKey(id)) {
// val updatedResource = update(resource, current[id]!!)
// current[id] = updatedResource
// } else {
// current[id] = resource
// }
// }
// }
//
// val typeId = DAO.Resource.getType(resourceId)
// ?: throw NullPointerException("type not found for resource $resourceId")
// val model = DAO.Resource.getComponentPowerModel(typeId, null) ?: return null
// val min = model.getMinPower(0.0)
// val powerUsage = (this.getPowerUsage(listOf(resourceId))[resourceId] as Double?) ?: min
// // logInfo(" Calculate utilization from power (${result}) ")
// return model.getUtil(powerUsage)
// }
\ No newline at end of file
// }
// private fun update(resource: Resource, old: Resource): Resource {
// var r = resource
// r = Resource(r.id, r.typeId, r.parentResource ?: old.parentResource,
// r.childResources ?: old.childResources, r.properties,
// r.resourceType ?: old.resourceType)
// old.properties.entries.forEach({
// r.properties.putIfAbsent(it.key, it.value)
//
// })
// return r
// }
......@@ -60,7 +60,7 @@ data class TimeInterval(val begin: Long = Instant.now().epochSecond, val length:
return this.begin + this.length
}
fun ttl(): Long {
return this.end() - Date().toInstant().epochSecond
}
// fun ttl(): Long {
// return this.end() - Date().toInstant().epochSecond
// }
}
\ No newline at end of file
......@@ -13,6 +13,7 @@ import java.io.File
*/
class ComponentPowerModel(val name: String, private val perfList: List<Double>, private val utilStep: Int =
ComponentPowerModel.DEFAULT_UTIL_STEP, val suspendPowerUsage: Double? = 1.0) {
//TODO: perfIdxMap jest rowne perflist?
//#region static
companion object {
const val HIGH_VALUE = 10000000.0
......
......@@ -8,7 +8,7 @@ import psnc.m2dc.rtm.utils.logError
/**
* Created by Tomek on 2017-08-27
*/
data class Resource(val id: String, var typeId: String, val parentResource: Resource?,
data class Resource(val id: String, var typeId: String, val parentId: String?,
var childResources: MutableList<Resource>? = null,
val properties: HashMap<String, Any> = HashMap<String, Any>(),
var resourceType: ResourceType? = null) {
......@@ -162,26 +162,26 @@ data class Resource(val id: String, var typeId: String, val parentResource: Reso
}
/**
* @param other less important resource's details
*/
fun extend(other: Resource): Resource {
if (this.typeId.isEmpty())
this.typeId = other.typeId
this.childResources?.let {
other.childResources?.forEach { otherChild ->
it.find { it.id == otherChild.id }?.extend(otherChild) ?: it.add(otherChild)
}
} ?: { this.childResources = other.childResources }.invoke()
this.parentResource ?: { this.parentResource == other.parentResource }.invoke()
this.properties.let {
other.properties.forEach { otherProperty ->
it.putIfAbsent(otherProperty.key, otherProperty.value)
}
}
return this
}
// /**
// * @param other less important resource's details
// */
// fun extend(other: Resource): Resource {
//
// if (this.typeId.isEmpty())
// this.typeId = other.typeId
// this.childResources?.let {
// other.childResources?.forEach { otherChild ->
// it.find { it.id == otherChild.id }?.extend(otherChild) ?: it.add(otherChild)
// }
// } ?: { this.childResources = other.childResources }.invoke()
// this.parentResource ?: { this.parentResource == other.parentResource }.invoke()
// this.properties.let {
// other.properties.forEach { otherProperty ->
// it.putIfAbsent(otherProperty.key, otherProperty.value)
// }
// }
// return this
// }
//#endregion
......
......@@ -27,8 +27,6 @@ class PCM {
// PCM + "simple_performance_restore", true,
// Boolean::class.java)
val notification_endpoint = RTMProperty(PCM + "notification_endpoint",
"example.org", description = "Notify about actions")
val default_node_priority = RTMProperty(PCM + "default_node_priority",
null, NodePriority::class.java, true,defaultKey = "\$[file]\$[basePath]/conf/default_priority.json")
......
......@@ -30,6 +30,8 @@ class RTM {
val default_ssh_user = RTMProperty(RTM + "default_ssh_user", null, String::class.java)
val model_map_directory = RTMProperty(RTM + "model_map_directory", "\$[basePath]/models",
String::class.java)
val notification_endpoint = RTMProperty(RTM + "notification_endpoint",
"example.org", description = "Notify about actions")
// val model_map by lazy {
......
......@@ -34,22 +34,6 @@ class RECSMonitoringApi private constructor(/*storage: IStorage<String>? = null*
val log = LoggerFactory.getLogger(RECSMonitoringApi::class.java.name)!!
}
// private fun getMM(name: String, type: ManagementMethodType): ManagementMethod {
// return ManagementMethod(name, name, type, ManagementApi.recs)
// }
// fun filterNodes(list: List<Node>): List<Node> {
// val filterMap = Keys.RTM.recs_node_filter.get().associateBy({ it }, { it })
// if (filterMap.isNotEmpty()) {
// return list.filter {
// // println("current recsnode id: " + it.id)
// filterMap.containsKey(it.id)
//
// }
// }
// return list
// }
fun listAllNodes(hosts: List<String>): List<Resource> {
logInfo("RECS: getnodes from: $hosts")
......@@ -57,9 +41,6 @@ class RECSMonitoringApi private constructor(/*storage: IStorage<String>? = null*
val l = ArrayList<Resource>()
hosts.forEach { host ->
val map = DAO.Resource.getNodes()
// printConsole(Keys.TestBed.resource_list.getNullable()?.joinToString(separator = ",") { it } ?: "null ")
// printConsole(Keys.TestBed.resource_list.getNullable()?.size?.toString() ?: "null ")
// printConsole(Keys.TestBed.resource_list.getNullable()?.first() ?: "null ")
val nodes = listNodes(host).nodeList.filter {
// printConsole(Keys.TestBed.resource_list.getNullable()?.contains(it.id)?.toString() ?: "null ")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment