Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 18 commits
  • 73 files changed
  • 0 commit comments
  • 1 contributor
Commits on May 30, 2013
@trajano Added emerging-technologies branch
This provides emerging technologies that are being evaluated for
inclusion into the sactioned technology stack.

This includes the following techonlogies:

* Scala/ScalaTest (for behaviour driven testing)
* OSGi
* MongoDB (for NOSQL)
* Hazelcast for clustering.

This is designed to work with IntelliJ primarily.  However, it is still
formatted in Eclipse.
3791556
@trajano Removed Karaf testing in favor of PaxExam
This allows OBR to be used and bypass older dependencies that are present
in Karaf.  The Karaf runner did not allow for using OBR to resolve
dependencies as such raw usage of the OBR APIs were performed.
60e1916
@trajano Merged OBR and osgi.tests projects to Assembly
This merges the OBR and osgi.test projects into a new project called
Assembly.  This assembly combines all the projects and dependencies into
one project that is tested using Pax Exam.

It also provides an artifact containing a zipped version of the OBR
containing only the files required for an OBR (i.e. no POMs)
fd72802
@trajano Implemented the use of OSGi CM
This uses pure OSGi and no use of any non-org.osgi namespaces in the
configuration. This was done through OSGi Blueprint.
8616ec3
@trajano upgrade Aries util 545b01d
@trajano Implemented a sample of using Apache Cassandra 0e4aa03
@trajano Implemented starts-with search on Cassandra
The dataset was reformatted using http://jsonformatter.curiousconcept.com/
with 2-space indentation.
52e7234
@trajano Split the implementation of NOSQL databases
Each implementation is changed to use its own module to prevent dependency
issues.
eaf6185
@trajano Relocate depdencies to sub-projects
Dependencies are moved to the sub-projects.
d828b01
@trajano Incremented the version of embedmongo to 1.17 95d384e
@trajano Reduced logging output 695440c
@trajano Upgraded Cassandra
1.1.3 fixes https://issues.apache.org/jira/browse/CASSANDRA-4400
thus the snappy libraries must be present otherwise the application will
fail.

However, a stacktrace still appears.
21f8659
@trajano Simplified unit tests to make it work with Windows 362c422
@trajano Implemented Akka and Hazelcast for clustering work e5687a1
@trajano Upgraded Embed Mongo and use Scala-IDE
This upgrades Embed Mongo to 1.22 which uses a new API for testing.
It also introduces the use of m2eclipse-scala along with reformatting
Scala code on Eclipse using the default formatters.
a3d39ac
@trajano ignore cache folder 8053f9c
@trajano Upgraded plugin and dependencies for MongoDB 68a9dc6
@trajano Added SVG files for book e6fe81c
Showing with 3,416 additions and 10 deletions.
  1. +1 −0  .gitignore
  2. +8 −0 behavior-driven-testing/README.md
  3. +29 −0 behavior-driven-testing/pom.xml
  4. +24 −0 behavior-driven-testing/src/test/scala/SampleScalaSpecTest.scala
  5. +26 −0 behavior-driven-testing/src/test/scala/SampleScalaTest.scala
  6. +59 −0 book/hierarchy-of-business-goals.svg
  7. +298 −0 book/zachman-framework-model.svg
  8. +4 −0 clustering/README.md
  9. +46 −0 clustering/pom.xml
  10. +11 −0 clustering/src/main/java/net/trajano/clustering/Calculate.java
  11. +11 −0 clustering/src/main/java/net/trajano/clustering/FinalResult.java
  12. +20 −0 clustering/src/main/java/net/trajano/clustering/PiApproximation.java
  13. +20 −0 clustering/src/main/java/net/trajano/clustering/PiCalculator.java
  14. +19 −0 clustering/src/main/java/net/trajano/clustering/Result.java
  15. +19 −0 clustering/src/main/java/net/trajano/clustering/Work.java
  16. +53 −0 clustering/src/main/java/net/trajano/clustering/internal/AkkaMaster.java
  17. +20 −0 clustering/src/main/java/net/trajano/clustering/internal/AkkaWorker.java
  18. +46 −0 clustering/src/main/java/net/trajano/clustering/internal/HazelcastMaster.java
  19. +29 −0 clustering/src/main/java/net/trajano/clustering/internal/HazelcastWorker.java
  20. +8 −0 clustering/src/main/java/net/trajano/clustering/package-info.java
  21. +47 −0 clustering/src/test/java/net/trajano/clustering/test/AkkaTest.java
  22. +26 −0 clustering/src/test/java/net/trajano/clustering/test/HazelcastTest.java
  23. +8 −0 clustering/src/test/java/net/trajano/clustering/test/package-info.java
  24. +24 −4 maven-jee6-parent/pom.xml
  25. +6 −5 maven-jee6-test/pom.xml
  26. +18 −0 nosql/README.md
  27. +67 −0 nosql/customer-cassandra/pom.xml
  28. +126 −0 nosql/customer-cassandra/src/main/java/net/trajano/nosql/internal/CassandraCustomers.java
  29. +5 −0 nosql/customer-cassandra/src/main/java/net/trajano/nosql/internal/package-info.java
  30. +145 −0 nosql/customer-cassandra/src/test/java/net/trajano/nosql/cassandra/test/CustomerTest.java
  31. +85 −0 nosql/customer-cassandra/src/test/java/net/trajano/nosql/cassandra/test/EmbeddedCassandraTest.java
  32. +163 −0 nosql/customer-cassandra/src/test/resources/customerDataSet.json
  33. +33 −0 nosql/customer-cassandra/src/test/resources/extendedDataSet.json
  34. +51 −0 nosql/customer-mongodb/pom.xml
  35. +71 −0 nosql/customer-mongodb/src/main/java/net/trajano/nosql/internal/MongoDbCustomers.java
  36. +5 −0 nosql/customer-mongodb/src/main/java/net/trajano/nosql/internal/package-info.java
  37. +65 −0 nosql/customer-mongodb/src/test/java/net/trajano/nosql/mongodb/test/CdiProducer.java
  38. +149 −0 nosql/customer-mongodb/src/test/java/net/trajano/nosql/mongodb/test/CdiTest.java
  39. +8 −0 nosql/customer-mongodb/src/test/java/net/trajano/nosql/mongodb/test/EmbeddedMongo.java
  40. +90 −0 nosql/customer-mongodb/src/test/java/net/trajano/nosql/mongodb/test/MongoDbTest.java
  41. +37 −0 nosql/customer-mongodb/src/test/java/net/trajano/nosql/mongodb/test/SerializationTest.java
  42. +56 −0 nosql/customer-mongodb/src/test/scala/net/trajano/nosql/mongodb/scala/test/CustomersTest.scala
  43. +22 −0 nosql/customer/pom.xml
  44. +55 −0 nosql/customer/src/main/java/net/trajano/nosql/Customer.java
  45. +28 −0 nosql/customer/src/main/java/net/trajano/nosql/Customers.java
  46. +6 −0 nosql/customer/src/main/java/net/trajano/nosql/package-info.java
  47. +43 −0 nosql/customer/src/test/java/net/trajano/nosql/test/MockTest.java
  48. +19 −0 nosql/pom.xml
  49. +17 −0 osgi-sample/README.md
  50. +235 −0 osgi-sample/assembly/pom.xml
  51. +20 −0 osgi-sample/assembly/src/main/assembly/obr.xml
  52. +25 −0 osgi-sample/assembly/src/site/apt/index.apt
  53. +214 −0 osgi-sample/assembly/src/test/java/net/trajano/osgi/test/PaxTest.java
  54. +6 −0 osgi-sample/blueprint.consumer/README.md
  55. +44 −0 osgi-sample/blueprint.consumer/pom.xml
  56. +38 −0 osgi-sample/blueprint.consumer/src/main/java/net/trajano/blueprint/consumer/IServiceUser.java
  57. +130 −0 osgi-sample/blueprint.consumer/src/main/java/net/trajano/blueprint/consumer/internal/ServiceUserBean.java
  58. +5 −0 osgi-sample/blueprint.consumer/src/main/java/net/trajano/blueprint/consumer/internal/package-info.java
  59. +5 −0 osgi-sample/blueprint.consumer/src/main/java/net/trajano/blueprint/consumer/package-info.java
  60. +29 −0 osgi-sample/blueprint.consumer/src/main/resources/OSGI-INF/blueprint/blueprint.xml
  61. +96 −0 osgi-sample/blueprint.consumer/src/test/java/net/trajano/blueprint/mongo/test/MongoDbTest.java
  62. +46 −0 osgi-sample/blueprint.consumer/src/test/java/net/trajano/blueprint/mongo/test/ServiceUserBeanTest.java
  63. +39 −0 osgi-sample/blueprint.producer/pom.xml
  64. +23 −0 osgi-sample/blueprint.producer/src/main/resources/OSGI-INF/blueprint/blueprint.xml
  65. +37 −0 osgi-sample/hello.osgi/pom.xml
  66. +17 −0 osgi-sample/hello.osgi/src/main/java/net/trajano/hello/osgi/IHello.java
  67. +18 −0 osgi-sample/hello.osgi/src/main/java/net/trajano/hello/osgi/internal/Hello.java
  68. +41 −0 osgi-sample/hello.osgi/src/main/java/net/trajano/hello/osgi/internal/HelloActivator.java
  69. +5 −0 osgi-sample/hello.osgi/src/main/java/net/trajano/hello/osgi/internal/package-info.java
  70. +5 −0 osgi-sample/hello.osgi/src/main/java/net/trajano/hello/osgi/package-info.java
  71. +48 −0 osgi-sample/hello.osgi/src/test/java/net/trajano/hello/osgi/test/HelloTest.java
  72. +59 −0 osgi-sample/pom.xml
  73. +5 −1 pom.xml
View
1  .gitignore
@@ -2,6 +2,7 @@ target/
.project
.settings/
.classpath
+.cache
.idea
*.iml
derby.log
View
8 behavior-driven-testing/README.md
@@ -0,0 +1,8 @@
+This is an example of doing testing combining ScalaTest with JUnit and
+Maven.
+
+Note: throughout the project, Scala must *only* be used for testing (as
+such the compile) goal is not defined in the parent POM.
+
+Scala is the only dependency added to the parent and test POMs in order
+to promote use of Scala Test for behavior driven testing.
View
29 behavior-driven-testing/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>net.trajano.maven-jee6</groupId>
+ <artifactId>maven-jee6-parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../maven-jee6-parent</relativePath>
+ </parent>
+ <artifactId>behavior-driven-testing</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>maven-jee6-test</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>net.alchim31.maven</groupId>
+ <artifactId>scala-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
+
View
24 behavior-driven-testing/src/test/scala/SampleScalaSpecTest.scala
@@ -0,0 +1,24 @@
+import scala.collection.mutable.Stack
+
+import org.junit.runner.RunWith
+import org.scalatest.FlatSpec
+import org.scalatest.junit.JUnitRunner
+import org.scalatest.matchers.ShouldMatchers
+
+@RunWith(classOf[JUnitRunner])
+class SampleScalaSpecTest extends FlatSpec with ShouldMatchers {
+ "A Stack" should "pop values in last-in-first-out order" in {
+ val stack = new Stack[Int]
+ stack.push(1)
+ stack.push(2)
+ stack.pop() should equal(2)
+ stack.pop() should equal(1)
+ }
+
+ it should "throw NoSuchElementException if an empty stack is popped" in {
+ val emptyStack = new Stack[String]
+ evaluating {
+ emptyStack.pop()
+ } should produce[NoSuchElementException]
+ }
+}
View
26 behavior-driven-testing/src/test/scala/SampleScalaTest.scala
@@ -0,0 +1,26 @@
+import scala.collection.mutable.Stack
+
+import org.junit.runner.RunWith
+import org.scalatest.FunSuite
+import org.scalatest.junit.JUnitRunner
+
+@RunWith(classOf[JUnitRunner])
+class SampleScalaTest extends FunSuite {
+ test("pop is invoked on a non-empty stack") {
+ val stack = new Stack[Int]
+ stack.push(1)
+ stack.push(2)
+ val oldSize = stack.size
+ val result = stack.pop()
+ assert(result === 2)
+ assert(stack.size === oldSize - 1)
+ }
+
+ test("pop is invoked on an empty stack") {
+ val emptyStack = new Stack[Int]
+ intercept[NoSuchElementException] {
+ emptyStack.pop()
+ }
+ assert(emptyStack.isEmpty)
+ }
+}
View
59 book/hierarchy-of-business-goals.svg
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:dc="http://purl.org/dc/elements/1.1/"
+ version="1.1" width="335" height="220">
+ <title property="dc:title">Hierarchy of business goals</title>
+ <desc property="dc:creator">Archimedes Trajano</desc>
+ <metadata id="license" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#">
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
+ </cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+
+ <defs>
+ <style type="text/css">
+ @import
+ url(http://fonts.googleapis.com/css?family=Noto+Sans);
+
+ .label {
+ text-anchor: end;
+ dominant-baseline: middle;
+ font-size: 12pt;
+ font-family: 'Noto Sans', sans-serif;
+ }
+ </style>
+ </defs>
+
+ <g transform="translate(10,10)">
+ <!-- colors from http://www.colourlovers.com/palette/1523080/hierarchy. -->
+ <polygon points="115.470054,0 0,200 230.940108,200" fill="#87776F"
+ stroke="black" stroke-linejoin="round" />
+ <polygon points="115.470054,0 28.867513,150 202.072594,150"
+ fill="#61AB9B" stroke="black" stroke-linejoin="round" />
+ <polygon points="115.470054,0 57.735027,100 173.2050808,100"
+ fill="#C7B2A7" stroke="black" stroke-linejoin="round" />
+ <polygon points="115.470054,0 86.602540,50 144.337567,50"
+ fill="#EBD9D1" stroke="black" stroke-linejoin="round" />
+
+ <line x1="28.867513" y1="150" x2="325" y2="150" stroke="black" />
+ <line x1="57.735027" y1="100" x2="325" y2="100" stroke="black" />
+ <line x1="86.602540" y1="50" x2="325" y2="50" stroke="black" />
+
+ <text x="325" y="25" class="label">Rewarding</text>
+ <text x="325" y="75" class="label">Growth</text>
+ <text x="325" y="125" class="label">Sustainability</text>
+ <text x="325" y="175" class="label">Legitimacy</text>
+ </g>
+</svg>
View
298 book/zachman-framework-model.svg
@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:dc="http://purl.org/dc/elements/1.1/"
+ version="1.1" width="1070" height="570">
+ <title property="dc:title">Zachman Framework Model</title>
+ <desc property="dc:creator">Archimedes Trajano</desc>
+ <metadata id="license" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#">
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
+ </cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+
+ <defs>
+ <style type="text/css"><![CDATA[
+ @import
+ url(http://fonts.googleapis.com/css?family=Noto+Sans);
+
+ .outer rect {
+ stroke: black;
+ fill: #C195ED;
+ stroke-width: 2;
+ }
+
+ .inner rect,
+ rect.inner{
+ stroke: black;
+ fill: none;
+ stroke-width: 2;
+ }
+
+ .inner.selected rect{
+ fill: #B5FFAB;
+ }
+
+ text {
+ fill: black;
+ text-anchor: middle;
+ dominant-baseline: middle;
+ font-size: 20px;
+ font-family: 'Noto Sans', sans-serif;
+ }
+
+ .outer text {
+ font-size: 20px;
+ }
+
+ .inner text {
+ font-size: 14px;
+ }
+ ]]></style>
+ </defs>
+ <g transform="translate(10,10)">
+
+ <g>
+ <g class="outer" transform="translate(0, 50)">
+ <rect x="0" y="0" width="150" height="100" class="outer" />
+ <text x="75" y="50" class="outer">Contextual</text>
+ </g>
+ <g class="outer" transform="translate(0, 150)">
+ <rect x="0" y="0" width="150" height="100" class="outer" />
+ <text x="75" y="50" class="outer">Conceptual</text>
+ </g>
+ <g class="outer" transform="translate(0, 250)">
+ <rect x="0" y="0" width="150" height="100" class="outer" />
+ <text x="75" y="50" class="outer">Logical</text>
+ </g>
+ <g class="outer" transform="translate(0, 350)">
+ <rect x="0" y="0" width="150" height="100" class="outer" />
+ <text x="75" y="50" class="outer">Physical</text>
+ </g>
+ <g class="outer" transform="translate(0, 450)">
+ <rect x="0" y="0" width="150" height="100" class="outer" />
+ <text x="75" y="50" class="outer">Detailed</text>
+ </g>
+ </g>
+
+ <g transform="translate(150)">
+ <g class="outer">
+ <rect x="0" y="0" width="150" height="50" />
+ <text x="75" y="25">Why</text>
+ </g>
+
+ <g transform="translate(0, 50)" class="inner selected" >
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Goal list</text>
+ </g>
+
+ <g transform="translate(0, 150)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Goal relationship</text>
+ </g>
+
+ <g transform="translate(0, 250)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Rules diagram</text>
+ </g>
+
+ <g transform="translate(0, 350)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Rules</text>
+ <text x="75" y="60">specification</text>
+ </g>
+
+ <g transform="translate(0, 450)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Rule details</text>
+ </g>
+ </g>
+
+ <g transform="translate(300)">
+ <g class="outer">
+ <rect x="0" y="0" width="150" height="50" />
+ <text x="75" y="25">How</text>
+ </g>
+
+ <g class="inner" transform="translate(0, 50)">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Process list</text>
+ </g>
+
+ <g transform="translate(0, 150)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Process model</text>
+ </g>
+
+ <g transform="translate(0, 250)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Process diagram</text>
+ </g>
+
+ <g transform="translate(0, 350)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Process function</text>
+ <text x="75" y="60">specification</text>
+ </g>
+
+ <g transform="translate(0, 450)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Process details</text>
+ </g>
+ </g>
+
+ <g transform="translate(450)">
+ <g class="outer">
+ <rect x="0" y="0" width="150" height="50" />
+ <text x="75" y="25">What</text>
+ </g>
+
+ <g class="inner" transform="translate(0, 50)">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Material list</text>
+ </g>
+
+ <g transform="translate(0, 150)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Entity</text>
+ <text x="75" y="60">relationship model</text>
+ </g>
+
+ <g transform="translate(0, 250)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Data model</text>
+ <text x="75" y="60">diagram</text>
+ </g>
+
+ <g transform="translate(0, 350)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Data entity</text>
+ <text x="75" y="60">specification</text>
+ </g>
+
+ <g transform="translate(0, 450)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Data details</text>
+ </g>
+ </g>
+
+ <g transform="translate(600)">
+ <g class="outer">
+ <rect x="0" y="0" width="150" height="50" />
+ <text x="75" y="25">Who</text>
+ </g>
+
+ <g class="inner" transform="translate(0, 50)">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="30">Organizational</text>
+ <text x="75" y="50">unit and</text>
+ <text x="75" y="70">role list</text>
+ </g>
+
+ <g transform="translate(0, 150)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="30">Organizational</text>
+ <text x="75" y="50">unit and role</text>
+ <text x="75" y="70">relationship model</text>
+ </g>
+
+ <g transform="translate(0, 250)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="30">Role</text>
+ <text x="75" y="50">relationship </text>
+ <text x="75" y="70">diagram</text>
+ </g>
+
+ <g transform="translate(0, 350)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Role</text>
+ <text x="75" y="60">specification</text>
+ </g>
+
+ <g transform="translate(0, 450)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Role details</text>
+ </g>
+ </g>
+
+ <g transform="translate(750)">
+ <g class="outer">
+ <rect x="0" y="0" width="150" height="50" />
+ <text x="75" y="25">Where</text>
+ </g>
+
+ <g class="inner" transform="translate(0, 50)">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Geographical</text>
+ <text x="75" y="60">location list</text>
+ </g>
+
+ <g transform="translate(0, 150)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Locations</text>
+ <text x="75" y="60">model</text>
+ </g>
+
+ <g transform="translate(0, 250)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Location</text>
+ <text x="75" y="60">diagram</text>
+ </g>
+
+ <g transform="translate(0, 350)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Location</text>
+ <text x="75" y="60">specification</text>
+ </g>
+
+ <g transform="translate(0, 450)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Location details</text>
+ </g>
+ </g>
+
+ <g transform="translate(900)">
+ <g class="outer">
+ <rect x="0" y="0" width="150" height="50" />
+ <text x="75" y="25">When</text>
+ </g>
+
+ <g class="inner" transform="translate(0, 50)">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Event list</text>
+ </g>
+
+ <g transform="translate(0, 150)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Event model</text>
+ </g>
+
+ <g transform="translate(0, 250)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Event diagram</text>
+ </g>
+
+ <g transform="translate(0, 350)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="40">Event</text>
+ <text x="75" y="60">specification</text>
+ </g>
+
+ <g transform="translate(0, 450)" class="inner">
+ <rect x="0" y="0" width="150" height="100" />
+ <text x="75" y="50">Event details</text>
+ </g>
+ </g>
+ </g>
+</svg>
View
4 clustering/README.md
@@ -0,0 +1,4 @@
+This tests out clustering implementations such as Hazelcast or Akka Actors.
+
+This is used to solve for pi using http://doc.akka.io/docs/akka/2.0.2/intro/getting-started-first-java.html
+as the basis.
View
46 clustering/pom.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>net.trajano.maven-jee6</groupId>
+ <artifactId>maven-jee6</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <name>akka-tutorial-first-java</name>
+ <artifactId>clustering</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.hazelcast</groupId>
+ <artifactId>hazelcast</artifactId>
+ <version>2.1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.typesafe.akka</groupId>
+ <artifactId>akka-actor</artifactId>
+ <version>2.0.3</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>maven-jee6-test</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>typesafe</id>
+ <name>Typesafe Repository</name>
+ <url>http://repo.typesafe.com/typesafe/releases/</url>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ </plugins>
+ </build>
+</project>
View
11 clustering/src/main/java/net/trajano/clustering/Calculate.java
@@ -0,0 +1,11 @@
+package net.trajano.clustering;
+
+/**
+ * Trigger the calculation message.
+ *
+ * @author trajano
+ *
+ */
+public class Calculate {
+
+}
View
11 clustering/src/main/java/net/trajano/clustering/FinalResult.java
@@ -0,0 +1,11 @@
+package net.trajano.clustering;
+
+/**
+ * This is the final result that would be asked of the master.
+ *
+ * @author trajano
+ *
+ */
+public class FinalResult {
+
+}
View
20 clustering/src/main/java/net/trajano/clustering/PiApproximation.java
@@ -0,0 +1,20 @@
+package net.trajano.clustering;
+
+import java.io.Serializable;
+
+public class PiApproximation implements Serializable {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 1L;
+
+ private final double pi;
+
+ public PiApproximation(final double pi) {
+ this.pi = pi;
+ }
+
+ public double getPi() {
+ return pi;
+ }
+}
View
20 clustering/src/main/java/net/trajano/clustering/PiCalculator.java
@@ -0,0 +1,20 @@
+package net.trajano.clustering;
+
+public class PiCalculator {
+ public static double calculatePiFor(final int start,
+ final int numberOfElements) {
+ double accumulator = 0.0;
+ for (int i = start * numberOfElements; i <= (start + 1)
+ * numberOfElements - 1; i++) {
+ accumulator += 4.0 * (1 - i % 2 * 2) / (2 * i + 1);
+ }
+ return accumulator;
+ }
+
+ /**
+ * Prevent instantiation of utility class.
+ */
+ private PiCalculator() {
+
+ }
+}
View
19 clustering/src/main/java/net/trajano/clustering/Result.java
@@ -0,0 +1,19 @@
+package net.trajano.clustering;
+
+import java.io.Serializable;
+
+public class Result implements Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private final double value;
+
+ public Result(final double value) {
+ this.value = value;
+ }
+
+ public double getValue() {
+ return value;
+ }
+}
View
19 clustering/src/main/java/net/trajano/clustering/Work.java
@@ -0,0 +1,19 @@
+package net.trajano.clustering;
+
+public class Work {
+ private final int numberOfElements;
+ private final int start;
+
+ public Work(final int start, final int numberOfElements) {
+ this.start = start;
+ this.numberOfElements = numberOfElements;
+ }
+
+ public int getNumberOfElements() {
+ return numberOfElements;
+ }
+
+ public int getStart() {
+ return start;
+ }
+}
View
53 clustering/src/main/java/net/trajano/clustering/internal/AkkaMaster.java
@@ -0,0 +1,53 @@
+package net.trajano.clustering.internal;
+
+import net.trajano.clustering.Calculate;
+import net.trajano.clustering.FinalResult;
+import net.trajano.clustering.PiApproximation;
+import net.trajano.clustering.Result;
+import net.trajano.clustering.Work;
+import akka.actor.ActorRef;
+import akka.actor.Props;
+import akka.actor.UntypedActor;
+import akka.routing.RoundRobinRouter;
+
+public class AkkaMaster extends UntypedActor {
+ private ActorRef listener;
+ private final int nrOfElements;
+
+ private final int nrOfMessages;
+ private int nrOfResults;
+ private double pi;
+
+ private final ActorRef workerRouter;
+
+ public AkkaMaster(final int nrOfWorkers, final int nrOfMessages,
+ final int nrOfElements) {
+ this.nrOfMessages = nrOfMessages;
+ this.nrOfElements = nrOfElements;
+
+ workerRouter = getContext().actorOf(
+ new Props(AkkaWorker.class).withRouter(new RoundRobinRouter(
+ nrOfWorkers)), "workerRouter");
+ }
+
+ @Override
+ public void onReceive(final Object message) {
+ if (message instanceof Calculate) {
+ for (int start = 0; start < nrOfMessages; ++start) {
+ workerRouter.tell(new Work(start, nrOfElements), getSelf());
+ }
+ } else if (message instanceof Result) {
+ final Result result = (Result) message;
+ pi += result.getValue();
+ nrOfResults += 1;
+ if (nrOfResults == nrOfMessages) {
+ listener.tell(new PiApproximation(pi), getSelf());
+ getContext().stop(getSelf());
+ }
+ } else if (message instanceof FinalResult) {
+ listener = getSender();
+ } else {
+ unhandled(message);
+ }
+ }
+}
View
20 clustering/src/main/java/net/trajano/clustering/internal/AkkaWorker.java
@@ -0,0 +1,20 @@
+package net.trajano.clustering.internal;
+
+import net.trajano.clustering.PiCalculator;
+import net.trajano.clustering.Result;
+import net.trajano.clustering.Work;
+import akka.actor.UntypedActor;
+
+public class AkkaWorker extends UntypedActor {
+ @Override
+ public void onReceive(final Object message) {
+ if (message instanceof Work) {
+ final Work work = (Work) message;
+ final double result = PiCalculator.calculatePiFor(work.getStart(),
+ work.getNumberOfElements());
+ getSender().tell(new Result(result), getSelf());
+ } else {
+ unhandled(message);
+ }
+ }
+}
View
46 clustering/src/main/java/net/trajano/clustering/internal/HazelcastMaster.java
@@ -0,0 +1,46 @@
+package net.trajano.clustering.internal;
+
+import java.io.Serializable;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import net.trajano.clustering.PiApproximation;
+import net.trajano.clustering.Result;
+
+import com.hazelcast.core.Hazelcast;
+
+public class HazelcastMaster implements Callable<PiApproximation>, Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private final int nrOfElements;
+ private final int nrOfMessages;
+
+ private double pi = 0.0;
+
+ public HazelcastMaster(final int nrOfMessages, final int nrOfElements) {
+ this.nrOfMessages = nrOfMessages;
+ this.nrOfElements = nrOfElements;
+ }
+
+ @Override
+ public PiApproximation call() throws Exception {
+ final ExecutorService executor = Hazelcast.getExecutorService(UUID
+ .randomUUID().toString());
+ @SuppressWarnings("unchecked")
+ final Future<Result>[] results = new Future[nrOfMessages];
+ for (int i = 0; i < nrOfMessages; ++i) {
+ results[i] = executor.submit(new HazelcastWorker(i, nrOfElements));
+ }
+
+ for (int i = 0; i < nrOfMessages; ++i) {
+ final Result result = results[i].get();
+ pi += result.getValue();
+ }
+ return new PiApproximation(pi);
+ }
+}
View
29 clustering/src/main/java/net/trajano/clustering/internal/HazelcastWorker.java
@@ -0,0 +1,29 @@
+package net.trajano.clustering.internal;
+
+import java.io.Serializable;
+import java.util.concurrent.Callable;
+
+import net.trajano.clustering.PiCalculator;
+import net.trajano.clustering.Result;
+
+public class HazelcastWorker implements Callable<Result>, Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ private final int nrOfElements;
+
+ private final int start;
+
+ public HazelcastWorker(final int start, final int nrOfElements) {
+ this.start = start;
+ this.nrOfElements = nrOfElements;
+ }
+
+ @Override
+ public Result call() throws Exception {
+ return new Result(PiCalculator.calculatePiFor(start, nrOfElements));
+ }
+}
View
8 clustering/src/main/java/net/trajano/clustering/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author trajano
+ *
+ */
+package net.trajano.clustering;
View
47 clustering/src/test/java/net/trajano/clustering/test/AkkaTest.java
@@ -0,0 +1,47 @@
+package net.trajano.clustering.test;
+
+import net.trajano.clustering.Calculate;
+import net.trajano.clustering.FinalResult;
+import net.trajano.clustering.PiApproximation;
+import net.trajano.clustering.internal.AkkaMaster;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import akka.actor.ActorRef;
+import akka.actor.ActorSystem;
+import akka.actor.Props;
+import akka.actor.UntypedActor;
+import akka.actor.UntypedActorFactory;
+import akka.dispatch.Await;
+import akka.dispatch.Future;
+import akka.pattern.Patterns;
+import akka.util.Duration;
+import akka.util.Timeout;
+
+public class AkkaTest {
+ @Test
+ public void test() throws Exception {
+ final ActorSystem system = ActorSystem.create("PiSystem");
+ final ActorRef master = system.actorOf(new Props(
+ new UntypedActorFactory() {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public UntypedActor create() {
+ return new AkkaMaster(4, 10000, 10000);
+ }
+ }), "master");
+ final Timeout timeout = new Timeout(Duration.parse("5 seconds"));
+ final Future<Object> future = Patterns.ask(master, new FinalResult(),
+ timeout);
+ master.tell(new Calculate());
+ final PiApproximation result = (PiApproximation) Await.result(future,
+ timeout.duration());
+ Assert.assertEquals(Math.PI, result.getPi(), 0.0001);
+ system.shutdown();
+ }
+}
View
26 clustering/src/test/java/net/trajano/clustering/test/HazelcastTest.java
@@ -0,0 +1,26 @@
+package net.trajano.clustering.test;
+
+import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import net.trajano.clustering.PiApproximation;
+import net.trajano.clustering.internal.HazelcastMaster;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.hazelcast.core.Hazelcast;
+
+public class HazelcastTest {
+ @Test
+ public void test() throws Exception {
+ ExecutorService executor = Hazelcast.getExecutorService(UUID
+ .randomUUID().toString());
+
+ final HazelcastMaster master = new HazelcastMaster(10000, 10000);
+
+ Future<PiApproximation> result = executor.submit(master);
+ Assert.assertEquals(Math.PI, result.get().getPi(), 0.0001);
+ }
+}
View
8 clustering/src/test/java/net/trajano/clustering/test/package-info.java
@@ -0,0 +1,8 @@
+/**
+ *
+ */
+/**
+ * @author trajano
+ *
+ */
+package net.trajano.clustering.test;
View
28 maven-jee6-parent/pom.xml
@@ -8,10 +8,9 @@
<packaging>pom</packaging>
<name>Project Parent POM</name>
<parent>
- <groupId>net.trajano.project</groupId>
- <artifactId>javaee-project</artifactId>
- <version>1-SNAPSHOT</version>
- <relativePath>remote</relativePath>
+ <groupId>net.trajano</groupId>
+ <artifactId>trajano</artifactId>
+ <version>4</version>
</parent>
<properties>
<project.build.sourceEncoding>utf8</project.build.sourceEncoding>
@@ -48,6 +47,11 @@
<artifactId>derbynet</artifactId>
<version>10.9.1.0</version>
</dependency>
+ <dependency>
+ <groupId>org.scala-lang</groupId>
+ <artifactId>scala-library</artifactId>
+ <version>2.10.0</version>
+ </dependency>
</dependencies>
</dependencyManagement>
<build>
@@ -125,6 +129,22 @@
<version>2.2</version>
</plugin>
<plugin>
+ <groupId>net.alchim31.maven</groupId>
+ <artifactId>scala-maven-plugin</artifactId>
+ <version>3.1.3</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ <configuration>
+ <checkMultipleScalaVersions>false</checkMultipleScalaVersions>
+ <fork>true</fork>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
View
11 maven-jee6-test/pom.xml
@@ -24,6 +24,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <version>4.11</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
@@ -51,11 +52,6 @@
</exclusions>
</dependency>
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- <version>3.1</version>
- </dependency>
- <dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.10.1.1</version>
@@ -91,6 +87,11 @@
<version>1.1.8.Final</version>
</dependency>
<dependency>
+ <groupId>org.scalatest</groupId>
+ <artifactId>scalatest_2.10.0</artifactId>
+ <version>1.8</version>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.6.6</version>
View
18 nosql/README.md
@@ -0,0 +1,18 @@
+An example of using MongoDB and Cassandra for NOSQL storage,
+and GSON for JSON parsing. Scala test is also used to perform
+some tests.
+
+Each implementation is its own module to prevent dependency
+issues as each NOSQL implementation has its own dependency
+versions and may not by the latest ones.
+
+A simple domain module "customer" is provided to show the
+separation between implementation and API.
+
+A high-level API was chosen for Cassandra as the web site also
+recommended a high-level API should be used.
+
+Hector was chosen as the Cassandra high-level API as it provides
+richer functionality such as connection pooling and JMX. It also
+had the added bonus that it was already included as part of the
+cassandra-unit test framework.
View
67 nosql/customer-cassandra/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>net.trajano.maven-jee6</groupId>
+ <artifactId>nosql</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>customer-cassandra</artifactId>
+ <packaging>bundle</packaging>
+ <description>Implementation using Apache Cassandra.</description>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>customer</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hectorclient</groupId>
+ <artifactId>hector-core</artifactId>
+ <version>1.1-1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.cassandra</groupId>
+ <artifactId>cassandra-all</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cassandra</groupId>
+ <artifactId>cassandra-all</artifactId>
+ <version>1.1.3</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.cassandraunit</groupId>
+ <artifactId>cassandra-unit</artifactId>
+ <version>1.1.0.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>maven-jee6-test</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
+
View
126 nosql/customer-cassandra/src/main/java/net/trajano/nosql/internal/CassandraCustomers.java
@@ -0,0 +1,126 @@
+package net.trajano.nosql.internal;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import me.prettyprint.cassandra.serializers.StringSerializer;
+import me.prettyprint.cassandra.serializers.UUIDSerializer;
+import me.prettyprint.cassandra.service.template.ColumnFamilyResult;
+import me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;
+import me.prettyprint.cassandra.service.template.ColumnFamilyUpdater;
+import me.prettyprint.cassandra.service.template.SuperCfResult;
+import me.prettyprint.cassandra.service.template.SuperCfTemplate;
+import me.prettyprint.cassandra.service.template.SuperCfUpdater;
+import me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;
+import me.prettyprint.cassandra.service.template.ThriftSuperCfTemplate;
+import me.prettyprint.hector.api.Keyspace;
+import net.trajano.nosql.Customer;
+import net.trajano.nosql.Customers;
+
+/**
+ * Represents customers DAO implemented using Apache Cassandra.
+ */
+public class CassandraCustomers implements Customers {
+
+ /**
+ * "CustomerNames" {@link ColumnFamilyTemplate} from the injected
+ * {@link Keyspace}. The key is actually stored in lowercase. This column
+ * family contains all the possible starts-with permutations for a given
+ * name.
+ */
+ private final SuperCfTemplate<String, String, String> customerNameTemplate;
+
+ /**
+ * "Customers" {@link ColumnFamilyTemplate} from the injected
+ * {@link Keyspace}.
+ */
+ private final ColumnFamilyTemplate<UUID, String> customerTemplate;
+
+ /**
+ * Constructs the DAO.
+ *
+ * @param keyspace
+ * Cassandra keyspace.
+ */
+ @Inject
+ public CassandraCustomers(final Keyspace keyspace) {
+ customerTemplate = new ThriftColumnFamilyTemplate<UUID, String>(
+ keyspace, "customer", UUIDSerializer.get(),
+ StringSerializer.get());
+ customerNameTemplate = new ThriftSuperCfTemplate<String, String, String>(
+ keyspace, "customerName", StringSerializer.get(),
+ StringSerializer.get(), StringSerializer.get());
+ }
+
+ /**
+ * Add the Customer to the database.
+ *
+ * @param customer
+ * customer
+ */
+ @Override
+ public void add(final Customer customer) {
+ final UUID uuid;
+ if (customer.getUuid() == null) {
+ uuid = UUID.randomUUID();
+ } else {
+ uuid = customer.getUuid();
+ }
+ final ColumnFamilyUpdater<UUID, String> updater = customerTemplate
+ .createUpdater(uuid);
+ updater.setUUID("uuid", uuid);
+ updater.setString("name", customer.getName());
+ updater.setDate("lastRecallTimestamp",
+ customer.getLastRecallTimestamp());
+ customerTemplate.update(updater);
+
+ for (int i = 1; i < customer.getName().length() + 1; ++i) {
+ final String key = customer.getName().substring(0, i).toLowerCase();
+ final SuperCfUpdater<String, String, String> customerNameUpdater = customerNameTemplate
+ .createUpdater(key, customer.getName());
+ customerNameUpdater.setUUID("uuid", uuid);
+ customerNameTemplate.update(customerNameUpdater);
+ }
+ }
+
+ /**
+ * This will query using case-insensitive starts-with match. Unfortunately
+ * there's no rich query capability with Cassandra to allow regular
+ * expression or even substrings.
+ *
+ * @param query
+ * key
+ * @return list of customers that satisfy the regular expression.
+ */
+ @Override
+ public List<Customer> find(final String query) {
+ final SuperCfResult<String, String, String> queryColumns = customerNameTemplate
+ .querySuperColumns(query.toLowerCase());
+ if (queryColumns == null) {
+ return Collections.emptyList();
+ }
+
+ final List<Customer> ret = new ArrayList<Customer>();
+ for (final String columnName : queryColumns.getSuperColumns()) {
+ final UUID uuid = queryColumns.getUUID(columnName, "uuid");
+ if (uuid == null) {
+ System.out.println(String.format("null uuid at [%s][%s]",
+ query, columnName));
+ continue;
+ }
+ final ColumnFamilyResult<UUID, String> columns = customerTemplate
+ .queryColumns(uuid);
+ final Customer customer = new Customer();
+ customer.setUuid(columns.getUUID("uuid"));
+ customer.setName(columns.getString("name"));
+ customer.setLastRecallTimestamp(columns
+ .getDate("lastRecallTimestamp"));
+ ret.add(customer);
+ }
+ return ret;
+ }
+}
View
5 nosql/customer-cassandra/src/main/java/net/trajano/nosql/internal/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Internal implementation classes.
+ */
+package net.trajano.nosql.internal;
+
View
145 nosql/customer-cassandra/src/test/java/net/trajano/nosql/cassandra/test/CustomerTest.java
@@ -0,0 +1,145 @@
+package net.trajano.nosql.cassandra.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import net.trajano.nosql.Customer;
+import net.trajano.nosql.Customers;
+import net.trajano.nosql.internal.CassandraCustomers;
+
+import org.cassandraunit.AbstractCassandraUnit4TestCase;
+import org.cassandraunit.dataset.DataSet;
+import org.cassandraunit.dataset.json.ClassPathJsonDataSet;
+import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CustomerTest extends AbstractCassandraUnit4TestCase {
+ private Customers customers;
+
+ @Override
+ public DataSet getDataSet() {
+ return new ClassPathJsonDataSet("customerDataSet.json");
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ customers = new CassandraCustomers(getKeyspace());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
+ }
+
+ @Test
+ public void testCustomerInsertSearch() {
+ final Customer customer = new Customer();
+ customer.setName("Archimedes Trajano");
+ customer.setLastRecallTimestamp(new Date());
+ customer.setUuid(UUID.randomUUID());
+
+ customers.add(customer);
+
+ {
+ final List<Customer> customerList = customers
+ .find("Archimedes Trajano");
+ assertEquals(1, customerList.size());
+ assertEquals("Archimedes Trajano", customerList.get(0).getName());
+ }
+ {
+ final List<Customer> customerList = customers
+ .find("archimedes trajano");
+ assertEquals(1, customerList.size());
+ assertEquals("Archimedes Trajano", customerList.get(0).getName());
+ }
+ {
+ final List<Customer> customerList = customers
+ .find("archimedes TRAJANO");
+ assertEquals(1, customerList.size());
+ assertEquals("Archimedes Trajano", customerList.get(0).getName());
+ }
+ {
+ final List<Customer> customerList = customers.find("archimedes");
+ assertEquals(1, customerList.size());
+ assertEquals("Archimedes Trajano", customerList.get(0).getName());
+ }
+ {
+ final List<Customer> customerList = customers.find("archie");
+ assertEquals(1, customerList.size());
+ assertEquals("Archie", customerList.get(0).getName());
+ }
+ {
+ final List<Customer> customerList = customers.find("archi");
+ assertEquals(2, customerList.size());
+ }
+ }
+
+ @Test
+ public void testExistingDataSearch() {
+ {
+ final List<Customer> customerList = customers.find("archie");
+ assertEquals(1, customerList.size());
+ assertEquals("Archie", customerList.get(0).getName());
+ }
+ }
+
+ @Test
+ public void testMultipleInserts() {
+ {
+ final Customer customer = new Customer();
+ customer.setName("Excel");
+ customer.setLastRecallTimestamp(new Date());
+ customer.setUuid(UUID.randomUUID());
+
+ customers.add(customer);
+ }
+ {
+ final Customer customer = new Customer();
+ customer.setName("Hyatt");
+ customer.setLastRecallTimestamp(new Date());
+ customer.setUuid(UUID.randomUUID());
+
+ customers.add(customer);
+ }
+ {
+ final Customer customer = new Customer();
+ customer.setName("Hayate");
+ customer.setLastRecallTimestamp(new Date());
+ customer.setUuid(UUID.randomUUID());
+
+ customers.add(customer);
+ }
+ {
+ final Customer customer = new Customer();
+ customer.setName("Hinagiku");
+ customer.setLastRecallTimestamp(new Date());
+ customer.setUuid(UUID.randomUUID());
+
+ customers.add(customer);
+ }
+ {
+ final List<Customer> customerList = customers
+ .find("Archimedes Trajano");
+ assertEquals(0, customerList.size());
+ }
+ {
+ final List<Customer> customerList = customers.find("e");
+ assertEquals(1, customerList.size());
+ assertEquals("Excel", customerList.get(0).getName());
+ }
+ {
+ final List<Customer> customerList = customers.find("H");
+ assertEquals(3, customerList.size());
+ }
+ {
+ final List<Customer> customerList = customers.find("hayate");
+ assertEquals(1, customerList.size());
+ assertEquals("Hayate", customerList.get(0).getName());
+ }
+ }
+}
View
85 nosql/customer-cassandra/src/test/java/net/trajano/nosql/cassandra/test/EmbeddedCassandraTest.java
@@ -0,0 +1,85 @@
+package net.trajano.nosql.cassandra.test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import me.prettyprint.cassandra.model.CqlQuery;
+import me.prettyprint.cassandra.model.CqlRows;
+import me.prettyprint.cassandra.serializers.LongSerializer;
+import me.prettyprint.cassandra.serializers.StringSerializer;
+import me.prettyprint.hector.api.query.QueryResult;
+
+import org.cassandraunit.AbstractCassandraUnit4TestCase;
+import org.cassandraunit.dataset.DataSet;
+import org.cassandraunit.dataset.json.ClassPathJsonDataSet;
+import org.cassandraunit.utils.EmbeddedCassandraServerHelper;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Embedding Cassandra test. Although Hector has a BaseEmbededServerSetupTest,
+ * CassandraUnit has extra functions like dataset loading that make testing a
+ * bit easier.
+ *
+ * @see <a
+ * href="https://github.com/jsevellec/cassandra-unit/wiki/How-to-integrate-it-in-your-project">cassandra-unit</a>
+ * @author Archimedes Trajano
+ *
+ */
+public class EmbeddedCassandraTest extends AbstractCassandraUnit4TestCase {
+
+ @Override
+ public DataSet getDataSet() {
+ return new ClassPathJsonDataSet("extendedDataSet.json");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
+ }
+
+ /**
+ * Use Hector as the client library but use CQL queries for readability.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testCql() throws Exception {
+ final CqlQuery<String, String, Long> cqlQuery = new CqlQuery<String, String, Long>(
+ getKeyspace(), StringSerializer.get(), StringSerializer.get(),
+ LongSerializer.get());
+ cqlQuery.setQuery("select * from beautifulColumnFamilyName");
+
+ final QueryResult<CqlRows<String, String, Long>> result = cqlQuery
+ .execute();
+
+ final CqlRows<String, String, Long> rows = result.get();
+ assertEquals(2, rows.getCount());
+ assertEquals(2, rows.getList().size());
+
+ }
+
+ /**
+ * Assert column family count
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testJSONData() throws Exception {
+ assertEquals(1, getDataSet().getColumnFamilies().size());
+ assertEquals("beautifulColumnFamilyName", getDataSet()
+ .getColumnFamilies().get(0).getName());
+ assertEquals(2, getDataSet().getColumnFamilies().get(0).getRows()
+ .size());
+ }
+
+ /**
+ * Verify connectivity.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testKeyspace() throws Exception {
+ assertNotNull(getKeyspace());
+ assertEquals("otherKeyspaceName", getKeyspace().getKeyspaceName());
+ }
+}
View
163 nosql/customer-cassandra/src/test/resources/customerDataSet.json
@@ -0,0 +1,163 @@
+{
+ "name":"otherKeyspaceName",
+ "replicationFactor":1,
+ "strategy":"org.apache.cassandra.locator.SimpleStrategy",
+ "columnFamilies":[
+ {
+ "name":"customer",
+ "comparatorType":"UTF8Type",
+ "defaultColumnValueType":"UTF8Type",
+ "keyType":"UUIDType",
+ "type":"STANDARD",
+ "columnsMetadata":[
+ {
+ "name":"uuid",
+ "validationClass":"UUIDType"
+ },
+ {
+ "indexType":"KEYS",
+ "name":"name",
+ "validationClass":"UTF8Type"
+ },
+ {
+ "indexType":"KEYS",
+ "name":"lastRecallTimestamp",
+ "validationClass":"LongType"
+ }
+ ],
+ "rows":[
+ {
+ "columns":[
+ {
+ "name":"uuid",
+ "value":"uuid(13816710-1dd2-11b2-879a-782bcb80ff6a)"
+ },
+ {
+ "name":"name",
+ "value":"Archie"
+ },
+ {
+ "name":"lastRecallTimestamp",
+ "value":"long(1)"
+ }
+ ],
+ "key":"13816710-1dd2-11b2-879a-782bcb80ff6a"
+ }
+ ]
+ },
+ {
+ "name":"customerName",
+ "comparatorType":"UTF8Type",
+ "defaultColumnValueType":"UTF8Type",
+ "keyType":"UTF8Type",
+ "subComparatorType":"UTF8Type",
+ "type":"SUPER",
+ "columnsMetadata":[
+ {
+ "name":"uuid",
+ "validationClass":"UUIDType"
+ }
+ ],
+ "rows":[
+ {
+ "key":"archie",
+ "superColumns":[
+ {
+ "name":"archie",
+ "columns":[
+ {
+ "name":"uuid",
+ "value":"uuid(13816710-1dd2-11b2-879a-782bcb80ff6a)"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "key":"archi",
+ "superColumns":[
+ {
+ "name":"archie",
+ "columns":[
+ {
+ "name":"uuid",
+ "value":"uuid(13816710-1dd2-11b2-879a-782bcb80ff6a)"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "key":"archi",
+ "superColumns":[
+ {
+ "name":"archie",
+ "columns":[
+ {
+ "name":"uuid",
+ "value":"uuid(13816710-1dd2-11b2-879a-782bcb80ff6a)"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "key":"arch",
+ "superColumns":[
+ {
+ "name":"archie",
+ "columns":[
+ {
+ "name":"uuid",
+ "value":"uuid(13816710-1dd2-11b2-879a-782bcb80ff6a)"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "key":"arc",
+ "superColumns":[
+ {
+ "name":"archie",
+ "columns":[
+ {
+ "name":"uuid",
+ "value":"uuid(13816710-1dd2-11b2-879a-782bcb80ff6a)"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "key":"ar",
+ "superColumns":[
+ {
+ "name":"archie",
+ "columns":[
+ {
+ "name":"uuid",
+ "value":"uuid(13816710-1dd2-11b2-879a-782bcb80ff6a)"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "key":"a",
+ "superColumns":[
+ {
+ "name":"archie",
+ "columns":[
+ {
+ "name":"uuid",
+ "value":"uuid(13816710-1dd2-11b2-879a-782bcb80ff6a)"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
View
33 nosql/customer-cassandra/src/test/resources/extendedDataSet.json
@@ -0,0 +1,33 @@
+{
+ "name" : "otherKeyspaceName",
+ "replicationFactor" : 1,
+ "strategy" : "org.apache.cassandra.locator.SimpleStrategy",
+ "columnFamilies" : [{
+ "name" : "beautifulColumnFamilyName",
+ "type" : "STANDARD",
+ "keyType" : "UTF8Type",
+ "comparatorType" : "LongType",
+ "rows" : [{
+ "key" : "key10",
+ "columns" : [{
+ "name" : "11",
+ "value" : "utf8(value11)"
+ },
+ {
+ "name" : "12",
+ "value" : "utf8(value12)"
+ }]
+ },
+ {
+ "key" : "key20",
+ "columns" : [{
+ "name" : "21",
+ "value" : "utf8(value11)"
+ },
+ {
+ "name" : "12",
+ "value" : "uuid(13816710-1dd2-11b2-879a-782bcb80ff6a)"
+ }]
+ }]
+ }]
+}
View
51 nosql/customer-mongodb/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>net.trajano.maven-jee6</groupId>
+ <artifactId>nosql</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>customer-mongodb</artifactId>
+ <packaging>bundle</packaging>
+ <description>Implementation using MongoDB.</description>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>customer</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mongodb</groupId>
+ <artifactId>mongo-java-driver</artifactId>
+ <version>2.11.1</version>
+ </dependency>
+ <dependency>
+ <groupId>de.flapdoodle.embed</groupId>
+ <artifactId>de.flapdoodle.embed.mongo</artifactId>
+ <version>1.31</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>maven-jee6-test</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>net.alchim31.maven</groupId>
+ <artifactId>scala-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
+
View
71 nosql/customer-mongodb/src/main/java/net/trajano/nosql/internal/MongoDbCustomers.java
@@ -0,0 +1,71 @@
+package net.trajano.nosql.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.inject.Inject;
+
+import net.trajano.nosql.Customer;
+import net.trajano.nosql.Customers;
+
+import com.google.gson.Gson;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+import com.mongodb.util.JSON;
+
+/**
+ * Represents customers DAO implemented using MongoDB.
+ */
+public class MongoDbCustomers implements Customers {
+ /**
+ * "Customers" {@link DBCollection} from the injected {@link DB}.
+ */
+ private final DBCollection collection;
+
+ /**
+ * Constructs the DAO.
+ *
+ * @param db
+ * MongoDB instance.
+ */
+ @Inject
+ public MongoDbCustomers(final DB db) {
+ collection = db.getCollection("Customers");
+ }
+
+ /**
+ * Add the Customer to the database.
+ *
+ * @param customer
+ * customer
+ */
+ @Override
+ public void add(final Customer customer) {
+ final Gson gson = new Gson();
+ collection.insert((DBObject) JSON.parse(gson.toJson(customer)));
+ }
+
+ /**
+ * Find a customer using a regular expression.
+ *
+ * @param customerRegexp
+ * regular expression
+ * @return list of customers that satisfy the regular expression.
+ */
+ @Override
+ public List<Customer> find(final String customerRegexp) {
+ final Gson gson = new Gson();
+ final BasicDBObject query = new BasicDBObject();
+ query.append("name",
+ Pattern.compile(customerRegexp, Pattern.CASE_INSENSITIVE));
+ final List<Customer> ret = new ArrayList<Customer>();
+ for (final DBObject dbObject : collection.find(query)) {
+ ret.add(gson.fromJson(dbObject.toString(), Customer.class));
+ }
+ return ret;
+ }
+
+}
View
5 nosql/customer-mongodb/src/main/java/net/trajano/nosql/internal/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Internal implementation classes.
+ */
+package net.trajano.nosql.internal;
+
View
65 nosql/customer-mongodb/src/test/java/net/trajano/nosql/mongodb/test/CdiProducer.java
@@ -0,0 +1,65 @@
+package net.trajano.nosql.mongodb.test;
+
+import java.io.IOException;
+import java.util.UUID;
+
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+import javax.inject.Singleton;
+
+import com.mongodb.DB;
+import com.mongodb.Mongo;
+
+import de.flapdoodle.embed.mongo.distribution.Version;
+import de.flapdoodle.embed.mongo.tests.MongodForTestsFactory;
+
+/**
+ * Created with IntelliJ IDEA. User: trajano Date: 12-05-28 Time: 11:05 PM To
+ * change this template use File | Settings | File Templates.
+ */
+public class CdiProducer {
+ @Produces
+ @Singleton
+ public Mongo createMongo(final MongodForTestsFactory testFactory)
+ throws Exception {
+ return testFactory.newMongo();
+ }
+
+ /**
+ * Produces a new mongo database using a random name.
+ *
+ * @param mongo
+ * mongo instance.
+ * @return database instance
+ */
+ @Produces
+ public DB createMongoDB(final Mongo mongo) {
+ return mongo.getDB(UUID.randomUUID().toString());
+ }
+
+ /**
+ * This produces an embedded MongoDB test factory used to create MongoDB
+ * objects in a test environment.
+ *
+ * @return an embedded MongoDB test factory.
+ * @throws IOException
+ */
+ @Produces
+ @Singleton
+ public MongodForTestsFactory createMongodExecutable() throws IOException {
+ return MongodForTestsFactory.with(Version.Main.V2_0);
+ }
+
+ public void disposeDB(@Disposes final DB db) {
+ db.dropDatabase();
+ }
+
+ public void disposeMongo(@Disposes final Mongo mongo) {
+ mongo.close();
+ }
+
+ public void disposeMongodForTestsFactory(
+ @Disposes final MongodForTestsFactory testFactory) {
+ testFactory.shutdown();
+ }
+}
View
149 nosql/customer-mongodb/src/test/java/net/trajano/nosql/mongodb/test/CdiTest.java
@@ -0,0 +1,149 @@
+package net.trajano.nosql.mongodb.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import net.trajano.maven_jee6.test.LogUtil;
+import net.trajano.nosql.Customer;
+import net.trajano.nosql.Customers;
+import net.trajano.nosql.internal.MongoDbCustomers;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+import com.mongodb.util.JSON;
+
+@RunWith(Arquillian.class)
+public class CdiTest {
+ @Deployment
+ public static JavaArchive createDeployment() {
+ return ShrinkWrap.create(JavaArchive.class).addClass(CdiProducer.class)
+ .addClass(Customers.class).addClass(MongoDbCustomers.class)
+ .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
+ }
+
+ @BeforeClass
+ public static void setLoggingConfiguration() throws IOException {
+ LogUtil.loadConfiguration();
+ }
+
+ @Inject
+ private Customers customers;
+
+ @Inject
+ private DB db;
+
+ @Test
+ public void testInjection() {
+ assertNotNull(db);
+ assertNotNull(customers);
+ }
+
+ @Test
+ public void testMongoDbJsonQueries() {
+ final DBCollection coll = db.getCollection("testCollection");
+ {
+ final BasicDBObject doc = new BasicDBObject();
+
+ doc.put("name", "MongoDB");
+ doc.put("type", "database");
+ doc.put("count", 1);
+
+ final BasicDBObject info = new BasicDBObject();
+
+ info.put("x", 203);
+ info.put("y", 102);
+
+ doc.put("info", info);
+
+ coll.insert(doc);
+ }
+ {
+ final DBObject query = (DBObject) JSON
+ .parse("{ type : 'database' }");
+ final DBObject myDoc = coll.findOne(query);
+ assertNotNull(myDoc);
+ assertEquals("MongoDB", myDoc.get("name"));
+ assertEquals(203, ((BasicDBObject) myDoc.get("info")).get("x"));
+ }
+ {
+ final DBObject query = (DBObject) JSON
+ .parse("{ 'info.x' : { $gt : 1 } }");
+ final DBObject myDoc = coll.findOne(query);
+ assertNotNull(myDoc);
+ assertEquals("MongoDB", myDoc.get("name"));
+ assertEquals(203, ((BasicDBObject) myDoc.get("info")).get("x"));
+ }
+ {
+ final DBObject query = (DBObject) JSON
+ .parse("{ 'info.x' : { $gt : 1 } }");
+ final DBObject fields = (DBObject) JSON.parse("{ type : 1 }");
+ final DBObject myDoc = coll.findOne(query, fields);
+ assertNotNull(myDoc);
+ assertNull(myDoc.get("name"));
+ assertEquals("database", myDoc.get("type"));
+ }
+ }
+
+ /**
+ * This is an example based on
+ * http://www.mongodb.org/display/DOCS/Java+Tutorial to see if things work.
+ */
+ @Test
+ public void testMongoDbTutorialSample() {
+ final DBCollection coll = db.getCollection("testCollection");
+ {
+ final BasicDBObject doc = new BasicDBObject();
+
+ doc.put("name", "MongoDB");
+ doc.put("type", "database");
+ doc.put("count", 1);
+
+ final BasicDBObject info = new BasicDBObject();
+
+ info.put("x", 203);
+ info.put("y", 102);
+
+ doc.put("info", info);
+
+ coll.insert(doc);
+ }
+ {
+ final DBObject myDoc = coll.findOne();
+ assertEquals("MongoDB", myDoc.get("name"));
+ assertEquals(203, ((BasicDBObject) myDoc.get("info")).get("x"));
+ }
+ }
+
+ @Test
+ public void testWithSerializedObject() throws Exception {
+ final Customer customer = new Customer();
+ customer.setName("Archimedes Trajano");
+ customer.setLastRecallTimestamp(new Date());
+ customer.setUuid(UUID.randomUUID());
+
+ customers.add(customer);
+
+ final List<Customer> customerList = customers.find("arch");
+ assertEquals(1, customerList.size());
+ assertEquals("Archimedes Trajano", customerList.get(0).getName());
+ }
+}
View
8 nosql/customer-mongodb/src/test/java/net/trajano/nosql/mongodb/test/EmbeddedMongo.java
@@ -0,0 +1,8 @@
+package net.trajano.nosql.mongodb.test;
+
+/**
+ * Created with IntelliJ IDEA. User: trajano Date: 12-05-29 Time: 01:50 PM To
+ * change this template use File | Settings | File Templates.
+ */
+public @interface EmbeddedMongo {
+}
View
90 nosql/customer-mongodb/src/test/java/net/trajano/nosql/mongodb/test/MongoDbTest.java
@@ -0,0 +1,90 @@
+package net.trajano.nosql.mongodb.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+
+import net.trajano.maven_jee6.test.LogUtil;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+import com.mongodb.Mongo;
+
+import de.flapdoodle.embed.mongo.distribution.Version;
+import de.flapdoodle.embed.mongo.tests.MongodForTestsFactory;
+
+/**
+ * Shows how to test using MongoDB without CDI. This is useful to show the steps
+ * necessary to use the embedded version of MongoDB for testing. This is based
+ * on http://stackoverflow.com/a/9830861/242042.
+ */
+public class MongoDbTest {
+ private static MongodForTestsFactory testsFactory;
+
+ @BeforeClass
+ public static void setLoggingConfiguration() throws IOException {
+ LogUtil.loadConfiguration();
+ }
+
+ @BeforeClass
+ public static void setMongoDB() throws IOException {
+ testsFactory = MongodForTestsFactory.with(Version.Main.PRODUCTION);
+ }
+
+ @AfterClass
+ public static void tearDownMongoDB() throws Exception {
+ testsFactory.shutdown();
+ }
+
+ private DB db;
+
+ @Before
+ public void setUpMongoDB() throws Exception {
+ final Mongo mongo = testsFactory.newMongo();
+ db = testsFactory.newDB(mongo);
+ }
+
+ /**
+ * This is an example based on
+ * http://www.mongodb.org/display/DOCS/Java+Tutorial to see if things work.
+ */
+ @Test
+ public void testCreateRuntime() throws Exception {
+
+ // perform operations
+ final DBCollection coll = db.getCollection("testCollection");
+ {
+ final BasicDBObject doc = new BasicDBObject();
+
+ doc.put("name", "MongoDB");
+ doc.put("type", "database");
+ doc.put("count", 1);
+
+ final BasicDBObject info = new BasicDBObject();
+
+ info.put("x", 203);
+ info.put("y", 102);
+
+ doc.put("info", info);
+
+ coll.insert(doc);
+ }
+ {
+ final DBObject myDoc = coll.findOne();
+ assertEquals("MongoDB", myDoc.get("name"));
+ assertEquals(203, ((BasicDBObject) myDoc.get("info")).get("x"));
+ }
+ }
+
+ public void testDatabaseCreated() {
+ assertNotNull(db);
+ }
+}
View
37 nosql/customer-mongodb/src/test/java/net/trajano/nosql/mongodb/test/SerializationTest.java
@@ -0,0 +1,37 @@
+package net.trajano.nosql.mongodb.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import net.trajano.nosql.Customer;
+
+import org.junit.Test;
+
+import com.google.gson.Gson;
+
+/**
+ * Test to use GSON as the JSON serialization engine.
+ */
+public class SerializationTest {
+ @Test
+ public void testCustomer() {
+ final Customer customer = new Customer();
+ customer.setName("Archimedes Trajano");
+ customer.setLastRecallTimestamp(new Date());
+ customer.setUuid(UUID.randomUUID());
+ final Gson gson = new Gson();
+ final String jsonString = gson.toJson(customer);
+ assertTrue(jsonString.contains("\"name\":\"Archimedes Trajano\""));
+ assertTrue(jsonString.contains("\"uuid\":\"" + customer.getUuid()