Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

Commit 9d1771c

Browse files
committed
Merge branch 'actor-dev'
2 parents 73a7c6c + 3f5d041 commit 9d1771c

File tree

5 files changed

+136
-11
lines changed

5 files changed

+136
-11
lines changed

build.sbt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,8 @@ libraryDependencies ++= Seq(
5353
//"com.typesafe.akka" %% "akka-testkit" % "2.5.18" % Test
5454
)
5555

56-
// Akka Actors
57-
libraryDependencies ++= Seq(
58-
"com.typesafe.akka" %% "akka-actor" % "2.5.18",
59-
//"com.typesafe.akka" %% "akka-testkit" % "2.5.18" % Test
60-
)
56+
// https://mvnrepository.com/artifact/com.google.code.gson/gson
57+
libraryDependencies += "com.google.code.gson" % "gson" % "2.8.5"
6158

6259

6360
// ---------------------------------------------------------------------------------------------------------------------
Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,60 @@
11
package org.codeoverflow.chatoverflow.connector.actor
22

3+
import java.io.PrintWriter
4+
import java.nio.file.Paths
5+
36
import akka.actor.Actor
47

8+
import scala.io.Source
9+
10+
/**
11+
* The file system actor provides simple utility methods to read and write files.
12+
*/
513
class FileSystemActor extends Actor {
6-
override def receive: Receive = ???
14+
15+
// TODO: Subject of change?
16+
private val resourceFilePath = "src/main/resources"
17+
18+
/**
19+
* Receives either LoadFile or SaveFile object, acts accordingly.
20+
*
21+
* @return a loaded file or a boolean if the saving process was successful
22+
*/
23+
override def receive: Receive = {
24+
case LoadFile(pathInResources) =>
25+
try {
26+
sender ! Some(Source.fromFile(s"$resourceFilePath${fixPath(pathInResources)}").mkString)
27+
} catch {
28+
case _: Exception => None
29+
}
30+
case SaveFile(pathInResources, content) =>
31+
try {
32+
val writer = new PrintWriter(s"$resourceFilePath${fixPath(pathInResources)}")
33+
writer.write(content)
34+
writer.close()
35+
sender ! true
36+
} catch {
37+
case _: Exception => sender ! false
38+
}
39+
}
40+
41+
private def fixPath(path: String): String = {
42+
val fixedPath = Paths.get("/", path).normalize()
43+
fixedPath.toString
44+
}
745
}
46+
47+
/**
48+
* Send a LoadFile-object to the FileSystemActor to load a specific file.
49+
*
50+
* @param pathInResources the relative Path in the resource folder
51+
*/
52+
case class LoadFile(pathInResources: String)
53+
54+
/**
55+
* Send a SaveFile-object to the FileSystemActor to save a file with given content.
56+
*
57+
* @param pathInResources the relative Path in the resource folder
58+
* @param content the content to save
59+
*/
60+
case class SaveFile(pathInResources: String, content: String)
Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,51 @@
11
package org.codeoverflow.chatoverflow.connector.actor
22

33
import akka.actor.Actor
4+
import org.apache.http.client.methods.HttpGet
5+
import org.apache.http.client.utils.URIBuilder
6+
import org.apache.http.impl.client.HttpClientBuilder
7+
import org.apache.http.util.EntityUtils
48

9+
/**
10+
* The HttpActor can be used to handle http requests.
11+
*/
512
class HttpActor extends Actor {
6-
override def receive: Receive = ???
13+
private val client = HttpClientBuilder.create.build
14+
15+
/**
16+
* Send a GetRequest-Object to perform a http get request.
17+
*
18+
* @return the http request answer as some string or none
19+
*/
20+
override def receive: Receive = {
21+
case GetRequest(uri, settings, queryParams) =>
22+
try {
23+
var httpGet = new HttpGet(uri)
24+
httpGet = settings(httpGet)
25+
26+
val urlBuilder = new URIBuilder(httpGet.getURI)
27+
queryParams.foreach(param => urlBuilder.addParameter(param._1, param._2))
28+
httpGet.setURI(urlBuilder.build())
29+
30+
val entity = client.execute(httpGet).getEntity
31+
if (entity != null) {
32+
sender ! Some(EntityUtils.toString(entity, "UTF-8"))
33+
} else {
34+
sender ! None
35+
}
36+
} catch {
37+
case _: Exception => None
38+
}
39+
}
740
}
41+
42+
/**
43+
* A get request consists of a URI at least. Http (e.g. header) settings and query parameters are optional.
44+
*
45+
* @param uri the web address incl. the protocol you want to request
46+
* @param settings a function manipulating the generated HttpGet-Element, e.g. by adding header-entries
47+
* @param queryParams the query params as sequence of key-value-tuple
48+
*/
49+
case class GetRequest(uri: String,
50+
settings: HttpGet => HttpGet = httpGet => httpGet,
51+
queryParams: Seq[(String, String)] = Seq[(String, String)]())
Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,30 @@
11
package org.codeoverflow.chatoverflow.connector.actor
22

33
import akka.actor.Actor
4+
import com.google.gson.{JsonObject, JsonParser}
45

6+
/**
7+
* The JSON Actor uses Google GSON to parse serialized json and enable traversing.
8+
*/
59
class JsonActor extends Actor {
6-
override def receive: Receive = ???
10+
val parser = new JsonParser
11+
12+
/**
13+
* Receives a ParseJSON Object to start parsing.
14+
*
15+
* @return the desired values, can be any type
16+
*/
17+
override def receive: Receive = {
18+
case ParseJSON(json, parse) =>
19+
val rootObject = parser.parse(json).getAsJsonObject
20+
parse(rootObject)
21+
}
722
}
23+
24+
/**
25+
* Send a ParseJSON-object to start parsing. The traversal is custom.
26+
*
27+
* @param json the serialized json string
28+
* @param parse a function what should happen with the parsed json. Return type is any
29+
*/
30+
case class ParseJSON(json: String, parse: JsonObject => Any)

src/main/scala/org/codeoverflow/chatoverflow/connector/actor/PrivilegedActor.scala

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,20 @@ import akka.actor.Actor
88
*/
99
class PrivilegedActor extends Actor {
1010
/**
11-
* Handles any function to call. Takes a tuple of any argument and any function and the arguments to pass.
12-
* Example: <code>((aNumber: Int) => s"I got: $aNumber", 42)</code>
11+
* Handles any function to call. Takes a Privileged containing any function and the arguments to pass.
12+
* Example: <code>Privileged((aNumber: Int) => s"I got: $aNumber", 42)</code>
1313
*
1414
* @return the result type of the function, specified in the message. Can be anything.
1515
*/
1616
override def receive: Receive = {
17-
case message: (((Any) => Any), Any) => sender ! message._1(message._2)
17+
case Privileged(function, args) => sender ! function(args)
1818
}
1919
}
20+
21+
/**
22+
* Send a Privileged-ojbect to the PrivilegedActor to get the function executed with the given args.
23+
*
24+
* @param function a function of type T => Any
25+
* @param args the args for the function of type T
26+
*/
27+
case class Privileged(function: Any => Any, args: Any)

0 commit comments

Comments
 (0)