From 13ca827ac13afddfd62470a1acb901f1f316bd02 Mon Sep 17 00:00:00 2001 From: Johannes Duesing Date: Thu, 22 Nov 2018 12:30:07 +0100 Subject: [PATCH 1/2] Adapted api to latest changes of the registry api Instances now have link-lists as attributes --- .../delphi/instancemanagement/Instance.scala | 115 ++++++++++++++---- .../instancemanagement/InstanceLink.scala | 38 ++++++ .../instancemanagement/InstanceRegistry.scala | 4 +- .../cs/swt/delphi/webapi/Configuration.scala | 6 +- 4 files changed, 132 insertions(+), 31 deletions(-) create mode 100644 src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceLink.scala diff --git a/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/Instance.scala b/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/Instance.scala index 7325b96..1d9babc 100644 --- a/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/Instance.scala +++ b/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/Instance.scala @@ -15,73 +15,134 @@ // limitations under the License. package de.upb.cs.swt.delphi.instancemanagement + import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport +import de.upb.cs.swt.delphi.instancemanagement.InstanceEnums.{ComponentType, InstanceState} import spray.json.{DefaultJsonProtocol, DeserializationException, JsString, JsValue, JsonFormat} -trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol { +/** + * Trait defining the implicit JSON formats needed to work with Instances + */ +trait InstanceJsonSupport extends SprayJsonSupport with DefaultJsonProtocol with InstanceLinkJsonSupport { - implicit val componentTypeFormat : JsonFormat[InstanceEnums.ComponentType] = new JsonFormat[InstanceEnums.ComponentType] { + //Custom JSON format for an ComponentType + implicit val componentTypeFormat : JsonFormat[ComponentType] = new JsonFormat[ComponentType] { - def write(compType : InstanceEnums.ComponentType) = JsString(compType.toString) + /** + * Custom write method for serializing an ComponentType + * @param compType The ComponentType to serialize + * @return JsString containing the serialized value + */ + def write(compType : ComponentType) = JsString(compType.toString) - def read(value: JsValue) : InstanceEnums.ComponentType = value match { + /** + * Custom read method for deserialization of an ComponentType + * @param value JsValue to deserialize (must be a JsString) + * @return ComponentType that has been read + * @throws DeserializationException Exception thrown when JsValue is in incorrect format + */ + def read(value: JsValue) : ComponentType = value match { case JsString(s) => s match { - case "Crawler" => InstanceEnums.ComponentType.Crawler - case "WebApi" => InstanceEnums.ComponentType.WebApi - case "WebApp" => InstanceEnums.ComponentType.WebApp - case "DelphiManagement" => InstanceEnums.ComponentType.DelphiManagement - case "ElasticSearch" => InstanceEnums.ComponentType.ElasticSearch + case "Crawler" => ComponentType.Crawler + case "WebApi" => ComponentType.WebApi + case "WebApp" => ComponentType.WebApp + case "DelphiManagement" => ComponentType.DelphiManagement + case "ElasticSearch" => ComponentType.ElasticSearch case x => throw DeserializationException(s"Unexpected string value $x for component type.") } - case y => throw DeserializationException(s"Unexpected type $y while deserializing component type.") + case y => throw DeserializationException(s"Unexpected type $y during deserialization component type.") } } - implicit val stateFormat : JsonFormat[InstanceEnums.State] = new JsonFormat[InstanceEnums.State] { + //Custom JSON format for an InstanceState + implicit val stateFormat : JsonFormat[InstanceState] = new JsonFormat[InstanceState] { - def write(compType : InstanceEnums.State) = JsString(compType.toString) + /** + * Custom write method for serializing an InstanceState + * @param state The InstanceState to serialize + * @return JsString containing the serialized value + */ + def write(state : InstanceState) = JsString(state.toString) - def read(value: JsValue) : InstanceEnums.State = value match { + /** + * Custom read method for deserialization of an InstanceState + * @param value JsValue to deserialize (must be a JsString) + * @return InstanceState that has been read + * @throws DeserializationException Exception thrown when JsValue is in incorrect format + */ + def read(value: JsValue) : InstanceState = value match { case JsString(s) => s match { - case "Running" => InstanceEnums.InstanceState.Running - case "Stopped" => InstanceEnums.InstanceState.Stopped - case "Failed" => InstanceEnums.InstanceState.Failed - case "Paused" => InstanceEnums.InstanceState.Paused - case "NotReachable" => InstanceEnums.InstanceState.NotReachable + case "Running" => InstanceState.Running + case "Stopped" => InstanceState.Stopped + case "Failed" => InstanceState.Failed + case "Paused" => InstanceState.Paused + case "NotReachable" => InstanceState.NotReachable + case "Deploying" => InstanceState.Deploying case x => throw DeserializationException(s"Unexpected string value $x for instance state.") } - case y => throw DeserializationException(s"Unexpected type $y while deserializing instance state.") + case y => throw DeserializationException(s"Unexpected type $y during deserialization instance state.") } } - implicit val instanceFormat : JsonFormat[Instance] = jsonFormat8(Instance) + //JSON format for Instances + implicit val instanceFormat : JsonFormat[Instance] = jsonFormat10(Instance) } +/** + * The instance type used for transmitting data about an instance from an to the registry + * @param id Id of the instance. This is an Option[Long], as an registering instance will not yet have an id. + * @param host Host of the instance. + * @param portNumber Port the instance is reachable at. + * @param name Name of the instance + * @param componentType ComponentType of the instance. + * @param dockerId The docker container id of the instance. This is an Option[String], as not all instance have to be docker containers. + * @param instanceState State of the instance + */ final case class Instance ( id: Option[Long], host: String, portNumber: Long, name: String, - componentType: InstanceEnums.ComponentType, + componentType: ComponentType, dockerId: Option[String], - instanceState: InstanceEnums.State, - labels: List[String] + instanceState: InstanceState, + labels: List[String], + linksTo: List[InstanceLink], + linksFrom: List[InstanceLink] ) + +/** + * Enumerations concerning instances + */ object InstanceEnums { + + //Type to use when working with component types type ComponentType = ComponentType.Value + + /** + * ComponentType enumeration defining the valid types of delphi components + */ object ComponentType extends Enumeration { val Crawler : Value = Value("Crawler") - val ElasticSearch : Value = Value("ElasticSearch") val WebApi : Value = Value("WebApi") val WebApp : Value = Value("WebApp") val DelphiManagement : Value = Value("DelphiManagement") + val ElasticSearch : Value = Value("ElasticSearch") } - type State = InstanceState.Value + + //Type to use when working with instance states + type InstanceState = InstanceState.Value + + /** + * InstanceState enumeration defining the valid states for instances of delphi components + */ object InstanceState extends Enumeration { + val Deploying : Value = Value("Deploying") val Running : Value = Value("Running") - val Paused : Value = Value("Paused") val Stopped : Value = Value("Stopped") val Failed : Value = Value("Failed") + val Paused : Value = Value("Paused") val NotReachable : Value = Value("NotReachable") } -} + +} \ No newline at end of file diff --git a/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceLink.scala b/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceLink.scala new file mode 100644 index 0000000..b3641b0 --- /dev/null +++ b/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceLink.scala @@ -0,0 +1,38 @@ +package de.upb.cs.swt.delphi.instancemanagement + +import LinkEnums.LinkState +import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport +import spray.json.{DefaultJsonProtocol, DeserializationException, JsString, JsValue, JsonFormat} + +trait InstanceLinkJsonSupport extends SprayJsonSupport with DefaultJsonProtocol { + + implicit val linkStateFormat: JsonFormat[LinkState] = new JsonFormat[LinkState] { + override def read(value: JsValue): LinkState = value match { + case JsString(s) => s match { + case "Assigned" => LinkState.Assigned + case "Outdated" => LinkState.Outdated + case "Failed" => LinkState.Failed + case x => throw DeserializationException(s"Unexpected string value $x for LinkState.") + } + case y => throw DeserializationException(s"Unexpected type $y during deserialization of LinkState") + } + + override def write(linkState: LinkState): JsValue = JsString(linkState.toString) + } + + implicit val instanceLinkFormat: JsonFormat[InstanceLink] = + jsonFormat3(InstanceLink) +} + + +final case class InstanceLink(idFrom: Long, idTo:Long, linkState: LinkState) + +object LinkEnums { + type LinkState = LinkState.Value + + object LinkState extends Enumeration { + val Assigned: Value = Value("Assigned") + val Failed: Value = Value("Failed") + val Outdated: Value = Value("Outdated") + } +} \ No newline at end of file diff --git a/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceRegistry.scala b/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceRegistry.scala index 9ca7c36..3aa6b28 100644 --- a/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceRegistry.scala +++ b/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceRegistry.scala @@ -30,7 +30,7 @@ import scala.concurrent.duration._ import scala.concurrent.{Await, Future} import scala.util.{Failure, Success, Try} -object InstanceRegistry extends JsonSupport with AppLogging { +object InstanceRegistry extends InstanceJsonSupport with AppLogging { lazy val instanceIdFromEnv: Option[Long] = Try[Long](sys.env("INSTANCE_ID").toLong).toOption @@ -248,7 +248,7 @@ object InstanceRegistry extends JsonSupport with AppLogging { private def createInstance(id: Option[Long], controlPort: Int, name: String): Instance = Instance(id, InetAddress.getLocalHost.getHostAddress, - controlPort, name, ComponentType.WebApi, None, InstanceState.Running, List.empty[String]) + controlPort, name, ComponentType.WebApi, None, InstanceState.Running, List.empty[String], List.empty[InstanceLink], List.empty[InstanceLink]) def reportStart(id: String, configuration: Configuration): Try[ResponseEntity] = { val request = HttpRequest(method = HttpMethods.GET, configuration.instanceRegistryUri + "/reportStart") diff --git a/src/main/scala/de/upb/cs/swt/delphi/webapi/Configuration.scala b/src/main/scala/de/upb/cs/swt/delphi/webapi/Configuration.scala index 1cc8b1a..84de7ed 100644 --- a/src/main/scala/de/upb/cs/swt/delphi/webapi/Configuration.scala +++ b/src/main/scala/de/upb/cs/swt/delphi/webapi/Configuration.scala @@ -19,7 +19,7 @@ package de.upb.cs.swt.delphi.webapi import com.sksamuel.elastic4s.http.ElasticDsl._ import com.sksamuel.elastic4s.{ElasticsearchClientUri, Index, IndexAndType} import de.upb.cs.swt.delphi.instancemanagement.InstanceEnums.{ComponentType, InstanceState} -import de.upb.cs.swt.delphi.instancemanagement.{Instance, InstanceRegistry} +import de.upb.cs.swt.delphi.instancemanagement.{Instance, InstanceLink, InstanceRegistry} import scala.util.{Failure, Success, Try} @@ -50,7 +50,9 @@ class Configuration( //Server and Elasticsearch configuration ComponentType.ElasticSearch, None, InstanceState.Running, - List.empty[String]) + List.empty[String], + List.empty[InstanceLink], + List.empty[InstanceLink]) } val defaultElasticSearchPort: Int = 9200 val defaultElasticSearchHost: String = "elasticsearch://localhost" From d2ddb3434916a4bc6454321fb4149809c3830d63 Mon Sep 17 00:00:00 2001 From: Johannes Duesing Date: Mon, 26 Nov 2018 21:20:43 +0100 Subject: [PATCH 2/2] Inserted missing file header --- .../delphi/instancemanagement/InstanceLink.scala | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceLink.scala b/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceLink.scala index b3641b0..9377251 100644 --- a/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceLink.scala +++ b/src/main/scala/de/upb/cs/swt/delphi/instancemanagement/InstanceLink.scala @@ -1,3 +1,18 @@ +// Copyright (C) 2018 The Delphi Team. +// See the LICENCE file distributed with this work for additional +// information regarding copyright ownership. +// +// 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 de.upb.cs.swt.delphi.instancemanagement import LinkEnums.LinkState