diff --git a/project/Build.scala b/project/Build.scala index 1a2c69c..aacce58 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -4,16 +4,16 @@ import Keys._ object ApplicationBuild extends Build { val dependencies = Seq( - "org.scalatest" %% "scalatest" % "1.8" % "test", - "io.spray" % "spray-can" % "1.0-M7", - "io.spray" % "spray-client" % "1.0-M7", - "io.spray" % "spray-json_2.9.2" % "1.2.3", - "com.typesafe.akka" % "akka-actor" % "2.0.4", + "org.scalatest" %% "scalatest" % "2.0" % "test", + "io.spray" % "spray-can" % "1.2.0", + "io.spray" % "spray-client" % "1.2.0", + "io.spray" % "spray-json_2.10" % "1.2.5", + "com.typesafe.akka" % "akka-actor_2.10" % "2.2.3", "com.novocode" % "junit-interface" % "0.10-M1" % "test" ) val main = Project(id = "sprouch", base = new File("."), settings = Project.defaultSettings ++ Seq( - (scalaVersion := "2.9.2"), + (scalaVersion := "2.10.3"), (libraryDependencies ++= dependencies), (resolvers ++= Seq( "spray repo" at "http://repo.spray.io", @@ -22,9 +22,9 @@ object ApplicationBuild extends Build { (testOptions in Test := Nil), (publishTo := Some(Resolver.file( "gh-pages", - new File("/home/k/workspaces/sprouch-pages/repository/") + new File("/Users/thadeu/Documents/source-codes/open-source/sprouch/pages") ))), - (version := "0.5.11") + (version := "0.5.11-custom") )) } diff --git a/project/build.properties b/project/build.properties index 4474a03..37b489c 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.12.1 +sbt.version=0.13.1 diff --git a/project/plugins.sbt b/project/plugins.sbt index fd28a6a..9f07fa1 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,3 +6,4 @@ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/release resolvers += "sonatype-snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/" +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0") \ No newline at end of file diff --git a/src/main/resources/reference.conf b/src/main/resources/reference.conf index 731eb98..17dd350 100644 --- a/src/main/resources/reference.conf +++ b/src/main/resources/reference.conf @@ -1,3 +1,3 @@ spray.can.client { - ssl-encryption = on + } diff --git a/src/main/scala/sprouch/Couch.scala b/src/main/scala/sprouch/Couch.scala index ece5215..b933d3f 100644 --- a/src/main/scala/sprouch/Couch.scala +++ b/src/main/scala/sprouch/Couch.scala @@ -1,10 +1,9 @@ package sprouch import akka.actor._ -import akka.dispatch.Future -import spray.can.client.HttpClient -import spray.client.HttpConduit -import HttpConduit._ +import scala.concurrent.Future +import spray.can.Http +import spray.client.pipelining._ import spray.http._ import HttpMethods._ import spray.httpx.encoding.{Gzip, Deflate} @@ -16,7 +15,6 @@ import spray.util._ import java.util.UUID import akka.event.Logging import java.net.URLEncoder.{encode => urlEncode} - import JsonProtocol._ private[sprouch] trait UriBuilder { @@ -35,7 +33,9 @@ case class SprouchException(error:ErrorResponse) extends Exception * Class that handles the connection to CouchDB. It contains methods for creating, looking up and deleting databases. */ class Couch(config:Config) extends UriBuilder { - + implicit val system = ActorSystem() + import system.dispatcher // execution context for futures + private val pipelines = new Pipelines(config) private lazy val pipeline = pipelines.pipeline[OkResponse] private lazy val getDbPipeline = pipelines.pipeline[GetDbResponse] diff --git a/src/main/scala/sprouch/Database.scala b/src/main/scala/sprouch/Database.scala index 93fef7f..a3e9fff 100644 --- a/src/main/scala/sprouch/Database.scala +++ b/src/main/scala/sprouch/Database.scala @@ -1,14 +1,14 @@ package sprouch +import akka.actor._ import java.util.UUID import spray.httpx.marshalling.Marshaller import spray.httpx.unmarshalling.Unmarshaller import akka.actor.ActorRef import spray.http.HttpMethods.HEAD -import spray.client.HttpConduit -import HttpConduit.{Post, Delete, Get, Put} +import spray.client.pipelining._ import spray.httpx.SprayJsonSupport._ -import akka.dispatch.Future +import scala.concurrent.Future import spray.json.RootJsonFormat import spray.httpx.RequestBuilding.RequestBuilder import spray.http.HttpRequest @@ -25,7 +25,9 @@ import spray.json.JsValue */ class Database private[sprouch](val name:String, pipelines:Pipelines) extends UriBuilder { import pipelines._ - + implicit val system = ActorSystem() + import system.dispatcher // execution context for futures + private def dbUri:String = dbUri(name) private def docUri(doc:Document[_]):String = docUri(doc.id) private def docUri(id:String) = path(name, id) diff --git a/src/main/scala/sprouch/JsonProtocol.scala b/src/main/scala/sprouch/JsonProtocol.scala index e97fb0d..2fae99f 100644 --- a/src/main/scala/sprouch/JsonProtocol.scala +++ b/src/main/scala/sprouch/JsonProtocol.scala @@ -1,8 +1,6 @@ package sprouch -import spray.can.client.HttpClient -import spray.client.HttpConduit -import HttpConduit._ +import spray.client.pipelining import spray.http._ import HttpMethods._ import spray.httpx.encoding.{Gzip, Deflate} diff --git a/src/main/scala/sprouch/LocalEnv.scala b/src/main/scala/sprouch/LocalEnv.scala index 0c5714a..e97fe11 100644 --- a/src/main/scala/sprouch/LocalEnv.scala +++ b/src/main/scala/sprouch/LocalEnv.scala @@ -1,9 +1,9 @@ package sprouch import akka.actor.ActorSystem -import akka.util.Duration -import akka.dispatch.Future -import akka.dispatch.Await +import scala.concurrent.duration.Duration +import scala.concurrent.Future +import scala.concurrent.Await /** * Convenience methods and values for the default config of a local CouchDb install. @@ -23,7 +23,7 @@ object LocalEnv { /** * timeout for futures, default 10 seconds */ - var testDuration = Duration("10 seconds") + val testDuration = Duration("10 seconds") /** * convenience method to wait for future completion */ diff --git a/src/main/scala/sprouch/Pipelines.scala b/src/main/scala/sprouch/Pipelines.scala index 66ed812..953039a 100644 --- a/src/main/scala/sprouch/Pipelines.scala +++ b/src/main/scala/sprouch/Pipelines.scala @@ -1,15 +1,15 @@ package sprouch +import akka.util.Timeout import akka.actor._ -import akka.dispatch.Future -import spray.can.client.HttpClient -import spray.client.HttpConduit -import HttpConduit._ +import scala.concurrent.Future +import spray.client.pipelining +import spray.client.pipelining._ import spray.http._ import HttpMethods._ import spray.httpx.encoding.{Gzip, Deflate} import spray.httpx.SprayJsonSupport._ -import spray.httpx.unmarshalling.Unmarshaller +import spray.httpx.unmarshalling.FromResponseUnmarshaller import spray.json._ import spray.util._ import java.util.UUID @@ -19,9 +19,12 @@ import akka.actor.Props import akka.event.Logging import sprouch.JsonProtocol.ErrorResponseBody import sprouch.JsonProtocol.ErrorResponse -import spray.io.IOBridge -import spray.io.IOExtension - +import akka.io.IO +import spray.can.Http +import akka.pattern.ask +import spray.io.{ ConnectionTimeouts, ClientSSLEngineProvider, ServerSSLEngineProvider } +import scala.concurrent.duration.Duration +import scala.concurrent.Await /** * Configuration data, default values should be valid for a default install of CouchDB. * @@ -39,44 +42,36 @@ case class Config( https:Boolean = false ) -private[sprouch] class Pipelines(config:Config) { - import config._ - - private val conduit = { - val ioBridge = IOExtension(actorSystem).ioBridge() - val httpClient = actorSystem.actorOf(Props(new HttpClient(ioBridge))) - actorSystem.actorOf(Props(new HttpConduit(httpClient, hostName, port, https))) - } - private val log = Logging(actorSystem, conduit) +private[sprouch] class Pipelines(config:Config) { + import config._ + implicit val system = actorSystem + implicit val timeout = Timeout(10000) + import system.dispatcher - private val logRequest: HttpRequest => HttpRequest = r => { - log.info(r.toString + "\n") - r - } + def transportActorRefFuture = for ( + Http.HostConnectorInfo(connector, _) <- IO(Http)(actorSystem) ? Http.HostConnectorSetup(host = hostName, port = port, sslEncryption = https) + ) yield connector - private val logResponse: HttpResponse => HttpResponse = r => { - log.info(r.toString + "\n") - r - } - def pipeline[A:Unmarshaller]: HttpRequest => Future[A] = pipeline[A](None) + def pipeline[A:FromResponseUnmarshaller]: HttpRequest => Future[A] = pipeline[A](None) - def pipeline[A:Unmarshaller](etag:Option[String]): HttpRequest => Future[A] = { - def unmarshalEither[A:Unmarshaller]: HttpResponse => A = { + def pipeline[A:FromResponseUnmarshaller](etag:Option[String]): HttpRequest => Future[A] = { + def unmarshalEither[A:FromResponseUnmarshaller]: HttpResponse => A = { hr => (hr match { - case HttpResponse(status, _, _, _) if status.value == 304 => {//not modified - throw new SprouchException(ErrorResponse(status.value, None)) + case HttpResponse(status, _, _, _) if status.intValue == 304 => {//not modified + throw new SprouchException(ErrorResponse(status.intValue, None)) } case HttpResponse(status, _, _, _) if status.isSuccess => { - unmarshal[A](implicitly[Unmarshaller[A]])(hr) + unmarshal[A](implicitly[FromResponseUnmarshaller[A]])(hr) } case HttpResponse(errorStatus, _, _, _) => { - log.error(hr.toString) - val ue = implicitly[Unmarshaller[ErrorResponseBody]] + val ue = implicitly[FromResponseUnmarshaller[ErrorResponseBody]] val body = unmarshal[ErrorResponseBody](ue)(hr.copy(status = StatusCodes.OK)) - throw new SprouchException(ErrorResponse(errorStatus.value, Option(body))) + throw new SprouchException(ErrorResponse(errorStatus.intValue, Option(body))) } }) } + val transportActorRef = Await.result[ActorRef](transportActorRefFuture, Duration("10 seconds")) + addHeader("accept", "application/json") ~> (etag match { case Some(etag) => addHeader("If-None-Match", "\"" + etag + "\"") @@ -86,9 +81,7 @@ private[sprouch] class Pipelines(config:Config) { case Some((u,p)) => addCredentials(BasicHttpCredentials(u, p)) case None => (x:HttpRequest) => x }) ~> -// logRequest ~> - sendReceive(conduit) ~> -// logResponse ~> + sendReceive(transportActorRef) ~> unmarshalEither[A] } diff --git a/src/main/scala/sprouch/dsl/DslNewDocument.scala b/src/main/scala/sprouch/dsl/DslNewDocument.scala index 71c52ad..955daa5 100644 --- a/src/main/scala/sprouch/dsl/DslNewDocument.scala +++ b/src/main/scala/sprouch/dsl/DslNewDocument.scala @@ -2,8 +2,9 @@ package sprouch.dsl import sprouch._ import java.util.UUID -import akka.dispatch.Future +import scala.concurrent.Future import spray.json.RootJsonFormat +import scala.concurrent.ExecutionContext.Implicits.global trait DslDocument[A] { diff --git a/src/main/scala/sprouch/dsl/DslRevedDocument.scala b/src/main/scala/sprouch/dsl/DslRevedDocument.scala index b4d4903..cafe46d 100644 --- a/src/main/scala/sprouch/dsl/DslRevedDocument.scala +++ b/src/main/scala/sprouch/dsl/DslRevedDocument.scala @@ -1,11 +1,12 @@ package sprouch.dsl import sprouch._ -import akka.dispatch.Future +import scala.concurrent.Future import spray.json.RootJsonFormat import sprouch.JsonProtocol.OkResponse import sprouch.JsonProtocol.AllDocsResponse import spray.json.JsonFormat +import scala.concurrent.ExecutionContext.Implicits.global class DslRevedDocument[A](id:String, rev:String, data:A, attachments:Map[String, AttachmentStub]) extends RevedDocument[A](id, rev, data, attachments) { diff --git a/src/main/scala/sprouch/dsl/package.scala b/src/main/scala/sprouch/dsl/package.scala index e3ff2fa..f3de0f7 100644 --- a/src/main/scala/sprouch/dsl/package.scala +++ b/src/main/scala/sprouch/dsl/package.scala @@ -1,11 +1,12 @@ package sprouch import spray.json.RootJsonFormat -import akka.dispatch.Future +import scala.concurrent.Future import scala.annotation.implicitNotFound import spray.json.JsonFormat import spray.json.JsValue import sprouch.StaleOption.notStale +import scala.concurrent.ExecutionContext.Implicits.global package object dsl { def queryView[K,V](viewDocName:String, viewName:String, diff --git a/src/main/scala/sprouch/synchronous/Couch.scala b/src/main/scala/sprouch/synchronous/Couch.scala index 27d4374..ac7f260 100644 --- a/src/main/scala/sprouch/synchronous/Couch.scala +++ b/src/main/scala/sprouch/synchronous/Couch.scala @@ -1,9 +1,9 @@ package sprouch.synchronous -import akka.util.Duration +import scala.concurrent.duration.Duration import sprouch.Config -import akka.dispatch.Future -import akka.dispatch.Await +import scala.concurrent.Future +import scala.concurrent.Await import sprouch.JsonProtocol.OkResponse /** diff --git a/src/main/scala/sprouch/synchronous/Database.scala b/src/main/scala/sprouch/synchronous/Database.scala index 34111d8..afdb986 100644 --- a/src/main/scala/sprouch/synchronous/Database.scala +++ b/src/main/scala/sprouch/synchronous/Database.scala @@ -1,8 +1,8 @@ package sprouch.synchronous -import akka.util.Duration -import akka.dispatch.Future -import akka.dispatch.Await +import scala.concurrent.duration.Duration +import scala.concurrent.Future +import scala.concurrent.Await import spray.json.{JsonFormat, RootJsonFormat} import sprouch._ import JsonProtocol._ diff --git a/src/test/scala/sprouch/AttachmentsSuite.scala b/src/test/scala/sprouch/AttachmentsSuite.scala index d6c7a9d..6bd60bc 100644 --- a/src/test/scala/sprouch/AttachmentsSuite.scala +++ b/src/test/scala/sprouch/AttachmentsSuite.scala @@ -5,6 +5,7 @@ import org.scalatest.FunSuite import org.scalatest.junit.JUnitRunner import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner +import scala.concurrent.ExecutionContext.Implicits.global @RunWith(classOf[JUnitRunner]) class AttachmentsSuite extends FunSuite with CouchSuiteHelpers { diff --git a/src/test/scala/sprouch/BulkActions.scala b/src/test/scala/sprouch/BulkActions.scala index 131a5f8..8f16e7d 100644 --- a/src/test/scala/sprouch/BulkActions.scala +++ b/src/test/scala/sprouch/BulkActions.scala @@ -5,6 +5,7 @@ import org.scalatest.FunSuite import org.scalatest.junit.JUnitRunner import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner +import scala.concurrent.ExecutionContext.Implicits.global @RunWith(classOf[JUnitRunner]) class BulkActions extends FunSuite with CouchSuiteHelpers { diff --git a/src/test/scala/sprouch/CouchSuite.scala b/src/test/scala/sprouch/CouchSuite.scala index bee6fcb..400ddee 100644 --- a/src/test/scala/sprouch/CouchSuite.scala +++ b/src/test/scala/sprouch/CouchSuite.scala @@ -4,24 +4,25 @@ import org.scalatest.FunSuite import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner import akka.actor.ActorSystem -import akka.dispatch.Await -import akka.util.Duration +import scala.concurrent.Await +import scala.concurrent.duration.Duration import java.util.UUID import spray.httpx.SprayJsonSupport._ import spray.json._ -import akka.dispatch.Future +import scala.concurrent.Future import spray.httpx.marshalling.Marshaller import com.typesafe.config.ConfigFactory +import scala.concurrent.ExecutionContext.Implicits.global @RunWith(classOf[JUnitRunner]) class CouchSuite extends FunSuite with CouchSuiteHelpers { import JsonProtocol._ - test("ssl enabled") { + /*test("ssl enabled") { val conf = ConfigFactory.load() val sslEnabled = conf.getBoolean("spray.can.client.ssl-encryption") assert(sslEnabled, "ssl not enabled in config") - } + }*/ test("create, get, and delete db") { val dbName = "tempdb" + UUID.randomUUID.toString.toLowerCase diff --git a/src/test/scala/sprouch/CouchSuiteHelpers.scala b/src/test/scala/sprouch/CouchSuiteHelpers.scala index c07d1a1..c7160ab 100644 --- a/src/test/scala/sprouch/CouchSuiteHelpers.scala +++ b/src/test/scala/sprouch/CouchSuiteHelpers.scala @@ -2,10 +2,11 @@ package sprouch import org.scalatest.FunSuite import akka.actor.ActorSystem -import akka.util.Duration -import akka.dispatch.Await -import akka.dispatch.Future +import scala.concurrent.duration.Duration +import scala.concurrent.Await +import scala.concurrent.Future import java.util.UUID +import scala.concurrent.ExecutionContext.Implicits.global case class Test(foo:Int, bar:String) diff --git a/src/test/scala/sprouch/Dsl.scala b/src/test/scala/sprouch/Dsl.scala index 1e01e69..94664d9 100644 --- a/src/test/scala/sprouch/Dsl.scala +++ b/src/test/scala/sprouch/Dsl.scala @@ -6,6 +6,7 @@ import org.scalatest.junit.JUnitRunner import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner import sprouch.dsl._ +import scala.concurrent.ExecutionContext.Implicits.global @RunWith(classOf[JUnitRunner]) class Dsl extends FunSuite with CouchSuiteHelpers { diff --git a/src/test/scala/sprouch/DslBulk.scala b/src/test/scala/sprouch/DslBulk.scala index 6742582..63609ef 100644 --- a/src/test/scala/sprouch/DslBulk.scala +++ b/src/test/scala/sprouch/DslBulk.scala @@ -6,7 +6,8 @@ import org.scalatest.junit.JUnitRunner import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner import sprouch.dsl._ -import akka.dispatch.Future +import scala.concurrent.Future +import scala.concurrent.ExecutionContext.Implicits.global class DslBulk extends FunSuite with CouchSuiteHelpers { diff --git a/src/test/scala/sprouch/EtagSuite.scala b/src/test/scala/sprouch/EtagSuite.scala index c7482ab..3c47ce5 100644 --- a/src/test/scala/sprouch/EtagSuite.scala +++ b/src/test/scala/sprouch/EtagSuite.scala @@ -5,6 +5,7 @@ import org.scalatest.FunSuite import org.scalatest.junit.JUnitRunner import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner +import scala.concurrent.ExecutionContext.Implicits.global @RunWith(classOf[JUnitRunner]) class EtagSuite extends FunSuite with CouchSuiteHelpers { diff --git a/src/test/scala/sprouch/JsonProtocol.scala b/src/test/scala/sprouch/JsonProtocol.scala index 0e8db07..f1867c7 100644 --- a/src/test/scala/sprouch/JsonProtocol.scala +++ b/src/test/scala/sprouch/JsonProtocol.scala @@ -5,7 +5,7 @@ import org.scalatest.FunSuite import org.scalatest.junit.JUnitRunner import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner -import akka.dispatch.Future +import scala.concurrent.Future import spray.json.{RootJsonFormat, JsonFormat, JsValue} import spray.json.JsObject import spray.json.JsString diff --git a/src/test/scala/sprouch/OldRevisions.scala b/src/test/scala/sprouch/OldRevisions.scala index 2366804..45dab49 100644 --- a/src/test/scala/sprouch/OldRevisions.scala +++ b/src/test/scala/sprouch/OldRevisions.scala @@ -5,6 +5,7 @@ import org.scalatest.FunSuite import org.scalatest.junit.JUnitRunner import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner +import scala.concurrent.ExecutionContext.Implicits.global @RunWith(classOf[JUnitRunner]) class OldRevisions extends FunSuite with CouchSuiteHelpers { diff --git a/src/test/scala/sprouch/ViewsSuite.scala b/src/test/scala/sprouch/ViewsSuite.scala index b88e028..78a30e3 100644 --- a/src/test/scala/sprouch/ViewsSuite.scala +++ b/src/test/scala/sprouch/ViewsSuite.scala @@ -5,9 +5,10 @@ import org.scalatest.FunSuite import org.scalatest.junit.JUnitRunner import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner -import akka.dispatch.Future +import scala.concurrent.Future import spray.json.JsonFormat import spray.json.JsValue +import scala.concurrent.ExecutionContext.Implicits.global class ViewsSuite extends FunSuite with CouchSuiteHelpers { import JsonProtocol._ @@ -33,7 +34,7 @@ class ViewsSuite extends FunSuite with CouchSuiteHelpers { """) ) val viewsDoc = new NewDocument("my views", Views(Map("sum" -> mr))) - val view <- db.createViews(viewsDoc) + view <- db.createViews(viewsDoc) queryRes <- db.queryView[Null,Int]("my views", "sum") groupedRes <- db.queryView[String,Int]("my views", "sum", flags = ViewQueryFlag(group = true)) keyRes <- db.queryView[Null,Int]("my views", "sum", key = Some("a"))