diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..48b44c8 --- /dev/null +++ b/build.sbt @@ -0,0 +1,62 @@ +name := "scalawebsocket" + +homepage := Some(url("https://github.com/pbuda/scalawebsocket")) + +licenses := Seq("Apache License 2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")) + +organization := "eu.piotrbuda" + +version := "0.1.2" + +scalaVersion := "2.11.6" + +crossScalaVersions := List("2.11.6", "2.10.5") + +fork in Test := true + +libraryDependencies ++= Seq( + "com.ning" % "async-http-client" % "1.7.13", + + //logging + "com.typesafe.scala-logging" %% "scala-logging-slf4j" % "2.1.2", + "ch.qos.logback" % "logback-classic" % "1.1.3", + + //jetty is used to setup test server + "org.eclipse.jetty" % "jetty-server" % "8.1.7.v20120910" % "test", + "org.eclipse.jetty" % "jetty-websocket" % "8.1.7.v20120910" % "test", + "org.eclipse.jetty" % "jetty-servlet" % "8.1.7.v20120910" % "test", + "org.eclipse.jetty" % "jetty-servlets" % "8.1.7.v20120910" % "test", + + "org.scalatest" %% "scalatest" % "2.2.4" % "test" +) + +publishMavenStyle := true + +publishTo <<= version { + (v: String) => + val nexus = "https://oss.sonatype.org/" + if (v.trim.endsWith("SNAPSHOT")) + Some("snapshots" at nexus + "content/repositories/snapshots") + else + Some("releases" at nexus + "service/local/staging/deploy/maven2") +} + +publishArtifact in Test := false + +pomIncludeRepository := { + _ => false +} + +pomExtra := ( + <scm> + <url>git@github.com:pbuda/scalawebsocket.git</url> + <connection>scm:git:git@github.com:pbuda/scalawebsocket.git</connection> + </scm> + <developers> + <developer> + <id>pbuda</id> + <name>Piotr Buda</name> + <url>http://www.piotrbuda.eu</url> + </developer> + </developers> +) diff --git a/project/Build.scala b/project/Build.scala deleted file mode 100644 index b1eb5dc..0000000 --- a/project/Build.scala +++ /dev/null @@ -1,70 +0,0 @@ -import sbt._ -import Keys._ - -object BuildSettings { - val buildSettings = Defaults.defaultSettings ++ Seq( - homepage := Some(url("https://github.com/pbuda/scalawebsocket")), - licenses := Seq("Apache License 2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")), - organization := "eu.piotrbuda", - name := "scalawebsocket", - version := "0.1.1", - scalaVersion := "2.10.1", - publishMavenStyle := true, - publishTo <<= version { - (v: String) => - val nexus = "https://oss.sonatype.org/" - if (v.trim.endsWith("SNAPSHOT")) - Some("snapshots" at nexus + "content/repositories/snapshots") - else - Some("releases" at nexus + "service/local/staging/deploy/maven2") - }, - publishArtifact in Test := false, - pomIncludeRepository := { - _ => false - }, - pomExtra := ( - <scm> - <url>git@github.com:pbuda/scalawebsocket.git</url> - <connection>scm:git:git@github.com:pbuda/scalawebsocket.git</connection> - </scm> - <developers> - <developer> - <id>pbuda</id> - <name>Piotr Buda</name> - <url>http://www.piotrbuda.eu</url> - </developer> - </developers> - ) - ) -} - -object Dependencies { - val asynchttpclient = "com.ning" % "async-http-client" % "1.7.13" - - //logging - val scalalogging = "com.typesafe" %% "scalalogging-log4j" % "1.0.1" - val log4japi = "org.apache.logging.log4j" % "log4j-api" % "2.0-beta4" - val log4jcore = "org.apache.logging.log4j" % "log4j-core" % "2.0-beta4" - val logback = "ch.qos.logback" % "logback-classic" % "1.0.9" - - val logging = Seq(scalalogging, log4japi, log4jcore, logback) - - //jetty is used to setup test server - val jettyServer = "org.eclipse.jetty" % "jetty-server" % "8.1.7.v20120910" % "test" - val jettyWebsocket = "org.eclipse.jetty" % "jetty-websocket" % "8.1.7.v20120910" % "test" - val jettyServlet = "org.eclipse.jetty" % "jetty-servlet" % "8.1.7.v20120910" % "test" - val jettyServlets = "org.eclipse.jetty" % "jetty-servlets" % "8.1.7.v20120910" % "test" - - val jetty = Seq(jettyServer, jettyWebsocket, jettyServlet, jettyServlets) - - val scalatest = "org.scalatest" %% "scalatest" % "1.9.1" % "test" -} - -object SWSBuild extends Build { - - import Dependencies._ - import BuildSettings._ - - val root = Project("scalawebsocket", file("."), settings = buildSettings) - .settings(libraryDependencies := Seq(asynchttpclient, scalatest) ++ logging ++ jetty) -} \ No newline at end of file diff --git a/project/build.properties b/project/build.properties index db255c2..9ad7e84 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.12.3 \ No newline at end of file +sbt.version=0.13.8 \ No newline at end of file diff --git a/project/project/SWSPlugins.scala b/project/project/SWSPlugins.scala deleted file mode 100644 index 403551e..0000000 --- a/project/project/SWSPlugins.scala +++ /dev/null @@ -1,7 +0,0 @@ -import sbt._ - -object SWSPlugins extends Build { - val plugins = Project("SWSPlugins", file(".")) - .settings(addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.3.0")) - .settings(addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8")) -} \ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index add74f9..123bb97 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -12,4 +12,4 @@ <root level="info"> <appender-ref ref="STDOUT" /> </root> -</configuration> \ No newline at end of file +</configuration> diff --git a/src/main/scala/scalawebsocket/WebSocket.scala b/src/main/scala/scalawebsocket/WebSocket.scala index 4380e71..9687113 100644 --- a/src/main/scala/scalawebsocket/WebSocket.scala +++ b/src/main/scala/scalawebsocket/WebSocket.scala @@ -18,7 +18,8 @@ package scalawebsocket import com.ning.http.client.{websocket, AsyncHttpClient} import com.ning.http.client.websocket.{WebSocketTextListener, WebSocketByteListener, WebSocketUpgradeHandler} -import com.typesafe.scalalogging.log4j.Logging +import com.typesafe.scalalogging.slf4j._ +// import com.typesafe.scalalogging.log4j.Logging object WebSocket { def apply() = { @@ -36,7 +37,7 @@ object WebSocket { * * @param client preconfigured instance of the [[com.ning.http.client.AsyncHttpClient]] */ -class WebSocket(client: AsyncHttpClient) extends Logging { +class WebSocket(client: AsyncHttpClient) extends StrictLogging { self => type OnTextMessageHandler = String => Unit diff --git a/src/test/scala/scalawebsocket/BaseTest.scala b/src/test/scala/scalawebsocket/BaseTest.scala index 305ad38..1b82cac 100644 --- a/src/test/scala/scalawebsocket/BaseTest.scala +++ b/src/test/scala/scalawebsocket/BaseTest.scala @@ -17,40 +17,28 @@ package scalawebsocket import org.eclipse.jetty.server.nio.SelectChannelConnector -import com.typesafe.scalalogging.log4j.Logging -import org.scalatest.matchers.ShouldMatchers -import org.scalatest.{FlatSpec, BeforeAndAfterAll} +import com.typesafe.scalalogging.slf4j._ import org.eclipse.jetty.server.{Request, Server} import org.eclipse.jetty.server.handler.HandlerWrapper -import org.eclipse.jetty.websocket.WebSocketFactory +import org.eclipse.jetty.websocket.{ WebSocketFactory } +import java.io.IOException import javax.servlet.http.{HttpServletResponse, HttpServletRequest} import java.net.ServerSocket -abstract class BaseTest extends Server with FlatSpec with BeforeAndAfterAll with ShouldMatchers with Logging { - protected var port1: Int = 0 - private var _connector: SelectChannelConnector = null +trait TestServer extends StrictLogging { + val server = new Server() + val connector = new SelectChannelConnector - override def beforeAll(configMap: Map[String, Any]) { - setUpGlobal() - } - - override def afterAll(configMap: Map[String, Any]) { - tearDownGlobal() - } - - def setUpGlobal() { - port1 = findFreePort - _connector = new SelectChannelConnector - _connector.setPort(port1) - addConnector(_connector) - val _wsHandler: BaseTest#WebSocketHandler = getWebSocketHandler - setHandler(_wsHandler) - start() + def setUpServer() { + server.addConnector(connector) + val _wsHandler = getWebSocketHandler + server.setHandler(_wsHandler) + server.start() logger.info("Local HTTP server started successfully") } - def tearDownGlobal() { - stop() + def tearDownServer() { + server.stop() } abstract class WebSocketHandler extends HandlerWrapper with WebSocketFactory.Acceptor { @@ -71,21 +59,59 @@ abstract class BaseTest extends Server with FlatSpec with BeforeAndAfterAll with private final val _webSocketFactory: WebSocketFactory = new WebSocketFactory(this, 32 * 1024) } - protected def findFreePort: Int = { - var socket: ServerSocket = null - try { - socket = new ServerSocket(0) - socket.getLocalPort - } finally { - if (socket != null) { - socket.close() + protected def getTargetUrl: String = + "ws://127.0.0.1:" + connector.getLocalPort() + + private final class EchoTextWebSocket extends org.eclipse.jetty.websocket.WebSocket with org.eclipse.jetty.websocket.WebSocket.OnTextMessage with org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage { + private var connection: org.eclipse.jetty.websocket.WebSocket.Connection = null + + def onOpen(connection: org.eclipse.jetty.websocket.WebSocket.Connection) { + this.connection = connection + connection.setMaxTextMessageSize(1000) + } + + def onClose(i: Int, s: String) { + connection.close() + } + + def onMessage(s: String) { + try { + connection.sendMessage(s) + } catch { + case e: IOException => { + try { + connection.sendMessage("FAIL") + } catch { + case e1: IOException => { + e1.printStackTrace() + } + } + } } } - } - protected def getTargetUrl: String = { - "ws://127.0.0.1:" + port1 + def onMessage(data: Array[Byte], offset: Int, length: Int) { + try { + connection.sendMessage(data, offset, length) + } catch { + case e: IOException => { + try { + connection.sendMessage("FAIL") + } catch { + case e1: IOException => { + e1.printStackTrace() + } + } + } + } + } } - def getWebSocketHandler: BaseTest#WebSocketHandler + def getWebSocketHandler: WebSocketHandler = { + new WebSocketHandler { + def doWebSocketConnect(httpServletRequest: HttpServletRequest, s: String): org.eclipse.jetty.websocket.WebSocket = { + new EchoTextWebSocket + } + } + } } diff --git a/src/test/scala/scalawebsocket/WebSocketSpec.scala b/src/test/scala/scalawebsocket/WebSocketSpec.scala index 67bc556..35a1317 100644 --- a/src/test/scala/scalawebsocket/WebSocketSpec.scala +++ b/src/test/scala/scalawebsocket/WebSocketSpec.scala @@ -21,65 +21,20 @@ package scalawebsocket import java.io.IOException import javax.servlet.http.HttpServletRequest -import com.typesafe.scalalogging.log4j.Logging +import com.typesafe.scalalogging.slf4j._ import java.util.concurrent.{TimeUnit, CountDownLatch} import com.ning.http.client.{AsyncHttpClient, websocket} -import org.scalatest.matchers.{MatchResult, BeMatcher} +import org.scalatest._ +import org.scalatest.matchers._ -class WebSocketSpec extends BaseTest with Logging { - - private final class EchoTextWebSocket extends org.eclipse.jetty.websocket.WebSocket with org.eclipse.jetty.websocket.WebSocket.OnTextMessage with org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage { - private var connection: org.eclipse.jetty.websocket.WebSocket.Connection = null - - def onOpen(connection: org.eclipse.jetty.websocket.WebSocket.Connection) { - this.connection = connection - connection.setMaxTextMessageSize(1000) - } - - def onClose(i: Int, s: String) { - connection.close() - } - - def onMessage(s: String) { - try { - connection.sendMessage(s) - } catch { - case e: IOException => { - try { - connection.sendMessage("FAIL") - } catch { - case e1: IOException => { - e1.printStackTrace() - } - } - } - } - } - - def onMessage(data: Array[Byte], offset: Int, length: Int) { - try { - connection.sendMessage(data, offset, length) - } catch { - case e: IOException => { - try { - connection.sendMessage("FAIL") - } catch { - case e1: IOException => { - e1.printStackTrace() - } - } - } - } - } +class WebSocketSpec extends FlatSpec with TestServer with BeforeAndAfterAll with Matchers with StrictLogging { + override def beforeAll() { + setUpServer() } - def getWebSocketHandler: BaseTest#WebSocketHandler = { - new WebSocketHandler { - def doWebSocketConnect(httpServletRequest: HttpServletRequest, s: String): org.eclipse.jetty.websocket.WebSocket = { - new EchoTextWebSocket - } - } + override def afterAll() { + tearDownServer() } it should "call all onOpen handlers" in {