Skip to content

Commit abd896d

Browse files
authored
Merge pull request #89 from delphi-hub/feature/modelService
Feature/model service
2 parents f117a50 + 905426a commit abd896d

38 files changed

+1713
-1396
lines changed

app/controllers/ApiRouter.scala

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class ApiRouter @Inject()(irController: InstanceRegistryController, sysControlle
3636
case GET(p"/numberOfInstances" ? q"componentType=$componentType") => irController.numberOfInstances(componentType)
3737
case GET(p"/instances" ? q"componentType=$componentType") => irController.instances(componentType)
3838
case GET(p"/systemInfo") => sysController.getInfo()
39+
case GET(p"/network") => irController.getNetwork()
3940
case POST(p"/postInstance" ? q"componentType=$componentType"& q"name=$name") => irController.postInstance(componentType, name)
4041
case POST(p"/startInstance" ? q"instanceID=$instanceID") => irController.handleRequest(action="/start", instanceID)
4142
case POST(p"/stopInstance" ? q"instanceID=$instanceID") => irController.handleRequest(action="/stop", instanceID)

app/controllers/InstanceRegistryController.scala

+12-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ package controllers
2020

2121
import akka.actor.{ActorRef, ActorSystem}
2222
import javax.inject.Inject
23-
import play.api.Configuration
23+
import play.api.{Configuration, Logger}
2424
import play.api.libs.concurrent.CustomExecutionContext
2525
import play.api.libs.json._
2626
import play.api.libs.ws.WSClient
@@ -80,6 +80,17 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
8080
}
8181
}
8282

83+
def getNetwork(): Action[AnyContent] = Action.async {
84+
ws.url(instanceRegistryUri + "/network").get().map { response =>
85+
// TODO: possible handling of parsing the data can be done here
86+
Logger.debug(response.body)
87+
if (response.status == 200) {
88+
Ok(response.body)
89+
} else {
90+
new Status(response.status)
91+
}
92+
}(myExecutionContext)
93+
}
8394

8495
def numberOfInstances(componentType: String) : Action[AnyContent] = Action.async {
8596
// TODO: handle what should happen if the instance registry is not reachable.

app/models/Event.scala

+47-21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package models
22

33
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
4+
import akka.http.scaladsl.model.DateTime
45
import models.EventEnums.EventType
56
import models.InstanceEnums.ComponentType
67
import play.api.libs.json.{Reads, Writes}
@@ -80,9 +81,31 @@ trait EventJsonSupport extends SprayJsonSupport with DefaultJsonProtocol with In
8081
}
8182

8283
}
84+
//Custom JSON format for event TimeStamp.
85+
implicit val timestampFormat: JsonFormat[DateTime] = new JsonFormat[DateTime] {
86+
/**
87+
* Custom write method for serialization of DateTime
88+
* @param obj DateTime object to serialize
89+
* @throws DeserializationException Exception in case of wrong input
90+
*/
91+
override def write(obj: DateTime) = JsString(obj.toIsoDateTimeString())
92+
/**
93+
* Custom read method for deserialization of DateTime
94+
* @param json JsValue that is to be deserialized
95+
* @throws DeserializationException Exception when JsValue is in incorrect format
96+
*/
97+
override def read(json: JsValue): DateTime = json match {
98+
case JsString(value) =>
99+
DateTime.fromIsoDateTimeString(value) match {
100+
case Some(date) => date
101+
case _ => throw DeserializationException("Failed to parse date time [" + value + "].")
102+
}
103+
case _ => throw DeserializationException("Failed to parse json string [" + json + "].")
104+
}
105+
}
83106

84107
//JSON format for RegistryEvents
85-
implicit val eventFormat : JsonFormat[RegistryEvent] = jsonFormat2(RegistryEvent)
108+
implicit val eventFormat : JsonFormat[RegistryEvent] = jsonFormat3(RegistryEvent)
86109

87110
//JSON format for an NumbersChangedPayload
88111
implicit val numbersChangedPayloadFormat: JsonFormat[NumbersChangedPayload] = jsonFormat2(NumbersChangedPayload)
@@ -96,18 +119,20 @@ trait EventJsonSupport extends SprayJsonSupport with DefaultJsonProtocol with In
96119

97120
//JSON format for an InstanceLinkPayload
98121
implicit val instanceLinkPayloadFormat: JsonFormat[InstanceLinkPayload] =
99-
jsonFormat1(InstanceLinkPayload)
122+
jsonFormat3(InstanceLinkPayload)
100123

101124
}
102125

103126
/**
104127
* The RegistryEvent used for communicating with the management application
105128
* @param eventType Type of the event
106129
* @param payload Payload of the event, depends on the type
130+
* @param timestamp TimeStamp of the event
107131
*/
108132
final case class RegistryEvent (
109133
eventType: EventType.Value,
110-
payload: RegistryEventPayload
134+
payload: RegistryEventPayload,
135+
timestamp: DateTime
111136
)
112137

113138
/**
@@ -119,59 +144,59 @@ object RegistryEventFactory {
119144
* Creates a new NumbersChangedEvent. Sets EventType and payload accordingly.
120145
* @param componentType ComponentType which's numbers have been updated
121146
* @param newNumber New number of components of the specified type
122-
* @return RegistryEvent with the respective type and payload.
147+
* @return RegistryEvent with the respective respective type, payload and current timestamp.
123148
*/
124149
def createNumbersChangedEvent(componentType: ComponentType, newNumber: Int) : RegistryEvent =
125-
RegistryEvent(EventType.NumbersChangedEvent, NumbersChangedPayload(componentType, newNumber))
150+
RegistryEvent(EventType.NumbersChangedEvent, NumbersChangedPayload(componentType, newNumber), DateTime.now)
126151

127152
/**
128153
* Creates a new InstanceAddedEvent. Sets EventType and payload accordingly.
129154
* @param instance Instance that has been added.
130-
* @return RegistryEvent with the respective type and payload.
155+
* @return RegistryEvent with the respective type, payload and current timestamp.
131156
*/
132157
def createInstanceAddedEvent(instance: Instance) : RegistryEvent =
133-
RegistryEvent(EventType.InstanceAddedEvent, InstancePayload(instance))
158+
RegistryEvent(EventType.InstanceAddedEvent, InstancePayload(instance), DateTime.now)
134159

135160
/**
136161
* Creates a new InstanceRemovedEvent. Sets EventType and payload accordingly.
137162
* @param instance Instance that has been removed.
138-
* @return RegistryEvent with the respective type and payload.
163+
* @return RegistryEvent with the respective type, payload and current timestamp.
139164
*/
140165
def createInstanceRemovedEvent(instance: Instance) : RegistryEvent =
141-
RegistryEvent(EventType.InstanceRemovedEvent, InstancePayload(instance))
166+
RegistryEvent(EventType.InstanceRemovedEvent, InstancePayload(instance), DateTime.now)
142167

143168
/**
144169
* Creates a new StateChangedEvent. Sets EventType and payload accordingly.
145170
* @param instance Instance which's state was changed.
146-
* @return RegistryEvent with tht respective type and payload.
171+
* @return RegistryEvent with tht respective type, payload and current timestamp.
147172
*/
148173
def createStateChangedEvent(instance: Instance) : RegistryEvent =
149-
RegistryEvent(EventType.StateChangedEvent, InstancePayload(instance))
174+
RegistryEvent(EventType.StateChangedEvent, InstancePayload(instance), DateTime.now)
150175

151176
/**
152177
* Creates a new DockerOperationErrorEvent. Sets EventType and payload accordingly.
153178
* @param affectedInstance Option[Instance] containing the instance that may be affected
154179
* @param message Error message
155-
* @return RegistryEvent with the respective type and payload.
180+
* @return RegistryEvent with the respective respective type, payload and current timestamp.
156181
*/
157182
def createDockerOperationErrorEvent(affectedInstance: Option[Instance], message: String) : RegistryEvent =
158-
RegistryEvent(EventType.DockerOperationErrorEvent, DockerOperationErrorPayload(affectedInstance, message))
183+
RegistryEvent(EventType.DockerOperationErrorEvent, DockerOperationErrorPayload(affectedInstance, message),DateTime.now)
159184

160185
/**
161186
* Creates a new LinkAddedEvent. Sets EventType and payload accordingly
162187
* @param link Link that was added
163-
* @return RegistryEvent with the respective type and payload
188+
* @return RegistryEvent with the respective type, payload and current timestamp.
164189
*/
165-
def createLinkAddedEvent(link: InstanceLink) : RegistryEvent =
166-
RegistryEvent(EventType.LinkAddedEvent, InstanceLinkPayload(link))
190+
def createLinkAddedEvent(link: InstanceLink, instanceFrom: Instance, instanceTo: Instance) : RegistryEvent =
191+
RegistryEvent(EventType.LinkAddedEvent, InstanceLinkPayload(link, instanceFrom, instanceTo),DateTime.now)
167192

168193
/**
169194
* Creates a new LinkStateChangedEvent. Sets EventType and payload accordingly.
170195
* @param link Link whichs state has been changed
171-
* @return RegistryEvent with the respective type and payload
196+
* @return RegistryEvent with the respective type, payload and current timestamp.
172197
*/
173-
def createLinkStateChangedEvent(link: InstanceLink) : RegistryEvent =
174-
RegistryEvent(EventType.LinkStateChangedEvent, InstanceLinkPayload(link))
198+
def createLinkStateChangedEvent(link: InstanceLink, instanceFrom: Instance, instanceTo: Instance) : RegistryEvent =
199+
RegistryEvent(EventType.LinkStateChangedEvent, InstanceLinkPayload(link, instanceFrom, instanceTo),DateTime.now)
175200
}
176201

177202
/**
@@ -209,7 +234,8 @@ final case class DockerOperationErrorPayload(affectedInstance: Option[Instance],
209234
* link that was added / changed.
210235
* @param link Link that caused the event
211236
*/
212-
final case class InstanceLinkPayload(link: InstanceLink) extends RegistryEventPayload
237+
final case class InstanceLinkPayload(link: InstanceLink, instanceFrom: Instance, instanceTo: Instance)
238+
extends RegistryEventPayload
213239

214240

215241
/**
@@ -235,5 +261,5 @@ object EventEnums {
235261

236262
implicit val EventTypeReads: Reads[EventType] = Reads.enumNameReads(EventType)
237263
implicit val EventTypeWrites: Writes[EventType] = Writes.enumNameWrites
238-
}
264+
}
239265
}

app/models/Instance.scala

+13-11
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import spray.json.{DefaultJsonProtocol, DeserializationException, JsString, JsVa
77
/**
88
* Trait defining the implicit JSON formats needed to work with Instances
99
*/
10-
trait InstanceJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
10+
trait InstanceJsonSupport extends SprayJsonSupport with DefaultJsonProtocol with InstanceLinkJsonSupport {
1111

1212
//Custom JSON format for an ComponentType
1313
implicit val componentTypeFormat : JsonFormat[ComponentType] = new JsonFormat[ComponentType] {
@@ -69,7 +69,7 @@ trait InstanceJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
6969
}
7070

7171
//JSON format for Instances
72-
implicit val instanceFormat : JsonFormat[Instance] = jsonFormat8(Instance)
72+
implicit val instanceFormat : JsonFormat[Instance] = jsonFormat10(Instance)
7373
}
7474

7575
/**
@@ -83,15 +83,17 @@ trait InstanceJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
8383
* @param instanceState State of the instance
8484
*/
8585
final case class Instance (
86-
id: Option[Long],
87-
host: String,
88-
portNumber: Long,
89-
name: String,
90-
componentType: ComponentType,
91-
dockerId: Option[String],
92-
instanceState: InstanceState,
93-
labels: List[String]
94-
)
86+
id: Option[Long],
87+
host: String,
88+
portNumber: Long,
89+
name: String,
90+
componentType: ComponentType,
91+
dockerId: Option[String],
92+
instanceState: InstanceState,
93+
labels: List[String],
94+
linksTo: List[InstanceLink],
95+
linksFrom: List[InstanceLink]
96+
)
9597

9698
/**
9799
* Enumerations concerning instances

0 commit comments

Comments
 (0)