├── .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 ListHello 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 | 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 |
--------------------------------------------------------------------------------