├── .gitignore ├── .travis.yml ├── ADMIN.md ├── CONTRIBUTING.md ├── LICENSE ├── README.asciidoc ├── dist ├── release.py └── utils.py ├── project └── VertxScalaBuild.scala ├── sbt └── src ├── main ├── resources │ └── mod.json └── scala │ └── org │ └── vertx │ └── scala │ ├── AsJava.scala │ ├── FutureOps.scala │ ├── Self.scala │ ├── core │ ├── ClientSSLSupport.scala │ ├── Closeable.scala │ ├── FunctionConverters.scala │ ├── NetworkSupport.scala │ ├── SSLSupport.scala │ ├── ServerSSLSupport.scala │ ├── ServerTCPSupport.scala │ ├── TCPSupport.scala │ ├── Vertx.scala │ ├── VertxAccess.scala │ ├── VertxExecutionContext.scala │ ├── buffer │ │ ├── Buffer.scala │ │ └── package.scala │ ├── datagram │ │ ├── DatagramPacket.scala │ │ ├── DatagramSocket.scala │ │ ├── InternetProtocolFamily.scala │ │ └── package.scala │ ├── dns │ │ ├── DnsClient.scala │ │ ├── DnsException.scala │ │ ├── DnsResponseCode.scala │ │ ├── MxRecord.scala │ │ └── SrvRecord.scala │ ├── eventbus │ │ ├── EventBus.scala │ │ ├── Message.scala │ │ ├── RegisteredHandler.scala │ │ ├── SendOrPublish.scala │ │ └── package.scala │ ├── file │ │ ├── AsyncFile.scala │ │ ├── FileProps.scala │ │ ├── FileSystem.scala │ │ └── FileSystemProps.scala │ ├── http │ │ ├── HttpClient.scala │ │ ├── HttpClientRequest.scala │ │ ├── HttpClientResponse.scala │ │ ├── HttpServer.scala │ │ ├── HttpServerFileUpload.scala │ │ ├── HttpServerRequest.scala │ │ ├── HttpServerResponse.scala │ │ ├── RouteMatcher.scala │ │ ├── ServerWebSocket.scala │ │ ├── WebSocket.scala │ │ ├── WebSocketBase.scala │ │ └── package.scala │ ├── json │ │ ├── Json.scala │ │ └── package.scala │ ├── logging │ │ └── Logger.scala │ ├── net │ │ ├── NetClient.scala │ │ ├── NetServer.scala │ │ └── NetSocket.scala │ ├── package.scala │ ├── parsetools │ │ └── RecordParser.scala │ ├── shareddata │ │ └── SharedData.scala │ ├── sockjs │ │ ├── EventBusBridgeHook.scala │ │ ├── SockJSServer.scala │ │ └── SockJSSocket.scala │ └── streams │ │ ├── DrainSupport.scala │ │ ├── ExceptionSupport.scala │ │ ├── Pump.scala │ │ ├── ReadStream.scala │ │ ├── ReadSupport.scala │ │ └── WriteStream.scala │ ├── lang │ ├── ClassLoaders.scala │ └── ScalaInterpreter.scala │ ├── mods │ ├── BusModException.scala │ ├── ScalaBusMod.scala │ ├── UnknownActionException.scala │ └── replies │ │ └── busmodreplies.scala │ ├── platform │ ├── Container.scala │ ├── Verticle.scala │ └── impl │ │ ├── ScalaVerticle.scala │ │ └── ScalaVerticleFactory.scala │ ├── router │ ├── Router.scala │ ├── RouterException.scala │ └── routing │ │ └── routing.scala │ └── testtools │ ├── ScalaClassRunner.java │ └── TestVerticle.scala └── test ├── keystores ├── client-keystore.jks ├── client-truststore.jks ├── server-keystore.jks ├── server-truststore.jks └── ssl.txt ├── resources ├── error404.html ├── helloscala.txt ├── langs.properties ├── log4j.properties ├── pumpfile.txt └── pumpfile.txt.copy ├── scala └── org │ └── vertx │ └── scala │ └── tests │ ├── core │ ├── buffer │ │ └── BufferTest.scala │ ├── datagram │ │ └── DatagramTest.scala │ ├── dns │ │ └── DnsTest.scala │ ├── eventbus │ │ ├── EventBusBridgeTest.scala │ │ ├── EventBusTest.scala │ │ └── EventBusTimeoutsTest.scala │ ├── file │ │ └── FileTest.scala │ ├── http │ │ ├── Compression.scala │ │ ├── HttpCompressionTest.scala │ │ ├── HttpConfigurationTest.scala │ │ ├── HttpTest.scala │ │ ├── HttpTestBase.scala │ │ └── WebSocketsTest.scala │ ├── json │ │ └── JsonTest.scala │ ├── net │ │ └── NetTest.scala │ └── streams │ │ └── PumpTest.scala │ ├── lang │ ├── ScalaInterpreterTest.scala │ ├── ScalaScriptingTest.scala │ ├── UnsupportedVerticleClass.scala │ └── VerticleClass.scala │ ├── mods │ ├── ScalaBusModTest.scala │ └── TestBusMod.scala │ ├── plattform │ └── impl │ │ ├── ScalaVerticleFactoryTest.scala │ │ └── SystemPropertyDefaultLangOverrideTest.scala │ ├── router │ ├── AuthRouter.scala │ ├── JsonRouter.scala │ ├── JsonRouterTest.scala │ ├── RouterAuthTest.scala │ └── RouterTestHelper.scala │ └── util │ └── TestUtils.scala └── scripts ├── ScriptingTest.scala └── VerticleScript.scala /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore IDEA files 2 | *.iml 3 | *.ipr 4 | *.iws 5 | .idea 6 | # ignore eclipse files 7 | .project 8 | .classpath 9 | .settings 10 | .scala_dependencies 11 | .externalToolBuilders 12 | .factorypath 13 | # ignore others 14 | out 15 | src/test/mod-test 16 | classes 17 | .cache 18 | .DS_Store 19 | .gradle 20 | .springBeans 21 | bin 22 | build 23 | *.pyc 24 | mods 25 | target 26 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk7 4 | - openjdk7 5 | -------------------------------------------------------------------------------- /ADMIN.md: -------------------------------------------------------------------------------- 1 | This guide walks through the basics on administrating the mod-lang-scala repository. 2 | Make sure you read the contribution guidelines in `CONTRIBUTE.md` before reading 3 | this file. 4 | 5 | # Source control - Git 6 | mod-lang-scala uses git, hosted on GitHub, for version control. In this section, 7 | we'll review the tasks and responsibilities of a mod-lang-scala repository 8 | Project Admin. 9 | 10 | ## Project Admin 11 | Project Admins have a very limited role. Only Project Admins are allowed to 12 | push to upstream, and Project Admins never write any code directly on the 13 | upstream repository. All Project Admins do is pull in and merge changes from 14 | contributors (even if the "contributor" happens to be themselves) into 15 | upstream, perform code reviews and either commit or reject such changes. 16 | 17 | > All Contributors who are also Project Admins are encouraged to not merge 18 | their own changes, to ensure that all changes are reviewed. 19 | 20 | This approach ensures mod-lang-scala maintains quality on the main code source 21 | tree, and allows for important code reviews to take place again ensuring 22 | quality. Further, it ensures clean and easily traceable code history and makes 23 | sure that more than one person knows about the changes being performed. 24 | 25 | ### Merging in patches 26 | 27 | ![Figure 2-1] 28 | (https://docs.jboss.org/author/download/attachments/4784485/git_wf_3.png "Merging patch") 29 | 30 | Patches submitted via JIRA are audited and promoted to the upstream repository 31 | as detailed above. A Project Admin would typically create a working branch to 32 | which the patch is applied and tested. The patch can be further modified, 33 | cleaned up, and commit messages made clearer if necessary. The branch should 34 | then be merged to the master or one of the maintenance branches before being 35 | pushed. 36 | 37 | More information on applying patches can be found in 38 | [Chapter 5, Section 3 of Pro Git](http://progit.org/book/ch5-3.html), under 39 | **Applying Patches From Email**. 40 | 41 | ### Handling pull requests 42 | 43 | ![Figure 2-2] 44 | (https://docs.jboss.org/author/download/attachments/4784485/git_wf_4.png "Handling pull request") 45 | 46 | Project Admins are also responsible for responding to pull requests. The 47 | process is similar to applying a patch directly, except that when pulling in 48 | changes from a forked repository, more than a single commit may be pulled in. 49 | Again, this should be done on a newly created working branch, code reviewed, 50 | tested and cleaned up as necessary. 51 | 52 | If commits need to be altered - e.g., rebasing to squash or split commits, or 53 | to alter commit messages - it is often better to contact the Contributor and 54 | ask the Contributor to do so and re-issue the pull request, since doing so on 55 | the upstream repo could cause update issues for contributors later on. If 56 | commits were altered or three-way merge was performed during a merge instead 57 | of fast-forward, it's also a good idea to check the log to make sure that the 58 | resulting repository history looks OK: 59 | 60 | $ git log --pretty=oneline --graph --abbrev-commit # History messed up due to a bad merge 61 | * 3005020 Merge branch 'ISPN-786' of git://github.com/Sanne/infinispan 62 | |\ 63 | | * e757265 ISPN-786 Make dependency to log4j optional <-- Same with cb4e5d6 - unnecessary 64 | * | cb4e5d6 ISPN-786 Make dependency to log4j optional <-- Cherry-picked commit by other admin 65 | |/ 66 | * ... 67 | 68 | $ git reset cb4e5d6 # revert the bad merge 69 | 70 | It is therefore strongly recommended that you use the [handle_pull_request] 71 | (https://github.com/maniksurtani/githelpers/blob/master/project_admins/handle_pull_request) 72 | script that ensures a clean merge. If you still wish to do this manually, 73 | please consider reading through the script first to get an idea of what needs 74 | to happen. 75 | 76 | More information on pulling changes from remote, forked repos can be found in 77 | [Chapter 5, Section 3 of Pro Git](http://progit.org/book/ch5-3.html), under 78 | **Checking Out Remote Branches**. 79 | 80 | #### Possible trouble handling pull requests 81 | If you have warnings about "Merge made by recursive" you have to fix it rebasing. 82 | If you have warnings about "non-fast-forward" you have to rebase. If you see 83 | "non-fast-forward updates were rejected" you shall never use "force" on upstream! 84 | It means that another patch was merged before you and you have to update your 85 | master again, and rebase again. "force" is allowed only in special maintenance 86 | circumstances. If you find you're needing it to handle a pull request, then 87 | you're doing it wrong, and the mistake might be a dangerous one! It's like the 88 | good rule of never commit when you're drunk (coding is allowed). 89 | 90 | > **Never use force on git push!** Using -f while pushing on a shared repository 91 | such as upstream you could effectively erase other committed patches. Noone 92 | shall ever use this option unless unanimously approved on the public mailing 93 | list: the most dangerous aspect of it is that nobody gets any notification if 94 | this happens, and we might think issues are solved but you silently removed 95 | the fix and it's history from the repository. 96 | 97 | ### Cutting releases 98 | Releases can only me cut by Project Admins... TBD. 99 | -------------------------------------------------------------------------------- /README.asciidoc: -------------------------------------------------------------------------------- 1 | = Vert.x 2.x is **deprecated** - use instead https://github.com/vert-x3/vertx-lang-scala 2 | 3 | == Scala Module for Vert.x 4 | 5 | Scala language implementation for Vert.x. 6 | 7 | === Versions 8 | 9 | Vert.x Scala 1.0.x is designed for Vert.x 2.1 and works with Scala 2.10 10 | 11 | === Quickstart 12 | 13 | To use it, we've added a first "Hello World"-like example to the 14 | https://github.com/vert-x/vertx-examples/blob/master/src/raw/scala[Vert.x Examples repository] 15 | which can be run like this: 16 | 17 | 1. Clone or download the https://github.com/vert-x/vertx-examples[Vert.x Examples Git repository] 18 | 2. Change directory to `src/raw/scala` and type: 19 | + 20 | ............................................................................... 21 | [VERTX_HOME]/bin/vertx run http/Server.scala 22 | ............................................................................... 23 | + 24 | 25 | 5. Go to http://localhost:8080/ and you should see the message: ""This is a Verticle script!" 26 | 27 | === Using the Vert.x Scala API 28 | 29 | The best places to look for examples on how to use the Vert.x Scala API are 30 | the https://github.com/vert-x/vertx-examples/blob/master/src/raw/scala[Vert.x Examples repository] 31 | and the https://github.com/vert-x/mod-lang-scala/tree/master/src/test/scala/org/vertx/scala/tests[Vert.x Scala testsuite]. 32 | Please inspect those if you have any doubts. The following sub sections explain 33 | some of the items to bear in mind when using this API. 34 | 35 | ==== Type annotations for handlers in for overloaded methods 36 | 37 | In some cases, the Scala compiler can fail to detect the type of a particular 38 | handler, for example: 39 | 40 | + 41 | ............................................................................... 42 | val datagramSocket = vertx.createDatagramSocket() 43 | datagramSocket.send("hello", "127.0.0.1", 1234, { h: AsyncResult[DatagramSocket] => 44 | ... 45 | } 46 | ............................................................................... 47 | + 48 | 49 | In this example, `send` method call explicitly needs to define the type 50 | annotation for the async result handler. This is because there's an overloaded 51 | method that sends a `org.vertx.scala.core.buffer.Buffer` instead of a String. 52 | 53 | A possible workaround would have been to use function currying, but doing so 54 | would limit the API capability to add `scala.concurrent.Future` based methods, 55 | which are better suited for implementing handlers. 56 | 57 | === Plugging Vert.x Scala language extension 58 | 59 | Vert.x 2.1 comes with Vert.x Scala language support embedded within it, but if 60 | you want to test a different version of the Vert.x Scala language 61 | implementation, follow these instructions: 62 | 63 | 1. Download a Vert.x distribution. 64 | 2. Open `[VERTX_HOME]/conf/langs.properties` file and modify this line to match 65 | the Vert.x Scala version to test: 66 | + 67 | ............................................................................... 68 | scala=io.vertx~lang-scala~X.Y.Z:org.vertx.scala.platform.impl.ScalaVerticleFactory 69 | ............................................................................... 70 | + 71 | 72 | Optionally, if you're testing a locally built Vert.x Scala extension, you'll 73 | need to do the following steps additionally: 74 | 75 | 1. Download latest http://www.scala-sbt.org/download.html[SBT release] 76 | 2. Put `[SBT_HOME]/bin/sbt` or `[SBT_HOME]/bin/sbt.bar` into your path 77 | 3. Clone the Vert.x Scala source repository 78 | 4a. If you want build plugin with the base Scala version used (e.g. 2.10), execute: 79 | + 80 | ............................................................................... 81 | $ sbt clean publishM2 82 | $ [VERTX_HOME]/bin/vertx install io.vertx~lang-scala_2.10~X.Y.Z 83 | ............................................................................... 84 | + 85 | 4b. On the other hand, if you want build plugin with a cross compiled Scala version (e.g. 2.11), execute: 86 | + 87 | ............................................................................... 88 | $ sbt clean +publishM2 89 | $ [VERTX_HOME]/bin/vertx install io.vertx~lang-scala_2.11~X.Y.Z 90 | ............................................................................... 91 | + 92 | 93 | For more information on building Vert.x Scala, check the contributing guide. 94 | -------------------------------------------------------------------------------- /src/main/resources/mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Scala language implementation module for Vert.x", 3 | "licenses": ["The Apache Software License Version 2.0"], 4 | "author": "Galder Zamarreño", 5 | "developers": ["Stuart Williams", 6 | "Edgar Chan", 7 | "Nicolas Melendez", 8 | "Joern Bernhardt", 9 | "Ranie Jade Ramiso" 10 | ], 11 | "keywords": ["scala", "language"], 12 | "homepage": "https://github.com/vert-x/mod-lang-scala", 13 | 14 | // Required for language modules 15 | "system": true, 16 | "resident": true 17 | } 18 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/AsJava.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala 17 | 18 | /** 19 | * This trait shows that this type is a wrapper around a Vert.x Java class. 20 | * Traits that require access to the Java object should extend this trait. 21 | * Concrete implementations will provide final information on the exact Java 22 | * type and they'd provide access to the actual java object. 23 | * 24 | * @author Joern Bernhardt 25 | * @author Galder Zamarreño 26 | */ 27 | private[scala] trait AsJava { 28 | 29 | /** The internal type of the Java wrapped class. */ 30 | type J 31 | 32 | /** The internal instance of the Java wrapped class. */ 33 | val asJava: J 34 | 35 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/FutureOps.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala 2 | 3 | import org.vertx.scala.core.FunctionConverters._ 4 | import org.vertx.scala.core._ 5 | 6 | import scala.concurrent.{Future, Promise} 7 | import scala.util.{Failure, Success, Try} 8 | 9 | /** 10 | * General helpers for generic scala problems that occur inside the Vert.x code. 11 | * 12 | * @author Joern Bernhardt 13 | */ 14 | object FutureOps { 15 | 16 | type ResultHandler[T] = AsyncResult[T] => Unit 17 | 18 | def futurify[T](x: Promise[T] => _): Future[T] = { 19 | val p = Promise[T]() 20 | x(p) 21 | p.future 22 | } 23 | 24 | def asyncResultToFuture[T](fn: ResultHandler[T] => _): Future[T] = futurify { p: Promise[T] => 25 | val t = { 26 | case Success(result) => p.success(result) 27 | case Failure(ex) => p.failure(ex) 28 | }: Try[T] => Unit 29 | fn(t) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/Self.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala 17 | 18 | /** 19 | * [[org.vertx.scala.Self]] allows fluent return types pointing to the type of 20 | * this object. 21 | * 22 | * @author Joern Bernhardt 23 | * @author Galder Zamarreño 24 | */ 25 | private[scala] trait Self { 26 | 27 | /** 28 | * Helper method wrapping invocations and returning the Scala type, once 29 | * again to help provide fluent return types 30 | */ 31 | protected[this] def wrap[X](doStuff: => X): this.type = { 32 | doStuff 33 | this 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/ClientSSLSupport.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import org.vertx.java.core.{ ClientSSLSupport => JClientSSLSupport } 19 | import org.vertx.scala.Self 20 | 21 | /** 22 | * Supports [[org.vertx.java.core.ClientSSLSupport]] functionality. 23 | * 24 | * @author Joern Bernhardt 25 | * @author Galder Zamarreño 26 | * 27 | */ 28 | trait ClientSSLSupport extends Self 29 | with SSLSupport { 30 | 31 | override type J <: JClientSSLSupport[_] 32 | 33 | /** 34 | * @return true if this client will trust all server certificates. 35 | */ 36 | def isTrustAll: Boolean = asJava.isTrustAll 37 | 38 | /** 39 | * If you want an SSL client to trust *all* server certificates rather than match them 40 | * against those in its trust store, you can set this to true.

41 | * Use this with caution as you may be exposed to "main in the middle" attacks 42 | * @param trustAll Set to true if you want to trust all server certificates 43 | */ 44 | def setTrustAll(trustAll: Boolean): this.type = wrap(asJava.setTrustAll(trustAll)) 45 | 46 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/Closeable.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import org.vertx.scala.AsJava 19 | import org.vertx.scala.core.FunctionConverters._ 20 | 21 | /** 22 | * Signals that an instance can be closed. 23 | * 24 | * @author Joern Bernhardt 25 | * @author Galder Zamarreño 26 | */ 27 | trait Closeable extends AsJava { 28 | 29 | override type J <: CloseType 30 | 31 | type CloseType = { 32 | def close(): Unit 33 | def close(handler: Handler[AsyncResult[Void]]): Unit 34 | } 35 | 36 | /** 37 | * Close this [[org.vertx.scala.core.Closeable]] instance asynchronously. 38 | */ 39 | def close(): Unit = asJava.close() 40 | 41 | /** 42 | * Close this [[org.vertx.scala.core.Closeable]] instance asynchronously 43 | * and notifies the handler once done. 44 | */ 45 | def close(handler: AsyncResult[Void] => Unit): Unit = asJava.close(fnToHandler(handler)) 46 | 47 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/FunctionConverters.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import scala.language.implicitConversions 19 | import org.vertx.java.core.AsyncResultHandler 20 | import org.vertx.java.core.eventbus.{ Message => JMessage } 21 | import org.vertx.scala.core.eventbus.Message 22 | import org.vertx.java.core.impl.DefaultFutureResult 23 | import scala.util.Try 24 | import scala.util.Success 25 | import scala.util.Failure 26 | 27 | /** 28 | * @author swilliams 29 | * @author Joern Bernhardt 30 | * @author Galder Zamarreño 31 | */ 32 | trait FunctionConverters { 33 | 34 | implicit def lazyToVoidHandler(func: => Unit): Handler[Void] = new Handler[Void]() { 35 | override def handle(event: Void) = func 36 | } 37 | 38 | implicit def fnToHandler[T](func: T => Unit): Handler[T] = new Handler[T]() { 39 | override def handle(event: T) = func(event) 40 | } 41 | 42 | implicit def messageFnToJMessageHandler[T](func: Message[T] => Unit): Handler[JMessage[T]] = new Handler[JMessage[T]]() { 43 | override def handle(event: JMessage[T]) = func.compose(Message.apply).apply(event) 44 | } 45 | 46 | implicit def handlerToFn[T](handler: Handler[T]): T => Unit = (event: T) => handler.handle(event) 47 | 48 | implicit def convertFunctionToVoidAsyncHandler(func: () => Unit): AsyncResultHandler[Void] = new AsyncResultHandler[Void]() { 49 | override def handle(event: AsyncResult[Void]) = func() 50 | } 51 | 52 | implicit def convertFunctionToParameterisedAsyncHandler[T](func: AsyncResult[T] => Unit): AsyncResultHandler[T] = new AsyncResultHandler[T]() { 53 | override def handle(event: AsyncResult[T]) = func(event) 54 | } 55 | 56 | implicit def tryToAsyncResultHandler[X](tryHandler: Try[X] => Unit): AsyncResult[X] => Unit = { 57 | tryHandler.compose { ar: AsyncResult[X] => 58 | if (ar.succeeded()) { 59 | Success(ar.result()) 60 | } else { 61 | Failure(ar.cause()) 62 | } 63 | } 64 | } 65 | 66 | def asyncResultConverter[ST, JT](mapFn: JT => ST)(handler: AsyncResult[ST] => Unit): Handler[AsyncResult[JT]] = { 67 | new Handler[AsyncResult[JT]]() { 68 | def handle(ar: AsyncResult[JT]) = { 69 | val scalaAr = new AsyncResult[ST]() { 70 | override def result(): ST = mapFn(ar.result()) 71 | override def cause() = ar.cause() 72 | override def succeeded() = ar.succeeded() 73 | override def failed() = ar.failed() 74 | } 75 | handler(scalaAr) 76 | } 77 | } 78 | } 79 | 80 | def asyncHandler[A, B, C](handler: AsyncResult[A] => B, f: C => A): Handler[AsyncResult[C]] = { 81 | new Handler[AsyncResult[C]] { 82 | def handle(rst: AsyncResult[C]) { 83 | handler( 84 | new DefaultFutureResult[A](f(rst.result))) 85 | } 86 | } 87 | } 88 | 89 | def voidAsyncHandler(handler: AsyncResult[Unit] => Unit): Handler[AsyncResult[Void]] = { 90 | new Handler[AsyncResult[Void]] { 91 | def handle(rst: AsyncResult[Void]) { 92 | handler(rst.asInstanceOf[AsyncResult[Unit]]) 93 | } 94 | } 95 | } 96 | 97 | } 98 | 99 | object FunctionConverters extends FunctionConverters -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/NetworkSupport.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import org.vertx.java.core.{NetworkSupport => JNetworkSupport} 19 | import org.vertx.scala.{Self, AsJava} 20 | 21 | /** 22 | * Offers methods that can be used to configure a service that provide network services. 23 | * 24 | * @author Norman Maurer 25 | * @author Joern Bernhardt 26 | * @author Galder Zamarreño 27 | */ 28 | trait NetworkSupport extends Self with AsJava { 29 | 30 | override type J <: JNetworkSupport[_] 31 | 32 | /** 33 | * Set the send buffer size for connections created by this instance to `size` in bytes. 34 | * @return a reference to this so multiple method calls can be chained together 35 | */ 36 | def setSendBufferSize(size: Int): this.type = wrap(asJava.setSendBufferSize(size)) 37 | 38 | /** 39 | * Set the receive buffer size for connections created by this instance to `size` in bytes. 40 | * @return a reference to this so multiple method calls can be chained together 41 | */ 42 | def setReceiveBufferSize(size: Int): this.type = wrap(asJava.setReceiveBufferSize(size)) 43 | 44 | /** 45 | * Set the reuseAddress setting for connections created by this instance to `reuse`. 46 | * @return a reference to this so multiple method calls can be chained together 47 | */ 48 | def setReuseAddress(reuse: Boolean): this.type = wrap(asJava.setReuseAddress(reuse)) 49 | 50 | /** 51 | * Set the trafficClass setting for connections created by this instance to `trafficClass`. 52 | * @return a reference to this so multiple method calls can be chained together 53 | */ 54 | def setTrafficClass(trafficClass: Int): this.type = wrap(asJava.setTrafficClass(trafficClass)) 55 | 56 | /** 57 | * @return The send buffer size 58 | */ 59 | def getSendBufferSize: Int = asJava.getSendBufferSize 60 | 61 | /** 62 | * @return The receive buffer size 63 | */ 64 | def getReceiveBufferSize: Int = asJava.getReceiveBufferSize 65 | 66 | /** 67 | * @return The value of reuse address 68 | */ 69 | def isReuseAddress: Boolean = asJava.isReuseAddress 70 | 71 | /** 72 | * @return the value of traffic class 73 | */ 74 | def getTrafficClass: Int = asJava.getTrafficClass 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/SSLSupport.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.core 2 | 3 | import org.vertx.java.core.{ SSLSupport => JSSLSupport } 4 | import org.vertx.scala.{Self, AsJava} 5 | 6 | trait SSLSupport extends Self 7 | with AsJava { 8 | 9 | override type J <: JSSLSupport[_] 10 | 11 | /** 12 | * If `ssl` is `true`, this signifies that any connections will be SSL connections. 13 | * @return A reference to this, so multiple invocations can be chained together. 14 | */ 15 | def setSSL(ssl: Boolean): this.type = wrap(asJava.setSSL(ssl)) 16 | 17 | /** 18 | * 19 | * @return Is SSL enabled? 20 | */ 21 | def isSSL: Boolean = asJava.isSSL 22 | 23 | /** 24 | * Set the path to the SSL key store. This method should only be used in SSL 25 | * mode, i.e. after [[org.vertx.scala.core.SSLSupport.setSSL(boolean)]] has been set to `true`.

26 | * The SSL key store is a standard Java Key Store, and will contain the client certificate. Client certificates are 27 | * only required if the server requests client authentication.

28 | * @return A reference to this, so multiple invocations can be chained together. 29 | */ 30 | def setKeyStorePath(path: String): this.type = wrap(asJava.setKeyStorePath(path)) 31 | 32 | /** 33 | * 34 | * @return Get the key store path 35 | */ 36 | def getKeyStorePath: String = asJava.getKeyStorePath 37 | 38 | /** 39 | * Set the password for the SSL key store. This method should only be used in SSL mode, i.e. after 40 | * [[org.vertx.scala.core.SSLSupport.setSSL(boolean)]] has been set to `true`.

41 | * @return A reference to this, so multiple invocations can be chained together. 42 | */ 43 | def setKeyStorePassword(pwd: String): this.type = wrap(asJava.setKeyStorePassword(pwd)) 44 | 45 | /** 46 | * 47 | * @return Get the key store password 48 | */ 49 | def getKeyStorePassword: String = asJava.getKeyStorePassword 50 | 51 | /** 52 | * Set the path to the SSL trust store. This method should only be used in SSL mode, i.e. after 53 | * [[org.vertx.scala.core.SSLSupport.setSSL(boolean)]] has been set to `true`.

54 | * The trust store is a standard Java Key Store, and should contain the certificates of any servers that the client trusts. 55 | * @return A reference to this, so multiple invocations can be chained together. 56 | */ 57 | def setTrustStorePath(path: String): this.type = wrap(asJava.setTrustStorePath(path)) 58 | 59 | /** 60 | * 61 | * @return Get the trust store path 62 | */ 63 | def getTrustStorePath: String = asJava.getTrustStorePath 64 | 65 | /** 66 | * Set the password for the SSL trust store. This method should only be used in SSL mode, i.e. after 67 | * [[org.vertx.scala.core.SSLSupport.setSSL(boolean)]] has been set to `true`.

68 | * @return A reference to this, so multiple invocations can be chained together. 69 | */ 70 | def setTrustStorePassword(pwd: String): this.type = wrap(asJava.setTrustStorePassword(pwd)) 71 | 72 | /** 73 | * 74 | * @return Get trust store password 75 | */ 76 | def getTrustStorePassword: String = asJava.getTrustStorePassword 77 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/ServerSSLSupport.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import org.vertx.java.core.{ ServerSSLSupport => JServerSSLSupport } 19 | import org.vertx.scala.Self 20 | 21 | /** 22 | * Supports [[org.vertx.java.core.ServerSSLSupport]] functionality. 23 | * 24 | * @author Joern Bernhardt 25 | * @author Galder Zamarreño 26 | */ 27 | trait ServerSSLSupport extends Self 28 | with SSLSupport { 29 | 30 | override type J <: JServerSSLSupport[_] 31 | 32 | /** 33 | * Is client auth required? 34 | */ 35 | def isClientAuthRequired: Boolean = asJava.isClientAuthRequired 36 | 37 | /** 38 | * Set `required` to true if you want the server to request client authentication from any connecting clients. This 39 | * is an extra level of security in SSL, and requires clients to provide client certificates. Those certificates must be added 40 | * to the server trust store. 41 | * @return A reference to this, so multiple invocations can be chained together. 42 | */ 43 | def setClientAuthRequired(required: Boolean): this.type = wrap(asJava.setClientAuthRequired(required)) 44 | 45 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/ServerTCPSupport.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import org.vertx.java.core.{ ServerTCPSupport => JServerTCPSupport } 19 | import org.vertx.scala.Self 20 | 21 | /** 22 | * Supports [[org.vertx.java.core.ServerTCPSupport]] functionality. 23 | * 24 | * @author Joern Bernhardt 25 | * @author Galder Zamarreño 26 | */ 27 | trait ServerTCPSupport extends Self 28 | with TCPSupport { 29 | 30 | override type J <: JServerTCPSupport[_] 31 | 32 | /** 33 | * Set the accept backlog 34 | * @return a reference to this so multiple method calls can be chained together 35 | */ 36 | def setAcceptBacklog(backlog: Int): this.type = wrap(asJava.setAcceptBacklog(backlog)) 37 | 38 | /** 39 | * 40 | * @return The accept backlog 41 | */ 42 | def getAcceptBacklog: Int = asJava.getAcceptBacklog 43 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/TCPSupport.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import org.vertx.java.core.{ TCPSupport => JTCPSupport } 19 | import org.vertx.scala.Self 20 | 21 | /** 22 | * Supports [[org.vertx.java.core.TCPSupport]] functionality. 23 | * 24 | * @author Joern Bernhardt 25 | * @author Galder Zamarreño 26 | */ 27 | trait TCPSupport extends Self 28 | with NetworkSupport { 29 | 30 | override type J <: JTCPSupport[_] 31 | 32 | /** 33 | * 34 | * @return the value of TCP so linger 35 | */ 36 | def getSoLinger: Int = asJava.getSoLinger 37 | 38 | /** 39 | * 40 | * @return true if TCP keep alive is enabled 41 | */ 42 | def isTCPKeepAlive: Boolean = asJava.isTCPKeepAlive 43 | 44 | /** 45 | * @return true if Nagle's algorithm is disabled. 46 | */ 47 | def isTCPNoDelay: Boolean = asJava.isTCPNoDelay 48 | 49 | /** 50 | * @return `true` if pooled buffers are used 51 | */ 52 | def isUsePooledBuffers: Boolean = asJava.isUsePooledBuffers 53 | 54 | /** 55 | * Set the TCP soLinger setting for connections created by this instance to `linger`. 56 | * Using a negative value will disable soLinger. 57 | * @return a reference to this so multiple method calls can be chained together 58 | * 59 | */ 60 | def setSoLinger(linger: Int): this.type = wrap(asJava.setSoLinger(linger)) 61 | 62 | /** 63 | * Set the TCP keepAlive setting for connections created by this instance to `keepAlive`. 64 | * @return a reference to this so multiple method calls can be chained together 65 | */ 66 | def setTCPKeepAlive(keepAlive: Boolean): this.type = wrap(asJava.setTCPKeepAlive(keepAlive)) 67 | 68 | /** 69 | * If `tcpNoDelay` is set to `true` then Nagle's algorithm 70 | * will turned off for the TCP connections created by this instance. 71 | * @return a reference to this so multiple method calls can be chained together 72 | */ 73 | def setTCPNoDelay(tcpNoDelay: Boolean): this.type = wrap(asJava.setTCPNoDelay(tcpNoDelay)) 74 | 75 | /** 76 | * Set if vertx should use pooled buffers for performance reasons. Doing so will give the best throughput but 77 | * may need a bit higher memory footprint. 78 | * @return a reference to this so multiple method calls can be chained together 79 | */ 80 | def setUsePooledBuffers(pooledBuffers: Boolean): this.type = wrap(asJava.setUsePooledBuffers(pooledBuffers)) 81 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/VertxAccess.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.core 2 | 3 | import org.vertx.scala.core.logging.Logger 4 | import org.vertx.scala.platform.Container 5 | 6 | /** 7 | * Classes implementing this trait provide direct access to `Vertx`, `Container` and `Logger`. Be 8 | * cautious when using this trait: Do not use the provided `vertx`, `container` and `logger` at 9 | * construction of the object, otherwise they might not be initialized yet. 10 | */ 11 | trait VertxAccess { 12 | val vertx: Vertx 13 | val container: Container 14 | val logger: Logger 15 | 16 | protected implicit val executionContext = VertxExecutionContext.fromVertx(vertx, logger) 17 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/VertxExecutionContext.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import scala.concurrent.ExecutionContext 19 | import org.vertx.scala.core.logging.Logger 20 | 21 | /** 22 | * Vert.x Scala execution context 23 | * 24 | * @author Joern Bernhardt 25 | * @author Galder Zamarreño 26 | */ 27 | object VertxExecutionContext { 28 | 29 | /** 30 | * Vert.x execution context for use in verticles extending [[VertxAccess]] 31 | * trait. Scala verticles do extend this trait to facilitate access to 32 | * internal components. 33 | */ 34 | def fromVertxAccess(vertxAccess: VertxAccess): ExecutionContext = 35 | new VertxExecutionContextImpl(vertxAccess.vertx, vertxAccess.logger) 36 | 37 | /** 38 | * Vert.x execution context for situations where verticles are written in 39 | * other languages except Scala, where there's no access to [[VertxAccess]], 40 | * but access to [[Logger]] and [[Vertx]] class instances are available. 41 | */ 42 | def fromVertx(vertx: => Vertx, logger: => Logger): ExecutionContext = 43 | new VertxExecutionContextImpl(vertx, logger) 44 | 45 | private final class VertxExecutionContextImpl(vertx: => Vertx, logger: => Logger) extends ExecutionContext { 46 | override def reportFailure(t: Throwable): Unit = 47 | logger.error("Error executing Future in VertxExecutionContext", t) 48 | override def execute(runnable: Runnable): Unit = 49 | runnable.run() 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/buffer/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import org.vertx.java.core.buffer.{ Buffer => JBuffer } 19 | import org.vertx.scala.core.FunctionConverters._ 20 | 21 | /** 22 | * @author swilliams 23 | * @author Edgar Chan 24 | * @author Joern Bernhardt 25 | */ 26 | package object buffer { 27 | 28 | trait BufferType[T] { 29 | def appendToBuffer(buffer: JBuffer, value: T): JBuffer 30 | } 31 | implicit object BufferElem extends BufferType[Buffer] { 32 | override def appendToBuffer(buffer: JBuffer, value: Buffer) = buffer.appendBuffer(value.asJava) 33 | } 34 | implicit object ByteElem extends BufferType[Byte] { 35 | override def appendToBuffer(buffer: JBuffer, value: Byte) = buffer.appendByte(value) 36 | } 37 | implicit object BytesElem extends BufferType[Array[Byte]] { 38 | override def appendToBuffer(buffer: JBuffer, value: Array[Byte]) = buffer.appendBytes(value) 39 | } 40 | implicit object DoubleElem extends BufferType[Double] { 41 | override def appendToBuffer(buffer: JBuffer, value: Double) = buffer.appendDouble(value) 42 | } 43 | implicit object FloatElem extends BufferType[Float] { 44 | override def appendToBuffer(buffer: JBuffer, value: Float) = buffer.appendFloat(value) 45 | } 46 | implicit object IntElem extends BufferType[Int] { 47 | override def appendToBuffer(buffer: JBuffer, value: Int) = buffer.appendInt(value) 48 | } 49 | implicit object LongElem extends BufferType[Long] { 50 | override def appendToBuffer(buffer: JBuffer, value: Long) = buffer.appendLong(value) 51 | } 52 | implicit object ShortElem extends BufferType[Short] { 53 | override def appendToBuffer(buffer: JBuffer, value: Short) = buffer.appendShort(value) 54 | } 55 | implicit object StringElem extends BufferType[String] { 56 | override def appendToBuffer(buffer: JBuffer, value: String) = buffer.appendString(value) 57 | } 58 | implicit object StringWithEncodingElem extends BufferType[(String, String)] { 59 | override def appendToBuffer(buffer: JBuffer, value: (String, String)) = buffer.appendString(value._1, value._2) 60 | } 61 | 62 | trait BufferSeekType[T] { 63 | def appendToBuffer(buffer: JBuffer, value: T, offset: Int, len: Int): JBuffer 64 | } 65 | implicit object BufferSeekElem extends BufferSeekType[Buffer] { 66 | override def appendToBuffer(buffer: JBuffer, value: Buffer, offset: Int, len: Int) = 67 | buffer.appendBuffer(value.asJava, offset, len) 68 | } 69 | implicit object BytesSeekElem extends BufferSeekType[Array[Byte]] { 70 | override def appendToBuffer(buffer: JBuffer, value: Array[Byte], offset: Int, len: Int) = 71 | buffer.appendBytes(value, offset, len) 72 | } 73 | 74 | def bufferHandlerToJava(handler: Buffer => Unit) = fnToHandler(handler.compose { jbuffer: JBuffer => Buffer.apply(jbuffer) }) 75 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/datagram/DatagramPacket.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.datagram 17 | 18 | import org.vertx.java.core.datagram.{ DatagramPacket => JDatagramPacket } 19 | import java.net.InetSocketAddress 20 | import org.vertx.scala.core.buffer.Buffer 21 | 22 | /** 23 | * A received Datagram packet (UDP) which contains the data and information about the sender of the data itself. 24 | * 25 | * @author Norman Maurer 26 | * @author Galder Zamarreño 27 | */ 28 | final class DatagramPacket private[scala] (val asJava: JDatagramPacket) extends AnyVal { 29 | 30 | /** 31 | * Returns the [[java.net.InetSocketAddress]] of the sender that send this 32 | * [[org.vertx.scala.core.datagram.DatagramPacket]]. 33 | */ 34 | def sender(): InetSocketAddress = asJava.sender() 35 | 36 | /** 37 | * Returns the data of the [[org.vertx.scala.core.datagram.DatagramPacket]] 38 | */ 39 | def data(): Buffer = Buffer(asJava.data()) 40 | 41 | } 42 | 43 | /** Factory for [[org.vertx.scala.core.datagram.DatagramPacket]] instances. */ 44 | object DatagramPacket { 45 | def apply(actual: JDatagramPacket) = new DatagramPacket(actual) 46 | } 47 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/datagram/InternetProtocolFamily.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.datagram 17 | 18 | import org.vertx.java.core.datagram.{InternetProtocolFamily => JInternetProtocolFamily} 19 | 20 | /** 21 | * Internet Protocol (IP) families used by [[org.vertx.scala.core.datagram.DatagramSocket]]. 22 | */ 23 | sealed trait InternetProtocolFamily 24 | case object IPv4 extends InternetProtocolFamily 25 | case object IPv6 extends InternetProtocolFamily 26 | 27 | object InternetProtocolFamily { 28 | implicit def toScalaIpFamily(family: JInternetProtocolFamily): InternetProtocolFamily = { 29 | family match { 30 | case JInternetProtocolFamily.IPv4 => IPv4 31 | case JInternetProtocolFamily.IPv6 => IPv6 32 | } 33 | } 34 | 35 | implicit def toJavaIpFamily(family: Option[InternetProtocolFamily]): Option[JInternetProtocolFamily] = { 36 | family match { 37 | case Some(IPv4) => Some(JInternetProtocolFamily.IPv4) 38 | case Some(IPv6) => Some(JInternetProtocolFamily.IPv6) 39 | case None => None 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/datagram/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import org.vertx.scala.core.FunctionConverters._ 19 | 20 | package object datagram { 21 | 22 | def dataPacketHandlerToJava(handler: DatagramPacket => Unit) = 23 | fnToHandler(handler.compose { DatagramPacket.apply }) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/dns/DnsException.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.dns 17 | 18 | case class DnsException(code: DnsResponseCode) extends Exception 19 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/dns/DnsResponseCode.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.dns 17 | 18 | import org.vertx.java.core.dns.{ DnsResponseCode => JDnsResponseCode } 19 | 20 | abstract sealed class DnsResponseCode(code: Int, message: String) { 21 | override def toString: String = getClass.getName + ": type " + code + ", " + message 22 | def toJava: JDnsResponseCode = JDnsResponseCode.valueOf(code) 23 | } 24 | 25 | object DnsResponseCode { 26 | def fromJava(x: JDnsResponseCode) = x.code() match { 27 | case 0 => NOERROR 28 | case 1 => FORMERROR 29 | case 2 => SERVFAIL 30 | case 3 => NXDOMAIN 31 | case 4 => NOTIMPL 32 | case 5 => REFUSED 33 | case 6 => YXDOMAIN 34 | case 7 => YXRRSET 35 | case 8 => NXRRSET 36 | case 9 => NOTAUTH 37 | case 10 => NOTZONE 38 | case 11 => BADVERS 39 | case 12 => BADSIG 40 | case 13 => BADKEY 41 | case 14 => BADTIME 42 | } 43 | } 44 | 45 | /** 46 | * ID 0, no error 47 | */ 48 | case object NOERROR extends DnsResponseCode(0, "no error") 49 | 50 | /** 51 | * ID 1, format error 52 | */ 53 | case object FORMERROR extends DnsResponseCode(1, "format error") 54 | 55 | /** 56 | * ID 2, server failure 57 | */ 58 | case object SERVFAIL extends DnsResponseCode(2, "server failure") 59 | 60 | /** 61 | * ID 3, name error 62 | */ 63 | case object NXDOMAIN extends DnsResponseCode(3, "name error") 64 | 65 | /** 66 | * ID 4, not implemented 67 | */ 68 | case object NOTIMPL extends DnsResponseCode(4, "not implemented") 69 | 70 | /** 71 | * ID 5, operation refused 72 | */ 73 | case object REFUSED extends DnsResponseCode(5, "operation refused") 74 | 75 | /** 76 | * ID 6, domain name should not exist 77 | */ 78 | case object YXDOMAIN extends DnsResponseCode(6, "domain name should not exist") 79 | 80 | /** 81 | * ID 7, resource record set should not exist 82 | */ 83 | case object YXRRSET extends DnsResponseCode(7, "resource record set should not exist") 84 | 85 | /** 86 | * ID 8, rrset does not exist 87 | */ 88 | case object NXRRSET extends DnsResponseCode(8, "rrset does not exist") 89 | 90 | /** 91 | * ID 9, not authoritative for zone 92 | */ 93 | case object NOTAUTH extends DnsResponseCode(9, "not authoritative for zone") 94 | 95 | /** 96 | * ID 10, name not in zone 97 | */ 98 | case object NOTZONE extends DnsResponseCode(10, "name not in zone") 99 | 100 | /** 101 | * ID 11, bad extension mechanism for version 102 | */ 103 | case object BADVERS extends DnsResponseCode(11, "bad extension mechanism for version") 104 | 105 | /** 106 | * ID 12, bad signature 107 | */ 108 | case object BADSIG extends DnsResponseCode(12, "bad signature") 109 | 110 | /** 111 | * ID 13, bad key 112 | */ 113 | case object BADKEY extends DnsResponseCode(13, "bad key") 114 | 115 | /** 116 | * ID 14, bad timestamp 117 | */ 118 | case object BADTIME extends DnsResponseCode(14, "bad timestamp") 119 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/dns/MxRecord.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.dns 17 | 18 | import org.vertx.java.core.dns.{ MxRecord => JMxRecord } 19 | 20 | /** 21 | * Represent a Mail-Exchange-Record (MX) which was resolved for a domain. 22 | * 23 | * @author Norman Maurer 24 | * @author Joern Bernhardt 25 | * @author Galder Zamarreño 26 | */ 27 | final class MxRecord private[scala] (val asJava: JMxRecord) extends AnyVal { 28 | 29 | /** 30 | * The priority of the MX record. 31 | */ 32 | def priority(): Int = asJava.priority() 33 | 34 | /** 35 | * The name of the MX record 36 | */ 37 | def name(): String = asJava.name() 38 | 39 | } 40 | 41 | /** Factory for [[org.vertx.scala.core.dns.MxRecord]] instances. */ 42 | object MxRecord { 43 | def apply(internal: JMxRecord) = new MxRecord(internal) 44 | } 45 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/dns/SrvRecord.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.dns 17 | 18 | import org.vertx.java.core.dns.{ SrvRecord => JSrvRecord } 19 | 20 | /** 21 | * Represent a Service-Record (SRV) which was resolved for a domain. 22 | * 23 | * @author Norman Maurer 24 | * @author Joern Bernhardt 25 | */ 26 | final class SrvRecord private[scala] (val asJava: JSrvRecord) extends AnyVal { 27 | 28 | /** 29 | * Returns the priority for this service record. 30 | */ 31 | def priority(): Int = asJava.priority() 32 | 33 | /** 34 | * Returns the weight of this service record. 35 | */ 36 | def weight(): Int = asJava.weight() 37 | 38 | /** 39 | * Returns the port the service is running on. 40 | */ 41 | def port(): Int = asJava.port() 42 | 43 | /** 44 | * Returns the name for the server being queried. 45 | */ 46 | def name(): String = asJava.name() 47 | 48 | /** 49 | * Returns the protocol for the service being queried (i.e. "_tcp"). 50 | */ 51 | def protocol(): String = asJava.protocol() 52 | 53 | /** 54 | * Returns the service's name (i.e. "_http"). 55 | */ 56 | def service(): String = asJava.service() 57 | 58 | /** 59 | * Returns the name of the host for the service. 60 | */ 61 | def target(): String = asJava.target() 62 | } 63 | 64 | /** Factory for [[org.vertx.scala.core.dns.SrvRecord]] instances. */ 65 | object SrvRecord { 66 | def apply(internal: JSrvRecord) = new SrvRecord(internal) 67 | } 68 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/eventbus/Message.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.eventbus 17 | 18 | import org.vertx.java.core.eventbus.{ Message => JMessage } 19 | import org.vertx.scala.core.FunctionConverters._ 20 | import org.vertx.scala.core.AsyncResult 21 | import org.vertx.scala.core.Handler 22 | 23 | /** 24 | * Represents a message on the event bus.

25 | * 26 | * Instances of this class are not thread-safe

27 | * 28 | * @author Tim Fox 29 | * @author Joern Bernhardt 30 | * @author Galder Zamarreño 31 | */ 32 | final class Message[T <% MessageData] private[scala] (val asJava: JMessage[T]) { 33 | 34 | /** 35 | * The address the message was sent to 36 | */ 37 | def address(): String = asJava.address() 38 | 39 | /** 40 | * The body of the message. 41 | */ 42 | def body(): T = anyToMessageData(asJava.body()).data.asInstanceOf[T] 43 | 44 | /** 45 | * The reply address (if any). 46 | * 47 | * @return An optional String containing the reply address. 48 | */ 49 | def replyAddress(): Option[String] = Option(asJava.replyAddress()) 50 | 51 | /** 52 | * Reply to this message. If the message was sent specifying a reply handler, that handler will be 53 | * called when it has received a reply. If the message wasn't sent specifying a receipt handler 54 | * this method does nothing. 55 | */ 56 | def reply(): Unit = asJava.reply() 57 | 58 | /** 59 | * Reply to this message. If the message was sent specifying a reply handler, that handler will be 60 | * called when it has received a reply. If the message wasn't sent specifying a receipt handler 61 | * this method does nothing. 62 | * 63 | * @param value The data to send with the reply. 64 | */ 65 | def reply(value: MessageData): Unit = value.reply(asJava) 66 | 67 | /** 68 | * The same as [[org.vertx.scala.core.eventbus.Message.reply(MessageData)]] but you can specify handler for the reply - i.e. 69 | * to receive the reply to the reply. 70 | * 71 | * @param value The value to send. 72 | * @param handler Handling the reply. 73 | */ 74 | def reply[B <% MessageData](value: MessageData, handler: Message[B] => Unit): Unit = value.reply(asJava, fnToHandler(handler.compose(Message.apply))) 75 | 76 | /** 77 | * The same as {@code reply()} but you can specify handler for the reply - i.e. 78 | * to receive the reply to the reply. 79 | * 80 | * @param handler Handling the reply. 81 | */ 82 | def reply[B <% MessageData](handler: Message[B] => Unit): Unit = asJava.reply(messageFnToJMessageHandler(handler)) 83 | 84 | /** 85 | * Reply to this message. Specifying a timeout and a reply handler. 86 | * 87 | * @param timeout The timeout in ms to wait for an answer. 88 | * @param replyHandler Handling the reply (success) or the timeout (failed). 89 | */ 90 | def replyWithTimeout[T <% MessageData](timeout: Long, replyHandler: AsyncResult[Message[T]] => Unit): Unit = 91 | asJava.replyWithTimeout(timeout, asyncResultConverter({ x: JMessage[T] => Message.apply(x) })(replyHandler)) 92 | 93 | /** 94 | * Reply to this message with data. Specifying a timeout and a reply handler. 95 | * 96 | * @param value The value to send. 97 | * @param timeout The timeout in ms to wait for an answer. 98 | * @param replyHandler Handling the reply (success) or the timeout (failed). 99 | */ 100 | def replyWithTimeout[T <% MessageData](value: MessageData, timeout: Long, replyHandler: AsyncResult[Message[T]] => Unit): Unit = 101 | value.replyWithTimeout(asJava, timeout, convertArHandler(replyHandler)) 102 | 103 | /** 104 | * Signal that processing of this message failed. If the message was sent specifying a result handler 105 | * the handler will be called with a failure corresponding to the failure code and message specified here 106 | * @param failureCode A failure code to pass back to the sender 107 | * @param message A message to pass back to the sender 108 | */ 109 | def fail(failureCode: Int, message: String): Unit = asJava.fail(failureCode, message) 110 | 111 | private def convertArHandler[T <% MessageData](handler: AsyncResult[Message[T]] => Unit): Handler[AsyncResult[JMessage[T]]] = { 112 | asyncResultConverter({x: JMessage[T] => Message.apply(x)})(handler) 113 | } 114 | } 115 | 116 | /** 117 | * Companion object for Message. 118 | * 119 | * @author pidster 120 | * @author Joern Bernhardt 121 | */ 122 | object Message { 123 | def apply[X <% MessageData](jmessage: JMessage[X]): Message[X] = new Message(jmessage) 124 | } 125 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/eventbus/RegisteredHandler.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.core.eventbus 2 | 3 | import org.vertx.java.core.{ Handler => JHandler } 4 | import org.vertx.java.core.eventbus.{ Message => JMessage } 5 | import org.vertx.scala.core._ 6 | import org.vertx.scala.core.FunctionConverters._ 7 | 8 | /** 9 | * A RegisteredHandler can be unregistered at a later point in time. 10 | * @param address The address the handler is listening on. 11 | * @param handler The (java) handler that is registered at the address. 12 | * @param eventbus The event bus where this handler is registered 13 | * 14 | * @author Joern Bernhardt 15 | * @author Galder Zamarreño 16 | */ 17 | case class RegisteredHandler[X <% MessageData] private[scala] 18 | (address: String, handler: JHandler[JMessage[X]], eventbus: EventBus) { 19 | 20 | /** 21 | * Unregisters the registered handler from the event bus. 22 | */ 23 | def unregister(): Unit = eventbus.asJava.unregisterHandler(address, handler) 24 | 25 | /** 26 | * Unregisters the registered handler from the event bus. 27 | * @param resultHandler Fires when the unregistration event propagated through the whole cluster. 28 | */ 29 | def unregister(resultHandler: AsyncResult[Void] => Unit): Unit = 30 | eventbus.asJava.unregisterHandler(address, handler, resultHandler) 31 | 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/eventbus/SendOrPublish.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.eventbus 17 | 18 | import org.vertx.scala.core._ 19 | import org.vertx.java.core.eventbus.{ Message => JMessage } 20 | 21 | /** 22 | * Send/Publish message wrappers. 23 | * 24 | * @author Joern Bernhardt 25 | * @author Galder Zamarreño 26 | */ 27 | private[eventbus] trait SendOrPublish 28 | private case class Publish(address: String, value: MessageData) extends SendOrPublish 29 | private case class Send[X](address: String, value: MessageData, 30 | replyHandler: Option[Either[Handler[JMessage[X]], Handler[AsyncResult[JMessage[X]]]]]) 31 | extends SendOrPublish 32 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/file/AsyncFile.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.file 17 | 18 | import org.vertx.java.core.file.{ AsyncFile => JAsyncFile } 19 | import org.vertx.scala.core.buffer._ 20 | import org.vertx.java.core.buffer.{ Buffer => JBuffer } 21 | import org.vertx.scala.core.{Closeable, AsyncResult} 22 | import org.vertx.scala.core.FunctionConverters._ 23 | import org.vertx.scala.core.streams.{WriteStream, ReadStream} 24 | import org.vertx.scala.Self 25 | 26 | /** 27 | * Represents a file on the file-system which can be read from, or written to asynchronously.

28 | * This class also implements [[org.vertx.scala.core.streams.ReadStream]] and 29 | * [[org.vertx.scala.core.streams.WriteStream]]. This allows the data to be pumped to and from 30 | * other streams, e.g. an [[org.vertx.scala.core.http.HttpClientRequest]] instance, 31 | * using the [[org.vertx.scala.core.streams.Pump]] class

32 | * Instances of AsyncFile are not thread-safe

33 | * 34 | * @author Tim Fox 35 | * @author Edgar Chan 36 | * @author swilliams 37 | * @author Joern Bernhardt 38 | * @author Galder Zamarreño 39 | */ 40 | final class AsyncFile private[scala] (val asJava: JAsyncFile) extends Self 41 | with ReadStream 42 | with WriteStream 43 | with Closeable { 44 | 45 | override type J = JAsyncFile 46 | 47 | /** 48 | * Write a [[org.vertx.scala.core.buffer.Buffer]] to the file at position `position` in the file, asynchronously. 49 | * If `position` lies outside of the current size 50 | * of the file, the file will be enlarged to encompass it.

51 | * When multiple writes are invoked on the same file 52 | * there are no guarantees as to order in which those writes actually occur.

53 | * The handler will be called when the write is complete, or if an error occurs. 54 | */ 55 | def write(buffer: Buffer, position: Int, handler: AsyncResult[Void] => Unit): AsyncFile = 56 | wrap(asJava.write(buffer.asJava, position, handler)) 57 | 58 | /** 59 | * Reads `length} bytes of data from the file at position `position` in the file, asynchronously. 60 | * The read data will be written into the specified `Buffer buffer} at position `offset`.

61 | * If data is read past the end of the file then zero bytes will be read.

62 | * When multiple reads are invoked on the same file there are no guarantees as to order in which those reads actually occur.

63 | * The handler will be called when the close is complete, or if an error occurs. 64 | */ 65 | def read(buffer: Buffer, offset: Int, position: Int, length: Int, handler: AsyncResult[Buffer] => Unit): AsyncFile = 66 | wrap(asJava.read(buffer.asJava, offset, position, length, asyncResultConverter { jbuf: JBuffer => Buffer.apply(jbuf) }(handler))) 67 | 68 | /** 69 | * Flush any writes made to this file to underlying persistent storage.

70 | * If the file was opened with `flush` set to `true` then calling this method will have no effect.

71 | * The actual flush will happen asynchronously. 72 | */ 73 | def flush(): AsyncFile = wrap(asJava.flush()) 74 | 75 | /** 76 | * Same as [[org.vertx.scala.core.file.AsyncFile.flush]] but the handler will be called when the flush is complete or if an error occurs 77 | */ 78 | def flush(handler: AsyncResult[Void] => Unit): AsyncFile = wrap(asJava.flush(handler)) 79 | 80 | } 81 | 82 | /** Factory for [[org.vertx.scala.core.file.AsyncFile]] instances. */ 83 | object AsyncFile { 84 | def apply(internal: JAsyncFile) = new AsyncFile(internal) 85 | } 86 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/file/FileProps.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.file 17 | 18 | import org.vertx.java.core.file.{ FileProps => JFileProps } 19 | import java.util.Date 20 | 21 | /** 22 | * Represents properties of a file on the file system

23 | * Instances of FileProps are thread-safe

24 | * 25 | * @author Tim Fox 26 | * @author Joern Bernhardt 27 | * @author Galder Zamarreño 28 | */ 29 | final class FileProps private[scala] (val asJava: JFileProps) extends AnyVal { 30 | 31 | /** 32 | * The date the file was created 33 | */ 34 | def creationTime(): Date = asJava.creationTime() 35 | 36 | /** 37 | * The date the file was last accessed 38 | */ 39 | def lastAccessTime(): Date = asJava.lastAccessTime() 40 | 41 | /** 42 | * The date the file was last modified 43 | */ 44 | def lastModifiedTime(): Date = asJava.lastModifiedTime() 45 | 46 | /** 47 | * Is the file a directory? 48 | */ 49 | def isDirectory: Boolean = asJava.isDirectory 50 | 51 | /** 52 | * Is the file some other type? (I.e. not a directory, regular file or symbolic link) 53 | */ 54 | def isOther: Boolean = asJava.isOther 55 | 56 | /** 57 | * Is the file a regular file? 58 | */ 59 | def isRegularFile: Boolean = asJava.isRegularFile 60 | 61 | /** 62 | * Is the file a symbolic link? 63 | */ 64 | def isSymbolicLink: Boolean = asJava.isSymbolicLink 65 | 66 | /** 67 | * The size of the file, in bytes 68 | */ 69 | def size(): Long = asJava.size() 70 | } 71 | 72 | /** Factory for [[org.vertx.scala.core.file.FileProps]] instances. */ 73 | object FileProps { 74 | def apply(internal: JFileProps) = new FileProps(internal) 75 | } 76 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/file/FileSystemProps.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.file 17 | 18 | import org.vertx.java.core.file.{ FileSystemProps => JFileSystemProps } 19 | 20 | /** 21 | * Represents properties of the file system.

22 | * Instances of FileSystemProps are thread-safe.

23 | * 24 | * @author Tim Fox 25 | * @author Joern Bernhardt 26 | * @author Galder Zamarreño 27 | */ 28 | final class FileSystemProps private[scala] (val asJava: JFileSystemProps) extends AnyVal { 29 | 30 | /** 31 | * The total space on the file system, in bytes 32 | */ 33 | def totalSpace(): Long = asJava.totalSpace() 34 | 35 | /** 36 | * The total un-allocated space on the file system, in bytes 37 | */ 38 | def unallocatedSpace(): Long = asJava.unallocatedSpace() 39 | 40 | /** 41 | * The total usable space on the file system, in bytes 42 | */ 43 | def usableSpace(): Long = asJava.usableSpace() 44 | 45 | } 46 | 47 | /** Factory for [[org.vertx.scala.core.file.FileSystemProps]] instances. */ 48 | object FileSystemProps { 49 | def apply(internal: JFileSystemProps) = new FileSystemProps(internal) 50 | } 51 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/http/HttpClientResponse.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.http 18 | 19 | import org.vertx.java.core.http.{ HttpClientResponse => JHttpClientResponse } 20 | import org.vertx.scala.core.MultiMap 21 | import org.vertx.scala.core.buffer._ 22 | import org.vertx.scala.core.net.NetSocket 23 | import org.vertx.scala.core.streams.ReadStream 24 | import org.vertx.scala.Self 25 | import scala.collection.JavaConverters._ 26 | 27 | /** 28 | * Represents a client-side HTTP response.

29 | * An instance is provided to the user via a [[org.vertx.java.core.Handler]] 30 | * instance that was specified when one of the HTTP method operations, or the 31 | * generic [[org.vertx.scala.core.http.HttpClient.request(String, String, org.vertx.java.core.Handler)]] 32 | * method was called on an instance of [[org.vertx.scala.core.http.HttpClient]].

33 | * It implements [[org.vertx.scala.core.streams.ReadStream]] so it can be used with 34 | * [[org.vertx.scala.core.streams.Pump]] to pump data with flow control.

35 | * Instances of this class are not thread-safe.

36 | * 37 | * @author Tim Fox 38 | * @author swilliams 39 | * @author Joern Bernhardt 40 | */ 41 | class HttpClientResponse private[scala] (val asJava: JHttpClientResponse) extends Self 42 | with ReadStream { 43 | 44 | override type J = JHttpClientResponse 45 | 46 | /** 47 | * Returns the HTTP status code of the response. 48 | * 49 | * @return The HTTP status code of the response. 50 | */ 51 | def statusCode(): Int = asJava.statusCode 52 | 53 | /** 54 | * Returns the HTTP status message of the response. 55 | * 56 | * @return The HTTP status message of the response. 57 | */ 58 | def statusMessage(): String = asJava.statusMessage 59 | 60 | /** 61 | * Returns the HTTP headers. 62 | * 63 | * This method converts a Java collection into a Scala collection every 64 | * time it gets called, so use it sensibly. 65 | * 66 | * @return The HTTP headers. 67 | */ 68 | def headers(): MultiMap = multiMapToScalaMultiMap(asJava.headers) 69 | 70 | /** 71 | * Returns the HTTP trailers. 72 | * 73 | * This method converts a Java collection into a Scala collection every 74 | * time it gets called, so call it sensibly. 75 | * 76 | * @return The HTTP trailers. 77 | */ 78 | def trailers(): MultiMap = multiMapToScalaMultiMap(asJava.trailers) 79 | 80 | /** 81 | * Returns the Set-Cookie headers (including trailers). 82 | * 83 | * @return The Set-Cookie headers (including trailers). 84 | */ 85 | def cookies(): List[String] = asJava.cookies().asScala.toList 86 | 87 | /** 88 | * Convenience method for receiving the entire request body in one piece. This saves the user having to manually 89 | * set a data and end handler and append the chunks of the body until the whole body received. 90 | * Don't use this if your request body is large - you could potentially run out of RAM. 91 | * 92 | * @param handler This handler will be called after all the body has been received. 93 | */ 94 | def bodyHandler(handler: Buffer => Unit): HttpClientResponse = 95 | wrap(asJava.bodyHandler(bufferHandlerToJava(handler))) 96 | 97 | /** 98 | * Get a net socket for the underlying connection of this request. USE THIS WITH CAUTION! 99 | * Writing to the socket directly if you don't know what you're doing can easily break the HTTP protocol. 100 | * 101 | * One valid use-case for calling this is to receive the [[NetSocket]] after a HTTP CONNECT was issued to the 102 | * remote peer and it responded with a status code of 200. 103 | * 104 | * @return the net socket 105 | */ 106 | def netSocket(): NetSocket = NetSocket(asJava.netSocket()) 107 | 108 | } 109 | 110 | /** Factory for [[org.vertx.scala.core.http.HttpClient]] instances by wrapping a Java instance. */ 111 | object HttpClientResponse { 112 | def apply(internal: JHttpClientResponse) = new HttpClientResponse(internal) 113 | } 114 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/http/HttpServerFileUpload.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.http 17 | 18 | import org.vertx.java.core.http.{ HttpServerFileUpload => JHttpServerFileUpload } 19 | import java.nio.charset.Charset 20 | import org.vertx.scala.Self 21 | import org.vertx.scala.core.streams.ReadStream 22 | 23 | /** 24 | * @author Galder Zamarreño 25 | */ 26 | final class HttpServerFileUpload private[scala] (val asJava: JHttpServerFileUpload) extends Self 27 | with ReadStream { 28 | 29 | override type J = JHttpServerFileUpload 30 | 31 | /** 32 | * Stream the content of this upload to the given filename. 33 | */ 34 | def streamToFileSystem(filename: String): HttpServerFileUpload = 35 | wrap(asJava.streamToFileSystem(filename)) 36 | 37 | /** 38 | * Returns the filename which was used when upload the file. 39 | */ 40 | def filename(): String = asJava.filename() 41 | 42 | /** 43 | * Returns the name of the attribute 44 | */ 45 | def name(): String = asJava.name() 46 | 47 | /** 48 | * Returns the contentType for the upload 49 | */ 50 | def contentType(): String = asJava.contentType() 51 | 52 | /** 53 | * Returns the contentTransferEncoding for the upload 54 | */ 55 | def contentTransferEncoding(): String = asJava.contentTransferEncoding() 56 | 57 | /** 58 | * Returns the charset for the upload 59 | */ 60 | def charset(): Charset = asJava.charset() 61 | 62 | /** 63 | * Returns the size of the upload (in bytes) 64 | */ 65 | def size(): Long = asJava.size() 66 | 67 | } 68 | 69 | object HttpServerFileUpload { 70 | def apply(internal: JHttpServerFileUpload) = new HttpServerFileUpload(internal) 71 | } 72 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/http/RouteMatcher.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.http 18 | 19 | import org.vertx.java.core.Handler 20 | import org.vertx.java.core.http.{ RouteMatcher => JRouteMatcher } 21 | import org.vertx.scala.core.FunctionConverters._ 22 | import org.vertx.scala.Self 23 | 24 | /** 25 | * Not sure whether this kind of RouteMatcher should stay in Scala... 26 | * 27 | * @author swilliams 28 | * @author Joern Bernhardt 29 | * @author Galder Zamarreño 30 | */ 31 | class RouteMatcher private[scala] (val asJava: JRouteMatcher = new JRouteMatcher()) extends Handler[HttpServerRequest] 32 | with (HttpServerRequest => Unit) 33 | with Self { 34 | 35 | def all(uri: String, handler: HttpServerRequest => Unit): RouteMatcher = 36 | wrap(asJava.all(uri, wrapHandler(handler))) 37 | 38 | def allWithRegEx(regex: String, handler: HttpServerRequest => Unit): RouteMatcher = 39 | wrap(asJava.allWithRegEx(regex, wrapHandler(handler))) 40 | 41 | def apply(request: HttpServerRequest): Unit = handle(request) 42 | 43 | def connect(uri: String, handler: HttpServerRequest => Unit): RouteMatcher = 44 | wrap(asJava.connect(uri, wrapHandler(handler))) 45 | 46 | def connectWithRegEx(regex: String, handler: HttpServerRequest => Unit): RouteMatcher = 47 | wrap(asJava.connectWithRegEx(regex, wrapHandler(handler))) 48 | 49 | def delete(uri: String, handler: HttpServerRequest => Unit): RouteMatcher = 50 | wrap(asJava.delete(uri, wrapHandler(handler))) 51 | 52 | def deleteWithRegEx(regex: String, handler: HttpServerRequest => Unit): RouteMatcher = 53 | wrap(asJava.deleteWithRegEx(regex, wrapHandler(handler))) 54 | 55 | def get(uri: String, handler: HttpServerRequest => Unit): RouteMatcher = 56 | wrap(asJava.get(uri, wrapHandler(handler))) 57 | 58 | def getWithRegEx(regex: String, handler: HttpServerRequest => Unit): RouteMatcher = 59 | wrap(asJava.getWithRegEx(regex, wrapHandler(handler))) 60 | 61 | def handle(request: HttpServerRequest): Unit = asJava.handle(request.asJava) 62 | 63 | def head(uri: String, handler: HttpServerRequest => Unit): RouteMatcher = 64 | wrap(asJava.head(uri, wrapHandler(handler))) 65 | 66 | def headWithRegEx(regex: String, handler: HttpServerRequest => Unit): RouteMatcher = 67 | wrap(asJava.headWithRegEx(regex, wrapHandler(handler))) 68 | 69 | def options(uri: String, handler: HttpServerRequest => Unit): RouteMatcher = 70 | wrap(asJava.options(uri, wrapHandler(handler))) 71 | 72 | def optionsWithRegEx(regex: String, handler: HttpServerRequest => Unit): RouteMatcher = 73 | wrap(asJava.optionsWithRegEx(regex, wrapHandler(handler))) 74 | 75 | def patch(uri: String, handler: HttpServerRequest => Unit): RouteMatcher = 76 | wrap(asJava.patch(uri, wrapHandler(handler))) 77 | 78 | def patchWithRegEx(regex: String, handler: HttpServerRequest => Unit): RouteMatcher = 79 | wrap(asJava.patchWithRegEx(regex, wrapHandler(handler))) 80 | 81 | def post(uri: String, handler: HttpServerRequest => Unit): RouteMatcher = 82 | wrap(asJava.post(uri, wrapHandler(handler))) 83 | 84 | def postWithRegEx(regex: String, handler: HttpServerRequest => Unit): RouteMatcher = 85 | wrap(asJava.postWithRegEx(regex, wrapHandler(handler))) 86 | 87 | def put(uri: String, handler: HttpServerRequest => Unit): RouteMatcher = 88 | wrap(asJava.put(uri, wrapHandler(handler))) 89 | 90 | def putWithRegEx(regex: String, handler: HttpServerRequest => Unit): RouteMatcher = 91 | wrap(asJava.putWithRegEx(regex, wrapHandler(handler))) 92 | 93 | def trace(uri: String, handler: HttpServerRequest => Unit): RouteMatcher = 94 | wrap(asJava.trace(uri, wrapHandler(handler))) 95 | 96 | def traceWithRegEx(regex: String, handler: HttpServerRequest => Unit): RouteMatcher = 97 | wrap(asJava.traceWithRegEx(regex, wrapHandler(handler))) 98 | 99 | private def wrapHandler(handler: HttpServerRequest => Unit) = 100 | fnToHandler(handler.compose(HttpServerRequest.apply)) 101 | 102 | } 103 | 104 | /** Factory for [[org.vertx.scala.core.http.RouteMatcher]] instances. */ 105 | object RouteMatcher { 106 | def apply(actual: JRouteMatcher): RouteMatcher = new RouteMatcher(actual) 107 | def apply(): RouteMatcher = new RouteMatcher() 108 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/http/ServerWebSocket.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.http 18 | 19 | import org.vertx.java.core.http.{ ServerWebSocket => JServerWebSocket } 20 | import org.vertx.scala.Self 21 | import org.vertx.scala.core.MultiMap 22 | 23 | /** 24 | * Represents a server side WebSocket that is passed into a the websocketHandler of an [[org.vertx.scala.core.http.HttpServer]]

25 | * Instances of this class are not thread-safe

26 | * 27 | * @author Tim Fox 28 | * @author swilliams 29 | * @author Galder Zamarreño 30 | * @author Joern Bernhardt 31 | */ 32 | final class ServerWebSocket private[scala] (val asJava: JServerWebSocket) extends Self 33 | with WebSocketBase { 34 | 35 | override type J = JServerWebSocket 36 | 37 | /** 38 | * The uri the websocket handshake occurred at 39 | */ 40 | def uri(): String = asJava.uri() 41 | 42 | /** 43 | * The path the websocket is attempting to connect at 44 | */ 45 | def path(): String = asJava.path() 46 | 47 | /** 48 | * The query string passed on the websocket uri 49 | */ 50 | def query(): String = asJava.query() 51 | 52 | /** 53 | * A map of all headers in the request to upgrade to websocket 54 | */ 55 | def headers(): MultiMap = multiMapToScalaMultiMap(asJava.headers()) 56 | 57 | /** 58 | * Reject the WebSocket

59 | * Calling this method from the websocketHandler gives you the opportunity to reject 60 | * the websocket, which will cause the websocket handshake to fail by returning 61 | * a 404 response code.

62 | * You might use this method, if for example you only want to accept websockets 63 | * with a particular path. 64 | */ 65 | def reject(): ServerWebSocket = wrap(asJava.reject()) 66 | } 67 | 68 | /** Factory for [[org.vertx.scala.core.http.ServerWebSocket]] instances. */ 69 | object ServerWebSocket { 70 | def apply(socket: JServerWebSocket) = new ServerWebSocket(socket) 71 | def unapply(socket: ServerWebSocket): JServerWebSocket = socket.asJava 72 | } 73 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/http/WebSocket.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.http 18 | 19 | import org.vertx.java.core.http.{ WebSocket => JWebSocket } 20 | import org.vertx.scala.Self 21 | 22 | /** 23 | * Represents a client side WebSocket.

24 | * Instances of this class are not thread-safe

25 | * 26 | * @author Tim Fox 27 | * @author swilliams 28 | * @author Galder Zamarreño 29 | * @author Joern Bernhardt 30 | */ 31 | final class WebSocket private[scala] (val asJava: JWebSocket) extends Self 32 | with WebSocketBase { 33 | 34 | override type J = JWebSocket 35 | 36 | } 37 | 38 | /** Factory for [[org.vertx.scala.core.http.WebSocket]] instances. */ 39 | object WebSocket { 40 | def apply(jsocket: JWebSocket) = new WebSocket(jsocket) 41 | } 42 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/http/WebSocketBase.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.core.http 2 | 3 | import org.vertx.java.core.http.{ WebSocketBase => JWebSocketBase } 4 | import org.vertx.scala.core.streams.{ WriteStream, ReadStream } 5 | import org.vertx.scala.core.FunctionConverters._ 6 | import org.vertx.scala.core.buffer.Buffer 7 | import org.vertx.scala.Self 8 | import java.net.InetSocketAddress 9 | 10 | /** 11 | * Represents an HTML 5 Websocket

12 | * Instances of this class are created and provided to the handler of an 13 | * [[org.vertx.scala.core.http.HttpClient]] when a successful websocket connect attempt occurs.

14 | * On the server side, the subclass [[org.vertx.scala.core.http.ServerWebSocket]] is used instead.

15 | * It implements both [[org.vertx.scala.core.streams.ReadStream]] and [[org.vertx.scala.core.streams.WriteStream]] so it can be used with 16 | * [[org.vertx.scala.core.streams.Pump]] to pump data with flow control.

17 | * Instances of this class are not thread-safe

18 | * 19 | * @author Tim Fox 20 | * @author Joern Bernhardt 21 | * @author Galder Zamarreño 22 | */ 23 | trait WebSocketBase extends Self 24 | with ReadStream 25 | with WriteStream { 26 | 27 | override type J <: JWebSocketBase[J] 28 | 29 | /** 30 | * When a `Websocket` is created it automatically registers an event handler with the eventbus, the ID of that 31 | * handler is given by `binaryHandlerID`.

32 | * Given this ID, a different event loop can send a binary frame to that event handler using the event bus and 33 | * that buffer will be received by this instance in its own event loop and written to the underlying connection. This 34 | * allows you to write data to other websockets which are owned by different event loops. 35 | */ 36 | def binaryHandlerID(): String = asJava.binaryHandlerID() 37 | 38 | /** 39 | * Close the websocket 40 | */ 41 | def close(): Unit = asJava.close() 42 | 43 | /** 44 | * Set a closed handler on the connection 45 | */ 46 | def closeHandler(handler: => Unit): this.type = wrap(asJava.closeHandler(handler)) 47 | 48 | /** 49 | * When a `Websocket} is created it automatically registers an event handler with the eventbus, the ID of that 50 | * handler is given by `textHandlerID}.

51 | * Given this ID, a different event loop can send a text frame to that event handler using the event bus and 52 | * that buffer will be received by this instance in its own event loop and written to the underlying connection. This 53 | * allows you to write data to other websockets which are owned by different event loops. 54 | */ 55 | def textHandlerID(): String = asJava.textHandlerID() 56 | 57 | /** 58 | * Write `data` to the websocket as a binary frame 59 | */ 60 | def writeBinaryFrame(data: Buffer): this.type = wrap(asJava.writeBinaryFrame(data.asJava)) 61 | 62 | /** 63 | * Write `str` to the websocket as a text frame 64 | */ 65 | def writeTextFrame(str: String): this.type = wrap(asJava.writeTextFrame(str)) 66 | 67 | /** 68 | * Return the remote address for this socket 69 | */ 70 | def remoteAddress(): InetSocketAddress = asJava.remoteAddress() 71 | 72 | /** 73 | * Return the local address for this socket 74 | */ 75 | def localAddress(): InetSocketAddress = asJava.localAddress() 76 | 77 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/http/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core 18 | 19 | import org.vertx.java.core.{ MultiMap => JMultiMap } 20 | import scala.collection.mutable 21 | import org.vertx.java.core.http.CaseInsensitiveMultiMap 22 | 23 | package object http { 24 | 25 | type HttpVersion = org.vertx.java.core.http.HttpVersion 26 | type WebSocketVersion = org.vertx.java.core.http.WebSocketVersion 27 | 28 | import scala.language.implicitConversions 29 | 30 | /** 31 | * Implicit conversion for [[org.vertx.java.core.MultiMap]] to [[scala.collection.mutable.MultiMap]]. 32 | */ 33 | implicit def multiMapToScalaMultiMap(n: JMultiMap): mutable.MultiMap[String, String] = { 34 | new JMultiMapWrapper(n) 35 | } 36 | 37 | /** 38 | * Implicit conversion for [[scala.collection.mutable.MultiMap]] to [[org.vertx.java.core.MultiMap]]. 39 | */ 40 | implicit def scalaMultiMapToMultiMap(n: mutable.MultiMap[String, String]): JMultiMap = { 41 | val jmultiMap = new CaseInsensitiveMultiMap 42 | n.foreach { entry => jmultiMap.put(entry._1, entry._2)} 43 | jmultiMap 44 | } 45 | 46 | private class JMultiMapWrapper(val underlying: JMultiMap) extends mutable.MultiMap[String, String] { 47 | 48 | override def addBinding(key: String, value: String): this.type = { 49 | underlying.add(key, value) 50 | this 51 | } 52 | 53 | override def removeBinding(key: String, value: String): this.type = { 54 | val it = underlying.iterator() 55 | while (it.hasNext) { 56 | val next = it.next() 57 | if (next.getKey.equalsIgnoreCase(key) && next.getValue == value) 58 | it.remove() 59 | } 60 | this 61 | } 62 | 63 | override def entryExists(key: String, p: (String) => Boolean): Boolean = { 64 | val it = underlying.iterator() 65 | while (it.hasNext) { 66 | val next = it.next() 67 | if (next.getKey.equalsIgnoreCase(key) && p(next.getValue)) 68 | return true 69 | } 70 | false 71 | } 72 | 73 | override def iterator: Iterator[(String, mutable.Set[String])] = { 74 | val mm = new mutable.HashMap[String, mutable.Set[String]] with MultiMap 75 | val it = underlying.iterator() 76 | while (it.hasNext) { 77 | val next = it.next() 78 | mm.addBinding(next.getKey, next.getValue) 79 | } 80 | mm.iterator 81 | } 82 | 83 | override def get(key: String): Option[mutable.Set[String]] = { 84 | val set = mutable.HashSet[String]() 85 | val it = underlying.iterator() 86 | while (it.hasNext) { 87 | val next = it.next() 88 | if (next.getKey.equalsIgnoreCase(key)) 89 | set.add(next.getValue) 90 | } 91 | if (seq.isEmpty) None else Some(set) 92 | } 93 | 94 | override def -=(key: String): this.type = { 95 | underlying.remove(key) 96 | this 97 | } 98 | 99 | override def +=(kv: (String, mutable.Set[String])): this.type = { 100 | kv._2.foreach { v => 101 | underlying.add(kv._1, v) 102 | } 103 | this 104 | } 105 | 106 | } 107 | 108 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/json/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core 17 | 18 | import scala.collection.mutable.Map 19 | 20 | /** 21 | * @author swilliams 22 | * @author Edgar Chan 23 | * 24 | */ 25 | package object json { 26 | 27 | type JsonElement = org.vertx.java.core.json.JsonElement 28 | type JsonArray = org.vertx.java.core.json.JsonArray 29 | type JsonObject = org.vertx.java.core.json.JsonObject 30 | 31 | import scala.language.implicitConversions 32 | 33 | implicit def toJsonObject(js: JsObject): JsonObject = js.internal 34 | 35 | implicit class JsObject(val internal: JsonObject) extends AnyVal { 36 | import scala.collection.JavaConverters._ 37 | def asMap: Map[String, AnyRef] = internal.toMap.asScala 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/logging/Logger.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.logging 17 | 18 | import org.vertx.java.core.logging.{ Logger => JLogger } 19 | 20 | /** 21 | * Small helper class to check for log level and delegate it to the real logger if enabled. 22 | * 23 | * @author Joern Bernhardt 24 | */ 25 | // constructor is private because users should use apply in companion 26 | // extends AnyVal to avoid object allocation and improve performance 27 | final class Logger private[scala] (val asJava: JLogger) extends AnyVal { 28 | 29 | def isInfoEnabled: Boolean = asJava.isInfoEnabled 30 | def isDebugEnabled: Boolean = asJava.isDebugEnabled 31 | def isTraceEnabled: Boolean = asJava.isTraceEnabled 32 | 33 | def trace(message: => AnyRef) = withTrace(asJava.trace(message)) 34 | def trace(message: => AnyRef, t: => Throwable) = withTrace(asJava.trace(message, t)) 35 | def debug(message: => AnyRef) = withDebug(asJava.debug(message)) 36 | def debug(message: => AnyRef, t: => Throwable) = withDebug(asJava.debug(message, t)) 37 | def info(message: => AnyRef) = withInfo(asJava.info(message)) 38 | def info(message: => AnyRef, t: => Throwable) = withInfo(asJava.info(message, t)) 39 | 40 | def warn(message: => AnyRef) = asJava.warn(message) 41 | def warn(message: => AnyRef, t: => Throwable) = asJava.warn(message, t) 42 | def error(message: => AnyRef) = asJava.error(message) 43 | def error(message: => AnyRef, t: => Throwable) = asJava.error(message, t) 44 | def fatal(message: => AnyRef) = asJava.fatal(message) 45 | def fatal(message: => AnyRef, t: => Throwable) = asJava.fatal(message, t) 46 | 47 | private def withTrace(fn: => Unit) = if (asJava.isTraceEnabled) { fn } 48 | private def withDebug(fn: => Unit) = if (asJava.isDebugEnabled) { fn } 49 | private def withInfo(fn: => Unit) = if (asJava.isInfoEnabled) { fn } 50 | 51 | } 52 | 53 | /** Factory for [[org.vertx.scala.core.logging.Logger]] instances. */ 54 | object Logger { 55 | def apply(internal: JLogger): Logger = new Logger(internal) 56 | } 57 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/net/NetClient.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.net 18 | 19 | import org.vertx.java.core.net.{ NetClient => JNetClient } 20 | import org.vertx.scala.core.FunctionConverters._ 21 | import org.vertx.scala.core.TCPSupport 22 | import org.vertx.scala.core.ClientSSLSupport 23 | import org.vertx.scala.core.AsyncResult 24 | import org.vertx.scala.Self 25 | 26 | /** 27 | * A TCP/SSL client.

28 | * Multiple connections to different servers can be made using the same instance.

29 | * This client supports a configurable number of connection attempts and a configurable delay 30 | * between attempts.

31 | * If an instance is instantiated from an event loop then the handlers of the instance will always 32 | * be called on that same event loop. If an instance is instantiated from some other arbitrary Java 33 | * thread (i.e. when using embedded) then an event loop will be assigned to the instance and used 34 | * when any of its handlers are called.

35 | * Instances of this class are thread-safe.

36 | * 37 | * @author Tim Fox 38 | * @author swilliams 39 | * @author Edgar Chan 40 | * @author Joern Bernhardt 41 | * @author Galder Zamarreño 42 | */ 43 | final class NetClient private[scala] (val asJava: JNetClient) extends Self 44 | with TCPSupport 45 | with ClientSSLSupport { 46 | 47 | override type J = JNetClient 48 | 49 | /** 50 | * Attempt to open a connection to a server at the specific `port` and host `localhost` 51 | * The connect is done asynchronously and on success, a 52 | * [[org.vertx.scala.core.net.NetSocket]] instance is supplied via the `connectHandler` instance. 53 | * 54 | * @return A reference to this so multiple method calls can be chained together. 55 | */ 56 | def connect(port: Int, connectCallback: AsyncResult[NetSocket] => Unit): NetClient = 57 | wrap(asJava.connect(port, arNetSocket(connectCallback))) 58 | 59 | /** 60 | * Attempt to open a connection to a server at the specific `port` and `host`. 61 | * `host` can be a valid host name or IP address. The connect is done asynchronously and on success, a 62 | * [[org.vertx.scala.core.net.NetSocket]] instance is supplied via the `connectHandler` instance. 63 | * 64 | * @return a reference to this so multiple method calls can be chained together 65 | */ 66 | def connect(port: Int, host: String, connectHandler: AsyncResult[NetSocket] => Unit): NetClient = 67 | wrap(asJava.connect(port, host, arNetSocket(connectHandler))) 68 | 69 | /** 70 | * Set the number of reconnection attempts. In the event a connection attempt fails, the client will attempt 71 | * to connect a further number of times, before it fails. Default value is zero. 72 | */ 73 | def setReconnectAttempts(attempts: Int): NetClient = 74 | wrap(asJava.setReconnectAttempts(attempts)) 75 | 76 | /** 77 | * Get the number of reconnect attempts. 78 | * 79 | * @return The number of reconnect attempts. 80 | */ 81 | def getReconnectAttempts: Int = asJava.getReconnectAttempts 82 | 83 | /** 84 | * Set the reconnect interval, in milliseconds. 85 | */ 86 | def setReconnectInterval(interval: Long): NetClient = 87 | wrap(asJava.setReconnectInterval(interval)) 88 | 89 | /** 90 | * Get the reconnect interval, in milliseconds. 91 | * 92 | * @return The reconnect interval in milliseconds. 93 | */ 94 | def getReconnectInterval: Long = asJava.getReconnectInterval 95 | 96 | /** 97 | * Set the connect timeout in milliseconds. 98 | * 99 | * @return a reference to this so multiple method calls can be chained together 100 | */ 101 | def setConnectTimeout(timeout: Int): NetClient = 102 | wrap(asJava.setConnectTimeout(timeout)) 103 | 104 | /** 105 | * Returns the connect timeout in milliseconds. 106 | * 107 | * @return The connect timeout in milliseconds. 108 | */ 109 | def getConnectTimeout: Int = asJava.getConnectTimeout 110 | 111 | /** 112 | * Close the client. Any sockets which have not been closed manually will be closed here. 113 | */ 114 | def close(): Unit = asJava.close() 115 | 116 | private def arNetSocket = asyncResultConverter(NetSocket.apply) _ 117 | } 118 | 119 | /** Factory for [[org.vertx.scala.core.net.NetClient]] instances. */ 120 | object NetClient { 121 | def apply(actual: JNetClient) = new NetClient(actual) 122 | } 123 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/net/NetServer.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.net 18 | 19 | import org.vertx.scala.core.FunctionConverters._ 20 | import org.vertx.java.core.net.{ NetServer => JNetServer } 21 | import org.vertx.java.core.AsyncResult 22 | import org.vertx.scala.core.ServerSSLSupport 23 | import org.vertx.scala.core.ServerTCPSupport 24 | import org.vertx.scala.core.Closeable 25 | import org.vertx.scala.Self 26 | 27 | /** 28 | * Represents a TCP or SSL server

29 | * If an instance is instantiated from an event loop then the handlers 30 | * of the instance will always be called on that same event loop. 31 | * If an instance is instantiated from some other arbitrary Java thread (i.e. when running embedded) then 32 | * and event loop will be assigned to the instance and used when any of its handlers 33 | * are called.

34 | * Instances of this class are thread-safe.

35 | * 36 | * @author Tim Fox 37 | * @author swilliams 38 | * @author Joern Bernhardt 39 | * @author Galder Zamarreño 40 | */ 41 | final class NetServer private[scala] (val asJava: JNetServer) extends Self 42 | with ServerSSLSupport 43 | with ServerTCPSupport 44 | with Closeable { 45 | 46 | override type J = JNetServer 47 | 48 | /** 49 | * Supply a connect handler for this server. The server can only have at most one connect handler at any one time. 50 | * As the server accepts TCP or SSL connections it creates an instance of [[org.vertx.scala.core.net.NetSocket]] and passes it to the 51 | * connect handler. 52 | * @return a reference to this so multiple method calls can be chained together 53 | */ 54 | def connectHandler(connectHandler: NetSocket => Unit): NetServer = 55 | wrap(asJava.connectHandler(connectHandler.compose(NetSocket.apply))) 56 | 57 | /** 58 | * Tell the server to start listening on all available interfaces and port `port`. Be aware this is an 59 | * async operation and the server may not bound on return of the method. 60 | */ 61 | def listen(port: Int): NetServer = wrap(asJava.listen(port)) 62 | 63 | /** 64 | * Instruct the server to listen for incoming connections on the specified `port` and all available interfaces. 65 | */ 66 | def listen(port: Int, listenHandler: AsyncResult[NetServer] => Unit): NetServer = 67 | wrap(asJava.listen(port, arNetServer(listenHandler))) 68 | 69 | /** 70 | * Tell the server to start listening on port `port` and hostname or ip address given by `host`. Be aware this is an 71 | * async operation and the server may not bound on return of the method. 72 | * 73 | */ 74 | def listen(port: Int, host: String): NetServer = wrap(asJava.listen(port, host)) 75 | 76 | /** 77 | * Instruct the server to listen for incoming connections on the specified `port` and `host`. `host` can 78 | * be a host name or an IP address. 79 | */ 80 | def listen(port: Int, host: String, listenHandler: AsyncResult[NetServer] => Unit): NetServer = 81 | wrap(asJava.listen(port, host, arNetServer(listenHandler))) 82 | 83 | /** 84 | * The actual port the server is listening on. This is useful if you bound the server specifying 0 as port number 85 | * signifying an ephemeral port 86 | */ 87 | def port(): Int = asJava.port() 88 | 89 | /** 90 | * The host. 91 | */ 92 | def host(): String = asJava.host() 93 | 94 | private def arNetServer = asyncResultConverter(NetServer.apply) _ 95 | 96 | } 97 | 98 | /** Factory for [[org.vertx.scala.core.net.NetServer]] instances. */ 99 | object NetServer { 100 | def apply(actual: JNetServer) = new NetServer(actual) 101 | } 102 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/net/NetSocket.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.net 18 | 19 | import org.vertx.java.core.net.{ NetSocket => JNetSocket } 20 | import java.net.InetSocketAddress 21 | import org.vertx.scala.core.FunctionConverters._ 22 | import org.vertx.scala.core.streams.{WriteStream, ReadStream} 23 | import org.vertx.scala.Self 24 | import org.vertx.scala.core._ 25 | 26 | /** 27 | * Represents a socket-like interface to a TCP/SSL connection on either the 28 | * client or the server side.

29 | * Instances of this class are created on the client side by an [[org.vertx.scala.core.net.NetClient]] 30 | * when a connection to a server is made, or on the server side by a [[org.vertx.scala.core.net.NetServer]] 31 | * when a server accepts a connection.

32 | * It implements both [[org.vertx.scala.core.streams.ReadStream]] and [[org.vertx.scala.core.streams.WriteStream]] so it can be used with 33 | * [[org.vertx.java.core.streams.Pump]] to pump data with flow control.

34 | * Instances of this class are not thread-safe.

35 | * 36 | * @author Tim Fox 37 | * @author swilliams 38 | * @author Joern Bernhardt 39 | * @author Galder Zamarreño 40 | */ 41 | final class NetSocket private[scala] (val asJava: JNetSocket) extends Self 42 | with ReadStream 43 | with WriteStream { 44 | 45 | override type J = JNetSocket 46 | 47 | /** 48 | * When a `NetSocket` is created it automatically registers an event handler with the event bus, the ID of that 49 | * handler is given by `writeHandlerID`.

50 | * Given this ID, a different event loop can send a buffer to that event handler using the event bus and 51 | * that buffer will be received by this instance in its own event loop and written to the underlying connection. This 52 | * allows you to write data to other connections which are owned by different event loops. 53 | */ 54 | def writeHandlerID(): String = asJava.writeHandlerID 55 | 56 | /** 57 | * Write a [[java.lang.String]] to the connection, encoded in UTF-8. 58 | * @return A reference to this, so multiple method calls can be chained. 59 | */ 60 | def write(data: String): NetSocket = wrap(asJava.write(data)) 61 | 62 | /** 63 | * Write a [[java.lang.String]] to the connection, encoded using the encoding `enc`. 64 | * @return A reference to this, so multiple method calls can be chained. 65 | */ 66 | def write(data: String, enc: String): NetSocket = wrap(asJava.write(data, enc)) 67 | 68 | /** 69 | * Tell the kernel to stream a file as specified by `filename` directly from disk to the outgoing connection, 70 | * bypassing userspace altogether (where supported by the underlying operating system. This is a very efficient way to stream files. 71 | */ 72 | def sendFile(filename: String): NetSocket = wrap(asJava.sendFile(filename)) 73 | 74 | /** 75 | * Same as [[NetSocket.sendFile()]] but also takes a handler that will be 76 | * called when the send has completed or a failure has occurred 77 | */ 78 | def sendFile(filename: String, handler: AsyncResult[Void] => Unit): NetSocket = 79 | wrap(asJava.sendFile(filename, fnToHandler(handler))) 80 | 81 | /** 82 | * Return the remote address for this socket 83 | */ 84 | def remoteAddress(): InetSocketAddress = asJava.remoteAddress() 85 | 86 | /** 87 | * Return the local address for this socket 88 | */ 89 | def localAddress(): InetSocketAddress = asJava.localAddress() 90 | 91 | /** 92 | * Close the NetSocket 93 | */ 94 | def close(): Unit = asJava.close() 95 | 96 | /** 97 | * Set a handler that will be called when the NetSocket is closed 98 | */ 99 | def closeHandler(handler: => Unit): NetSocket = wrap(asJava.closeHandler(handler)) 100 | 101 | /** 102 | * Upgrade channel to use SSL/TLS. Be aware that for this to work SSL must be configured. 103 | */ 104 | def ssl(handler: => Unit): NetSocket = wrap(asJava.ssl(handler)) 105 | 106 | /** 107 | * Returns `true` if this [[org.vertx.scala.core.net.NetSocket]] is encrypted via SSL/TLS. 108 | */ 109 | def isSsl: Boolean = asJava.isSsl 110 | } 111 | 112 | object NetSocket { 113 | def apply(socket: JNetSocket) = new NetSocket(socket) 114 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/package.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala 18 | 19 | import org.vertx.java.core.{ Vertx => JVertx } 20 | import org.vertx.java.core.{ VertxFactory => JVertxFactory } 21 | 22 | package object core { 23 | 24 | type AsyncResult[T] = org.vertx.java.core.AsyncResult[T] 25 | type Handler[T] = org.vertx.java.core.Handler[T] 26 | type MultiMap = scala.collection.mutable.MultiMap[String, String] 27 | 28 | def newVertx() = new Vertx(JVertxFactory.newVertx()) 29 | 30 | def newVertx(port: Int, hostname: String) = new Vertx(JVertxFactory.newVertx(port, hostname)) 31 | 32 | def newVertx(hostname: String) = new Vertx(JVertxFactory.newVertx(hostname)) 33 | 34 | implicit def javaVertxToScalaVertx(jvertx: JVertx): Vertx = new Vertx(jvertx) 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/parsetools/RecordParser.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2012 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.parsetools 18 | 19 | import org.vertx.java.core.parsetools.{ RecordParser => JRecordParser } 20 | import org.vertx.scala.core.buffer._ 21 | import scala.language.implicitConversions 22 | 23 | 24 | /** 25 | * A helper class which allows you to easily parse protocols which are delimited by a sequence of bytes, or fixed 26 | * size records.

27 | * Instances of this class take as input [[org.vertx.scala.core.buffer.Buffer]] instances containing raw bytes, and output records.

28 | * For example, if I had a simple ASCII text protocol delimited by '\n' and the input was the following:

29 | *

30 |  * buffer1:HELLO\nHOW ARE Y
31 |  * buffer2:OU?\nI AM
32 |  * buffer3: DOING OK
33 |  * buffer4:\n
34 |  * 
35 | * Then the output would be:

36 | *

37 |  * buffer1:HELLO
38 |  * buffer2:HOW ARE YOU?
39 |  * buffer3:I AM DOING OK
40 |  * 
41 | * Instances of this class can be changed between delimited mode and fixed size record mode on the fly as 42 | * individual records are read, this allows you to parse protocols where, for example, the first 5 records might 43 | * all be fixed size (of potentially different sizes), followed by some delimited records, followed by more fixed 44 | * size records.

45 | * Instances of this class can't currently be used for protocols where the text is encoded with something other than 46 | * a 1-1 byte-char mapping. TODO extend this class to cope with arbitrary character encodings

47 | * 48 | * @author Tim Fox 49 | */ 50 | object RecordParser { 51 | /** 52 | * Helper method to convert a latin-1 String to an array of bytes for use as a delimiter 53 | * Please do not use this for non latin-1 characters 54 | * 55 | * @param str string to convert 56 | * @return The byte[] form of the string 57 | */ 58 | def latin1StringToBytes(str: String): Array[Byte] = JRecordParser.latin1StringToBytes(str) 59 | 60 | /** 61 | * Create a new `RecordParser` instance, initially in delimited mode, and where the delimiter can be represented 62 | * by the String delim endcoded in latin-1 . Don't use this if your String contains other than latin-1 characters.

63 | * `output` Will receive whole records which have been parsed. 64 | */ 65 | def newDelimited(delim: String, handler: Buffer => Unit) = JRecordParser.newDelimited(delim, bufferHandlerToJava(handler)) 66 | 67 | /** 68 | * Create a new `RecordParser` instance, initially in delimited mode, and where the delimiter can be represented 69 | * by the `byte[]` delim.

70 | * `output` Will receive whole records which have been parsed. 71 | */ 72 | def newDelimited(delim: Array[Byte], handler: Buffer => Unit) = JRecordParser.newDelimited(delim, bufferHandlerToJava(handler)) 73 | 74 | /** 75 | * Create a new `RecordParser` instance, initially in fixed size mode, and where the record size is specified 76 | * by the `size` parameter.

77 | * `output` Will receive whole records which have been parsed. 78 | */ 79 | def newFixed(size: Int, handler: Buffer => Unit) = JRecordParser.newFixed(size, bufferHandlerToJava(handler)) 80 | } 81 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/shareddata/SharedData.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.shareddata 17 | 18 | import org.vertx.java.core.shareddata.{ SharedData => JSharedData } 19 | import scala.collection.concurrent 20 | import scala.collection.mutable 21 | import scala.collection.JavaConversions._ 22 | 23 | /** 24 | * Sometimes it is desirable to share immutable data between different event loops, for example to implement a 25 | * cache of data.

26 | * This class allows instances of shared data structures to be looked up and used from different event loops.

27 | * The data structures themselves will only allow certain data types to be stored into them. This shields you from 28 | * worrying about any thread safety issues might occur if mutable objects were shared between event loops.

29 | * The following types can be stored in a shareddata data structure:

30 | *

31 |  *   [[java.lang.String]]
32 |  *   [[java.lang.Integer]]
33 |  *   [[java.lang.Long]]
34 |  *   [[java.lang.Double]]
35 |  *   [[java.lang.Float]]
36 |  *   [[java.lang.Short]]
37 |  *   [[java.lang.Byte]]
38 |  *   [[java.lang.Character]]
39 |  *   `byte[]` - this will be automatically copied, and the copy will be stored in the structure.
40 |  *   [[org.vertx.scala.core.buffer.Buffer]] - this will be automatically copied, and the copy will be stored in the
41 |  *   structure.
42 |  * 
43 | *

44 | * 45 | * Instances of this class are thread-safe.

46 | * 47 | * @author Tim Fox 48 | * @author Joern Bernhardt 49 | * @author Galder Zamarreño 50 | */ 51 | final class SharedData private[scala] (val asJava: JSharedData) extends AnyVal { 52 | 53 | /** 54 | * Return a [[scala.collection.concurrent.Map]] facade for the internal map 55 | * with the specific `name`. All invocations of this method with the same 56 | * value of `name` are guaranteed to return the same underlying internal 57 | * map instance.

58 | * 59 | * This method converts a Java collection into a Scala collection every 60 | * time it gets called, so use it sensibly. 61 | */ 62 | def getMap[K, V](name: String): concurrent.Map[K, V] = mapAsScalaConcurrentMap(asJava.getMap(name)) 63 | 64 | /** 65 | * Return a [[scala.collection.mutable.Set]] facade for the internal set 66 | * with the specific `name`. All invocations of this method with the same 67 | * value of `name` are guaranteed to return the same underlying internal 68 | * set instance.

69 | * 70 | * This method converts a Java collection into a Scala collection every 71 | * time it gets called, so use it sensibly. 72 | */ 73 | def getSet[E](name: String): mutable.Set[E] = asScalaSet(asJava.getSet(name)) 74 | 75 | /** 76 | * Remove the `Map` with the specific `name`. 77 | */ 78 | def removeMap(name: String): Boolean = asJava.removeMap(name) 79 | 80 | /** 81 | * Remove the `Set` with the specific `name`. 82 | */ 83 | def removeSet(name: String): Boolean = asJava.removeSet(name) 84 | 85 | } 86 | 87 | /** Factory for [[org.vertx.scala.core.shareddata.SharedData]] instances. */ 88 | object SharedData { 89 | def apply(actual: JSharedData) = new SharedData(actual) 90 | } 91 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/sockjs/EventBusBridgeHook.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.sockjs 17 | 18 | import org.vertx.java.core.sockjs.{EventBusBridgeHook => JEventBusBridgeHook} 19 | import org.vertx.scala.core.json.JsonObject 20 | import org.vertx.scala.core._ 21 | import org.vertx.scala.core.FunctionConverters._ 22 | 23 | /** 24 | * A hook that you can use to receive various events on the EventBusBridge. 25 | * 26 | * @author Galder Zamarreño 27 | */ 28 | final class EventBusBridgeHook private[scala] (val asJava: JEventBusBridgeHook) extends AnyVal { 29 | 30 | /** 31 | * Called when a new socket is created 32 | * You can override this method to do things like check the origin header of a socket before 33 | * accepting it 34 | * @param sock The socket 35 | * @return true to accept the socket, false to reject it 36 | */ 37 | def handleSocketCreated(sock: SockJSSocket): Boolean = 38 | asJava.handleSocketCreated(sock.asJava) 39 | 40 | /** 41 | * The socket has been closed 42 | * @param sock The socket 43 | */ 44 | def handleSocketClosed(sock: SockJSSocket): Unit = 45 | asJava.handleSocketClosed(sock.asJava) 46 | 47 | /** 48 | * Client is sending or publishing on the socket 49 | * @param sock The sock 50 | * @param send if true it's a send else it's a publish 51 | * @param msg The message 52 | * @param address The address the message is being sent/published to 53 | * @return true To allow the send/publish to occur, false otherwise 54 | */ 55 | def handleSendOrPub(sock: SockJSSocket, send: Boolean, msg: JsonObject, address: String): Boolean = 56 | asJava.handleSendOrPub(sock.asJava, send, msg, address) 57 | 58 | /** 59 | * Called before client registers a handler 60 | * @param sock The socket 61 | * @param address The address 62 | * @return true to let the registration occur, false otherwise 63 | */ 64 | def handlePreRegister(sock: SockJSSocket, address: String): Boolean = 65 | asJava.handlePreRegister(sock.asJava, address) 66 | 67 | /** 68 | * Called after client registers a handler 69 | * @param sock The socket 70 | * @param address The address 71 | */ 72 | def handlePostRegister(sock: SockJSSocket, address: String): Unit = 73 | asJava.handlePostRegister(sock.asJava, address) 74 | 75 | /** 76 | * Client is unregistering a handler 77 | * @param sock The socket 78 | * @param address The address 79 | */ 80 | def handleUnregister(sock: SockJSSocket, address: String): Boolean = 81 | asJava.handleUnregister(sock.asJava, address) 82 | 83 | /** 84 | * Called before authorisation - you can override authorisation here if you don't want the default 85 | * @param message The auth message 86 | * @param sessionID The session ID 87 | * @param handler Handler - call this when authorisation is complete 88 | * @return true if you wish to override authorisation 89 | */ 90 | def handleAuthorise(message: JsonObject, sessionID: String, handler: AsyncResult[Boolean] => Unit): Boolean = 91 | asJava.handleAuthorise(message, sessionID, asyncResultConverter((x: java.lang.Boolean) => x.booleanValue)(handler)) 92 | 93 | } 94 | 95 | object EventBusBridgeHook { 96 | def apply(internal: JEventBusBridgeHook) = new EventBusBridgeHook(internal) 97 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/sockjs/SockJSSocket.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.sockjs 18 | 19 | import org.vertx.java.core.sockjs.{ SockJSSocket => JSockJSSocket } 20 | import org.vertx.scala.core.streams.{WriteStream, ReadStream} 21 | import org.vertx.scala.core.http._ 22 | import org.vertx.scala.Self 23 | import java.net.InetSocketAddress 24 | import org.vertx.scala.core.MultiMap 25 | 26 | /** 27 | * You interact with SockJS clients through instances of SockJS socket. 28 | *

The API is very similar to [[org.vertx.scala.core.http.WebSocket]]. It implements both 29 | * [[org.vertx.scala.core.streams.ReadStream]] and [[org.vertx.scala.core.streams.WriteStream]] so it can be used with 30 | * [[org.vertx.scala.core.streams.Pump]] to pump data with flow control. 31 | *

Instances of this class are not thread-safe. 32 | * 33 | * @author Tim Fox 34 | * @author swilliams 35 | * @author Joern Bernhardt 36 | */ 37 | final class SockJSSocket private[scala] (val asJava: JSockJSSocket) extends Self 38 | with ReadStream 39 | with WriteStream { 40 | 41 | override type J = JSockJSSocket 42 | 43 | /** 44 | * When a `SockJSSocket` is created it automatically registers an event handler with the event bus, the ID of that 45 | * handler is given by `writeHandlerID`.

46 | * Given this ID, a different event loop can send a buffer to that event handler using the event bus and 47 | * that buffer will be received by this instance in its own event loop and written to the underlying socket. This 48 | * allows you to write data to other sockets which are owned by different event loops. 49 | */ 50 | def writeHandlerID(): String = asJava.writeHandlerID() 51 | 52 | /** 53 | * Close it 54 | */ 55 | def close(): Unit = asJava.close() 56 | 57 | /** 58 | * Return the remote address for this socket 59 | */ 60 | def remoteAddress(): InetSocketAddress = asJava.remoteAddress() 61 | 62 | /** 63 | * Return the local address for this socket 64 | */ 65 | def localAddress(): InetSocketAddress = asJava.localAddress() 66 | 67 | /** 68 | * Return the headers corresponding to the last request for this socket or the websocket handshake 69 | * Any cookie headers will be removed for security reasons 70 | * 71 | * This method converts a Java collection into a Scala collection every 72 | * time it gets called, so use it sensibly. 73 | */ 74 | def headers: MultiMap = multiMapToScalaMultiMap(asJava.headers()) 75 | 76 | /** 77 | * Return the URI corresponding to the last request for this socket or the websocket handshake 78 | */ 79 | def uri: String = asJava.uri() 80 | 81 | } 82 | 83 | /** Factory for [[org.vertx.scala.core.sockjs.SockJSSocket]] instances. */ 84 | object SockJSSocket { 85 | def apply(internal: JSockJSSocket) = new SockJSSocket(internal) 86 | } 87 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/streams/DrainSupport.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.streams 17 | 18 | import org.vertx.java.core.streams.{ DrainSupport => JDrainSupport } 19 | import org.vertx.scala.{Self, AsJava} 20 | import org.vertx.scala.core.FunctionConverters._ 21 | 22 | /** 23 | * Allows to set a `Handler` which is notified once the write queue is 24 | * drained again. This way you can stop writing once the write queue consumes 25 | * to much memory and so prevent an OutOfMemoryError. 26 | * 27 | * @author Norman Maurer 28 | * @author Galder Zamarreño 29 | */ 30 | trait DrainSupport extends Self 31 | with AsJava { 32 | 33 | override type J <: JDrainSupport[_] 34 | 35 | /** 36 | * Set the maximum size of the write queue to `maxSize`. You will still be 37 | * able to write to the stream even if there is more than `maxSize` bytes in 38 | * the write queue. This is used as an indicator by classes such as `Pump` 39 | * to provide flow control. 40 | */ 41 | def setWriteQueueMaxSize(maxSize: Int): this.type = wrap(asJava.setWriteQueueMaxSize(maxSize)) 42 | 43 | /** 44 | * This will return `true` if there are more bytes in the write queue than 45 | * the value set using [[org.vertx.scala.core.streams.DrainSupport.setWriteQueueMaxSize]] 46 | */ 47 | def writeQueueFull: Boolean = asJava.writeQueueFull() 48 | 49 | /** 50 | * Set a drain handler on the stream. If the write queue is full, then the 51 | * handler will be called when the write queue has been reduced to 52 | * maxSize / 2. See `Pump` for an example of this being used. 53 | */ 54 | def drainHandler(handler: => Unit): this.type = wrap(asJava.drainHandler(lazyToVoidHandler(handler))) 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/streams/ExceptionSupport.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.streams 18 | 19 | import org.vertx.java.core.streams.{ ExceptionSupport => JExceptionSupport } 20 | import org.vertx.scala.{Self, AsJava} 21 | import org.vertx.scala.core.FunctionConverters._ 22 | 23 | /** 24 | * Exception handler. 25 | * 26 | * @author swilliams 27 | * @author Joern Bernhardt 28 | * @author Galder Zamarreño 29 | */ 30 | trait ExceptionSupport extends Self 31 | with AsJava { 32 | 33 | override type J <: JExceptionSupport[_] 34 | 35 | /** 36 | * Set an exception handler. 37 | */ 38 | def exceptionHandler(handler: Throwable => Unit): this.type = wrap(asJava.exceptionHandler(handler)) 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/streams/Pump.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.core.streams 17 | 18 | import org.vertx.java.core.streams.{ Pump => JPump } 19 | import org.vertx.scala.Self 20 | 21 | /** 22 | * Pumps data from a [[org.vertx.scala.core.streams.ReadStream]] to a 23 | * [[org.vertx.scala.core.streams.WriteStream]] and performs flow control where necessary to 24 | * prevent the write stream buffer from getting overfull.

25 | * Instances of this class read bytes from a [[org.vertx.scala.core.streams.ReadStream]] 26 | * and write them to a [[org.vertx.scala.core.streams.WriteStream]]. If data 27 | * can be read faster than it can be written this could result in the write 28 | * queue of the [[org.vertx.scala.core.streams.WriteStream]] growing 29 | * without bound, eventually causing it to exhaust all available RAM.

30 | * To prevent this, after each write, instances of this class check whether the write queue of the 31 | * [[org.vertx.scala.core.streams.WriteStream]] is full, and if so, the 32 | * [[org.vertx.scala.core.streams.ReadStream]] is paused, and a `drainHandler` is set on the 33 | * [[org.vertx.scala.core.streams.WriteStream]]. When the [[org.vertx.scala.core.streams.WriteStream]] 34 | * has processed half of its backlog, the `drainHandler` will be 35 | * called, which results in the pump resuming the [[org.vertx.scala.core.streams.ReadStream]].

36 | * This class can be used to pump from any [[org.vertx.scala.core.streams.ReadStream]] 37 | * to any [[org.vertx.scala.core.streams.WriteStream]], e.g. from an 38 | * [[org.vertx.scala.core.http.HttpServerRequest]] to an [[org.vertx.scala.core.file.AsyncFile]], 39 | * or from [[org.vertx.scala.core.net.NetSocket]] to a [[org.vertx.scala.core.http.WebSocket]].

40 | * 41 | * Instances of this class are not thread-safe.

42 | * 43 | * @author Tim Fox 44 | * @author swilliams 45 | * @author Joern Bernhardt 46 | */ 47 | final class Pump private[scala] (val asJava: JPump) extends Self { 48 | 49 | /** 50 | * Set the write queue max size to `maxSize` 51 | */ 52 | def setWriteQueueMaxSize(maxSize: Int): Pump = wrap(asJava.setWriteQueueMaxSize(maxSize)) 53 | 54 | /** 55 | * Start the Pump. The Pump can be started and stopped multiple times. 56 | */ 57 | def start(): Pump = wrap(asJava.start()) 58 | 59 | /** 60 | * Stop the Pump. The Pump can be started and stopped multiple times. 61 | */ 62 | def stop(): Pump = wrap(asJava.stop()) 63 | 64 | /** 65 | * Return the total number of bytes pumped by this pump. 66 | */ 67 | def bytesPumped(): Int = asJava.bytesPumped() 68 | 69 | } 70 | 71 | object Pump { 72 | 73 | /** 74 | * Create a new `Pump` with the given `ReadStream` and `WriteStream` 75 | */ 76 | def apply[A <: ReadStream, B <: WriteStream](rs: ReadStream, ws: WriteStream) = createPump(rs, ws) 77 | 78 | /** 79 | * Create a new `Pump` with the given `ReadStream` and `WriteStream` and 80 | * `writeQueueMaxSize` 81 | */ 82 | def apply[A <: ReadStream, B <: WriteStream](rs: ReadStream, ws: WriteStream, writeQueueMaxSize: Int) = 83 | createPump(rs, ws, writeQueueMaxSize) 84 | 85 | /** 86 | * Create a new `Pump` with the given `ReadStream` and `WriteStream` 87 | */ 88 | def createPump[A <: ReadStream, B <: WriteStream](rs: ReadStream, ws: WriteStream) = 89 | new Pump(JPump.createPump(rs.asJava, ws.asJava)) 90 | 91 | /** 92 | * Create a new `Pump` with the given `ReadStream` and `WriteStream` and 93 | * `writeQueueMaxSize` 94 | */ 95 | def createPump[A <: ReadStream, B <: WriteStream](rs: ReadStream, ws: WriteStream, writeQueueMaxSize: Int) = 96 | new Pump(JPump.createPump(rs.asJava, ws.asJava, writeQueueMaxSize)) 97 | 98 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/streams/ReadStream.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.streams 18 | 19 | import org.vertx.java.core.streams.{ ReadStream => JReadStream } 20 | import org.vertx.java.core.streams.{ ExceptionSupport => JExceptionSupport } 21 | import org.vertx.scala.core.buffer._ 22 | import org.vertx.scala.{Self, AsJava} 23 | import org.vertx.scala.core.FunctionConverters._ 24 | 25 | /** 26 | * Represents a stream of data that can be read from.

27 | * Any class that implements this interface can be used by a [[org.vertx.scala.core.streams.Pump]] 28 | * to pump data from it to a [[org.vertx.scala.core.streams.WriteStream]].

29 | * This interface exposes a fluent api and the type T represents the type of the object that implements 30 | * the interface to allow method chaining 31 | * 32 | * @author Tim Fox 33 | * @author swilliams 34 | * @author Joern Bernhardt 35 | * @author Galder Zamarreño 36 | */ 37 | trait ReadStream extends Self 38 | with ReadSupport[Buffer] 39 | with AsJava { 40 | 41 | override type J <: JReadStream[_] with JExceptionSupport[_] 42 | 43 | /** 44 | * Set an end handler. Once the stream has ended, and there is no more data 45 | * to be read, this handler will be called. 46 | */ 47 | def endHandler(handler: => Unit): this.type = wrap(asJava.endHandler(lazyToVoidHandler(handler))) 48 | 49 | /** 50 | * Set a data handler. As data is read, the handler will be called with the data. 51 | */ 52 | override def dataHandler(handler: Buffer => Unit): this.type = wrap(asJava.dataHandler(bufferHandlerToJava(handler))) 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/streams/ReadSupport.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.core.streams 2 | 3 | import org.vertx.java.core.streams.{ ReadSupport => JReadSupport } 4 | import org.vertx.java.core.streams.{ ExceptionSupport => JExceptionSupport } 5 | import org.vertx.scala.{Self, AsJava} 6 | 7 | /** 8 | * Allows to set a handler which is notified once data was read. 9 | * It also allows to pause reading and resume later. 10 | * 11 | * @author Norman Maurer 12 | * @author Galder Zamarreño 13 | */ 14 | trait ReadSupport[E] extends Self 15 | with ExceptionSupport 16 | with AsJava { 17 | 18 | override type J <: JReadSupport[_, _] with JExceptionSupport[_] 19 | 20 | /** 21 | * Set a data handler. As data is read, the handler will be called with the data. 22 | */ 23 | def dataHandler(handler: E => Unit): this.type 24 | 25 | /** 26 | * Pause the `ReadSupport`. While it's paused, no data will be sent to the `dataHandler` 27 | */ 28 | def pause(): this.type = wrap(asJava.pause()) 29 | 30 | /** 31 | * Resume reading. If the `ReadSupport` has been paused, reading will recommence on it. 32 | */ 33 | def resume(): this.type = wrap(asJava.resume()) 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/core/streams/WriteStream.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.core.streams 18 | 19 | import org.vertx.java.core.streams.{ WriteStream => JWriteStream } 20 | import org.vertx.scala.core.buffer.Buffer 21 | import org.vertx.scala.{Self, AsJava} 22 | import org.vertx.scala.core.FunctionConverters._ 23 | 24 | /** 25 | * Represents a stream of data that can be written to

26 | * Any class that implements this interface can be used by a [[org.vertx.scala.core.streams.Pump]] 27 | * to pump data from a [[org.vertx.scala.core.streams.ReadStream]] 28 | * to it.

29 | * This interface exposes a fluent api and the type T represents the type of 30 | * the object that implements the interface to allow method chaining 31 | * 32 | * @author Tim Fox 33 | * @author swilliams 34 | * @author Joern Bernhardt 35 | * @author Galder Zamarreño 36 | */ 37 | trait WriteStream extends Self 38 | with ExceptionSupport 39 | with AsJava { 40 | 41 | override type J <: JWriteStream[_] 42 | 43 | /** 44 | * Write some data to the stream. The data is put on an internal write queue, and the write actually happens 45 | * asynchronously. To avoid running out of memory by putting too much on the write queue, 46 | * check the [[org.vertx.scala.core.streams.WriteStream.writeQueueFull()]] 47 | * method before writing. This is done automatically if using a [[org.vertx.scala.core.streams.Pump]]. 48 | */ 49 | def write(data: Buffer): this.type = wrap(asJava.write(data.asJava)) 50 | 51 | /** 52 | * Set the maximum size of the write queue to `maxSize`. You will still be able to write to the stream even 53 | * if there is more than `maxSize` bytes in the write queue. This is used as an indicator by classes such as 54 | * `Pump` to provide flow control. 55 | */ 56 | def setWriteQueueMaxSize(maxSize: Int): this.type = wrap(asJava.setWriteQueueMaxSize(maxSize)) 57 | 58 | /** 59 | * This will return `true` if there are more bytes in the write queue than the value set using 60 | * [[org.vertx.scala.core.streams.WriteStream.setWriteQueueMaxSize()]] 61 | */ 62 | def writeQueueFull(): Boolean = asJava.writeQueueFull() 63 | 64 | /** 65 | * Set a drain handler on the stream. If the write queue is full, then the handler will be called when the write 66 | * queue has been reduced to maxSize / 2. See [[org.vertx.scala.core.streams.Pump]] for an example of this being used. 67 | */ 68 | def drainHandler(handler: => Unit): this.type = wrap(asJava.drainHandler(lazyToVoidHandler(handler))) 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/lang/ClassLoaders.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.lang 17 | 18 | import scala.util.Try 19 | 20 | /** 21 | * Class loading utility class. 22 | * 23 | * @author Galder Zamarreño 24 | */ 25 | object ClassLoaders { 26 | 27 | /** 28 | * Instantiates the given class name using the classloader provided 29 | * @param className String containing the class name to instantiate 30 | * @param classLoader where to find the given class name 31 | * @tparam T type of instance expected back 32 | * @return [[scala.util.Success]] containing a new instance of the given 33 | * class or [[scala.util.Failure]] with any errors reported 34 | */ 35 | def newInstance[T](className: String, classLoader: ClassLoader): Try[T] = { 36 | Try { 37 | val clazz = classLoader.loadClass(className) 38 | clazz.newInstance().asInstanceOf[T] 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/lang/ScalaInterpreter.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.lang 2 | 3 | import java.io.{ File, PrintWriter } 4 | import scala.annotation.tailrec 5 | import scala.io.Source 6 | import scala.reflect.internal.util.BatchSourceFile 7 | import scala.reflect.io.PlainFile 8 | import scala.tools.nsc.Settings 9 | import scala.tools.nsc.interpreter.{NamedParamClass, IMain} 10 | import scala.tools.nsc.interpreter.Results.Result 11 | import scala.tools.nsc.interpreter.Results.{ Error => InterpreterError } 12 | import scala.tools.nsc.interpreter.Results.{ Incomplete => InterpreterIncomplete} 13 | import scala.tools.nsc.interpreter.Results.{ Success => InterpreterSuccess } 14 | import org.vertx.scala.core.Vertx 15 | import scala.tools.nsc.NewLinePrintWriter 16 | import scala.tools.nsc.ConsoleWriter 17 | import java.net.URL 18 | import org.vertx.scala.platform.Container 19 | import scala.util.{Success, Failure, Try} 20 | 21 | /** 22 | * Scala interpreter 23 | * 24 | * @author Galder Zamarreño 25 | */ 26 | class ScalaInterpreter( 27 | settings: Settings, 28 | vertx: Vertx, 29 | container: Container, 30 | out: PrintWriter = new NewLinePrintWriter(new ConsoleWriter, true)) { 31 | 32 | private val interpreter = new IMain(settings, out) 33 | interpreter.setContextClassLoader() 34 | 35 | def addBootClasspathJar(path: String): Unit = 36 | settings.bootclasspath.append(path) 37 | 38 | def close(): Unit = interpreter.close() 39 | 40 | def runScript(script: URL): Try[Unit] = { 41 | val content = Source.fromURL(script).mkString 42 | val ops = List( 43 | () => addImport("org.vertx.scala._"), 44 | () => addImport("org.vertx.scala.core._"), 45 | () => addImport("org.vertx.scala.core.buffer._"), 46 | () => addImport("org.vertx.scala.core.dns._"), 47 | () => addImport("org.vertx.scala.core.eventbus._"), 48 | () => addImport("org.vertx.scala.core.file._"), 49 | () => addImport("org.vertx.scala.core.http._"), 50 | () => addImport("org.vertx.scala.core.json._"), 51 | () => addImport("org.vertx.scala.core.net._"), 52 | () => addImport("org.vertx.scala.core.streams._"), 53 | () => bind("vertx", "org.vertx.scala.core.Vertx", vertx), 54 | () => bind("container", "org.vertx.scala.platform.Container", container), 55 | () => interpret(content) 56 | ) 57 | val result = interpret(ops, InterpreterIncomplete) 58 | result match { 59 | case InterpreterError => Failure(new ScalaCompilerError(s"Interpreter error running $script")) 60 | case InterpreterIncomplete => Failure(new ScalaCompilerError(s"Incomplete script $script")) 61 | case InterpreterSuccess => Success() 62 | } 63 | } 64 | 65 | private def addImport(id: String): Result = 66 | interpret("import " + id) 67 | 68 | private def bind(name: String, boundType: String, value: Any): Result = 69 | verboseOrQuiet( 70 | interpreter.bind(name, boundType, value), 71 | interpreter.quietBind(NamedParamClass(name, boundType, value))) 72 | 73 | private def interpret(content: String): Result = 74 | verboseOrQuiet( 75 | interpreter.interpret(content), 76 | interpreter.beQuietDuring(interpreter.interpret(content))) 77 | 78 | private def verboseOrQuiet(verbose: => Result, quiet: => Result): Result = { 79 | if (ScalaInterpreter.isVerbose) verbose else quiet 80 | } 81 | 82 | def compileClass(classFile: File): Try[ClassLoader] = { 83 | val source = new BatchSourceFile(new PlainFile(classFile)) 84 | val result = interpreter.compileSources(source) 85 | if (result) 86 | Success(interpreter.classLoader) 87 | else 88 | Failure(new IllegalArgumentException(s"Unable to compile $classFile")) 89 | } 90 | 91 | @tailrec 92 | private def interpret(ops: List[() => Result], accumulate: Result): Result = { 93 | ops match { 94 | case List() => accumulate 95 | case x :: xs => 96 | val result = x() 97 | result match { 98 | case InterpreterError | InterpreterIncomplete => result 99 | case InterpreterSuccess => interpret(xs, result) 100 | } 101 | } 102 | } 103 | 104 | private class ScalaCompilerError(message: String) extends Exception(message) 105 | } 106 | 107 | object ScalaInterpreter { 108 | 109 | def isVerbose: Boolean = 110 | System.getProperty("vertx.scala.interpreter.verbose", "false").toBoolean 111 | 112 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/mods/BusModException.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.mods 17 | 18 | case class BusModException(message: String = null, cause: Throwable = null, id: String = "MODULE_EXCEPTION") extends Exception(message, cause) 19 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/mods/UnknownActionException.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.mods 17 | 18 | class UnknownActionException(msg: String = null, cause: Throwable = null) extends BusModException(msg, cause, "UNKNOWN_ACTION") 19 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/mods/replies/busmodreplies.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.mods.replies 17 | 18 | import org.vertx.scala.core.json._ 19 | import scala.concurrent.Future 20 | import org.vertx.scala.mods.ScalaBusMod._ 21 | 22 | sealed trait BusModReceiveEnd 23 | sealed trait BusModReply extends BusModReceiveEnd 24 | 25 | case class AsyncReply(replyWhenDone: Future[BusModReply]) extends BusModReply 26 | 27 | sealed trait ReplyReceiver { 28 | val handler: Receive 29 | } 30 | case class Receiver(handler: Receive) extends ReplyReceiver 31 | case class ReceiverWithTimeout(handler: Receive, timeout: Long, timeoutHandler: () => Unit) extends ReplyReceiver 32 | 33 | sealed trait SyncReply extends BusModReply { 34 | val replyHandler: Option[ReplyReceiver] 35 | def toJson: JsonObject 36 | } 37 | case class Ok(x: JsonObject = Json.obj(), replyHandler: Option[ReplyReceiver] = None) extends SyncReply { 38 | def toJson = x.putString("status", "ok") 39 | } 40 | 41 | case class Error(message: String, id: String = "MODULE_EXCEPTION", obj: JsonObject = Json.obj(), replyHandler: Option[ReplyReceiver] = None) extends SyncReply { 42 | def toJson = Json.obj("status" -> "error", "message" -> message, "error" -> id).mergeIn(obj) 43 | } 44 | 45 | case object NoReply extends BusModReceiveEnd 46 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/platform/Container.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.platform 17 | 18 | import scala.language.implicitConversions 19 | import scala.collection.JavaConverters._ 20 | import org.vertx.java.platform.{ Container => JContainer } 21 | import org.vertx.scala.core.AsyncResult 22 | import org.vertx.scala.core.json._ 23 | import org.vertx.scala.core.FunctionConverters._ 24 | import org.vertx.scala.core.logging.Logger 25 | 26 | /** 27 | * This class represents a Verticle's view of the container in which it is running.

28 | * An instance of this class will be created by the system and made available to 29 | * a running Verticle.

30 | * It contains methods to programmatically deploy other verticles, undeploy 31 | * verticles, deploy modules, get the configuration for a verticle and get the logger for a 32 | * verticle, amongst other things.

33 | * 34 | * @author Tim Fox 35 | * @author swilliams 36 | * @author Joern Bernhardt 37 | * @author Galder Zamarreño 38 | */ 39 | final class Container private[scala] (val asJava: JContainer) extends AnyVal { 40 | 41 | /** 42 | * Deploy a module programmatically 43 | * @param name The main of the module to deploy 44 | * @param config JSON config to provide to the module 45 | * @param instances The number of instances to deploy (defaults to 1) 46 | * @param handler The handler will be called passing in the unique deployment id when deployment is complete 47 | */ 48 | def deployModule(name: String, config: JsonObject = Json.emptyObj(), instances: Int = 1, handler: AsyncResult[String] => Unit = { ar: AsyncResult[String] => }): Unit = 49 | asJava.deployModule(name, config, instances, handler) 50 | 51 | /** 52 | * Deploy a verticle programmatically 53 | * @param name The main of the verticle 54 | * @param config JSON config to provide to the verticle 55 | * @param instances The number of instances to deploy (defaults to 1) 56 | * @param handler The handler will be called passing in the unique deployment id when deployment is complete 57 | */ 58 | def deployVerticle(name: String, config: JsonObject = Json.emptyObj(), instances: Int = 1, handler: AsyncResult[String] => Unit = { ar: AsyncResult[String] => }): Unit = 59 | asJava.deployVerticle(name, config, instances, handler) 60 | 61 | /** 62 | * Deploy a worker verticle programmatically 63 | * @param name The main of the verticle 64 | * @param config JSON config to provide to the verticle (defaults to empty JSON) 65 | * @param instances The number of instances to deploy (defaults to 1) 66 | * @param multiThreaded if true then the verticle will be deployed as a multi-threaded worker (default is false) 67 | * @param handler The handler will be called passing in the unique deployment id when deployment is complete 68 | */ 69 | def deployWorkerVerticle(name: String, config: JsonObject = Json.emptyObj(), instances: Int = 1, multiThreaded: Boolean = false, handler: AsyncResult[String] => Unit = { ar: AsyncResult[String] => }): Unit = 70 | asJava.deployWorkerVerticle(name, config, instances, multiThreaded, handler) 71 | 72 | /** 73 | * Get the verticle configuration 74 | * @return a JSON object representing the configuration 75 | */ 76 | def config(): JsonObject = asJava.config() 77 | 78 | /** 79 | * Get an umodifiable map of system, environment variables. 80 | * @return The map 81 | */ 82 | def env(): Map[String, String] = mapAsScalaMapConverter(asJava.env()).asScala.toMap 83 | 84 | /** 85 | * Cause the container to exit 86 | */ 87 | def exit(): Unit = asJava.exit() 88 | 89 | /** 90 | * Get the verticle logger 91 | * @return The logger 92 | */ 93 | def logger(): Logger = new Logger(asJava.logger()) 94 | 95 | /** 96 | * Undeploy a module 97 | * @param deploymentID The deployment ID 98 | * @param handler The handler will be called when undeployment is complete 99 | */ 100 | def undeployModule(deploymentID: String, handler: () => Unit): Unit = asJava.undeployModule(deploymentID, handler) 101 | 102 | /** 103 | * Undeploy a module 104 | * @param deploymentID The deployment ID 105 | * @param handler The handler will be called when undeployment is complete 106 | */ 107 | def undeployVerticle(deploymentID: String, handler: () => Unit): Unit = asJava.undeployVerticle(deploymentID, handler) 108 | 109 | } 110 | 111 | /** Factory for [[org.vertx.scala.platform.Container]] instances. */ 112 | object Container { 113 | def apply(actual: JContainer) = new Container(actual) 114 | } 115 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/platform/Verticle.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.platform 18 | 19 | import org.vertx.scala.core.Vertx 20 | import org.vertx.scala.core.VertxAccess 21 | import org.vertx.scala.core.logging.Logger 22 | import scala.concurrent.Promise 23 | 24 | /** 25 | * A verticle is the unit of execution in the Vert.x platform

26 | * Vert.x code is packaged into Verticle's and then deployed and executed by the Vert.x platform.

27 | * Verticles can be written in different languages.

28 | * 29 | * @author Tim Fox 30 | * @author swilliams 31 | * @author Joern Bernhardt 32 | */ 33 | trait Verticle extends VertxAccess { 34 | 35 | private var _vertx: Vertx = _ 36 | private var _container: Container = _ 37 | 38 | /** 39 | * A reference to the Vert.x runtime. 40 | * @return A reference to a Vertx. 41 | */ 42 | lazy val vertx: Vertx = _vertx 43 | 44 | /** 45 | * A reference to the Vert.x container. 46 | * @return A reference to the Container. 47 | */ 48 | lazy val container: Container = _container 49 | 50 | /** 51 | * 52 | */ 53 | lazy val logger: Logger = container.logger() 54 | 55 | /** 56 | * Injects the vertx. 57 | */ 58 | private[platform] def setVertx(newVertx: Vertx): Unit = _vertx = newVertx 59 | 60 | /** 61 | * Injects the container. 62 | */ 63 | private[platform] def setContainer(newContainer: Container): Unit = _container = newContainer 64 | 65 | /** 66 | * Vert.x calls the start method when the verticle is deployed. 67 | */ 68 | def start(): Unit = {} 69 | 70 | /** 71 | * Override this method to signify that start is complete sometime _after_ the start() method has returned. 72 | * This is useful if your verticle deploys other verticles or modules and you don't want this verticle to 73 | * be considered started until the other modules and verticles have been started. 74 | * 75 | * @param promise When you are happy your verticle is started set the result. 76 | */ 77 | def start(promise: Promise[Unit]): Unit = promise.success() 78 | 79 | /** 80 | * Vert.x calls the stop method when the verticle is undeployed. 81 | * Put any cleanup code for your verticle in here 82 | */ 83 | def stop(): Unit = {} 84 | 85 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/platform/impl/ScalaVerticle.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.vertx.scala.platform.impl 18 | 19 | import org.vertx.java.core.Future 20 | import org.vertx.java.core.{ Vertx => JVertx } 21 | import org.vertx.java.platform.{ Container => JContainer } 22 | import org.vertx.java.platform.{ Verticle => JVerticle } 23 | import org.vertx.scala.core.Vertx 24 | import org.vertx.scala.core.VertxExecutionContext 25 | import org.vertx.scala.platform.Container 26 | import org.vertx.scala.platform.Verticle 27 | import scala.concurrent.Promise 28 | import scala.util.Failure 29 | import scala.util.Success 30 | 31 | /** 32 | * @author swilliams 33 | * @author Joern Bernhardt 34 | */ 35 | object ScalaVerticle { 36 | def newVerticle(delegate: Verticle, vertx: Vertx, container: Container): ScalaVerticle = { 37 | val verticle = new ScalaVerticle(delegate) 38 | verticle.setVertx(vertx.asJava) 39 | verticle.setContainer(container.asJava) 40 | verticle 41 | } 42 | } 43 | 44 | final private[platform] class ScalaVerticle(delegate: Verticle) extends JVerticle { 45 | 46 | implicit val executionContext = VertxExecutionContext.fromVertxAccess(delegate) 47 | 48 | override def setContainer(jcontainer: JContainer) = { 49 | delegate.setContainer(new Container(jcontainer)) 50 | super.setContainer(jcontainer) 51 | } 52 | 53 | override def setVertx(jvertx: JVertx) = { 54 | delegate.setVertx(new Vertx(jvertx)) 55 | super.setVertx(jvertx) 56 | } 57 | 58 | override def start(): Unit = { 59 | delegate.start() 60 | } 61 | 62 | override def start(future: Future[Void]): Unit = { 63 | val p = Promise[Unit]() 64 | delegate.start() 65 | delegate.start(p) 66 | p.future onComplete { 67 | case Success(_) => 68 | future.setResult(null) 69 | case Failure(x) => 70 | future.setFailure(x) 71 | } 72 | } 73 | 74 | override def stop(): Unit = delegate.stop() 75 | 76 | } -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/router/RouterException.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.router 2 | 3 | /** 4 | * @author Joern Bernhardt 5 | */ 6 | case class RouterException(message: String = "", 7 | cause: Throwable = null, 8 | id: String = "UNKNOWN_SERVER_ERROR", 9 | statusCode: Int = 500) 10 | extends Exception(message, cause) 11 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/router/routing/routing.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.router.routing 2 | 3 | import org.vertx.scala.core.json._ 4 | import org.vertx.scala.router.RouterException 5 | 6 | import scala.concurrent.Future 7 | 8 | sealed trait Reply 9 | 10 | sealed trait SyncReply extends Reply 11 | 12 | case object NoBody extends SyncReply 13 | 14 | case class Ok(json: JsonObject) extends SyncReply 15 | 16 | case class SendFile(file: String, absolute: Boolean = false) extends SyncReply 17 | 18 | case class Error(ex: RouterException) extends SyncReply 19 | 20 | case class AsyncReply(replyWhenDone: Future[Reply]) extends Reply 21 | 22 | case class Header(key: String, value: String, endReply: Reply) extends Reply 23 | 24 | case class SetCookie(key: String, value: String, endReply: Reply) extends Reply 25 | 26 | sealed trait RouteMatch 27 | 28 | case class All(path: String) extends RouteMatch 29 | 30 | case class Connect(path: String) extends RouteMatch 31 | 32 | case class Delete(path: String) extends RouteMatch 33 | 34 | case class Get(path: String) extends RouteMatch 35 | 36 | case class Head(path: String) extends RouteMatch 37 | 38 | case class Options(path: String) extends RouteMatch 39 | 40 | case class Patch(path: String) extends RouteMatch 41 | 42 | case class Post(path: String) extends RouteMatch 43 | 44 | case class Put(path: String) extends RouteMatch 45 | 46 | case class Trace(path: String) extends RouteMatch 47 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/testtools/ScalaClassRunner.java: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.testtools; 2 | 3 | import org.junit.runners.model.FrameworkMethod; 4 | import org.junit.runners.model.InitializationError; 5 | import org.junit.runners.model.TestClass; 6 | import org.vertx.testtools.JavaClassRunner; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Scala class runner. This class used to be a Scala class, but due to the lack 12 | * of support for SBT project detection in JavaClassRunner, a static 13 | * initialization is needed to set the correct value for -Dvertx.mods system 14 | * property before super() constructor executes. 15 | */ 16 | public class ScalaClassRunner extends JavaClassRunner { 17 | 18 | static { 19 | if (System.getProperty("vertx.mods") == null) { 20 | // JavaClassRunner can currently only detect gradle/maven projects, 21 | // so force SBT expectations when it comes to modules location 22 | // if not pre-configured. 23 | System.setProperty("vertx.mods", "target/mods"); 24 | } 25 | } 26 | 27 | public ScalaClassRunner(Class clazz) throws InitializationError { 28 | super(clazz); 29 | } 30 | 31 | @Override 32 | protected List computeTestMethods() { 33 | Class testClass = getTestClass().getJavaClass(); 34 | if (!TestVerticle.class.isAssignableFrom(testClass)) { 35 | throw new IllegalArgumentException("Scala Test classes must extend org.vertx.scala.testtools.TestVerticle"); 36 | } 37 | this.main = "scala:" + testClass.getName(); 38 | return getTestMethods(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/scala/org/vertx/scala/testtools/TestVerticle.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.testtools 2 | 3 | import java.lang.reflect.{Method, InvocationTargetException} 4 | import org.junit.runner.RunWith 5 | import org.vertx.scala.platform.Verticle 6 | import org.vertx.testtools.VertxAssert 7 | import scala.concurrent.{ExecutionContext, Future} 8 | import org.vertx.java.core.impl.{WorkerContext, DefaultContext, VertxInternal} 9 | import org.vertx.scala.core.VertxExecutionContext 10 | 11 | @RunWith(classOf[ScalaClassRunner]) 12 | abstract class TestVerticle extends Verticle { 13 | 14 | override final def start() { 15 | initialize() 16 | before() 17 | asyncBefore() map { _ => 18 | startTests() 19 | } recover { 20 | case ex: Throwable => 21 | VertxAssert.handleThrowable(ex) 22 | } 23 | } 24 | 25 | /** 26 | * Override this method if you want to do things synchronously before starting the tests. 27 | */ 28 | def before(): Unit = {} 29 | 30 | /** 31 | * Override this method if you want to do things asynchronously before starting the tests. 32 | */ 33 | def asyncBefore(): Future[Unit] = Future.successful() 34 | 35 | /** 36 | * Expected thread 37 | */ 38 | var th: Thread = _ 39 | 40 | /** 41 | * Vertx internal context 42 | */ 43 | var context: DefaultContext = _ 44 | 45 | protected final def initialize(): Unit = { 46 | VertxAssert.initialize(vertx.asJava) 47 | th = Thread.currentThread 48 | context = vertx.asJava.asInstanceOf[VertxInternal].getContext 49 | } 50 | 51 | protected final def startTests() { 52 | val methodName = container.config().getString("methodName") 53 | try { 54 | val m = findMethod(getClass, methodName) 55 | m.invoke(this) 56 | } catch { 57 | case e: InvocationTargetException => 58 | val targetEx = e.getTargetException 59 | VertxAssert.handleThrowable(targetEx) 60 | case t: Throwable => 61 | // Problem with invoking 62 | VertxAssert.handleThrowable(t) 63 | } 64 | } 65 | 66 | protected final def assertThread() { 67 | if (!context.isInstanceOf[WorkerContext] && th != Thread.currentThread) 68 | throw new IllegalStateException( 69 | s"Expected: $th Actual: ${Thread.currentThread}") 70 | 71 | if (context != vertx.asJava.asInstanceOf[VertxInternal].getContext) 72 | throw new IllegalStateException( 73 | s"Wrong context: Expected: $context Actual: ${vertx.asInstanceOf[VertxInternal].getContext}") 74 | } 75 | 76 | def findMethod(clazz: Class[_], methodName: String): Method = { 77 | try { 78 | clazz.getDeclaredMethod(methodName) 79 | } catch { 80 | case e: NoSuchMethodException => 81 | if ((clazz == classOf[AnyRef]) || clazz.isInterface) 82 | throw e 83 | 84 | val superclass = clazz.getSuperclass 85 | logger.info(s"Method not found, try super-class $superclass") 86 | findMethod(superclass, methodName) 87 | } 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /src/test/keystores/client-keystore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vert-x/mod-lang-scala/a88cc48e2fcf4f9c96e623e02bc88a9ff76825fd/src/test/keystores/client-keystore.jks -------------------------------------------------------------------------------- /src/test/keystores/client-truststore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vert-x/mod-lang-scala/a88cc48e2fcf4f9c96e623e02bc88a9ff76825fd/src/test/keystores/client-truststore.jks -------------------------------------------------------------------------------- /src/test/keystores/server-keystore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vert-x/mod-lang-scala/a88cc48e2fcf4f9c96e623e02bc88a9ff76825fd/src/test/keystores/server-keystore.jks -------------------------------------------------------------------------------- /src/test/keystores/server-truststore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vert-x/mod-lang-scala/a88cc48e2fcf4f9c96e623e02bc88a9ff76825fd/src/test/keystores/server-truststore.jks -------------------------------------------------------------------------------- /src/test/keystores/ssl.txt: -------------------------------------------------------------------------------- 1 | 1) Create a private key + certificate for the server in a new key store: 2 | 3 | keytool -genkey -alias test-store -keyalg RSA -keystore server-keystore.jks -keysize 2048 4 | 5 | 2) Export the cert from the store 6 | 7 | keytool -export -alias test-store -file localhost.crt -keystore server-keystore.jks 8 | 9 | 3) Import the cert into a new trust-store for the client 10 | 11 | keytool -import -trustcacerts -alias test-store -file localhost.crt -keystore client-truststore.jks -------------------------------------------------------------------------------- /src/test/resources/error404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Not found! 4 | File not found. 5 | -------------------------------------------------------------------------------- /src/test/resources/helloscala.txt: -------------------------------------------------------------------------------- 1 | Hello Scala (sendFile)! -------------------------------------------------------------------------------- /src/test/resources/langs.properties: -------------------------------------------------------------------------------- 1 | scala=io.vertx~lang-scala_2.10~1.1.0-SNAPSHOT:org.vertx.scala.platform.impl.ScalaVerticleFactory 2 | .scala=scala 3 | -------------------------------------------------------------------------------- /src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2011 the original author or authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | log4j.rootCategory=WARN, stdout 17 | 18 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 19 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 20 | log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss.SSS} %-5p [%t][%c] %m%n 21 | 22 | log4j.category.org.vertx=WARN 23 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/core/eventbus/EventBusBridgeTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.tests.core.eventbus 17 | 18 | import org.vertx.scala.testtools.TestVerticle 19 | import org.vertx.scala.core.json.Json 20 | import org.vertx.testtools.VertxAssert._ 21 | import org.junit.Test 22 | 23 | class EventBusBridgeTest extends TestVerticle { 24 | 25 | @Test 26 | def letAllThroughBridge(): Unit = { 27 | val server = vertx.createHttpServer() 28 | 29 | val permitted = Json.arr() 30 | permitted.add(Json.obj()) // Let everything through 31 | 32 | val sockJSServer = vertx.createSockJSServer(server) 33 | sockJSServer.bridge(Json.obj("prefix" -> "/eventbus"), permitted, permitted) 34 | 35 | server.listen(8080, result => { 36 | assertThread() 37 | def client = vertx.createHttpClient().setPort(8080) 38 | // We use rawwebsocket transport 39 | client.connectWebsocket("/eventbus/websocket", websocket => { 40 | assertThread() 41 | // Register 42 | val msg = Json.obj("type" -> "register", "address" -> "someaddress") 43 | websocket.writeTextFrame(msg.encode()) 44 | 45 | // Send 46 | val msg2 = Json.obj("type" -> "send", "address" -> "someaddress", "body" -> "hello world") 47 | websocket.writeTextFrame(msg2.encode()) 48 | 49 | websocket.dataHandler { buffer => 50 | assertThread() 51 | val msg = buffer.toString() 52 | val received = Json.fromObjectString(msg) 53 | assert(received.getString("body").equals("hello world")) 54 | testComplete() 55 | } 56 | }) 57 | }) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/core/http/Compression.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.core.http 2 | 3 | /** 4 | * @author Galder Zamarreño 5 | */ 6 | sealed trait Compression { 7 | def enabled(): Boolean 8 | } 9 | 10 | case object Compressed extends Compression{ 11 | override def enabled(): Boolean = true 12 | } 13 | 14 | case object Uncompressed extends Compression{ 15 | override def enabled(): Boolean = false 16 | } 17 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/core/http/HttpCompressionTest.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.core.http 2 | 3 | import org.junit.Test 4 | import org.vertx.scala.tests.util.TestUtils._ 5 | import org.vertx.testtools.VertxAssert._ 6 | 7 | final class HttpCompressionTest extends HttpTestBase { 8 | 9 | val compression: Compression = Compressed 10 | 11 | @Test override def sendFile(): Unit = { 12 | val (file, content) = generateRandomContentFile("test-send-file.html", 10000) 13 | withClient(vertx.createHttpServer(), _.response().sendFile(file.getAbsolutePath)) { c => 14 | c.getNow("some-uri", { res => 15 | assertEquals(200, res.statusCode()) 16 | assertTrue(res.headers().entryExists("content-type", _ == "text/html")) 17 | res.bodyHandler { buff => 18 | assertEquals(content, buff.toString()) 19 | file.delete() 20 | testComplete() 21 | } 22 | }) 23 | } 24 | } 25 | 26 | @Test override def sendFileWithHandler(): Unit = { 27 | val (file, content) = generateRandomContentFile("test-send-file.html", 10000) 28 | var sendComplete = false 29 | withClient(vertx.createHttpServer(), _.response().sendFile(file.getAbsolutePath, { res => 30 | sendComplete = true 31 | } )) { c => 32 | c.getNow("some-uri", { res => 33 | assertEquals(200, res.statusCode()) 34 | assertTrue(res.headers().entryExists("content-type", _ == "text/html")) 35 | res.bodyHandler { buff => 36 | assertEquals(content, buff.toString()) 37 | file.delete() 38 | assertTrue(sendComplete) 39 | testComplete() 40 | } 41 | }) 42 | } 43 | } 44 | 45 | @Test override def sendFileOverrideHeaders(): Unit = { 46 | val (file, content) = generateRandomContentFile("test-send-file.html", 10000) 47 | withClient(vertx.createHttpServer(), 48 | _.response().putHeader("Content-Type", "wibble").sendFile(file.getAbsolutePath) 49 | ) { c => 50 | c.getNow("some-uri", { res => 51 | assertEquals(200, res.statusCode()) 52 | assertTrue(res.headers().entryExists("content-type", _ == "wibble")) 53 | res.bodyHandler { buff => 54 | assertEquals(content, buff.toString()) 55 | file.delete() 56 | testComplete() 57 | } 58 | }) 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/core/http/HttpConfigurationTest.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.core.http 2 | 3 | import org.junit.Test 4 | import org.vertx.scala.testtools.TestVerticle 5 | import org.vertx.testtools.VertxAssert._ 6 | 7 | class HttpConfigurationTest extends TestVerticle { 8 | 9 | @Test def testSetGetMaxWebSocketFrameSizeServer() { 10 | val server = vertx.createHttpServer() 11 | val size = 61231763 12 | assertEquals(server, server.setMaxWebSocketFrameSize(size)) 13 | assertEquals(size, server.getMaxWebSocketFrameSize) 14 | testComplete() 15 | } 16 | 17 | @Test def testSetGetMaxWebSocketFrameSizeClient() { 18 | val client = vertx.createHttpClient() 19 | val size = 61231763 20 | assertEquals(client, client.setMaxWebSocketFrameSize(size)) 21 | assertEquals(size, client.getMaxWebSocketFrameSize) 22 | testComplete() 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/core/http/HttpTest.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.core.http 2 | 3 | final class HttpTest extends HttpTestBase { 4 | 5 | val compression: Compression = Uncompressed 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/core/http/WebSocketsTest.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.core.http 2 | 3 | import org.vertx.scala.testtools.TestVerticle 4 | import org.vertx.testtools.VertxAssert._ 5 | import org.junit.Test 6 | import org.vertx.scala.core.AsyncResult 7 | import org.vertx.scala.core.http.HttpServer 8 | import org.vertx.scala.core.http.HttpClient 9 | import org.vertx.scala.core.http.HttpClientResponse 10 | import org.vertx.scala.core.http.ServerWebSocket 11 | import org.vertx.scala.core.http.WebSocket 12 | import org.vertx.scala.core.buffer.Buffer 13 | import org.vertx.scala.tests.util.TestUtils._ 14 | 15 | class WebSocketsTest extends TestVerticle { 16 | val testPort = 8844 17 | 18 | val html = 19 | 20 | test 21 | 22 | 23 |

Hello world!

24 | 25 | .toString() 26 | 27 | @Test def websocketServer(): Unit = { 28 | vertx.createHttpServer.websocketHandler(regularRequestHandler).listen(testPort, checkServer({ c => 29 | assertThread() 30 | c.connectWebsocket("/", correctBodyHandler(testComplete)) 31 | })) 32 | } 33 | 34 | @Test def secureWebsocketServer(): Unit = { 35 | val server = vertx.createHttpServer.setSSL(true) 36 | 37 | server.setKeyStorePath("./src/test/keystores/server-keystore.jks").setKeyStorePassword("wibble") 38 | server.setTrustStorePath("./src/test/keystores/server-truststore.jks").setTrustStorePassword("wibble") 39 | 40 | server.websocketHandler(regularRequestHandler).listen(testPort, checkServer({ c => 41 | assertThread() 42 | c.setSSL(true) 43 | c.setKeyStorePath("./src/test/keystores/client-keystore.jks").setKeyStorePassword("wibble") 44 | c.setTrustStorePath("./src/test/keystores/client-truststore.jks").setTrustStorePassword("wibble") 45 | c.exceptionHandler(ex => fail("Should not get exception but got " + ex)) connectWebsocket ("/", correctBodyHandler(testComplete)) 46 | })) 47 | } 48 | 49 | @Test def pingPongMessages(): Unit = { 50 | vertx.createHttpServer.websocketHandler({ ws: ServerWebSocket => 51 | ws.dataHandler({ buf => 52 | assertThread() 53 | if (buf.toString() == "ping") { 54 | ws.write(Buffer("pong")) 55 | } else if (buf.toString() == "ping2") { 56 | ws.write(Buffer("pong2")) 57 | } 58 | }) 59 | }).listen(testPort, checkServer({ c => 60 | assertThread() 61 | c.connectWebsocket("/", { resp: WebSocket => 62 | assertThread() 63 | resp.dataHandler({ buf => 64 | assertThread() 65 | assertEquals("pong", buf.toString) 66 | resp.dataHandler({ buf => 67 | assertThread() 68 | assertEquals("pong2", buf.toString) 69 | testComplete() 70 | }) 71 | resp.write(Buffer("ping2")) 72 | }) 73 | resp.write(Buffer("ping")) 74 | }) 75 | })) 76 | } 77 | 78 | @Test def websocketAddresses(): Unit = { 79 | vertx.createHttpServer.websocketHandler({ ws: ServerWebSocket => 80 | assertNotNull(ws.remoteAddress()) 81 | assertNotNull(ws.localAddress()) 82 | ws.dataHandler({ buf => 83 | assertThread() 84 | val addresses = buf.toString().split("\n") 85 | assertEquals(ws.remoteAddress().getAddress().getHostAddress().toString(), addresses(1)) 86 | assertEquals(ws.localAddress().getAddress().getHostAddress().toString(), addresses(0)) 87 | testComplete() 88 | }) 89 | }).listen(testPort, checkServer({ c => 90 | c.connectWebsocket("/", { ws: WebSocket => 91 | assertThread() 92 | ws.write(Buffer(ws.remoteAddress().getAddress().getHostAddress().toString() + "\n" 93 | + ws.localAddress().getAddress().getHostAddress().toString())) 94 | }) 95 | })) 96 | } 97 | 98 | private def regularRequestHandler: ServerWebSocket => Unit = { ws => 99 | ws.write(Buffer(html)) 100 | 101 | ws.dataHandler({ buf => 102 | assertThread() 103 | assertEquals(html, buf.toString) 104 | testComplete() 105 | }): Unit 106 | } 107 | 108 | private def correctBodyHandler(fn: () => Unit) = { resp: WebSocket => 109 | resp.dataHandler({ buf => 110 | assertThread() 111 | assertEquals(html, buf.toString) 112 | fn() 113 | }): Unit 114 | } 115 | 116 | private def checkServer(clientFn: HttpClient => Unit) = { ar: AsyncResult[HttpServer] => 117 | assertThread() 118 | if (ar.succeeded()) { 119 | val httpClient = vertx.createHttpClient.setPort(testPort) 120 | clientFn(httpClient) 121 | } else { 122 | fail("listening did not succeed: " + ar.cause().getMessage()) 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/core/streams/PumpTest.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.core.streams 2 | 3 | import java.nio.file.{Paths, Files} 4 | import org.junit.Test 5 | import org.vertx.scala.core.AsyncResult 6 | import org.vertx.scala.core.buffer.{ Buffer, BufferElem } 7 | import org.vertx.scala.core.file.AsyncFile 8 | import org.vertx.scala.core.http.{ HttpClient, HttpClientResponse, HttpServer, HttpServerRequest } 9 | import org.vertx.scala.core.streams.Pump 10 | import org.vertx.scala.testtools.TestVerticle 11 | import org.vertx.testtools.VertxAssert._ 12 | 13 | class PumpTest extends TestVerticle { 14 | 15 | val testPort = 8844 16 | 17 | val html = 18 | 19 | test 20 | 21 | 22 |

Hello world!

23 | 24 | .toString() 25 | 26 | @Test 27 | def pumpingHttp(): Unit = { 28 | vertx.createHttpServer.requestHandler(regularRequestHandler).listen(testPort, checkServer({ c => 29 | assertThread() 30 | val chunk = Buffer("hello pump") 31 | val req = c.post("/", { resp => 32 | assertEquals(200, resp.statusCode) 33 | val buffer = Buffer() 34 | resp.dataHandler { buff => 35 | assertThread() 36 | buffer.append(buff) 37 | } 38 | resp.endHandler { 39 | assertThread() 40 | assertEquals(chunk.length(), buffer.length()) 41 | assertEquals(chunk, buffer) 42 | testComplete() 43 | } 44 | }) 45 | req.setChunked(true) 46 | req.write(chunk) 47 | req.end() 48 | })) 49 | } 50 | 51 | @Test 52 | def pumpingFile(): Unit = withPumpFiles { (filename, oldFile, newFile) => 53 | oldFile.endHandler({ 54 | assertThread() 55 | oldFile.close { readCloseResult => 56 | if (readCloseResult.failed()) 57 | fail("Fail to close read file") 58 | else { 59 | newFile.close { writeCloseResult => 60 | if (writeCloseResult.failed()) 61 | fail("Fail to close write file") 62 | else { 63 | val readFileSize = vertx.fileSystem.propsSync(filename).size() 64 | val writtenBytes = Files.readAllBytes(Paths.get(filename + ".copy")) 65 | assertEquals(readFileSize, writtenBytes.length) 66 | vertx.fileSystem.deleteSync(filename + ".copy") 67 | testComplete() 68 | } 69 | } 70 | } 71 | } 72 | }) 73 | 74 | Pump.createPump(oldFile, newFile).start() 75 | } 76 | 77 | @Test 78 | def pumpStopAndResume(): Unit = withPumpFiles { (filename, oldFile, newFile) => 79 | val filesize = vertx.fileSystem.propsSync(filename).size 80 | val pump = Pump.createPump(oldFile, newFile) 81 | pump.setWriteQueueMaxSize((filesize / 10).intValue) 82 | 83 | for (i <- 0 to 9) { 84 | pump.start 85 | pump.stop 86 | } 87 | 88 | oldFile.endHandler({ 89 | assertThread() 90 | val filesizeNew = vertx.fileSystem.propsSync(filename + ".copy").size 91 | val oldContents = vertx.fileSystem.readFileSync(filename) 92 | val newContents = vertx.fileSystem.readFileSync(filename + ".copy") 93 | assertEquals("Filesize should match", filesize, filesizeNew) 94 | assertEquals("Filesize should match pumped bytes", filesize, pump.bytesPumped) 95 | assertEquals("Contents should match", oldContents, newContents) 96 | testComplete 97 | }) 98 | pump.start 99 | } 100 | 101 | private def withPumpFiles(fn: (String, AsyncFile, AsyncFile) => Unit): Unit = { 102 | val file = "src/test/resources/pumpfile.txt" 103 | if (vertx.fileSystem.existsSync(file + ".copy")) { 104 | vertx.fileSystem.deleteSync(file + ".copy") 105 | } 106 | vertx.fileSystem.createFileSync(file + ".copy") 107 | vertx.fileSystem.open(file, { ar1: AsyncResult[AsyncFile] => 108 | assertThread() 109 | assertTrue("Should be able to open " + file, ar1.succeeded()) 110 | val oldFile = ar1.result() 111 | vertx.fileSystem.open(file + ".copy", { ar2: AsyncResult[AsyncFile] => 112 | assertThread() 113 | assertTrue("Should be able to open " + file + ".copy", ar2.succeeded()) 114 | val newFile = ar2.result() 115 | fn(file, oldFile, newFile) 116 | }) 117 | }) 118 | } 119 | 120 | private def regularRequestHandler: HttpServerRequest => Unit = { req => 121 | req.response.setChunked(true) 122 | req.endHandler({ req.response.end }) 123 | Pump.createPump(req, req.response).start 124 | } 125 | 126 | private def checkServer(clientFn: HttpClient => Unit) = { ar: AsyncResult[HttpServer] => 127 | assertThread() 128 | if (ar.succeeded()) { 129 | val httpClient = vertx.createHttpClient.setPort(testPort) 130 | clientFn(httpClient) 131 | } else { 132 | fail("listening did not succeed: " + ar.cause().getMessage()) 133 | } 134 | } 135 | 136 | private def correctHandler(fn: () => Unit) = { resp: HttpClientResponse => 137 | resp.bodyHandler({ buf => 138 | assertThread() 139 | assertEquals(html, buf.toString) 140 | fn() 141 | }): Unit 142 | } 143 | 144 | } -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/lang/ScalaInterpreterTest.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.lang 2 | 3 | import java.io.{File, PrintWriter, StringWriter, Writer} 4 | 5 | import org.junit.Assert.fail 6 | import org.junit.Test 7 | import org.vertx.scala.lang.{ClassLoaders, ScalaInterpreter} 8 | import org.vertx.scala.platform.Verticle 9 | import org.vertx.scala.platform.impl.ScalaVerticle 10 | import org.vertx.scala.testtools.TestVerticle 11 | import org.vertx.testtools.VertxAssert._ 12 | 13 | import scala.tools.nsc.Settings 14 | import scala.util.{Failure, Success} 15 | 16 | class ScalaInterpreterTest extends TestVerticle { 17 | 18 | @Test 19 | def runScriptTest(): Unit = { 20 | val path = new File("src/test/scripts/VerticleScript.scala").toURI.toURL 21 | val out = new StringWriter() 22 | val interpreter = createInterpreter(out) 23 | interpreter.runScript(path) match { 24 | case Success(s) => 25 | assertHttpClientGetNow("Hello verticle script!") 26 | case Failure(ex) => 27 | println(out.toString) 28 | fail(ex.toString) 29 | } 30 | } 31 | 32 | @Test 33 | def runClassTest(): Unit = { 34 | val filePath = "src/test/scala/org/vertx/scala/tests/lang/VerticleClass.scala" 35 | val out = new StringWriter() 36 | val interpreter = createInterpreter(out) 37 | val classLoader = interpreter.compileClass(new File(filePath)) 38 | val className = "org.vertx.scala.tests.lang.VerticleClass" 39 | val delegate = ClassLoaders.newInstance[Verticle](className, classLoader.get) 40 | val verticle = ScalaVerticle.newVerticle(delegate.get, vertx, container) 41 | verticle.start() 42 | assertHttpClientGetNow("Hello verticle class!") 43 | } 44 | 45 | private def createInterpreter(out: Writer): ScalaInterpreter = { 46 | val settings = new Settings() 47 | settings.usejavacp.value = true 48 | settings.verbose.value = ScalaInterpreter.isVerbose 49 | new ScalaInterpreter(settings, vertx, container, new PrintWriter(out)) 50 | } 51 | 52 | private def assertHttpClientGetNow(expected: String) { 53 | val client = vertx.createHttpClient().setPort(8080) 54 | client.getNow("/", { h => 55 | assertThread() 56 | h.bodyHandler { data => { 57 | assertThread() 58 | assertEquals(expected, data.toString()) 59 | testComplete() 60 | } 61 | } 62 | }) 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/lang/ScalaScriptingTest.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.lang 2 | 3 | import org.vertx.testtools.ScriptClassRunner 4 | import org.junit.runner.RunWith 5 | import org.junit.Test 6 | import org.vertx.testtools.TestVerticleInfo 7 | 8 | /** 9 | * This is dummy JUnit test class which is used to run any Scala test scripts as JUnit tests. 10 | * 11 | * The scripts by default go in src/test/resources/integration_tests. 12 | * 13 | * If you don't have any Scala tests in your project you can delete this 14 | * 15 | * You do not need to edit this file unless you want it to look for tests elsewhere 16 | */ 17 | @TestVerticleInfo(filenameFilter = ".+\\.scala", funcRegex = "def[\\s]+(test[^\\s(]+)") 18 | @RunWith(classOf[ScriptClassRunner]) 19 | class ScalaScriptingTest { 20 | @Test 21 | def __vertxDummy(): Unit = {} 22 | } -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/lang/UnsupportedVerticleClass.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.tests.lang 17 | 18 | import org.vertx.scala.core.http.HttpServerRequest 19 | import org.vertx.scala.platform.Verticle 20 | 21 | // Class name different to file name for testing purposes 22 | class VerticleClassWithDifferentName extends Verticle { 23 | 24 | override def start() { 25 | vertx.createHttpServer().requestHandler { req: HttpServerRequest => 26 | req.response().end("Hello verticle class!") 27 | }.listen(8080) 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/lang/VerticleClass.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.tests.lang 17 | 18 | import org.vertx.scala.core.http.HttpServerRequest 19 | import org.vertx.scala.platform.Verticle 20 | 21 | class VerticleClass extends Verticle { 22 | 23 | override def start() { 24 | vertx.createHttpServer().requestHandler { req: HttpServerRequest => 25 | req.response().end("Hello verticle class!") 26 | }.listen(8080) 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/mods/TestBusMod.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.mods 2 | 3 | import org.vertx.scala.platform.Verticle 4 | import org.vertx.scala.mods.ScalaBusMod 5 | import org.vertx.scala.core.eventbus.Message 6 | import org.vertx.scala.core.json._ 7 | import org.vertx.scala.core.FunctionConverters._ 8 | import org.vertx.scala.mods.replies._ 9 | import scala.concurrent.Promise 10 | import scala.util.Try 11 | import scala.util.Success 12 | import scala.util.Failure 13 | import org.vertx.scala.mods.BusModException 14 | import scala.concurrent.Future 15 | import org.vertx.testtools.VertxAssert 16 | 17 | class TestBusMod extends Verticle with ScalaBusMod { 18 | override def start(promise: Promise[Unit]): Unit = { 19 | vertx.eventBus.registerHandler("test-bus-mod", this, { 20 | case Success(_) => promise.success() 21 | case Failure(ex) => promise.failure(ex) 22 | }: Try[Void] => Unit) 23 | } 24 | 25 | override def receive = (msg: Message[JsonObject]) => { 26 | case "sync-hello" => Ok(Json.obj("result" -> "sync-hello-result")) 27 | case "sync-error" => throw new RuntimeException("sync-error-result") 28 | case "sync-echo" => 29 | Option(msg.body.getString("echo")) match { 30 | case Some(echo) => Ok(Json.obj("echo" -> echo)) 31 | case None => Error("No echo argument given!", "NO_ECHO_GIVEN") 32 | } 33 | case "async-hello" => AsyncReply { 34 | val p = Promise[BusModReply] 35 | vertx.setTimer(10, { timerId => p.success(Ok(Json.obj("result" -> "async-hello-result"))) }) 36 | p.future 37 | } 38 | case "async-cascade" => AsyncReply { 39 | val p = Promise[BusModReply] 40 | vertx.setTimer(10, { timerId => 41 | p.success(AsyncReply { 42 | val p2 = Promise[BusModReply] 43 | vertx.setTimer(10, { timerId2 => 44 | p2.success(Ok(Json.obj("result" -> "async-cascade-result"))) 45 | }) 46 | p2.future 47 | }) 48 | }) 49 | p.future 50 | } 51 | case "async-cascade-uncaught" => AsyncReply { 52 | val p = Promise[BusModReply] 53 | vertx.setTimer(10, { timerId => 54 | p.failure(new RuntimeException("async-uncaught-exception")) 55 | }) 56 | p.future 57 | } 58 | case "async-error-1" => AsyncReply { 59 | throw new RuntimeException("uncaught-exception") 60 | } 61 | case "async-error-2" => AsyncReply { 62 | Future.failed(new BusModException("caught-exception", id = "CAUGHT_EXCEPTION")) 63 | } 64 | case "reply-notimeout" => 65 | Ok(Json.obj("echo" -> msg.body.getString("echo")), Some(Receiver(msg => { 66 | case "reply-notimeout-reply" => Ok(Json.obj("echo" -> msg.body.getString("echo"))) 67 | }))) 68 | case "reply-timeout" => 69 | val clientAddress = msg.body().getString("address") 70 | Ok(Json.obj("state" -> "waitForTimeout"), Some(ReceiverWithTimeout(msg => { 71 | case x => 72 | vertx.eventBus.send(clientAddress, Json.obj("state" -> "error:should-not-get-reply")) 73 | Error("should not receive message") 74 | }, 500L, { () => 75 | vertx.eventBus.send(clientAddress, Json.obj("state" -> "timeout")) 76 | }))) 77 | case "reply-error-ok" => 78 | Error("no.", replyHandler = Some(Receiver(msg => { 79 | case "please" => Ok(Json.obj("echo" -> msg.body.getString("echo"))) 80 | }))) 81 | case "no-direct-reply" => 82 | val clientAddress = msg.body.getString("address") 83 | vertx.eventBus.send(clientAddress, Json.obj("echo" -> msg.body.getString("echo"))) 84 | NoReply 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/plattform/impl/ScalaVerticleFactoryTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.tests.plattform.impl 17 | 18 | import org.junit.Test 19 | import org.vertx.scala.testtools.TestVerticle 20 | import org.vertx.scala.platform.impl.ScalaVerticleFactory 21 | import org.vertx.testtools.VertxAssert._ 22 | 23 | /** 24 | * Scala verticle factory tests. 25 | * 26 | * @author Galder Zamarreño 27 | */ 28 | class ScalaVerticleFactoryTest extends TestVerticle { 29 | 30 | @Test 31 | def createVerticleWithSystemPath(): Unit = { 32 | val factory = createScalaVerticleFactory() 33 | val path = "src/test/scala/org/vertx/scala/tests/lang/VerticleClass.scala" 34 | val verticle = factory.createVerticle(path) 35 | verticle.start() 36 | assertHttpClientGetNow("Hello verticle class!") 37 | } 38 | 39 | @Test 40 | def createVerticleWithUnmatchingPathAndClassName(): Unit = { 41 | val factory = createScalaVerticleFactory() 42 | val path = "src/test/scala/org/vertx/scala/tests/lang/UnsupportedVerticleClass.scala" 43 | try { 44 | factory.createVerticle(path) 45 | fail("Should have failed with an exception") 46 | } catch { 47 | case e: ClassNotFoundException => testComplete() // expected 48 | } 49 | } 50 | 51 | private def createScalaVerticleFactory(): ScalaVerticleFactory = { 52 | val factory = new ScalaVerticleFactory 53 | factory.init(vertx.asJava, container.asJava, this.getClass.getClassLoader) 54 | factory 55 | } 56 | 57 | private def assertHttpClientGetNow(expected: String) { 58 | val client = vertx.createHttpClient().setPort(8080) 59 | client.getNow("/", {h => 60 | assertThread() 61 | h.bodyHandler { data => { 62 | assertThread() 63 | assertEquals(expected, data.toString()) 64 | testComplete() 65 | } 66 | } 67 | }) 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/plattform/impl/SystemPropertyDefaultLangOverrideTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.vertx.scala.tests.plattform.impl 17 | 18 | import java.net.{URLClassLoader, URL} 19 | import org.hamcrest.Matchers.startsWith 20 | import org.junit.Assert._ 21 | import org.junit.{After, Before, Test} 22 | import org.vertx.java.platform.{PlatformManager, PlatformLocator} 23 | import org.vertx.scala.core.AsyncResult 24 | import org.vertx.scala.core.FunctionConverters._ 25 | import org.vertx.scala.tests.lang.VerticleClass 26 | import scala.collection.mutable 27 | import scala.concurrent.duration._ 28 | import scala.concurrent.{Await, Promise} 29 | 30 | /** 31 | * @author Galder Zamarreño 32 | */ 33 | class SystemPropertyDefaultLangOverrideTest { 34 | 35 | var mgr: PlatformManager = _ 36 | 37 | @Before def beforeTest() { 38 | System.setProperty("vertx.langs..", "scala") // override default via system property 39 | mgr = PlatformLocator.factory.createPlatformManager 40 | } 41 | 42 | @After def afterTest() { 43 | System.clearProperty("vertx.langs..") 44 | mgr.stop() 45 | } 46 | 47 | @Test def testDeployVerticle(): Unit = { 48 | val p = Promise[String]() 49 | 50 | val handler: AsyncResult[String] => Unit = { res => 51 | if (res.succeeded()) p.success(res.result()) else p.failure(res.cause()) 52 | } 53 | 54 | mgr.deployVerticle(classOf[VerticleClass].getName, null, findURLs().orNull, 1, null, handler) 55 | assertThat(Await.result(p.future, 10 second), startsWith("deployment-")) 56 | } 57 | 58 | private def findURLs(): Option[Array[URL]] = { 59 | val urls = mutable.ListBuffer[URL]() 60 | val pcl = Thread.currentThread.getContextClassLoader 61 | pcl match { 62 | case u: URLClassLoader => 63 | for (url <- u.getURLs) { 64 | val stringUrl = url.toString 65 | if (!stringUrl.endsWith(".jar") && !stringUrl.endsWith(".zip")) 66 | urls += url 67 | } 68 | Some(urls.toArray) 69 | case _ => None 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/router/AuthRouter.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.router 2 | 3 | import org.vertx.scala.platform.Verticle 4 | import org.vertx.scala.core.FunctionConverters._ 5 | import scala.concurrent.{Future, Promise} 6 | import scala.util.{Try, Failure, Success} 7 | import org.vertx.scala.core.http.{HttpServerRequest, HttpServer} 8 | import org.vertx.scala.router.{RouterException, Router} 9 | import org.vertx.scala.router.routing.{SendFile, Get} 10 | 11 | /** 12 | * @author Joern Bernhardt 13 | */ 14 | class AuthRouter extends Verticle with Router { 15 | override def start(p: Promise[Unit]) = { 16 | vertx.createHttpServer().requestHandler(this).listen(8080, { 17 | case Success(s) => p.success() 18 | case Failure(x) => p.failure(x) 19 | }: Try[HttpServer] => Unit) 20 | } 21 | 22 | override def checkAuthentication(req: HttpServerRequest): Future[Boolean] = { 23 | req.path() match { 24 | case "/teapot" => 25 | Future.failed( 26 | RouterException(message = RouterTestHelper.customAuthExceptionMessage(), id = "TEAPOT", statusCode = 418)) 27 | case _ => 28 | val option = for { 29 | tokenSet <- req.headers().get("X-XSRF-TOKEN") 30 | token <- tokenSet.headOption 31 | } yield token == "secret" 32 | 33 | Future.successful(option.getOrElse(false)) 34 | } 35 | } 36 | 37 | override def routes(implicit req: HttpServerRequest): Routing = { 38 | case Get("/member") 39 | | Get("/teapot") => authed { 40 | SendFile("helloscala.txt") 41 | } 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/router/JsonRouter.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.router 2 | 3 | import org.vertx.scala.router.{RouterException, Router} 4 | import org.vertx.scala.core.http.{HttpServer, HttpServerRequest} 5 | import org.vertx.scala.core.FunctionConverters._ 6 | import org.vertx.scala.router.routing._ 7 | import org.vertx.scala.platform.Verticle 8 | import scala.concurrent.Promise 9 | import scala.util.{Try, Failure, Success} 10 | import org.vertx.scala.core.json.Json 11 | import scala.util.matching.Regex 12 | 13 | /** 14 | * @author Joern Bernhardt 15 | */ 16 | class JsonRouter extends Verticle with Router { 17 | 18 | override def start(p: Promise[Unit]) = { 19 | vertx.createHttpServer().requestHandler(this).listen(8080, { 20 | case Success(s) => p.success() 21 | case Failure(x) => p.failure(x) 22 | }: Try[HttpServer] => Unit) 23 | } 24 | 25 | override def notFoundFile = "error404.html" 26 | 27 | val IdMatcher = "/get/(\\d+)".r 28 | 29 | override def routes(implicit req: HttpServerRequest): Routing = { 30 | case Get("/") => SendFile("helloscala.txt") 31 | case Get("/test.txt") => SendFile("helloscala.txt") 32 | case Get("/not-found") => SendFile("not-existing.txt") 33 | case Get("/cookies1") => SetCookie("a", "1", Ok(Json.obj())) 34 | case Get("/cookies2") => SetCookie("a", "1", SetCookie("b", "2", Ok(Json.obj()))) 35 | case Get(IdMatcher(id)) => Ok(Json.obj("result" -> id)) 36 | case Post("/") => Ok(Json.obj("status" -> "ok")) 37 | case Post("/post-ok") => Ok(Json.obj("status" -> "ok")) 38 | case Head("/head") => Header("x-custom-head", "hello", NoBody) 39 | case Delete("/forbidden") => Error(RouterException(message = "not authorized", statusCode = 403)) 40 | case All("/all-test") => SendFile("helloscala.txt") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/router/JsonRouterTest.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.router 2 | 3 | import org.junit.Test 4 | import org.vertx.scala.FutureOps 5 | import org.vertx.testtools.VertxAssert._ 6 | import FutureOps._ 7 | import org.vertx.scala.core.FunctionConverters._ 8 | import scala.concurrent.{ExecutionContext, Promise, Future} 9 | import scala.util.{Try, Failure, Success} 10 | import org.vertx.scala.core.json.Json 11 | import org.vertx.scala.core.http.HttpClientResponse 12 | 13 | /** 14 | * @author Joern Bernhardt 15 | */ 16 | class JsonRouterTest extends RouterTestHelper { 17 | 18 | override def asyncBefore(): Future[Unit] = futurify { p: Promise[Unit] => 19 | container.deployVerticle("scala:org.vertx.scala.tests.router.JsonRouter", handler = { 20 | case Success(deployId) => p.success() 21 | case Failure(ex) => p.failure(ex) 22 | }: Try[String] => Unit) 23 | } 24 | 25 | @Test def indexGet(): Unit = doHttp("GET", "/") map bodyOkCompleter { body => 26 | assertEquals(testFileContents(), body) 27 | } 28 | 29 | @Test def pathGet(): Unit = doHttp("GET", "/test.txt") map bodyOkCompleter { body => 30 | assertEquals(testFileContents(), body) 31 | } 32 | 33 | @Test def missingFileSend(): Unit = doHttp("GET", "/not-found") map { res: HttpClientResponse => 34 | assertEquals(404, res.statusCode()) 35 | checkBody { body => 36 | assertEquals(error404FileContents(), body) 37 | }(res) 38 | } 39 | 40 | @Test def singleCookie(): Unit = doHttp("GET", "/cookies1") map { res => 41 | assertEquals(200, res.statusCode()) 42 | assertEquals(Set("a=1"), res.headers().get("Set-Cookie").get) 43 | res.endHandler(testComplete()) 44 | } 45 | 46 | @Test def multipleCookies(): Unit = doHttp("GET", "/cookies2") map { res => 47 | assertEquals(200, res.statusCode()) 48 | assertEquals(Set("a=1", "b=2"), res.headers().get("Set-Cookie").get) 49 | res.endHandler(testComplete()) 50 | } 51 | 52 | @Test def indexPost(): Unit = doHttp("POST", "/") map bodyOkCompleter({ body => 53 | assertEquals("ok", Json.fromObjectString(body).getString("status")) 54 | }) 55 | 56 | @Test def pathPost(): Unit = doHttp("POST", "/post-ok") map bodyOkCompleter({ body => 57 | assertEquals("ok", Json.fromObjectString(body).getString("status")) 58 | }) 59 | 60 | @Test def patchNotFound(): Unit = doHttp("PATCH", "/not-found") map { res => 61 | assertEquals(404, res.statusCode()) 62 | testComplete() 63 | } 64 | 65 | @Test def deleteForbidden(): Unit = doHttp("DELETE", "/forbidden") map { res => 66 | assertEquals(403, res.statusCode()) 67 | testComplete() 68 | } 69 | 70 | @Test def customHead(): Unit = doHttp("HEAD", "/head") map { res => 71 | assertEquals(200, res.statusCode()) 72 | assertTrue(res.headers().entryExists("x-custom-head", _ == "hello")) 73 | testComplete() 74 | } 75 | 76 | @Test def allMatchesGet(): Unit = doHttp("GET", "/all-test") map bodyOkCompleter { body => 77 | assertEquals(testFileContents(), body) 78 | } 79 | 80 | @Test def allMatchesPost(): Unit = doHttp("POST", "/all-test") map bodyOkCompleter { body => 81 | assertEquals(testFileContents(), body) 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/router/RouterAuthTest.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.router 2 | 3 | import org.vertx.scala.FutureOps 4 | 5 | import scala.concurrent.{ExecutionContext, Promise, Future} 6 | import FutureOps._ 7 | import org.vertx.scala.core.FunctionConverters._ 8 | import scala.util.Try 9 | import org.junit.Test 10 | import org.vertx.testtools.VertxAssert._ 11 | import scala.util.Failure 12 | import scala.util.Success 13 | import org.vertx.scala.core.http.HttpClientResponse 14 | 15 | /** 16 | * @author Joern Bernhardt 17 | */ 18 | class RouterAuthTest extends RouterTestHelper { 19 | override def asyncBefore(): Future[Unit] = futurify { p: Promise[Unit] => 20 | container.deployVerticle("scala:org.vertx.scala.tests.router.AuthRouter", handler = { 21 | case Success(deployId) => p.success() 22 | case Failure(ex) => p.failure(ex) 23 | }: Try[String] => Unit) 24 | } 25 | 26 | @Test def unauthorizedGet(): Unit = doHttp("GET", "/member") map { res => 27 | assertEquals("Should get a 401-UNAUTHORIZED status code", 401, res.statusCode()) 28 | testComplete() 29 | } 30 | 31 | @Test def authorizedGet(): Unit = doAuthedHttp("GET", "/member") map bodyOkCompleter({ body => 32 | assertEquals("Should receive the real test file contents", testFileContents(), body) 33 | }) 34 | 35 | @Test def wrongAuthTokenGet(): Unit = doHttpInternal("GET", "/member") { req => 36 | req.putHeader("X-XSRF-TOKEN", "wrong") 37 | } map { res: HttpClientResponse => 38 | assertEquals("Should get a 401-UNAUTHORIZED status code", 401, res.statusCode()) 39 | testComplete() 40 | } 41 | 42 | @Test def shouldGetOwnException(): Unit = doHttpInternal("GET", "/teapot") { req => 43 | req.putHeader("X-XSRF-TOKEN", "whatever") 44 | } map { res => 45 | res.bodyHandler { buffer => 46 | assertEquals("Should get the customized auth message", RouterTestHelper.customAuthExceptionMessage(), buffer.toString("UTF-8")) 47 | logger.info("got right body") 48 | testComplete() 49 | } 50 | assertEquals("Should get a 418 status code", 418, res.statusCode()) 51 | assertEquals("Should get a TEAPOT status message", "TEAPOT", res.statusMessage()) 52 | vertx.setTimer(2000, { id => 53 | fail("Test didn't handle the body -> broken!") 54 | }) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/router/RouterTestHelper.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.router 2 | 3 | import org.vertx.scala.FutureOps 4 | import org.vertx.scala.core.http.{HttpClientRequest, HttpClientResponse} 5 | import org.vertx.testtools.VertxAssert._ 6 | import scala.concurrent.{Promise, Future} 7 | import FutureOps._ 8 | import org.vertx.scala.testtools.TestVerticle 9 | 10 | /** 11 | * @author Joern Bernhardt 12 | */ 13 | trait RouterTestHelper extends TestVerticle { 14 | 15 | protected def error404FileContents(): String = 16 | vertx.fileSystem.readFileSync("error404.html").toString("UTF-8") 17 | 18 | protected def testFileContents(): String = 19 | vertx.fileSystem.readFileSync("helloscala.txt").toString("UTF-8") 20 | 21 | protected def bodyOkCompleter[B](fn: String => B): HttpClientResponse => Unit = { res: HttpClientResponse => 22 | assertEquals(200, res.statusCode()) 23 | checkBody(fn)(res) 24 | } 25 | 26 | protected def checkBody[B](fn: String => B): HttpClientResponse => Unit = { res: HttpClientResponse => 27 | res.bodyHandler { body => 28 | logger.info("in checkBody test") 29 | fn(body.toString("UTF-8")) 30 | testComplete() 31 | } 32 | logger.info("set checkBody test") 33 | } 34 | 35 | protected def doHttp(method: String, uri: String): Future[HttpClientResponse] = { 36 | doHttpInternal(method, uri) { _ =>} 37 | } 38 | 39 | protected def doAuthedHttp(method: String, uri: String): Future[HttpClientResponse] = { 40 | doHttpInternal(method, uri) { request => 41 | request.putHeader("X-XSRF-TOKEN", "secret") 42 | } 43 | } 44 | 45 | protected def doHttpInternal(method: String, uri: String)(fn: HttpClientRequest => Unit): 46 | Future[HttpClientResponse] = futurify { 47 | p: Promise[HttpClientResponse] => 48 | val request = vertx.createHttpClient() 49 | .setPort(8080) 50 | .request(method, uri, { res => 51 | p.success(res) 52 | }) 53 | fn(request) 54 | request.end() 55 | } 56 | 57 | } 58 | 59 | object RouterTestHelper { 60 | def customAuthExceptionMessage(): String = "i'm a teapot." 61 | } -------------------------------------------------------------------------------- /src/test/scala/org/vertx/scala/tests/util/TestUtils.scala: -------------------------------------------------------------------------------- 1 | package org.vertx.scala.tests.util 2 | 3 | import org.vertx.scala.core.AsyncResult 4 | import org.vertx.testtools.VertxAssert._ 5 | import org.vertx.scala.platform.Container 6 | import org.vertx.scala.core.buffer.Buffer 7 | import scala.annotation.tailrec 8 | import java.io.{FileOutputStream, OutputStreamWriter, BufferedWriter, File} 9 | 10 | /** 11 | * Port of some of the original TestUtils Helper methods. 12 | * 13 | * @author Edgar Chan 14 | * @author Galder Zamarreño 15 | */ 16 | object TestUtils { 17 | 18 | def completeWithArFailed[T]: AsyncResult[T] => Unit = { ar => 19 | assertTrue(ar.failed()) 20 | assertTrue(ar.cause() != null) 21 | testComplete() 22 | } 23 | 24 | def startTests(script: AnyRef, container: Container): Unit = { 25 | val methodName = container.config().getString("methodName") 26 | script.getClass.getMethod(methodName).invoke(script) 27 | } 28 | 29 | def generateRandomBuffer(length: Int): Buffer = 30 | generateRandomBuffer(length, avoid = false, 0.toByte) 31 | 32 | def generateRandomBuffer(length: Int, avoid: Boolean, avoidByte: Byte): Buffer = 33 | Buffer(generateRandomByteArray(length, avoid, avoidByte)) 34 | 35 | def generateRandomByteArray(length: Int): Array[Byte] = 36 | generateRandomByteArray(length, avoid = false, 0.toByte) 37 | 38 | def generateRandomByteArray(length: Int, avoid: Boolean, avoidByte: Byte): Array[Byte] = { 39 | val line = new Array[Byte](length) 40 | var i = 0 41 | do { 42 | var rand:Byte = 0.toByte 43 | do { 44 | rand = ((Math.random() * 255) - 128).toByte 45 | } while(avoid && rand == avoidByte) 46 | line(i) = rand 47 | i += 1 48 | } while(i < length) 49 | line 50 | } 51 | 52 | def generateRandomUnicodeString(length: Int): String = { 53 | val builder = new StringBuilder(length) 54 | for (i <- 0 until length) { 55 | @tailrec def generateChar(): Char = { 56 | val c = (0xFFFF * Math.random()).toChar 57 | // Skip illegal chars 58 | if ((c >= 0xFFFE && c <= 0xFFFF) || (c >= 0xD800 && c <= 0xDFFF)) 59 | generateChar() 60 | else 61 | c 62 | } 63 | 64 | builder.append(generateChar()) 65 | } 66 | builder.toString() 67 | } 68 | 69 | def generateRandomContentFile(filename: String, len: Int): (File, String) = { 70 | val content = TestUtils.generateRandomUnicodeString(len) 71 | val file = createFile(filename, content) 72 | (file, content) 73 | } 74 | 75 | def generateFile(filename: String, content: String): (File, String) = { 76 | val file = createFile(filename, content) 77 | (file, content) 78 | } 79 | 80 | private def createFile(filename: String, content: String): File = { 81 | val file = new File(System.getProperty("java.io.tmpdir"), filename) 82 | if (file.exists()) 83 | file.delete() 84 | 85 | val out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) 86 | try { 87 | out.write(content) 88 | } finally { 89 | out.close() 90 | } 91 | 92 | file 93 | } 94 | 95 | } -------------------------------------------------------------------------------- /src/test/scripts/ScriptingTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import org.vertx.scala.tests.util.TestUtils._ 18 | import org.vertx.testtools.VertxAssert._ 19 | import org.vertx.testtools.VertxAssert 20 | 21 | VertxAssert.initialize(vertx.asJava) 22 | 23 | vertx.createHttpServer.requestHandler { req: HttpServerRequest => 24 | req.response.end("Hello verticle test script!") 25 | }.listen(8080, { ar: AsyncResult[HttpServer] => { 26 | startTests(this, container) 27 | }}) 28 | 29 | def testHttpServer(): Unit = { 30 | vertx.createHttpClient.setPort(8080).getNow("/", { resp => 31 | resp.bodyHandler({ buf => 32 | assertEquals("Hello verticle test script!", buf.toString) 33 | testComplete() 34 | }) 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /src/test/scripts/VerticleScript.scala: -------------------------------------------------------------------------------- 1 | vertx.createHttpServer.requestHandler { req: HttpServerRequest => 2 | req.response.end("Hello verticle script!") 3 | }.listen(8080) 4 | --------------------------------------------------------------------------------