Skip to content

Commit 48b84a6

Browse files
authored
Merge pull request #119 from delphi-hub/release/0.9.0
Release/0.9.0
2 parents be0fe92 + 4701813 commit 48b84a6

File tree

78 files changed

+1970
-564
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1970
-564
lines changed

app/authorization/AuthProvider.scala

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (C) 2018 The Delphi Team.
2+
// See the LICENCE file distributed with this work for additional
3+
// information regarding copyright ownership.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
package authorization
17+
18+
19+
import pdi.jwt.{Jwt, JwtAlgorithm, JwtClaim}
20+
import play.api.Configuration
21+
22+
object AuthProvider {
23+
24+
var Token = "" // scalastyle:ignore
25+
26+
/** This method generates JWT token for registering Delphi-Management at the Instance-Registry
27+
*
28+
* @param validFor
29+
* @return
30+
*/
31+
32+
def generateJwt(validFor: Long = 1)(implicit configuration: Configuration): String = {
33+
val jwtSecretKey = configuration.get[String]("play.http.secret.JWTkey")
34+
if (Token == "" || !Jwt.isValid(Token, jwtSecretKey, Seq(JwtAlgorithm.HS256))) {
35+
val claim = JwtClaim()
36+
.issuedNow
37+
.expiresIn(validFor * 300)
38+
.startsNow
39+
. +("user_id", configuration.get[String]("play.http.instance"))
40+
. +("user_type", "Admin")
41+
42+
Token = Jwt.encode(claim, jwtSecretKey, JwtAlgorithm.HS256)
43+
}
44+
Token
45+
}
46+
}

app/controllers/ApiRouter.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,6 @@ class ApiRouter @Inject()(irController: InstanceRegistryController, sysControlle
4343
case POST(p"/pauseInstance" ? q"instanceID=$instanceID") => irController.handleRequest(action="/pause", instanceID)
4444
case POST(p"/resumeInstance" ? q"instanceID=$instanceID") => irController.handleRequest(action="/resume", instanceID)
4545
case POST(p"/deleteInstance" ? q"instanceID=$instanceID") => irController.handleRequest(action="/delete", instanceID)
46-
46+
case POST(p"/reconnectInstance" ? q"from=$from"& q"to=$to") => irController.reconnect(from.toInt, to.toInt)
4747
}
4848
}

app/controllers/InstanceRegistryController.scala

+66-23
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@ import akka.actor.{ActorRef, ActorSystem}
2222
import javax.inject.Inject
2323
import play.api.{Configuration, Logger}
2424
import play.api.libs.concurrent.CustomExecutionContext
25-
import play.api.libs.json._
2625
import play.api.libs.ws.WSClient
2726
import akka.stream.Materializer
2827
import play.api.libs.streams.ActorFlow
2928
import actors.{ClientSocketActor, PublishSocketMessageActor}
3029
import play.api.mvc._
31-
3230
import scala.concurrent.ExecutionContext
31+
import authorization.AuthProvider
32+
import play.api.libs.json.Json
33+
3334

3435

3536
trait MyExecutionContext extends ExecutionContext
@@ -63,9 +64,15 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
6364
val instanceRegistryUri = config.get[String]("app.instanceRegistryUri")
6465
val instanceRegistryBasePath = config.get[String]("app.instanceRegistryBasePath")
6566

67+
/**This method maps list of instances with specific componentType.
68+
*
69+
* @param componentType
70+
* @return
71+
*/
6672
def instances(componentType: String): Action[AnyContent] = Action.async {
67-
68-
ws.url(instanceRegistryUri + "/instances").addQueryStringParameters("ComponentType" -> componentType).get().map { response =>
73+
ws.url(instanceRegistryUri).addQueryStringParameters("ComponentType" -> componentType)
74+
.withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
75+
.get().map { response =>
6976
// TODO: possible handling of parsing the data can be done here
7077

7178
Ok(response.body)
@@ -80,8 +87,15 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
8087
}
8188
}
8289

90+
/**Called to fetch network graph of current registry. Contains a list of all instances and all links
91+
* currently registered.
92+
*
93+
* @return
94+
*/
95+
8396
def getNetwork(): Action[AnyContent] = Action.async {
84-
ws.url(instanceRegistryUri + "/network").get().map { response =>
97+
ws.url(instanceRegistryUri + "/instances/network").withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
98+
.get().map { response =>
8599
// TODO: possible handling of parsing the data can be done here
86100
Logger.debug(response.body)
87101
if (response.status == 200) {
@@ -92,10 +106,20 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
92106
}(myExecutionContext)
93107
}
94108

95-
def numberOfInstances(componentType: String) : Action[AnyContent] = Action.async {
109+
/**
110+
* Fetches the number of instances for the specified ComponentType. The ComponentType is an optional parameter which is passed as an query
111+
* argument named 'ComponentType'
112+
*
113+
* @param componentType
114+
* @return
115+
*/
116+
117+
def numberOfInstances(componentType: String): Action[AnyContent] = Action.async {
96118
// TODO: handle what should happen if the instance registry is not reachable.
97119
// TODO: create constants for the urls
98-
ws.url(instanceRegistryUri + "/numberOfInstances").addQueryStringParameters("ComponentType" -> componentType).get().map { response =>
120+
ws.url(instanceRegistryUri + "/count").addQueryStringParameters("ComponentType" -> componentType)
121+
.withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
122+
.get().map { response =>
99123
// TODO: possible handling of parsing the data can be done here
100124
if (response.status == 200) {
101125
Ok(response.body)
@@ -106,31 +130,51 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
106130
}
107131

108132
/**
109-
* This function is for handling all(start, stop, play, pause, resume) POST request.
110-
* To control the instance State
111-
* @param componentId
112-
*/
133+
* This function is for handling all(start, stop, play, pause, resume) POST request.
134+
* To control the instance State (E.g. /instances/42/stop )
135+
*
136+
* @param componentId
137+
*/
113138

114139

115140
def handleRequest(action: String, instanceID: String): Action[AnyContent] = Action.async { request =>
116-
ws.url(instanceRegistryUri + action)
117-
.addQueryStringParameters("Id" -> instanceID)
141+
ws.url(instanceRegistryUri + "/instances/" + instanceID + action)
142+
.withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
118143
.post("")
119144
.map { response =>
120145
new Status(response.status)
121146
}(myExecutionContext)
122147
}
123148

149+
def reconnect(from: Int, to: Int): Action[AnyContent] = Action.async { request =>
150+
151+
ws.url(instanceRegistryUri + "/instances/" + from + "/assignInstance"
152+
)
153+
.withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
154+
.post(Json.obj("AssignedInstanceId" -> to))
155+
.map { response =>
156+
response.status match {
157+
case 200 =>
158+
Ok(response.body)
159+
case x =>
160+
new Status(x)
161+
}
162+
}(myExecutionContext)
163+
}
124164
/**
125-
* This function is for handling an POST request for adding an instance to the Scala web server
126-
*
127-
* @param componentType
128-
* @param name
129-
*/
130-
def postInstance(compType: String, name: String): Action[AnyContent] = Action.async { request =>
131-
ws.url(instanceRegistryUri + "/deploy")
132-
.addQueryStringParameters("ComponentType" -> compType, "InstanceName" -> name)
133-
.post("")
165+
* This function is for handling an POST request for adding an instance to the Scala web server
166+
* (E.g. .../instances/deploy
167+
*
168+
* @param componentType
169+
* @param name
170+
*/
171+
172+
def postInstance(compType: String, name: String): Action[AnyContent] = Action.async
173+
{
174+
request =>
175+
ws.url(instanceRegistryUri + "/instances/deploy")
176+
.withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
177+
.post(Json.obj("ComponentType" -> compType, "InstanceName" -> name))
134178
.map { response =>
135179
response.status match {
136180
// scalastyle:off magic.number
@@ -142,5 +186,4 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
142186
}
143187
}(myExecutionContext)
144188
}
145-
146189
}

build.sbt

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ name := "delphi-management"
44

55
organization := "de.upb"
66

7-
version := "0.8.0"
7+
8+
version := "0.9.0"
9+
810

911
scalaVersion := "2.12.4"
1012

@@ -58,3 +60,5 @@ libraryDependencies ++= Seq(
5860
"com.google.guava" % "guava" % "25.1-jre",
5961
"org.apache.commons" % "commons-compress" % "1.16"
6062
)
63+
64+
libraryDependencies += "com.pauldijou" %% "jwt-core" % "1.0.0"

0 commit comments

Comments
 (0)