├── .circleci
└── config.yml
├── .coveralls.yml
├── .gitignore
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── LICENSE
├── Readme.md
├── build.gradle
├── buildsupport
└── eclipsesupport
│ └── settings
│ ├── org.eclipse.jdt.core.prefs
│ └── org.eclipse.jdt.ui.prefs
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
├── main
└── java
│ └── io
│ └── jsondb
│ ├── CollectionMetaData.java
│ ├── DefaultSchemaVersionComparator.java
│ ├── InvalidJsonDbApiUsageException.java
│ ├── JsonDBConfig.java
│ ├── JsonDBException.java
│ ├── JsonDBOperations.java
│ ├── JsonDBTemplate.java
│ ├── SchemaVersion.java
│ ├── Util.java
│ ├── annotation
│ ├── Document.java
│ ├── Id.java
│ └── Secret.java
│ ├── crypto
│ ├── CryptoUtil.java
│ ├── Default1Cipher.java
│ ├── DefaultAESCBCCipher.java
│ └── ICipher.java
│ ├── events
│ ├── CollectionFileChangeAdapter.java
│ ├── CollectionFileChangeListener.java
│ └── EventListenerList.java
│ ├── io
│ ├── JsonFileLockException.java
│ ├── JsonReader.java
│ └── JsonWriter.java
│ └── query
│ ├── Update.java
│ └── ddl
│ ├── AbstractOperation.java
│ ├── AddOperation.java
│ ├── CollectionSchemaUpdate.java
│ ├── DeleteOperation.java
│ ├── IOperation.java
│ └── RenameOperation.java
└── test
├── java
└── io
│ └── jsondb
│ └── tests
│ ├── CollectionMetaDataTests.java
│ ├── CollectionSchemaUpdateTests.java
│ ├── CreateDropCollectionTests.java
│ ├── DefaultAESCipherTests.java
│ ├── EncryptionTests.java
│ ├── ExceptionTests.java
│ ├── FileChangeAdapterTests.java
│ ├── FileChangeListenerTests.java
│ ├── FindAndModifyTests.java
│ ├── FindAndRemoveTests.java
│ ├── FindByIdTests.java
│ ├── FindQueryTests.java
│ ├── InitializeDBNegativeTests.java
│ ├── InitializeDBTests.java
│ ├── InsertTests.java
│ ├── JsonDBConfigTests.java
│ ├── JsonReaderTests.java
│ ├── JsonWriterTests.java
│ ├── LoadInvalidJsonTests.java
│ ├── PojoWithEnumFieldsTest.java
│ ├── RemoveTests.java
│ ├── SaveTests.java
│ ├── UpsertTests.java
│ ├── UtilTests.java
│ ├── model
│ ├── Instance.java
│ ├── LoadBalancer.java
│ ├── PojoForPrivateGetIdTest.java
│ ├── PojoForPrivateSetIdTest.java
│ ├── PojoWithEnumFields.java
│ ├── PojoWithList.java
│ ├── SecureVolume.java
│ ├── Site.java
│ └── Volume.java
│ └── util
│ └── TestUtils.java
└── resources
└── dbfiles
├── instances.json
├── loadbalancer.json
└── pojowithenumfields.json
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | jobs:
4 | build:
5 | environment:
6 | # Configure the JVM and Gradle to avoid OOM errors
7 | _JAVA_OPTIONS: "-Xmx3g"
8 | GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2"
9 | docker: # run the steps with Docker
10 | - image: circleci/openjdk:8u222-jdk-stretch-node-browsers-legacy
11 |
12 | steps:
13 | - checkout
14 | - run:
15 | name: Build and Test
16 | command:
17 | ./gradlew test
18 |
19 | workflows:
20 | version: 2
21 | workflow:
22 | jobs:
23 | - build
24 |
--------------------------------------------------------------------------------
/.coveralls.yml:
--------------------------------------------------------------------------------
1 | repo_token: KaiaNcXBfP2cda4WAV2tMJyqepXXLei5l
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.*~
2 | *.swp
3 | .gradle
4 | *.log
5 | .DS_Store
6 |
7 | **/build/*
8 |
9 | **/.DS_Store
10 |
11 | **/bin/**/*.class
12 |
13 | #Eclipse Files
14 | **/.classpath
15 | **/.project
16 | **/.settings/*
17 | **/.springBeans
18 |
19 | #Ignore .gitignore from subdirectories
20 | */.gitignore
21 | /bin/
22 | /.idea/
23 | *.iml
24 | *.ipr
25 | *.iws
26 | /out/
27 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | dist: trusty
3 |
4 | git:
5 | depth: 3
6 |
7 | jdk:
8 | - oraclejdk8
9 |
10 | script:
11 | - ./gradlew clean build
12 |
13 | after_success:
14 | - ./gradlew jacocoTestReport coveralls
15 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at farooq_m_khan@yahoo.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Farooq Khan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | [](https://circleci.com/gh/Jsondb/jsondb-core) [](https://travis-ci.org/Jsondb/jsondb-core) [](https://coveralls.io/github/Jsondb/jsondb-core?branch=master)
2 |
3 | JsonDB is a pure java database that stores its data as Json Files.
4 |
5 | A very small memory footprint, runs embedded within your java program.
6 |
7 | Provides APIs that are very similar and inspired by MongoDB.
8 |
9 | Provides a Apache JxPath based query system.
10 |
11 | Visit https://jsondb.github.io for detailed information about Jsondb, Why Jsondb and Using Jsondb
12 |
13 |
14 |
15 |
16 | ## Stargazers over time
17 |
18 | [](https://starchart.cc/Jsondb/jsondb-core)
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | plugins {
22 | //id 'net.saliman.cobertura' version '2.3.1'
23 | id 'jacoco'
24 | id 'com.github.kt3k.coveralls' version '2.6.3'
25 | id 'idea'
26 | }
27 |
28 | apply plugin: "java"
29 | apply plugin: "jacoco"
30 | apply plugin: "eclipse"
31 | apply plugin: "signing"
32 | apply plugin: "maven"
33 |
34 | description = 'A pure java JSON based database.'
35 | group = 'io.jsondb'
36 | version = getVersionName()
37 |
38 | ext {
39 | println "Build Version: $version"
40 | }
41 |
42 | repositories {
43 | mavenCentral()
44 | }
45 |
46 | dependencies {
47 | compile "org.slf4j:slf4j-api:1.7.21",
48 | "com.fasterxml.jackson.core:jackson-annotations:2.9.9",
49 | "com.fasterxml.jackson.core:jackson-core:2.9.9",
50 | "com.fasterxml.jackson.core:jackson-databind:2.9.9",
51 | "com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.9",
52 | "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.9",
53 | "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.9",
54 | "org.reflections:reflections:0.9.10",
55 | "org.javassist:javassist:3.20.0-GA",
56 | "commons-jxpath:commons-jxpath:1.3",
57 | "com.google.guava:guava:19.0",
58 | "commons-beanutils:commons-beanutils:1.9.3"
59 |
60 | testCompile "junit:junit:4.12",
61 | "org.hamcrest:hamcrest-library:1.3",
62 | "org.springframework:spring-beans:4.3.3.RELEASE",
63 | "org.springframework:spring-test:4.3.3.RELEASE"
64 | }
65 |
66 | //cobertura.coverageFormats = ['html', 'xml'] // coveralls plugin depends on xml format report
67 |
68 | jacocoTestReport {
69 | reports {
70 | xml.enabled = true // coveralls plugin depends on xml format report
71 | html.enabled = true
72 | }
73 | }
74 |
75 | eclipse {
76 | project {
77 | name = "${project.name}"
78 | }
79 | }
80 |
81 | eclipseJdt {
82 | inputFile = file("${rootDir}/buildsupport/eclipsesupport/settings/org.eclipse.jdt.core.prefs")
83 | doLast {
84 | copy {
85 | from "${rootDir}/buildsupport/eclipsesupport/settings/org.eclipse.jdt.ui.prefs"
86 | into "${projectDir}/.settings"
87 | fileMode 0644
88 | }
89 | }
90 | }
91 |
92 | cleanEclipseJdt {
93 | doFirst {
94 | delete "${projectDir}/.settings"
95 | }
96 | }
97 | tasks.eclipse.dependsOn(cleanEclipse)
98 |
99 | task javadocJar(type: Jar) {
100 | classifier = 'javadoc'
101 | from javadoc
102 | }
103 |
104 | task sourcesJar(type: Jar) {
105 | classifier = 'sources'
106 | from sourceSets.main.allSource
107 | }
108 |
109 | artifacts {
110 | archives javadocJar, sourcesJar
111 | }
112 |
113 | signing {
114 | required { gradle.taskGraph.hasTask("uploadArchives") }
115 | sign configurations.archives
116 | }
117 |
118 | uploadArchives {
119 | //How to publish to MavenCentral: http://weibeld.net/java/publish-to-maven-central.html
120 | repositories {
121 | mavenDeployer {
122 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
123 |
124 | repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
125 | authentication(userName: OSSRH_USERNAME, password: OSSRH_PASSWORD)
126 | }
127 |
128 | snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
129 | authentication(userName: OSSRH_USERNAME, password: OSSRH_PASSWORD)
130 | }
131 |
132 | pom.project {
133 | name 'jsondb-core'
134 | packaging 'jar'
135 | // optionally artifactId can be defined here
136 | description 'A pure java JSON based database.'
137 | url 'http://www.jsondb.io'
138 |
139 | scm {
140 | connection 'scm:git:https://github.com/Jsondb/jsondb-core.git'
141 | developerConnection 'scm:git:https://github.com/Jsondb/jsondb-core.git'
142 | url 'scm:git:https://github.com/Jsondb/jsondb-core.git'
143 | }
144 |
145 | licenses {
146 | license {
147 | name 'MIT License'
148 | url 'https://opensource.org/licenses/MIT'
149 | }
150 | }
151 |
152 | developers {
153 | developer {
154 | id 'FarooqKhan'
155 | name 'Farooq Khan'
156 | email 'FarooqKhan@users.noreply.github.com'
157 | }
158 | }
159 | }
160 | }
161 | }
162 | }
163 |
164 | /*
165 | * Gets the version name from the latest Git tag
166 | */
167 | def getVersionName() {
168 | def stdout = new ByteArrayOutputStream()
169 | exec {
170 | commandLine 'git', 'describe', '--tags'
171 | standardOutput = stdout
172 | }
173 | def versionString = stdout.toString().replaceFirst("-", ".");
174 | versionString = versionString.substring(0, versionString.indexOf("-"));
175 |
176 | if (JavaVersion.current().isJava8()) {
177 | versionString = versionString + '-j8'
178 | } else if (JavaVersion.current().isJava11()){
179 | versionString = versionString + '-j11'
180 | } else {
181 | assert 'Only build with Java LTS version'
182 | }
183 |
184 | return versionString
185 | }
186 |
--------------------------------------------------------------------------------
/buildsupport/eclipsesupport/settings/org.eclipse.jdt.ui.prefs:
--------------------------------------------------------------------------------
1 | cleanup.add_default_serial_version_id=true
2 | cleanup.add_generated_serial_version_id=false
3 | cleanup.add_missing_annotations=true
4 | cleanup.add_missing_deprecated_annotations=true
5 | cleanup.add_missing_methods=false
6 | cleanup.add_missing_nls_tags=false
7 | cleanup.add_missing_override_annotations=true
8 | cleanup.add_missing_override_annotations_interface_methods=true
9 | cleanup.add_serial_version_id=false
10 | cleanup.always_use_blocks=true
11 | cleanup.always_use_parentheses_in_expressions=false
12 | cleanup.always_use_this_for_non_static_field_access=false
13 | cleanup.always_use_this_for_non_static_method_access=false
14 | cleanup.convert_to_enhanced_for_loop=false
15 | cleanup.correct_indentation=false
16 | cleanup.format_source_code=false
17 | cleanup.format_source_code_changes_only=false
18 | cleanup.make_local_variable_final=true
19 | cleanup.make_parameters_final=false
20 | cleanup.make_private_fields_final=true
21 | cleanup.make_type_abstract_if_missing_method=false
22 | cleanup.make_variable_declarations_final=false
23 | cleanup.never_use_blocks=false
24 | cleanup.never_use_parentheses_in_expressions=true
25 | cleanup.organize_imports=false
26 | cleanup.qualify_static_field_accesses_with_declaring_class=false
27 | cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
28 | cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
29 | cleanup.qualify_static_member_accesses_with_declaring_class=true
30 | cleanup.qualify_static_method_accesses_with_declaring_class=false
31 | cleanup.remove_private_constructors=true
32 | cleanup.remove_trailing_whitespaces=false
33 | cleanup.remove_trailing_whitespaces_all=true
34 | cleanup.remove_trailing_whitespaces_ignore_empty=false
35 | cleanup.remove_unnecessary_casts=true
36 | cleanup.remove_unnecessary_nls_tags=true
37 | cleanup.remove_unused_imports=true
38 | cleanup.remove_unused_local_variables=false
39 | cleanup.remove_unused_private_fields=true
40 | cleanup.remove_unused_private_members=false
41 | cleanup.remove_unused_private_methods=true
42 | cleanup.remove_unused_private_types=true
43 | cleanup.sort_members=false
44 | cleanup.sort_members_all=false
45 | cleanup.use_blocks=false
46 | cleanup.use_blocks_only_for_return_and_throw=false
47 | cleanup.use_parentheses_in_expressions=false
48 | cleanup.use_this_for_non_static_field_access=false
49 | cleanup.use_this_for_non_static_field_access_only_if_necessary=true
50 | cleanup.use_this_for_non_static_method_access=false
51 | cleanup.use_this_for_non_static_method_access_only_if_necessary=true
52 | cleanup_profile=org.eclipse.jdt.ui.default.eclipse_clean_up_profile
53 | cleanup_settings_version=2
54 | eclipse.preferences.version=1
55 | formatter_profile=_Farooq_AutoGenerated
56 | formatter_settings_version=12
57 | org.eclipse.jdt.ui.javadoc=true
58 | org.eclipse.jdt.ui.text.custom_code_templates=/**\r\n * @return the ${bare_field_name}\r\n *//**\r\n * @param ${param} the ${bare_field_name} to set\r\n *//**\r\n * ${tags}\r\n *//*\r\n * Copyright (c) 2016 Farooq Khan\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the "Software"), to \r\n * deal in the Software without restriction, including without limitation the\r\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\r\n * sell copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be included in\r\n * all copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR \r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL \r\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n *//**\r\n * @version 1.0 ${date}\r\n * ${tags}\r\n *//**\r\n * \r\n *//**\r\n * ${tags}\r\n *//* (non-Javadoc)\r\n * ${see_to_overridden}\r\n *//**\r\n * ${tags}\r\n * ${see_to_target}\r\n */${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}\r\n\r\n\r\n\r\n// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();// ${todo} Auto-generated method stub\r\n${body_statement}${body_statement}\r\n// ${todo} Auto-generated constructor stubreturn ${field};${field} \= ${param};
59 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #sonatype login used for uploading build to MavenCentral
2 | #This only exist so that the build goes fine even on circleci or travisci or for everyone else
3 | OSSRH_USERNAME=
4 | OSSRH_PASSWORD=
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jsondb/jsondb-core/f45460cd4667f79c3548c76baf5215a695b1a956/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS='"-Xmx64m"'
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS="-Xmx64m"
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/DefaultSchemaVersionComparator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb;
22 |
23 | import java.util.Comparator;
24 |
25 | /**
26 | * A default schema version comparator that expects the version to be in x.y.z form where each of the digits is
27 | * strictly a integer.
28 | *
29 | * @author Farooq Khan
30 | * @version 1.0 25-Sep-2016
31 | */
32 | public class DefaultSchemaVersionComparator implements Comparator {
33 |
34 | /**
35 | * compare the expected version with the actual version.
36 | *
37 | * Checkout: http://stackoverflow.com/questions/6701948/efficient-way-to-compare-version-strings-in-java
38 | *
39 | * @param expected the version that is obtained from @Document annotation
40 | * @param actual the version that is read from the .json file
41 | * @return a negative integer, zero, or a positive integer as the first argument is less
42 | * than, equal to, or greater than the second.
43 | */
44 | @Override
45 | public int compare(String expected, String actual) {
46 | String[] vals1 = expected.split("\\.");
47 | String[] vals2 = actual.split("\\.");
48 |
49 | int i = 0;
50 | while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) {
51 | i++;
52 | }
53 |
54 | if (i < vals1.length && i < vals2.length) {
55 | int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i]));
56 | return Integer.signum(diff);
57 | } else {
58 | return Integer.signum(vals1.length - vals2.length);
59 | }
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/InvalidJsonDbApiUsageException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb;
22 |
23 | /**
24 | * @author Farooq Khan
25 | * @version 1.0 25-Sep-2016
26 | */
27 | public class InvalidJsonDbApiUsageException extends RuntimeException {
28 | private static final long serialVersionUID = 5146122546986827377L;
29 |
30 | public InvalidJsonDbApiUsageException(String msg) {
31 | super(msg);
32 | }
33 |
34 | public InvalidJsonDbApiUsageException(String msg, Throwable cause) {
35 | super(msg, cause);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/JsonDBConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb;
22 |
23 | import java.io.File;
24 | import java.nio.charset.Charset;
25 | import java.nio.file.Path;
26 | import java.util.Comparator;
27 |
28 | import com.fasterxml.jackson.databind.DeserializationFeature;
29 | import com.fasterxml.jackson.databind.ObjectMapper;
30 |
31 | import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
32 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
33 | import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
34 | import io.jsondb.crypto.ICipher;
35 |
36 | /**
37 | * A POJO that has settings for the functioning of DB.
38 | * @author Farooq Khan
39 | * @version 1.0 25-Sep-2016
40 | */
41 | public class JsonDBConfig {
42 | //Settings
43 | private Charset charset;
44 | private String dbFilesLocationString;
45 | private File dbFilesLocation;
46 | private Path dbFilesPath;
47 | private String baseScanPackage;
48 | private ICipher cipher;
49 | private boolean compatibilityMode;
50 |
51 | //References
52 | private ObjectMapper objectMapper;
53 | private Comparator schemaComparator;
54 |
55 | public JsonDBConfig(String dbFilesLocationString, String baseScanPackage,
56 | ICipher cipher, boolean compatibilityMode, Comparator schemaComparator) {
57 |
58 | this.charset = Charset.forName("UTF-8");
59 | this.dbFilesLocationString = dbFilesLocationString;
60 | this.dbFilesLocation = new File(dbFilesLocationString);
61 | this.dbFilesPath = dbFilesLocation.toPath();
62 | this.baseScanPackage = baseScanPackage;
63 | this.cipher = cipher;
64 |
65 | this.compatibilityMode = compatibilityMode;
66 | this.objectMapper = new ObjectMapper()
67 | .registerModule(new ParameterNamesModule())
68 | .registerModule(new Jdk8Module())
69 | .registerModule(new JavaTimeModule());
70 |
71 | if (compatibilityMode) {
72 | objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
73 | }
74 |
75 | if (null == schemaComparator) {
76 | this.schemaComparator = new DefaultSchemaVersionComparator();
77 | } else {
78 | this.schemaComparator = schemaComparator;
79 | }
80 | }
81 |
82 | public Charset getCharset() {
83 | return charset;
84 | }
85 | public void setCharset(Charset charset) {
86 | this.charset = charset;
87 | }
88 | public String getDbFilesLocationString() {
89 | return dbFilesLocationString;
90 | }
91 | public void setDbFilesLocationString(String dbFilesLocationString) {
92 | this.dbFilesLocationString = dbFilesLocationString;
93 | this.dbFilesLocation = new File(dbFilesLocationString);
94 | this.dbFilesPath = dbFilesLocation.toPath();
95 | }
96 | public File getDbFilesLocation() {
97 | return dbFilesLocation;
98 | }
99 | public Path getDbFilesPath() {
100 | return dbFilesPath;
101 | }
102 |
103 | public String getBaseScanPackage() {
104 | return baseScanPackage;
105 | }
106 | public void setBaseScanPackage(String baseScanPackage) {
107 | this.baseScanPackage = baseScanPackage;
108 | }
109 | public ICipher getCipher() {
110 | return cipher;
111 | }
112 | public void setCipher(ICipher cipher) {
113 | this.cipher = cipher;
114 | }
115 | public boolean isCompatibilityMode() {
116 | return compatibilityMode;
117 | }
118 | public void setCompatibilityMode(boolean compatibilityMode) {
119 | this.compatibilityMode = compatibilityMode;
120 | if (compatibilityMode) {
121 | objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
122 | } else {
123 | objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
124 | }
125 | }
126 | public ObjectMapper getObjectMapper() {
127 | return objectMapper;
128 | }
129 | public void setObjectMapper(ObjectMapper objectMapper) {
130 | this.objectMapper = objectMapper;
131 | }
132 | public Comparator getSchemaComparator() {
133 | return schemaComparator;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/JsonDBException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb;
22 |
23 | /**
24 | * @version 1.0 06-Oct-2016
25 | */
26 | public class JsonDBException extends RuntimeException {
27 |
28 | private static final long serialVersionUID = -1397228179744504376L;
29 |
30 | public JsonDBException(String msg) {
31 | super(msg);
32 | }
33 |
34 | public JsonDBException(String msg, Throwable cause) {
35 | super(msg, cause);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/SchemaVersion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb;
22 |
23 | /**
24 | * @author Farooq Khan
25 | * @version 1.0 25-Sep-2016
26 | */
27 | public class SchemaVersion {
28 | private String schemaVersion;
29 |
30 | //Default constructor required for Jackson
31 | public SchemaVersion() { }
32 |
33 | public SchemaVersion(String schemaVersion) {
34 | this.schemaVersion = schemaVersion;
35 | }
36 |
37 | public String getSchemaVersion() {
38 | return schemaVersion;
39 | }
40 |
41 | public void setSchemaVersion(String schemaVersion) {
42 | this.schemaVersion = schemaVersion;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/annotation/Document.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.annotation;
22 |
23 | import java.lang.annotation.ElementType;
24 | import java.lang.annotation.Inherited;
25 | import java.lang.annotation.Retention;
26 | import java.lang.annotation.RetentionPolicy;
27 | import java.lang.annotation.Target;
28 |
29 | /**
30 | * @version 1.0 25-Sep-2016
31 | */
32 | @Inherited
33 | @Retention(RetentionPolicy.RUNTIME)
34 | @Target({ ElementType.TYPE })
35 | public @interface Document {
36 | String collection();
37 | String schemaVersion();
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/annotation/Id.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.annotation;
22 |
23 | import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
24 | import static java.lang.annotation.ElementType.FIELD;
25 | import static java.lang.annotation.ElementType.METHOD;
26 |
27 | import java.lang.annotation.Retention;
28 | import java.lang.annotation.RetentionPolicy;
29 | import java.lang.annotation.Target;
30 |
31 | /**
32 | * @version 1.0 25-Sep-2016
33 | */
34 | @Retention(RetentionPolicy.RUNTIME)
35 | @Target(value = { FIELD, METHOD, ANNOTATION_TYPE })
36 | public @interface Id {
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/annotation/Secret.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.annotation;
22 |
23 | import java.lang.annotation.ElementType;
24 | import java.lang.annotation.Inherited;
25 | import java.lang.annotation.Retention;
26 | import java.lang.annotation.RetentionPolicy;
27 | import java.lang.annotation.Target;
28 |
29 | /**
30 | * @version 1.0 25-Sep-2016
31 | */
32 | @Inherited
33 | @Retention(RetentionPolicy.RUNTIME)
34 | @Target({ ElementType.FIELD })
35 | public @interface Secret {
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/crypto/CryptoUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.crypto;
22 |
23 | import java.io.UnsupportedEncodingException;
24 | import java.lang.reflect.InvocationTargetException;
25 | import java.lang.reflect.Method;
26 | import java.security.NoSuchAlgorithmException;
27 | import java.security.spec.InvalidKeySpecException;
28 | import java.security.spec.KeySpec;
29 | import java.util.Base64;
30 |
31 | import javax.crypto.SecretKey;
32 | import javax.crypto.SecretKeyFactory;
33 | import javax.crypto.spec.PBEKeySpec;
34 |
35 | import org.slf4j.Logger;
36 | import org.slf4j.LoggerFactory;
37 |
38 | import io.jsondb.CollectionMetaData;
39 |
40 | /**
41 | * @author Farooq Khan
42 | * @version 1.0 25-Sep-2016
43 | */
44 | public class CryptoUtil {
45 | private static Logger logger = LoggerFactory.getLogger(CryptoUtil.class);
46 |
47 | /**
48 | * A utility method to encrypt the value of field marked by the @Secret annotation using its
49 | * setter/mutator method.
50 | * @param object the actual Object representing the POJO we want the Id of.
51 | * @param cmd the CollectionMetaData object from which we can obtain the list
52 | * containing names of fields which have the @Secret annotation
53 | * @param cipher the actual cipher implementation to use
54 | * @throws IllegalAccessException Error when invoking method for a @Secret annotated field due to permissions
55 | * @throws IllegalArgumentException Error when invoking method for a @Secret annotated field due to wrong arguments
56 | * @throws InvocationTargetException Error when invoking method for a @Secret annotated field, the method threw a exception
57 | */
58 | public static void encryptFields(Object object, CollectionMetaData cmd, ICipher cipher)
59 | throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
60 | for (String secretAnnotatedFieldName: cmd.getSecretAnnotatedFieldNames()) {
61 | Method getterMethod = cmd.getGetterMethodForFieldName(secretAnnotatedFieldName);
62 | Method setterMethod = cmd.getSetterMethodForFieldName(secretAnnotatedFieldName);
63 |
64 | String value;
65 | String encryptedValue = null;
66 | try {
67 | value = (String)getterMethod.invoke(object);
68 | if (null != value) {
69 | encryptedValue = cipher.encrypt(value);
70 | setterMethod.invoke(object, encryptedValue);
71 | }
72 | } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
73 | logger.error("Error when invoking method for a @Secret annotated field", e);
74 | throw e;
75 | }
76 | }
77 | }
78 |
79 | /**
80 | * A utility method to decrypt the value of field marked by the @Secret annotation using its
81 | * setter/mutator method.
82 | * @param object the actual Object representing the POJO we want the Id of.
83 | * @param cmd the CollectionMetaData object from which we can obtain the list
84 | * containing names of fields which have the @Secret annotation
85 | * @param cipher the actual cipher implementation to use
86 | * @throws IllegalAccessException Error when invoking method for a @Secret annotated field due to permissions
87 | * @throws IllegalArgumentException Error when invoking method for a @Secret annotated field due to wrong arguments
88 | * @throws InvocationTargetException Error when invoking method for a @Secret annotated field, the method threw a exception
89 | */
90 | public static void decryptFields(Object object, CollectionMetaData cmd, ICipher cipher)
91 | throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
92 |
93 | for (String secretAnnotatedFieldName: cmd.getSecretAnnotatedFieldNames()) {
94 | Method getterMethod = cmd.getGetterMethodForFieldName(secretAnnotatedFieldName);
95 | Method setterMethod = cmd.getSetterMethodForFieldName(secretAnnotatedFieldName);
96 |
97 | String value;
98 | String decryptedValue = null;
99 | try {
100 | value = (String)getterMethod.invoke(object);
101 | if (null != value) {
102 | decryptedValue = cipher.decrypt(value);
103 | setterMethod.invoke(object, decryptedValue);
104 | }
105 | } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
106 | logger.error("Error when invoking method for a @Secret annotated field", e);
107 | throw e;
108 | }
109 | }
110 | }
111 |
112 | /**
113 | * Utility method to help generate a strong 128 bit Key to be used for the DefaultAESCBCCipher.
114 | *
115 | * Note: This function is only provided as a utility to generate strong password it should
116 | * be used statically to generate a key and then the key should be captured and used in your program.
117 | *
118 | * This function defaults to using 65536 iterations and 128 bits for key size. If you wish to use 256 bits key size
119 | * then ensure that you have Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy installed
120 | * and change the last argument to {@link javax.crypto.spec.PBEKeySpec} below to 256
121 | *
122 | * @param password A password which acts as a seed for generation of the key
123 | * @param salt A salt used in combination with the password for the generation of the key
124 | *
125 | * @return A Base64 Encoded string representing the 128 bit key
126 | *
127 | * @throws NoSuchAlgorithmException if the KeyFactory algorithm is not found in available crypto providers
128 | * @throws UnsupportedEncodingException if the char encoding of the salt is not known.
129 | * @throws InvalidKeySpecException invalid generated key
130 | */
131 | public static String generate128BitKey(String password, String salt)
132 | throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException {
133 |
134 | SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
135 |
136 | KeySpec spec = new PBEKeySpec(password.toCharArray(), salt.getBytes(), 65536, 128);
137 | SecretKey key = factory.generateSecret(spec);
138 | byte[] keybyte = key.getEncoded();
139 | return Base64.getEncoder().encodeToString(keybyte);
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/crypto/Default1Cipher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019 Reinier Zwitserloot
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.crypto;
22 |
23 | import java.nio.ByteBuffer;
24 | import java.nio.charset.Charset;
25 | import java.nio.charset.StandardCharsets;
26 | import java.security.GeneralSecurityException;
27 | import java.security.InvalidAlgorithmParameterException;
28 | import java.security.InvalidKeyException;
29 | import java.security.NoSuchAlgorithmException;
30 | import java.security.NoSuchProviderException;
31 | import java.security.SecureRandom;
32 | import java.util.Base64;
33 |
34 | import javax.crypto.AEADBadTagException;
35 | import javax.crypto.BadPaddingException;
36 | import javax.crypto.Cipher;
37 | import javax.crypto.IllegalBlockSizeException;
38 | import javax.crypto.NoSuchPaddingException;
39 | import javax.crypto.ShortBufferException;
40 | import javax.crypto.spec.GCMParameterSpec;
41 | import javax.crypto.spec.SecretKeySpec;
42 |
43 | import io.jsondb.JsonDBException;
44 |
45 | /**
46 | * A default AES (GCM Mode) Cipher. AES is a 128-bit block cipher supporting keys of 128, 192, and 256 bits.
47 | *
48 | * The constructors do not check if key provided as parameter indeed specifies a valid AES key. It does not check key size,
49 | * nor does it check for weak or sem-weak keys.
50 | *
51 | * Note: If you want to use Key > 128 bits then you need to install Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction
52 | * Policy files.
53 | *
54 | * @author Reinier Zwitserloot
55 | * @version 1.0 20-Jun-2019
56 | */
57 | public class Default1Cipher implements ICipher {
58 | private static final String ENCRYPTION_ALGORITHM = "AES";
59 | private static final String MODE_ALGORITHM = "GCM";
60 | private static final String PADDING_ALGORITHM = "NoPadding";
61 | private static final String PROVIDER = "SunJCE";
62 | private static final String CIPHER_ALGORITHM = ENCRYPTION_ALGORITHM + "/" + MODE_ALGORITHM + "/" + PADDING_ALGORITHM;
63 | private static final int IV_SIZE = 16;
64 | private static final int TAG_SIZE = 128;
65 |
66 | /* intentionally letting the system pick a sane SecureRandom; SecureRandom.getInstanceStrong() can block and is overkill. */
67 | private static final SecureRandom rnd = createNewSecureRandom();
68 |
69 | private static final SecureRandom createNewSecureRandom() {
70 | try {
71 | return SecureRandom.getInstance("NativePRNGNonBlocking");
72 | } catch (NoSuchAlgorithmException e) {
73 | try {
74 | return SecureRandom.getInstance("SHA1PRNG");
75 | } catch (NoSuchAlgorithmException e2) {
76 | return new SecureRandom();
77 | }
78 | }
79 | }
80 |
81 | private final Charset charset;
82 | private final SecretKeySpec key;
83 |
84 | /**
85 | * Creates a new default cipher using 'UTF-8' encoding, with a base64-encoded key.
86 | *
87 | * @param base64CodedEncryptionKey A base 64 encoded symmetric key to be used during encryption and decryption.
88 | * @throws GeneralSecurityException a general security exception
89 | */
90 | public Default1Cipher(String base64CodedEncryptionKey) throws GeneralSecurityException {
91 | this(Base64.getDecoder().decode(base64CodedEncryptionKey), StandardCharsets.UTF_8);
92 | }
93 |
94 | /**
95 | * Creates a new default cipher using 'UTF-8' encoding and key.
96 | *
97 | * @param encryptionKey A symmetric key to be used during encryption and decryption.
98 | * @throws GeneralSecurityException a general security exception
99 | */
100 | public Default1Cipher(byte[] encryptionKey) throws GeneralSecurityException {
101 | this(encryptionKey, StandardCharsets.UTF_8);
102 | }
103 |
104 | /**
105 | * Creates a new default cipher with the specified charset encoding, with a base64-encoded key.
106 | *
107 | * @param base64CodedEncryptionKey A base 64 encoded symmetric key to be used during encryption and decryption.
108 | * @param charset The charset to be considered when encrypting plaintext or decrypting ciphertext.
109 | * @throws GeneralSecurityException a general security exception
110 | */
111 | public Default1Cipher(String base64CodedEncryptionKey, Charset charset) throws GeneralSecurityException {
112 | this(Base64.getDecoder().decode(base64CodedEncryptionKey), charset);
113 | }
114 |
115 | /**
116 | * Creates a new default cipher with the specified charset encoding and key.
117 | *
118 | * @param encryptionKey A symmetric key to be used during encryption and decryption.
119 | * @param charset The charset to be considered when encrypting plaintext or decrypting ciphertext.
120 | * @throws GeneralSecurityException a general security exception
121 | */
122 | public Default1Cipher(byte[] encryptionKey, Charset charset) throws GeneralSecurityException {
123 | if (charset == null) throw new NullPointerException("charset");
124 | if (encryptionKey == null) throw new NullPointerException("encryptionKey");
125 | this.charset = charset;
126 | this.key = new SecretKeySpec(encryptionKey, ENCRYPTION_ALGORITHM);
127 | }
128 |
129 | /**
130 | * This method is used to encrypt(Symmetric) plainText coming in input using AES algorithm
131 | * @param plainText the plain text string to be encrypted
132 | * @return Base64 encoded AES encrypted cipher text
133 | */
134 | @Override
135 | public String encrypt(String plainText) {
136 | try {
137 | byte[] iv = new byte[IV_SIZE];
138 | rnd.nextBytes(iv);
139 | Cipher enc = Cipher.getInstance(CIPHER_ALGORITHM, PROVIDER);
140 | enc.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(TAG_SIZE, iv));
141 | byte[] input = plainText.getBytes(charset);
142 | int sizeReq = IV_SIZE + enc.getOutputSize(input.length);
143 | byte[] output = new byte[sizeReq];
144 | ByteBuffer store = ByteBuffer.wrap(output);
145 | store.put(iv);
146 | int extra = enc.doFinal(input, 0, input.length, output, IV_SIZE);
147 | store.position(store.position() + extra);
148 | store.flip();
149 | ByteBuffer bb = Base64.getEncoder().encode(store);
150 | return new String(bb.array(), 0, bb.limit(), StandardCharsets.US_ASCII);
151 | } catch (NoSuchPaddingException | NoSuchProviderException | NoSuchAlgorithmException | IllegalBlockSizeException |InvalidAlgorithmParameterException e) {
152 | throw new JsonDBException("Default cipher cannot be used on this VM installation", e);
153 | } catch (InvalidKeyException e) {
154 | throw new JsonDBException("Invalid key", e);
155 | } catch (BadPaddingException | ShortBufferException e) {
156 | throw new JsonDBException("Unexpected (bug?) crypto error", e);
157 | }
158 | }
159 |
160 | /**
161 | * A method to decrypt the provided cipher text.
162 | *
163 | * @param cipherText AES encrypted cipherText
164 | * @return decrypted text
165 | */
166 | @Override
167 | public String decrypt(String cipherText) {
168 | byte[] in = Base64.getDecoder().decode(cipherText);
169 | try {
170 | Cipher dec = Cipher.getInstance(CIPHER_ALGORITHM, PROVIDER);
171 | dec.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(TAG_SIZE, in, 0, IV_SIZE));
172 | return new String(dec.doFinal(in, IV_SIZE, in.length - IV_SIZE), charset);
173 | } catch (NoSuchPaddingException | NoSuchProviderException | NoSuchAlgorithmException | IllegalBlockSizeException e) {
174 | throw new JsonDBException("Default cipher cannot be used on this VM installation", e);
175 | } catch (InvalidKeyException e) {
176 | throw new JsonDBException("Invalid key", e);
177 | } catch (AEADBadTagException e) {
178 | throw new JsonDBException("Incorrect key for this ciphertext (or ciphertext is corrupted)", e);
179 | } catch (BadPaddingException | InvalidAlgorithmParameterException e) {
180 | throw new JsonDBException("Unexpected (bug?) crypto error", e);
181 | }
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/crypto/ICipher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.crypto;
22 |
23 | /**
24 | * @author Farooq Khan
25 | * @version 1.0 25-Sep-2016
26 | */
27 | public interface ICipher {
28 | String encrypt(String plainText);
29 | String decrypt(String cipherText);
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/events/CollectionFileChangeAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.events;
22 |
23 | /**
24 | * An abstract adapter class for receiving Collection File Change events.
25 | * The methods in this class are empty.
26 | * This class exists as convenience for creating listener objects.
27 | *
28 | * Extend this class to create a Collection File Change listener and override only the methods for
29 | * the events of interest. (If you implement the CollectionFileChangeListener interface, you have to
30 | * define all of the methods in it. This abstract class defines null methods for them all, so you
31 | * can only have to define methods for events you care about.)
32 | *
33 | * @author Farooq Khan
34 | * @version 1.0 21 Aug 2016
35 | */
36 | public abstract class CollectionFileChangeAdapter implements CollectionFileChangeListener {
37 |
38 | @Override
39 | public void collectionFileAdded(String collectionName) { }
40 |
41 | @Override
42 | public void collectionFileDeleted(String collectionName) { }
43 |
44 | @Override
45 | public void collectionFileModified(String collectionName) { }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/events/CollectionFileChangeListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.events;
22 |
23 | import java.util.EventListener;
24 |
25 | /**
26 | * A listener which fires when a change to one or more files which have corresponding identified collections is detected.
27 | *
28 | * @author Farooq Khan
29 | * @version 1.0 21 Aug 2016
30 | */
31 | public interface CollectionFileChangeListener extends EventListener {
32 | /**
33 | * Invoked when a new file is detected which has a corresponding identified collection.
34 | * A identified collection is that for which the package scan found a POJO with the @Document annotation.
35 | * This also means that such a identified collection did not have a corresponding collection file before.
36 | *
37 | * New files which do not have corresponding identified collection are ignored.
38 | *
39 | * @param collectionName the name of the collection for which a file was detected.
40 | */
41 | void collectionFileAdded(String collectionName);
42 |
43 | /**
44 | * Invoked when a file which has a corresponding identified collection is deleted
45 | *
46 | * Deleting files in the background is a dangerous operation after such a operation if the database is
47 | * reloaded that data will be permanently lost. However if any operation that modifies the database is
48 | * done then it will automatically recreate the file.
49 | *
50 | * @param collectionName the name of the collection for which a file was deleted.
51 | */
52 | void collectionFileDeleted(String collectionName);
53 |
54 | /**
55 | * Invoked when a file which has a corresponding identified collection is modified by program other than this one.
56 | *
57 | * Ideally you might want to reload the database on receiving this event. If you ignore and change to the database happens due to
58 | * a insert of update or any other Database mutating operation the file will be overwritten with the in memory state.
59 | *
60 | * @param collectionName the name of the collection whose corresponding file was modified.
61 | */
62 | void collectionFileModified(String collectionName);
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/events/EventListenerList.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.events;
22 |
23 | import java.io.File;
24 | import java.io.IOException;
25 | import java.nio.file.Path;
26 | import java.nio.file.StandardWatchEventKinds;
27 | import java.nio.file.WatchEvent;
28 | import java.nio.file.WatchKey;
29 | import java.nio.file.WatchService;
30 | import java.util.ArrayList;
31 | import java.util.List;
32 | import java.util.Map;
33 | import java.util.concurrent.ExecutorService;
34 | import java.util.concurrent.Executors;
35 |
36 | import org.slf4j.Logger;
37 | import org.slf4j.LoggerFactory;
38 |
39 | import com.google.common.util.concurrent.ThreadFactoryBuilder;
40 |
41 | import io.jsondb.CollectionMetaData;
42 | import io.jsondb.JsonDBConfig;
43 | import io.jsondb.JsonDBException;
44 |
45 | /**
46 | * A class that holds a list of CollectionFileChangeListeners.
47 | * @version 1.0 15-Oct-2016
48 | */
49 | public class EventListenerList {
50 | private Logger logger = LoggerFactory.getLogger(EventListenerList.class);
51 |
52 | private JsonDBConfig dbConfig = null;
53 | private Map cmdMap;
54 |
55 | private List listeners;
56 | private ExecutorService collectionFilesWatcherExecutor;
57 | private WatchService watcher = null;
58 | private boolean stopWatcher;
59 |
60 | public EventListenerList(JsonDBConfig dbConfig, Map cmdMap) {
61 | this.dbConfig = dbConfig;
62 | this.cmdMap = cmdMap;
63 | }
64 |
65 | public void addCollectionFileChangeListener(CollectionFileChangeListener listener) {
66 | if (null == listeners) {
67 | listeners = new ArrayList();
68 |
69 | listeners.add(listener);
70 |
71 | collectionFilesWatcherExecutor = Executors.newSingleThreadExecutor(
72 | new ThreadFactoryBuilder().setNameFormat("jsondb-files-watcher-thread-%d").build());
73 |
74 | try {
75 | watcher = dbConfig.getDbFilesPath().getFileSystem().newWatchService();
76 | dbConfig.getDbFilesPath().register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
77 | StandardWatchEventKinds.ENTRY_DELETE,
78 | StandardWatchEventKinds.ENTRY_MODIFY);
79 | } catch (IOException e) {
80 | logger.error("Failed to create the WatchService for the dbFiles location", e);
81 | throw new JsonDBException("Failed to create the WatchService for the dbFiles location", e);
82 | }
83 |
84 | collectionFilesWatcherExecutor.execute(new CollectionFilesWatcherRunnable());
85 | } else {
86 | listeners.add(listener);
87 | }
88 | }
89 |
90 | public void removeCollectionFileChangeListener(CollectionFileChangeListener listener) {
91 | if (null != listeners) {
92 | listeners.remove(listener);
93 | }
94 | if (listeners.size() < 1) {
95 | stopWatcher = true;
96 | collectionFilesWatcherExecutor.shutdownNow();
97 | try {
98 | watcher.close();
99 | } catch (IOException e) {
100 | logger.error("Failed to close the WatchService for the dbFiles location", e);
101 | }
102 | }
103 | }
104 |
105 | public boolean hasCollectionFileChangeListener() {
106 | if ((null != listeners) && (listeners.size() > 0)) {
107 | return true;
108 | }
109 | return false;
110 | }
111 |
112 | public void shutdown() {
113 | if (null != listeners && listeners.size() > 0) {
114 | stopWatcher = true;
115 | collectionFilesWatcherExecutor.shutdownNow();
116 | try {
117 | watcher.close();
118 | } catch (IOException e) {
119 | logger.error("Failed to close the WatchService for the dbFiles location", e);
120 | }
121 | listeners.clear();
122 | }
123 | }
124 |
125 | private class CollectionFilesWatcherRunnable implements Runnable {
126 | @Override
127 | public void run() {
128 | while (!stopWatcher) {
129 | WatchKey watckKey = null;
130 | try {
131 | watckKey = watcher.take();
132 | } catch (InterruptedException e) {
133 | logger.debug("The watcher service thread was interrupted", e);
134 | return;
135 | }
136 | List> events = watckKey.pollEvents();
137 | for (WatchEvent> event : events) {
138 | WatchEvent.Kind> kind = event.kind();
139 | if (kind == StandardWatchEventKinds.OVERFLOW) {
140 | continue;
141 | }
142 | @SuppressWarnings("unchecked")
143 | WatchEvent ev = (WatchEvent)event;
144 | File file = ev.context().toFile();
145 | String fileName = file.getName();
146 | int extnLocation = fileName.lastIndexOf('.');
147 | if(extnLocation != -1) {
148 | String collectionName = fileName.substring(0, extnLocation);
149 | if (fileName.endsWith(".json") && (cmdMap.containsKey(collectionName))) {
150 | if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
151 | for (CollectionFileChangeListener listener : listeners) {
152 | listener.collectionFileAdded(collectionName);
153 | }
154 | } else if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
155 | for (CollectionFileChangeListener listener : listeners) {
156 | listener.collectionFileDeleted(collectionName);
157 | }
158 | } else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
159 | for (CollectionFileChangeListener listener : listeners) {
160 | listener.collectionFileModified(collectionName);
161 | }
162 | }
163 | }
164 | }
165 | }
166 | }
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/io/JsonFileLockException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.io;
22 |
23 | import java.io.IOException;
24 |
25 | /**
26 | * @author Farooq Khan
27 | * @version 1.0 25-Sep-2016
28 | */
29 | public class JsonFileLockException extends IOException {
30 | private static final long serialVersionUID = -8387556796643594285L;
31 |
32 | public JsonFileLockException(String message, Throwable cause) {
33 | super(message, cause);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/io/JsonReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.io;
22 |
23 | import java.io.BufferedReader;
24 | import java.io.File;
25 | import java.io.FileInputStream;
26 | import java.io.IOException;
27 | import java.io.InputStreamReader;
28 | import java.io.RandomAccessFile;
29 | import java.nio.channels.FileChannel;
30 | import java.nio.channels.FileLock;
31 | import java.nio.channels.OverlappingFileLockException;
32 | import java.nio.charset.CharsetDecoder;
33 | import java.nio.charset.CodingErrorAction;
34 |
35 | import org.slf4j.Logger;
36 | import org.slf4j.LoggerFactory;
37 |
38 | import io.jsondb.JsonDBConfig;
39 |
40 | /**
41 | * A special File Reader to read the .json DB files that ensures
42 | * proper character encoding is used and the necessary File Locks are created.
43 | *
44 | * @author Farooq Khan
45 | * @version 1.0 25-Sep-2016
46 | */
47 | public class JsonReader {
48 |
49 | private Logger logger = LoggerFactory.getLogger(JsonReader.class);
50 |
51 | private File collectionFile;
52 |
53 | private RandomAccessFile raf;
54 | private FileInputStream fis;
55 | private FileChannel channel;
56 | private InputStreamReader isr;
57 | private BufferedReader reader;
58 | private FileLock lock;
59 | private File lockFilesLocation;
60 | private File fileLockLocation;
61 |
62 | public JsonReader(JsonDBConfig dbConfig, File collectionFile) throws IOException {
63 | this.collectionFile = collectionFile;
64 | this.lockFilesLocation = new File(collectionFile.getParentFile(), "lock");
65 | this.fileLockLocation = new File(lockFilesLocation, collectionFile.getName() + ".lock");
66 |
67 | if(!lockFilesLocation.exists()) {
68 | lockFilesLocation.mkdirs();
69 | }
70 | if(!fileLockLocation.exists()) {
71 | fileLockLocation.createNewFile();
72 | }
73 |
74 | CharsetDecoder decoder = dbConfig.getCharset().newDecoder();
75 | decoder.onMalformedInput(CodingErrorAction.REPORT);
76 | decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
77 |
78 | raf = new RandomAccessFile(fileLockLocation, "rw");
79 | channel = raf.getChannel();
80 | try {
81 | lock = channel.lock();
82 | } catch (IOException | OverlappingFileLockException e) {
83 | try {
84 | channel.close();
85 | raf.close();
86 | } catch (IOException e1) {
87 | logger.error("Failed while closing RandomAccessFile for collection file {}", collectionFile.getName());
88 | }
89 | throw new JsonFileLockException("JsonReader failed to obtain a file lock for file " + fileLockLocation, e);
90 | }
91 |
92 | fis = new FileInputStream(collectionFile);
93 | isr = new InputStreamReader(fis, decoder);
94 | reader = new BufferedReader(isr);
95 | }
96 |
97 | /**
98 | * A utility method that reads the next line and returns it.
99 | * Since we use a BufferedReader this method may often read more
100 | * than the next line to determine if the line ended.
101 | * @return the content of the line just read
102 | * @throws IOException if an I/O error occurs
103 | */
104 | public String readLine() throws IOException {
105 | return reader.readLine();
106 | }
107 |
108 | public void close() {
109 | try {
110 | reader.close();
111 | } catch (IOException e) {
112 | logger.error("Failed to close BufferedReader for collection file {}", collectionFile.getName(), e);
113 | }
114 | try {
115 | isr.close();
116 | } catch (IOException e) {
117 | logger.error("Failed to close InputStreamReader for collection file {}", collectionFile.getName(), e);
118 | }
119 | try {
120 | if(lock.isValid()) {
121 | lock.release();
122 | }
123 | } catch (IOException e) {
124 | logger.error("Failed to release lock for collection file {}", collectionFile.getName(), e);
125 | }
126 | try {
127 | channel.close();
128 | } catch (IOException e) {
129 | logger.error("Failed to close FileChannel for collection file {}", collectionFile.getName(), e);
130 | }
131 | try {
132 | fis.close();
133 | } catch (IOException e) {
134 | logger.error("Failed to close FileInputStream for collection file {}", collectionFile.getName(), e);
135 | }
136 | try {
137 | raf.close();
138 | } catch (IOException e) {
139 | logger.error("Failed to close RandomAccessFile for collection file {}", collectionFile.getName(), e);
140 | }
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/query/Update.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.query;
22 |
23 | import java.util.Map;
24 | import java.util.TreeMap;
25 |
26 | /**
27 | * @author Farooq Khan
28 | * @version 1.0 21 Aug 2016
29 | */
30 | public class Update {
31 |
32 | private Map updateData;
33 |
34 | public Update() {
35 | updateData = new TreeMap();
36 | }
37 |
38 | /**
39 | * Static factory method to create an Update using the provided key
40 | *
41 | * @param key the field name for the update operation
42 | * @param value the value to set for the field
43 | * @return Updated object
44 | */
45 | public static Update update(String key, Object value) {
46 | return new Update().set(key, value);
47 | }
48 |
49 | public Update set(String key, Object value) {
50 | updateData.put(key, value);
51 | return this;
52 | }
53 |
54 | public Map getUpdateData() {
55 | return updateData;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/query/ddl/AbstractOperation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.query.ddl;
22 |
23 | import io.jsondb.query.ddl.CollectionSchemaUpdate.Type;
24 |
25 | /**
26 | * @author Farooq Khan
27 | * @version 1.0 21 Aug 2016
28 | */
29 | public abstract class AbstractOperation implements IOperation {
30 | protected Type operationType;
31 | public Type getOperationType() {
32 | return operationType;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/query/ddl/AddOperation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.query.ddl;
22 |
23 | import io.jsondb.query.ddl.CollectionSchemaUpdate.Type;
24 |
25 | /**
26 | * Represents a CollectionUpdate ADD operation type.
27 | *
28 | * This operation allows for adding a new field to a POJO
29 | *
30 | * @author Farooq Khan
31 | * @version 1.0 21 Aug 2016
32 | */
33 | public class AddOperation extends AbstractOperation {
34 | private Object defaultValue;
35 | private boolean isSecret;
36 |
37 | public AddOperation(Object defaultValue, boolean isSecret) {
38 | this.operationType = Type.ADD;
39 | this.defaultValue = defaultValue;
40 | this.isSecret = isSecret;
41 | }
42 |
43 | public Object getDefaultValue() {
44 | return defaultValue;
45 | }
46 |
47 | public boolean isSecret() {
48 | return isSecret;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/query/ddl/CollectionSchemaUpdate.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.query.ddl;
22 |
23 | import java.util.Map;
24 | import java.util.Map.Entry;
25 | import java.util.TreeMap;
26 |
27 | /**
28 | * @author Farooq Khan
29 | * @version 1.0 21 Aug 2016
30 | */
31 | public class CollectionSchemaUpdate {
32 |
33 | public enum Type {ADD, RENAME, DELETE};
34 |
35 | private Map collectionUpdateData;
36 |
37 | public CollectionSchemaUpdate() {
38 | collectionUpdateData = new TreeMap();
39 | }
40 |
41 | /**
42 | * Static factory method to create an CollectionUpdate for the specified key
43 | *
44 | * @param key: JSON attribute to update
45 | * @param operation: operation to carry out on the attribute
46 | * @return the updated CollectionSchemaUpdate
47 | */
48 | public static CollectionSchemaUpdate update(String key, IOperation operation) {
49 | return new CollectionSchemaUpdate().set(key, operation);
50 | }
51 |
52 | /**
53 | * A method to set a new Operation for a key. It may be of type ADD, RENAME or DELETE.
54 | * Only one operation per key can be specified. Attempt to add a second operation for a any key will override the first one.
55 | * Attempt to add a ADD operation for a key which already exists will have no effect.
56 | * Attempt to add a DELETE operation for akey which does not exist will have no effect.
57 | *
58 | * @param key (a.k.a JSON Field name) for which operation is being added
59 | * @param operation operation to perform
60 | * @return the updated CollectionSchemaUpdate
61 | */
62 | public CollectionSchemaUpdate set(String key, IOperation operation) {
63 | collectionUpdateData.put(key, operation);
64 | return this;
65 | }
66 |
67 | public Map getUpdateData() {
68 | return collectionUpdateData;
69 | }
70 |
71 | /**
72 | * Returns a Map of ADD operations which have a non-null default value specified.
73 | *
74 | * @return Map of ADD operations which have a non-null default value specified
75 | */
76 | public Map getAddOperations() {
77 | Map addOperations = new TreeMap();
78 | for (Entry entry : collectionUpdateData.entrySet()) {
79 | String key = entry.getKey();
80 | IOperation op = entry.getValue();
81 | if (op.getOperationType().equals(Type.ADD)) {
82 | AddOperation aop = (AddOperation)op;
83 | if (null != aop.getDefaultValue()) {
84 | addOperations.put(key, aop);
85 | }
86 | }
87 | }
88 | return addOperations;
89 | }
90 |
91 | /**
92 | * Returns a Map of RENAME operations.
93 | *
94 | * @return Map of RENAME operations which have a non-null default value specified
95 | */
96 | public Map getRenameOperations() {
97 | Map renOperations = new TreeMap();
98 | for (Entry entry : collectionUpdateData.entrySet()) {
99 | String key = entry.getKey();
100 | IOperation op = entry.getValue();
101 | if (op.getOperationType().equals(Type.RENAME)) {
102 | renOperations.put(key, (RenameOperation)op);
103 | }
104 | }
105 | return renOperations;
106 | }
107 |
108 | /**
109 | * Returns a Map of DELETE operations.
110 | *
111 | * @return Map of DELETE operations which have a non-null default value specified
112 | */
113 | public Map getDeleteOperations() {
114 | Map delOperations = new TreeMap();
115 | for (Entry entry : collectionUpdateData.entrySet()) {
116 | String key = entry.getKey();
117 | IOperation op = entry.getValue();
118 | if (op.getOperationType().equals(Type.DELETE)) {
119 | delOperations.put(key, (DeleteOperation)op);
120 | }
121 | }
122 | return delOperations;
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/query/ddl/DeleteOperation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.query.ddl;
22 |
23 | import io.jsondb.query.ddl.CollectionSchemaUpdate.Type;
24 |
25 | /**
26 | * Represents a CollectionUpdate DELETE operation type.
27 | *
28 | * This operation allows for deleting a field from a POJO
29 | *
30 | * @author Farooq Khan
31 | * @version 1.0 21 Aug 2016
32 | */
33 | public class DeleteOperation extends AbstractOperation {
34 | public DeleteOperation() {
35 | this.operationType = Type.DELETE;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/query/ddl/IOperation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.query.ddl;
22 |
23 | import io.jsondb.query.ddl.CollectionSchemaUpdate.Type;
24 |
25 | /**
26 | * @author Farooq Khan
27 | * @version 1.0 21 Aug 2016
28 | */
29 | public interface IOperation {
30 | Type getOperationType();
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/io/jsondb/query/ddl/RenameOperation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.query.ddl;
22 |
23 | import io.jsondb.query.ddl.CollectionSchemaUpdate.Type;
24 |
25 | /**
26 | * Represents a CollectionUpdate RENAME operation type.
27 | *
28 | * This operation allows for changing the name of a field in a POJO
29 | *
30 | * @author Farooq Khan
31 | * @version 1.0 21 Aug 2016
32 | */
33 | public class RenameOperation extends AbstractOperation {
34 | private String newName;
35 |
36 | public RenameOperation(String newName) {
37 | this.operationType = Type.RENAME;
38 | this.newName = newName;
39 | }
40 |
41 | public String getNewName() {
42 | return newName;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/CollectionMetaDataTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertFalse;
25 | import static org.junit.Assert.assertNotNull;
26 | import static org.junit.Assert.assertNull;
27 | import static org.junit.Assert.assertTrue;
28 |
29 | import java.io.File;
30 | import java.util.List;
31 | import java.util.Map;
32 |
33 | import org.junit.After;
34 | import org.junit.Before;
35 | import org.junit.Test;
36 |
37 | import com.google.common.io.Files;
38 |
39 | import io.jsondb.CollectionMetaData;
40 | import io.jsondb.JsonDBConfig;
41 | import io.jsondb.Util;
42 | import io.jsondb.crypto.DefaultAESCBCCipher;
43 | import io.jsondb.crypto.ICipher;
44 | import io.jsondb.tests.model.SecureVolume;
45 | import io.jsondb.tests.model.Volume;
46 |
47 | /**
48 | * @version 1.0 06-Oct-2016
49 | */
50 | public class CollectionMetaDataTests {
51 | private String dbFilesLocation = "src/test/resources/dbfiles/collectionMetadataTests";
52 | private File dbFilesFolder = new File(dbFilesLocation);
53 | private File instancesJson = new File(dbFilesFolder, "instances.json");
54 | ICipher cipher = null;
55 |
56 | @Before
57 | public void setUp() throws Exception {
58 | dbFilesFolder.mkdir();
59 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
60 | cipher = new DefaultAESCBCCipher("1r8+24pibarAWgS85/Heeg==");
61 | }
62 |
63 | @After
64 | public void tearDown() throws Exception {
65 | Util.delete(dbFilesFolder);
66 | }
67 |
68 | @Test
69 | public void test_MetadataLoad_Simple() {
70 | Volume volume = new Volume();
71 | CollectionMetaData cmd = new CollectionMetaData("volumes", volume.getClass(), "1.0", null);
72 |
73 | assertEquals("id", cmd.getIdAnnotatedFieldName());
74 | assertEquals("getId", cmd.getIdAnnotatedFieldGetterMethod().getName());
75 | assertEquals("setId", cmd.getIdAnnotatedFieldSetterMethod().getName());
76 |
77 | List secretAnnotatedFieldNames = cmd.getSecretAnnotatedFieldNames();
78 | assertEquals(0, secretAnnotatedFieldNames.size());
79 | assertEquals(false, cmd.isSecretField("SomeField"));
80 |
81 | assertEquals("setName", cmd.getSetterMethodForFieldName("name").getName());
82 | assertEquals("getName", cmd.getGetterMethodForFieldName("name").getName());
83 |
84 | assertEquals("setFlash", cmd.getSetterMethodForFieldName("flash").getName());
85 | assertEquals("isFlash", cmd.getGetterMethodForFieldName("flash").getName());
86 |
87 | assertFalse(cmd.hasSecret());
88 |
89 | assertEquals("1.0", cmd.getSchemaVersion());
90 |
91 | assertNull(cmd.getActualSchemaVersion());
92 |
93 | assertEquals("volumes", cmd.getCollectionName());
94 | }
95 |
96 | @Test
97 | public void test_MetadataLoad_CollectionWithSecret() {
98 | SecureVolume server = new SecureVolume();
99 | CollectionMetaData cmd = new CollectionMetaData("servers", server.getClass(), "1.0", null);
100 |
101 | assertEquals("id", cmd.getIdAnnotatedFieldName());
102 | assertEquals("getId", cmd.getIdAnnotatedFieldGetterMethod().getName());
103 | assertEquals("setId", cmd.getIdAnnotatedFieldSetterMethod().getName());
104 |
105 | List secretAnnotatedFieldNames = cmd.getSecretAnnotatedFieldNames();
106 | assertEquals(1, secretAnnotatedFieldNames.size());
107 | assertEquals(true, cmd.isSecretField("encryptionKey"));
108 |
109 | assertTrue(cmd.hasSecret());
110 | }
111 |
112 | @Test
113 | public void test_MetadataLoad_UsingBuilder() {
114 | JsonDBConfig dbConfig = new JsonDBConfig(dbFilesLocation, "io.jsondb.tests.model", cipher, false, null);
115 | Map cmdMap = CollectionMetaData.builder(dbConfig);
116 | CollectionMetaData cmd = cmdMap.get("instances");
117 | assertNotNull(cmd);
118 | assertEquals("1.0", cmd.getSchemaVersion());
119 | assertEquals("id", cmd.getIdAnnotatedFieldName());
120 | assertEquals("getId", cmd.getIdAnnotatedFieldGetterMethod().getName());
121 | assertEquals("setId", cmd.getIdAnnotatedFieldSetterMethod().getName());
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/CreateDropCollectionTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertFalse;
25 | import static org.junit.Assert.assertTrue;
26 |
27 | import java.io.File;
28 | import java.util.List;
29 | import java.util.Set;
30 |
31 | import com.google.common.io.Files;
32 |
33 | import io.jsondb.DefaultSchemaVersionComparator;
34 | import io.jsondb.InvalidJsonDbApiUsageException;
35 | import io.jsondb.JsonDBTemplate;
36 | import io.jsondb.Util;
37 | import io.jsondb.tests.model.Instance;
38 | import io.jsondb.tests.model.Site;
39 |
40 | import org.junit.After;
41 | import org.junit.Before;
42 | import org.junit.Test;
43 |
44 | /**
45 | * @author Farooq Khan
46 | * @version 1.0 06-Oct-2016
47 | */
48 | public class CreateDropCollectionTests {
49 | private String dbFilesLocation = "src/test/resources/dbfiles/createDropCollectionTests";
50 | private File dbFilesFolder = new File(dbFilesLocation);
51 | private File instancesJson = new File(dbFilesFolder, "instances.json");
52 | private File sitesJson = new File(dbFilesFolder, "sites.json");
53 |
54 | private JsonDBTemplate jsonDBTemplate = null;
55 |
56 | @Before
57 | public void setUp() throws Exception {
58 | dbFilesFolder.mkdir();
59 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
60 | jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model", false, new DefaultSchemaVersionComparator());
61 | }
62 |
63 | @After
64 | public void tearDown() throws Exception {
65 | Util.delete(dbFilesFolder);
66 | }
67 |
68 | @Test
69 | public void testCreateDropCollection() {
70 | Set collectionNames = jsonDBTemplate.getCollectionNames();
71 | assertTrue(collectionNames.contains("instances"));
72 | assertEquals("instances", jsonDBTemplate.getCollectionName(Instance.class));
73 | assertEquals(collectionNames.size(), 1);
74 |
75 | jsonDBTemplate.createCollection(Site.class);
76 | assertTrue(sitesJson.exists());
77 |
78 | collectionNames = jsonDBTemplate.getCollectionNames();
79 | assertTrue(collectionNames.contains("instances"));
80 | assertTrue(collectionNames.contains("sites"));
81 | assertEquals(collectionNames.size(), 2);
82 |
83 | List sites = jsonDBTemplate.findAll(Site.class);
84 | assertEquals(sites.size(), 0);
85 |
86 | jsonDBTemplate.dropCollection(Site.class);
87 | assertFalse(sitesJson.exists());
88 |
89 | collectionNames = jsonDBTemplate.getCollectionNames();
90 | assertTrue(collectionNames.contains("instances"));
91 | assertEquals(collectionNames.size(), 1);
92 | }
93 |
94 | @Test
95 | public void testGetCollection() {
96 | Set collectionNames = jsonDBTemplate.getCollectionNames();
97 | assertTrue(collectionNames.contains("instances"));
98 | assertEquals(collectionNames.size(), 1);
99 |
100 | jsonDBTemplate.getCollection(Site.class);
101 | assertTrue(sitesJson.exists());
102 |
103 | collectionNames = jsonDBTemplate.getCollectionNames();
104 | assertTrue(collectionNames.contains("instances"));
105 | assertTrue(collectionNames.contains("sites"));
106 | assertEquals(collectionNames.size(), 2);
107 |
108 | jsonDBTemplate.dropCollection(Site.class);
109 | assertFalse(sitesJson.exists());
110 | }
111 |
112 | @Test(expected=InvalidJsonDbApiUsageException.class)
113 | public void testCreateCollectionForUnknownCollectionName() {
114 | jsonDBTemplate.createCollection("somecollection");
115 | }
116 |
117 | private class SomeClass {}
118 |
119 | @Test(expected=InvalidJsonDbApiUsageException.class)
120 | public void testCreateCollectionForUnknownCollectionClass() {
121 | jsonDBTemplate.createCollection(SomeClass.class);
122 | }
123 |
124 | @Test(expected=InvalidJsonDbApiUsageException.class)
125 | public void testCreateCollectionWhenAlreadyExisting() {
126 | jsonDBTemplate.createCollection("instances");
127 | }
128 |
129 | @Test
130 | public void testCollectionExists() {
131 | assertFalse(jsonDBTemplate.collectionExists("somecollection"));
132 | }
133 |
134 | @Test(expected=InvalidJsonDbApiUsageException.class)
135 | public void testDropCollectionForUnknownCollection() {
136 | jsonDBTemplate.dropCollection("SomeCollection");
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/DefaultAESCipherTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.*;
24 |
25 | import java.io.UnsupportedEncodingException;
26 | import java.nio.charset.StandardCharsets;
27 | import java.security.GeneralSecurityException;
28 | import java.security.InvalidKeyException;
29 |
30 | import org.hamcrest.core.IsInstanceOf;
31 | import org.junit.Rule;
32 | import org.junit.Test;
33 | import org.junit.rules.ExpectedException;
34 |
35 | import io.jsondb.JsonDBException;
36 | import io.jsondb.crypto.CryptoUtil;
37 | import io.jsondb.crypto.DefaultAESCBCCipher;
38 | import io.jsondb.crypto.Default1Cipher;
39 | import io.jsondb.crypto.ICipher;
40 |
41 | @SuppressWarnings("deprecation")
42 | public class DefaultAESCipherTests {
43 | @Rule
44 | public ExpectedException expectedException = ExpectedException.none();
45 |
46 | @Test
47 | public void testKeyValidityAesCbc() throws UnsupportedEncodingException, GeneralSecurityException {
48 | expectedException.expect(InvalidKeyException.class);
49 | expectedException.expectMessage("Failed to create DefaultAESCBCCipher, something wrong with the key");
50 |
51 | @SuppressWarnings("unused")
52 | DefaultAESCBCCipher cipher = new DefaultAESCBCCipher("badkey", "UTF-8");
53 | }
54 |
55 | @Test
56 | public void testKeyAesCbc() throws UnsupportedEncodingException, GeneralSecurityException {
57 | String base64EncodedKey = CryptoUtil.generate128BitKey("MyPassword", "ksdfkja923u4anf");
58 |
59 | ICipher cipher = new DefaultAESCBCCipher(base64EncodedKey);
60 |
61 | String encryptedText = cipher.encrypt("Hallo, Wie gehts");
62 | assertEquals("cEIxZFDVSlWIN+ZmOGyvmbWv4+ziI884BNu0Hplglws=", encryptedText);
63 | String decryptedText = cipher.decrypt(encryptedText);
64 | assertEquals("Hallo, Wie gehts", decryptedText);
65 | }
66 |
67 | @Test
68 | public void testKeyValidityDefault1() throws UnsupportedEncodingException, GeneralSecurityException {
69 | expectedException.expect(JsonDBException.class);
70 | expectedException.expectCause(IsInstanceOf.any(InvalidKeyException.class));
71 |
72 | Default1Cipher cipher = new Default1Cipher("badkey", StandardCharsets.UTF_8);
73 | @SuppressWarnings("unused")
74 | String encryptedText = cipher.encrypt("Hallo, Wie gehts");
75 | }
76 |
77 | @Test
78 | public void testKeyDefault1() throws UnsupportedEncodingException, GeneralSecurityException {
79 | String base64EncodedKey = CryptoUtil.generate128BitKey("MyPassword", "ksdfkja923u4anf");
80 | ICipher cipher = new Default1Cipher(base64EncodedKey);
81 |
82 | String msg = "Hallo, gru\u00DF";
83 |
84 | String encryptedText = cipher.encrypt(msg);
85 | String decryptedText = cipher.decrypt(encryptedText);
86 | assertEquals(msg, decryptedText);
87 | assertTrue("ciphertext too short", encryptedText.length() > 40);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/EncryptionTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 - 2018 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 |
25 | import java.io.File;
26 | import java.security.GeneralSecurityException;
27 |
28 | import org.junit.After;
29 | import org.junit.Before;
30 | import org.junit.Rule;
31 | import org.junit.Test;
32 | import org.junit.rules.ExpectedException;
33 |
34 | import com.google.common.io.Files;
35 |
36 | import io.jsondb.InvalidJsonDbApiUsageException;
37 | import io.jsondb.JsonDBTemplate;
38 | import io.jsondb.Util;
39 | import io.jsondb.crypto.DefaultAESCBCCipher;
40 | import io.jsondb.crypto.ICipher;
41 | import io.jsondb.tests.model.Instance;
42 | import io.jsondb.tests.util.TestUtils;
43 |
44 | /**
45 | * Test for the encryption functionality
46 | * @version 1.0 22-Oct-2016
47 | */
48 | @SuppressWarnings("deprecation")
49 | public class EncryptionTests {
50 | private String dbFilesLocation = "src/test/resources/dbfiles/encryptionTests";
51 | private File dbFilesFolder = new File(dbFilesLocation);
52 | private File instancesJson = new File(dbFilesFolder, "instances.json");
53 |
54 | private String dbFilesLocation2 = "src/test/resources/dbfiles/encryptionTests2";
55 | private File dbFilesFolder2 = new File(dbFilesLocation2);
56 |
57 | private JsonDBTemplate jsonDBTemplate = null;
58 | private JsonDBTemplate unencryptedjsonDBTemplate = null;
59 |
60 | @Rule
61 | public ExpectedException expectedException = ExpectedException.none();
62 |
63 | @Before
64 | public void setUp() throws Exception {
65 | dbFilesFolder.mkdir();
66 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
67 | ICipher cipher = new DefaultAESCBCCipher("1r8+24pibarAWgS85/Heeg==");
68 |
69 | jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model", cipher);
70 |
71 | unencryptedjsonDBTemplate = new JsonDBTemplate(dbFilesLocation2, "io.jsondb.tests.model");
72 | }
73 |
74 | @After
75 | public void tearDown() throws Exception {
76 | Util.delete(dbFilesFolder);
77 | Util.delete(dbFilesFolder2);
78 | }
79 |
80 | @Test
81 | public void encryptionTest() {
82 | Instance instance = new Instance();
83 | instance.setId("11");
84 | instance.setHostname("ec2-54-191-11");
85 | instance.setPrivateKey("b87eb02f5dd7e5232d7b0fc30a5015e4");
86 | instance.setPublicKey("d3aa045f71bf4d1dffd2c5f485a4bc1d");
87 | jsonDBTemplate.insert(instance);
88 |
89 | String[] expectedLastLineAtEnd = {
90 | "{\"id\":\"11\",\"hostname\":\"ec2-54-191-11\","
91 | + "\"privateKey\":\"Zf9vl5K6WV6BA3eL7JbnrfPMjfJxc9Rkoo0zlROQlgTslmcp9iFzos+MP93GZqop\","
92 | + "\"publicKey\":\"d3aa045f71bf4d1dffd2c5f485a4bc1d\"}"};
93 |
94 | TestUtils.checkLastLines(instancesJson, expectedLastLineAtEnd);
95 |
96 | Instance i = jsonDBTemplate.findById("11", "instances");
97 | assertEquals("b87eb02f5dd7e5232d7b0fc30a5015e4", i.getPrivateKey());
98 | }
99 |
100 | @Test
101 | public void changeEncryptionTest() {
102 | ICipher newCipher = null;
103 | try {
104 | newCipher = new DefaultAESCBCCipher("jCt039xT0eUwkIqAWACw/w==");
105 | } catch (GeneralSecurityException e) {
106 | e.printStackTrace();
107 | }
108 |
109 | jsonDBTemplate.changeEncryption(newCipher);
110 |
111 | String[] expectedLastLineAtEnd = {
112 | "{\"id\":\"06\",\"hostname\":\"ec2-54-191-06\","
113 | + "\"privateKey\":\"J5CnDOTBe4OwePT43esS7vDb5DVqi+VGtRoICipcTdtyyh5N1gxbUdtvx8N9sCpZ\","
114 | + "\"publicKey\":\"\"}"};
115 |
116 | TestUtils.checkLastLines(instancesJson, expectedLastLineAtEnd);
117 |
118 | Instance i = jsonDBTemplate.findById("01", "instances");
119 | assertEquals("b87eb02f5dd7e5232d7b0fc30a5015e4", i.getPrivateKey());
120 | }
121 |
122 | @Test
123 | public void changeEncryptionTest2() throws GeneralSecurityException {
124 | ICipher newCipher = new DefaultAESCBCCipher("jCt039xT0eUwkIqAWACw/w==");
125 |
126 | expectedException.expect(InvalidJsonDbApiUsageException.class);
127 | expectedException.expectMessage("DB is not encrypted, nothing to change for EncryptionKey");
128 |
129 | unencryptedjsonDBTemplate.changeEncryption(newCipher);
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/ExceptionTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import org.junit.Rule;
24 | import org.junit.Test;
25 | import org.junit.rules.ExpectedException;
26 |
27 | import io.jsondb.InvalidJsonDbApiUsageException;
28 | import io.jsondb.JsonDBException;
29 | import io.jsondb.io.JsonFileLockException;
30 |
31 | /**
32 | * Dumb unit tests for some of the Exception classes
33 | * @version 1.0 25-Oct-2016
34 | */
35 | public class ExceptionTests {
36 |
37 | @Rule
38 | public ExpectedException expectedException = ExpectedException.none();
39 |
40 | @Test
41 | public void testJsonfileLockException() throws JsonFileLockException {
42 | expectedException.expect(JsonFileLockException.class);
43 | expectedException.expectMessage("JsonReader failed to obtain a file lock for file");
44 |
45 | throw new JsonFileLockException("JsonReader failed to obtain a file lock for file", null);
46 | }
47 |
48 | @Test
49 | public void testJsonDBException1() throws JsonDBException {
50 | expectedException.expect(JsonDBException.class);
51 | expectedException.expectMessage("Some Exception");
52 |
53 | throw new JsonDBException("Some Exception");
54 | }
55 |
56 | @Test
57 | public void testJsonDBException2() throws JsonDBException {
58 | expectedException.expect(JsonDBException.class);
59 | expectedException.expectMessage("Some Exception");
60 |
61 | throw new JsonDBException("Some Exception", null);
62 | }
63 |
64 | @Test
65 | public void testInvalidJsonDbApiUsageException() throws InvalidJsonDbApiUsageException {
66 | expectedException.expect(InvalidJsonDbApiUsageException.class);
67 | expectedException.expectMessage("Some Invalid usage");
68 |
69 | throw new InvalidJsonDbApiUsageException("Some Invalid usage", null);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/FileChangeAdapterTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertFalse;
25 | import static org.junit.Assert.assertNotEquals;
26 | import static org.junit.Assert.assertNotNull;
27 | import static org.junit.Assert.assertTrue;
28 | import static org.junit.Assert.fail;
29 | import static org.junit.Assume.assumeTrue;
30 |
31 | import java.io.File;
32 | import java.io.FileNotFoundException;
33 | import java.io.IOException;
34 | import java.io.PrintWriter;
35 | import java.util.List;
36 | import java.util.Scanner;
37 |
38 | import org.junit.After;
39 | import org.junit.Before;
40 | import org.junit.Rule;
41 | import org.junit.Test;
42 | import org.junit.rules.ExpectedException;
43 |
44 | import com.google.common.io.Files;
45 |
46 | import io.jsondb.JsonDBTemplate;
47 | import io.jsondb.Util;
48 | import io.jsondb.crypto.DefaultAESCBCCipher;
49 | import io.jsondb.crypto.ICipher;
50 | import io.jsondb.events.CollectionFileChangeAdapter;
51 | import io.jsondb.tests.model.Instance;
52 | import io.jsondb.tests.model.PojoWithEnumFields;
53 | import io.jsondb.tests.util.TestUtils;
54 |
55 | /**
56 | * @version 1.0 24-Oct-2016
57 | */
58 | public class FileChangeAdapterTests {
59 |
60 | private static final long DB_RELOAD_TIMEOUT = 5 * 1000;
61 | private String dbFilesLocation = "src/test/resources/dbfiles/eventsTests";
62 | private File dbFilesFolder = new File(dbFilesLocation);
63 | private File instancesJson = new File(dbFilesFolder, "instances.json");
64 | private File pojoWithEnumFieldsJson = new File(dbFilesFolder, "pojowithenumfields.json");
65 |
66 | private JsonDBTemplate jsonDBTemplate = null;
67 |
68 | @Rule
69 | public ExpectedException expectedException = ExpectedException.none();
70 |
71 | @Before
72 | public void setUp() throws Exception {
73 | //Filewatcher does not work on Mac and hence JsonDB events will never fire
74 | //and so the EventTests will never succeed. So we run the tests only if
75 | //it is not a Mac system
76 | assumeTrue(!TestUtils.isMac());
77 |
78 | dbFilesFolder.mkdir();
79 | Files.copy(new File("src/test/resources/dbfiles/pojowithenumfields.json"), pojoWithEnumFieldsJson);
80 | ICipher cipher = new DefaultAESCBCCipher("1r8+24pibarAWgS85/Heeg==");
81 |
82 | jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model", cipher);
83 | }
84 |
85 | @After
86 | public void tearDown() throws Exception {
87 | Util.delete(dbFilesFolder);
88 | }
89 |
90 | private boolean collectionFileAddedFired = false;
91 | private class FileAddedChangeAdapter extends CollectionFileChangeAdapter {
92 | @Override
93 | public void collectionFileAdded(String collectionName) {
94 | super.collectionFileAdded(collectionName);
95 | jsonDBTemplate.reloadCollection(collectionName);
96 | collectionFileAddedFired = true;
97 | }
98 | }
99 | @Test
100 | public void testAutoReloadOnCollectionFileAdded() {
101 | jsonDBTemplate.addCollectionFileChangeListener(new FileAddedChangeAdapter());
102 | assertFalse(jsonDBTemplate.collectionExists(Instance.class));
103 | try {
104 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
105 | } catch (IOException e1) {
106 | fail("Failed to copy data store files");
107 | }
108 | try {
109 | // Give it some time to reload DB
110 | Thread.sleep(DB_RELOAD_TIMEOUT);
111 | } catch (InterruptedException e) {
112 | fail("Failed to wait for db reload");
113 | }
114 | assertTrue(collectionFileAddedFired);
115 | List instances = jsonDBTemplate.findAll(Instance.class);
116 | assertNotNull(instances);
117 | assertNotEquals(instances.size(), 0);
118 | }
119 |
120 | private boolean collectionFileModifiedFired = false;
121 | private class FileModifiedChangeAdapter extends CollectionFileChangeAdapter {
122 | @Override
123 | public void collectionFileModified(String collectionName) {
124 | super.collectionFileModified(collectionName);
125 | jsonDBTemplate.reloadCollection(collectionName);
126 | collectionFileModifiedFired = true;
127 | }
128 | }
129 | @Test
130 | public void testAutoReloadOnCollectionFileModified() throws FileNotFoundException {
131 | try {
132 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
133 | } catch (IOException e1) {
134 | fail("Failed to copy data store files");
135 | }
136 | jsonDBTemplate.reLoadDB();
137 | int oldCount = jsonDBTemplate.findAll(Instance.class).size();
138 | jsonDBTemplate.addCollectionFileChangeListener(new FileModifiedChangeAdapter());
139 |
140 | @SuppressWarnings("resource")
141 | Scanner sc = new Scanner(new File("src/test/resources/dbfiles/instances.json")).useDelimiter("\\Z");
142 | String content = sc.next();
143 | sc.close();
144 |
145 | content = content + "\n" + "{\"id\":\"07\",\"hostname\":\"ec2-54-191-07\","
146 | + "\"privateKey\":\"Zf9vl5K6WV6BA3eL7JbnrfPMjfJxc9Rkoo0zlROQlgTslmcp9iFzos+MP93GZqop\","
147 | + "\"publicKey\":\"d3aa045f71bf4d1dffd2c5f485a4bc1d\"}";
148 |
149 | PrintWriter out = new PrintWriter(instancesJson);
150 | out.println(content);
151 | out.close();
152 |
153 | try {
154 | // Give it some time to reload DB
155 | Thread.sleep(DB_RELOAD_TIMEOUT);
156 | } catch (InterruptedException e) {
157 | fail("Failed to wait for db reload");
158 | }
159 | assertTrue(collectionFileModifiedFired);
160 | int newCount = jsonDBTemplate.findAll(Instance.class).size();
161 | assertEquals(oldCount + 1, newCount);
162 | }
163 |
164 | private boolean collectionFileDeletedFired = false;
165 | private class FileDeletedChangeAdapter extends CollectionFileChangeAdapter {
166 | @Override
167 | public void collectionFileDeleted(String collectionName) {
168 | super.collectionFileDeleted(collectionName);
169 | jsonDBTemplate.reLoadDB();
170 | collectionFileDeletedFired = true;
171 | }
172 | }
173 | @Test
174 | public void testAutoReloadOnCollectionFileDeleted() throws FileNotFoundException {
175 | assertTrue(jsonDBTemplate.collectionExists(PojoWithEnumFields.class));
176 |
177 | jsonDBTemplate.addCollectionFileChangeListener(new FileDeletedChangeAdapter());
178 |
179 | pojoWithEnumFieldsJson.delete();
180 |
181 | try {
182 | // Give it some time to reload DB
183 | Thread.sleep(DB_RELOAD_TIMEOUT);
184 | } catch (InterruptedException e) {
185 | fail("Failed to wait for db reload");
186 | }
187 |
188 | assertTrue(collectionFileDeletedFired);
189 | assertFalse(jsonDBTemplate.collectionExists(PojoWithEnumFields.class));
190 | }
191 |
192 | private class DoNothingChangeAdapter extends CollectionFileChangeAdapter {
193 | }
194 | @Test
195 | public void testRemoveListener() {
196 | assertFalse(jsonDBTemplate.hasCollectionFileChangeListener());
197 |
198 | CollectionFileChangeAdapter adapter = new DoNothingChangeAdapter();
199 | jsonDBTemplate.addCollectionFileChangeListener(adapter);
200 | assertTrue(jsonDBTemplate.hasCollectionFileChangeListener());
201 |
202 | jsonDBTemplate.removeCollectionFileChangeListener(adapter);
203 | assertFalse(jsonDBTemplate.hasCollectionFileChangeListener());
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/FindAndModifyTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 |
25 | import java.io.File;
26 | import java.util.List;
27 | import java.util.Map;
28 |
29 | import org.junit.After;
30 | import org.junit.Before;
31 | import org.junit.Rule;
32 | import org.junit.Test;
33 | import org.junit.rules.ExpectedException;
34 |
35 | import com.google.common.io.Files;
36 |
37 | import io.jsondb.InvalidJsonDbApiUsageException;
38 | import io.jsondb.JsonDBTemplate;
39 | import io.jsondb.Util;
40 | import io.jsondb.crypto.DefaultAESCBCCipher;
41 | import io.jsondb.crypto.ICipher;
42 | import io.jsondb.query.Update;
43 | import io.jsondb.tests.model.Instance;
44 | import io.jsondb.tests.model.Site;
45 |
46 | /**
47 | * @version 1.0 15-Oct-2016
48 | */
49 | public class FindAndModifyTests {
50 | private String dbFilesLocation = "src/test/resources/dbfiles/findAndModifyTests";
51 | private File dbFilesFolder = new File(dbFilesLocation);
52 | private File instancesJson = new File(dbFilesFolder, "instances.json");
53 |
54 | private JsonDBTemplate jsonDBTemplate = null;
55 |
56 | @Rule
57 | public ExpectedException expectedException = ExpectedException.none();
58 |
59 | @Before
60 | public void setUp() throws Exception {
61 | dbFilesFolder.mkdir();
62 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
63 | ICipher cipher = new DefaultAESCBCCipher("1r8+24pibarAWgS85/Heeg==");
64 | jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model", cipher);
65 | }
66 |
67 | @After
68 | public void tearDown() throws Exception {
69 | Util.delete(dbFilesFolder);
70 | }
71 |
72 | @Test
73 | public void testFindAndModify_1() {
74 | Update update = new Update();
75 | update.set("privateKey", "SavingPrivateRyan");
76 |
77 | String jxQuery = String.format("/.[id='%s']", "01");
78 | jsonDBTemplate.findAndModify(jxQuery, update, "instances");
79 |
80 | Instance instance = jsonDBTemplate.findById("01", "instances");
81 | assertEquals("SavingPrivateRyan", instance.getPrivateKey());
82 | }
83 |
84 | @Test
85 | public void testFindAndModify_2() {
86 | Update update = Update.update("publicKey", "Its all Public");
87 |
88 | String jxQuery = String.format("/.[id='%s']", "02");
89 | jsonDBTemplate.findAndModify(jxQuery, update, "instances");
90 |
91 | Instance instance = jsonDBTemplate.findById("02", "instances");
92 | assertEquals("Its all Public", instance.getPublicKey());
93 | }
94 |
95 | @Test
96 | public void testFindAndModify_3() {
97 | Update update = Update.update("SomeColumn1", "Value 1");
98 | update.set("SomeColumn2", "Value 2");
99 |
100 | Map allUpdates = update.getUpdateData();
101 | assertEquals(2, allUpdates.size());
102 |
103 | assertEquals("Value 1", allUpdates.get("SomeColumn1"));
104 | assertEquals("Value 2", allUpdates.get("SomeColumn2"));
105 | }
106 |
107 | @Test
108 | public void testFindAndModify_4() {
109 | Update update = Update.update("privateKey", "SavingPrivateRyan");
110 | update.set("publicKey", "SavedByPublic");
111 |
112 | String jxQuery = String.format("/.[id='%s']", "03");
113 | Instance retInstance = jsonDBTemplate.findAndModify(jxQuery, update, "instances");
114 | assertEquals("SavingPrivateRyan", retInstance.getPrivateKey());
115 | assertEquals("SavedByPublic", retInstance.getPublicKey());
116 |
117 | Instance instance = jsonDBTemplate.findById("03", "instances");
118 | assertEquals("SavingPrivateRyan", instance.getPrivateKey());
119 | assertEquals("SavedByPublic", instance.getPublicKey());
120 | }
121 |
122 | @Test
123 | public void testFindAndModify_NonExistingCollection_1() {
124 | expectedException.expect(InvalidJsonDbApiUsageException.class);
125 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
126 |
127 | String jxQuery = String.format("/.[id>'%s']", "03");
128 | jsonDBTemplate.findAndModify(jxQuery, null, "sites");
129 | }
130 |
131 | @Test
132 | public void testFindAndModify_NonExistingCollection_2() {
133 | expectedException.expect(InvalidJsonDbApiUsageException.class);
134 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
135 |
136 | String jxQuery = String.format("/.[id>'%s']", "03");
137 |
138 | jsonDBTemplate.findAndModify(jxQuery, null, Site.class);
139 | }
140 |
141 | @Test
142 | public void testFindAllAndModify() {
143 | Update update = Update.update("privateKey", "SavingPrivateRyan");
144 | update.set("publicKey", "SavedByPublic");
145 |
146 | String jxQuery = String.format("/.[id>'%s']", "03");
147 | List retInstances = jsonDBTemplate.findAllAndModify(jxQuery, update, "instances");
148 | assertEquals(3, retInstances.size());
149 | assertEquals("SavingPrivateRyan", retInstances.get(0).getPrivateKey());
150 | assertEquals("SavedByPublic", retInstances.get(0).getPublicKey());
151 | assertEquals("SavingPrivateRyan", retInstances.get(1).getPrivateKey());
152 | assertEquals("SavedByPublic", retInstances.get(1).getPublicKey());
153 | assertEquals("SavingPrivateRyan", retInstances.get(2).getPrivateKey());
154 | assertEquals("SavedByPublic", retInstances.get(2).getPublicKey());
155 |
156 | Instance instance1 = jsonDBTemplate.findById("04", "instances");
157 | assertEquals("SavingPrivateRyan", instance1.getPrivateKey());
158 | assertEquals("SavedByPublic", instance1.getPublicKey());
159 |
160 | Instance instance2 = jsonDBTemplate.findById("05", "instances");
161 | assertEquals("SavingPrivateRyan", instance2.getPrivateKey());
162 | assertEquals("SavedByPublic", instance2.getPublicKey());
163 |
164 | Instance instance3 = jsonDBTemplate.findById("06", "instances");
165 | assertEquals("SavingPrivateRyan", instance3.getPrivateKey());
166 | assertEquals("SavedByPublic", instance3.getPublicKey());
167 | }
168 |
169 | @Test
170 | public void testFindAllAndModify_NonExistingCollection_1() {
171 | expectedException.expect(InvalidJsonDbApiUsageException.class);
172 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
173 |
174 | String jxQuery = String.format("/.[id>'%s']", "03");
175 | jsonDBTemplate.findAllAndModify(jxQuery, null, "sites");
176 | }
177 |
178 | @Test
179 | public void testFindAllAndModify_NonExistingCollection_2() {
180 | expectedException.expect(InvalidJsonDbApiUsageException.class);
181 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
182 |
183 | String jxQuery = String.format("/.[id>'%s']", "03");
184 | jsonDBTemplate.findAllAndModify(jxQuery, null, Site.class);
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/FindAndRemoveTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertNotNull;
25 | import static org.junit.Assert.assertNull;
26 |
27 | import java.io.File;
28 | import java.util.List;
29 |
30 | import org.junit.After;
31 | import org.junit.Before;
32 | import org.junit.Rule;
33 | import org.junit.Test;
34 | import org.junit.rules.ExpectedException;
35 |
36 | import com.google.common.io.Files;
37 |
38 | import io.jsondb.InvalidJsonDbApiUsageException;
39 | import io.jsondb.JsonDBTemplate;
40 | import io.jsondb.Util;
41 | import io.jsondb.crypto.DefaultAESCBCCipher;
42 | import io.jsondb.crypto.ICipher;
43 | import io.jsondb.tests.model.Instance;
44 | import io.jsondb.tests.model.Site;
45 |
46 | /**
47 | * @version 1.0 11-Oct-2016
48 | */
49 | public class FindAndRemoveTests {
50 | private String dbFilesLocation = "src/test/resources/dbfiles/findAndRemoveTests";
51 | private File dbFilesFolder = new File(dbFilesLocation);
52 | private File instancesJson = new File(dbFilesFolder, "instances.json");
53 |
54 | private JsonDBTemplate jsonDBTemplate = null;
55 |
56 | @Rule
57 | public ExpectedException expectedException = ExpectedException.none();
58 |
59 | @Before
60 | public void setUp() throws Exception {
61 | dbFilesFolder.mkdir();
62 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
63 | ICipher cipher = new DefaultAESCBCCipher("1r8+24pibarAWgS85/Heeg==");
64 | jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model", cipher);
65 | }
66 |
67 | @After
68 | public void tearDown() throws Exception {
69 | Util.delete(dbFilesFolder);
70 | }
71 |
72 | /**
73 | * Test to remove a single non-existing object from a collection
74 | */
75 | @Test
76 | public void testRemove_NonExistingObject() {
77 | String jxQuery = String.format("/.[id='%s']", "12");
78 | Instance i = jsonDBTemplate.findAndRemove(jxQuery, Instance.class);
79 |
80 | assertNull(i);
81 | }
82 |
83 | /**
84 | * Test to remove a null object from a collection
85 | */
86 | @Test
87 | public void testRemove_NullObject() {
88 | expectedException.expect(InvalidJsonDbApiUsageException.class);
89 | expectedException.expectMessage("Query string cannot be null.");
90 |
91 | jsonDBTemplate.findAndRemove(null, Instance.class);
92 | }
93 |
94 | /**
95 | * Test to remove a object from a non-existent collection
96 | */
97 | @Test
98 | public void testRemove_FromNonExistingCollection_1() {
99 | expectedException.expect(InvalidJsonDbApiUsageException.class);
100 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
101 |
102 | String jxQuery = String.format("/.[id='%s']", "12");
103 | jsonDBTemplate.findAndRemove(jxQuery, Site.class);
104 | }
105 |
106 | /**
107 | * Test to remove a object from a non-existent collection
108 | */
109 | @Test
110 | public void testRemove_FromNonExistingCollection_2() {
111 | expectedException.expect(InvalidJsonDbApiUsageException.class);
112 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
113 |
114 | String jxQuery = String.format("/.[id='%s']", "12");
115 | jsonDBTemplate.findAndRemove(jxQuery, "sites");
116 | }
117 |
118 | /**
119 | * Test to remove a single object from a collection
120 | */
121 | @Test
122 | public void testRemove_ValidObject() {
123 | List instances = jsonDBTemplate.getCollection(Instance.class);
124 | int size = instances.size();
125 |
126 | String jxQuery = String.format("/.[id='%s']", "05");
127 | Instance removedObject = jsonDBTemplate.findAndRemove(jxQuery, Instance.class);
128 |
129 | instances = jsonDBTemplate.getCollection(Instance.class);
130 | assertNotNull(instances);
131 | assertEquals(size-1, instances.size());
132 | assertNotNull(removedObject);
133 | assertEquals("05", removedObject.getId());
134 | }
135 |
136 | /**
137 | * Test to remove a batch of objects from collection
138 | */
139 | @Test
140 | public void testRemove_OneofManyObjects() {
141 | List instances = jsonDBTemplate.getCollection(Instance.class);
142 | int size = instances.size();
143 |
144 | String jxQuery = String.format("/.[id>'%s']", "04");
145 |
146 | Instance removedObjects = jsonDBTemplate.findAndRemove(jxQuery, Instance.class);
147 |
148 | instances = jsonDBTemplate.getCollection(Instance.class);
149 | assertNotNull(instances);
150 | assertEquals(size-1, instances.size());
151 | assertNotNull(removedObjects);
152 | }
153 |
154 | /**
155 | * Test to remove a batch of objects from collection
156 | */
157 | @Test
158 | public void testRemove_BatchOfObjects() {
159 | List instances = jsonDBTemplate.getCollection(Instance.class);
160 | int size = instances.size();
161 |
162 | String jxQuery = String.format("/.[id>'%s']", "04");
163 |
164 | List removedObjects = jsonDBTemplate.findAllAndRemove(jxQuery, Instance.class);
165 |
166 | instances = jsonDBTemplate.getCollection(Instance.class);
167 | assertNotNull(instances);
168 | assertEquals(size-2, instances.size());
169 | assertNotNull(removedObjects);
170 | assertEquals(2, removedObjects.size());
171 | }
172 |
173 | /**
174 | * Test to remove a object from a non-existent collection
175 | */
176 | @Test
177 | public void testFindAllAndRemove_FromNonExistingCollection_1() {
178 | expectedException.expect(InvalidJsonDbApiUsageException.class);
179 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
180 |
181 | String jxQuery = String.format("/.[id='%s']", "12");
182 | jsonDBTemplate.findAllAndRemove(jxQuery, Site.class);
183 | }
184 |
185 | /**
186 | * Test to remove a object from a non-existent collection
187 | */
188 | @Test
189 | public void testFindAllAndRemove_FromNonExistingCollection_2() {
190 | expectedException.expect(InvalidJsonDbApiUsageException.class);
191 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
192 |
193 | String jxQuery = String.format("/.[id='%s']", "12");
194 | jsonDBTemplate.findAllAndRemove(jxQuery, "sites");
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/FindByIdTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertNotNull;
25 | import static org.junit.Assert.assertNull;
26 |
27 | import java.io.File;
28 |
29 | import org.junit.After;
30 | import org.junit.Before;
31 | import org.junit.Rule;
32 | import org.junit.Test;
33 | import org.junit.rules.ExpectedException;
34 |
35 | import com.google.common.io.Files;
36 |
37 | import io.jsondb.InvalidJsonDbApiUsageException;
38 | import io.jsondb.JsonDBTemplate;
39 | import io.jsondb.Util;
40 | import io.jsondb.crypto.DefaultAESCBCCipher;
41 | import io.jsondb.crypto.ICipher;
42 | import io.jsondb.tests.model.Instance;
43 |
44 | /**
45 | * @version 1.0 14-Oct-2016
46 | */
47 | public class FindByIdTests {
48 | private String dbFilesLocation = "src/test/resources/dbfiles/findByIdTests";
49 | private File dbFilesFolder = new File(dbFilesLocation);
50 | private File instancesJson = new File(dbFilesFolder, "instances.json");
51 |
52 | private JsonDBTemplate jsonDBTemplate = null;
53 |
54 | @Rule
55 | public ExpectedException expectedException = ExpectedException.none();
56 |
57 | @Before
58 | public void setUp() throws Exception {
59 | dbFilesFolder.mkdir();
60 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
61 | ICipher cipher = new DefaultAESCBCCipher("1r8+24pibarAWgS85/Heeg==");
62 | jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model", cipher);
63 | }
64 |
65 | @After
66 | public void tearDown() throws Exception {
67 | Util.delete(dbFilesFolder);
68 | }
69 |
70 | /**
71 | * test to find a document with a existing id.
72 | */
73 | @Test
74 | public void testFindById_ForExistingId() {
75 | Instance instance = jsonDBTemplate.findById("01", Instance.class);
76 | assertNotNull(instance);
77 | assertEquals(instance.getId(), "01");
78 | }
79 |
80 | /**
81 | * test to find a document with a non-existent id.
82 | */
83 | @Test
84 | public void testFindById_ForNonExistentId() {
85 | Instance instance = jsonDBTemplate.findById("00", Instance.class);
86 | assertNull(instance);
87 | }
88 |
89 | private class NonAnotatedClass {}
90 |
91 | /**
92 | * test to find a document formEntity type which does not have @Document annotation
93 | */
94 | @Test
95 | public void testFindById_NonAnotatedClass() {
96 | expectedException.expect(InvalidJsonDbApiUsageException.class);
97 | expectedException.expectMessage("Entity 'NonAnotatedClass' is not annotated with annotation @Document");
98 | jsonDBTemplate.findById("000000", NonAnotatedClass.class);
99 | }
100 |
101 | /**
102 | * test to find a document for a unknown collection name
103 | */
104 | @Test
105 | public void testFindById_UnknownCollectionName() {
106 | expectedException.expect(InvalidJsonDbApiUsageException.class);
107 | expectedException.expectMessage("Collection by name 'SomeCollection' not found. Create collection first");
108 | jsonDBTemplate.findById("000000", "SomeCollection");
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/InitializeDBNegativeTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertTrue;
25 | import static org.junit.Assert.fail;
26 |
27 | import java.io.File;
28 | import java.io.IOException;
29 | import java.security.GeneralSecurityException;
30 | import java.util.Set;
31 |
32 | import org.junit.After;
33 | import org.junit.Before;
34 | import org.junit.Rule;
35 | import org.junit.Test;
36 | import org.junit.rules.ExpectedException;
37 |
38 | import com.google.common.io.Files;
39 |
40 | import io.jsondb.InvalidJsonDbApiUsageException;
41 | import io.jsondb.JsonDBTemplate;
42 | import io.jsondb.Util;
43 | import io.jsondb.crypto.DefaultAESCBCCipher;
44 | import io.jsondb.crypto.ICipher;
45 |
46 | /**
47 | * Unit tests that cover all aspects of DB initialization
48 | *
49 | * @author Farooq Khan
50 | * @version 1.0 06-Oct-2016
51 | */
52 | public class InitializeDBNegativeTests {
53 |
54 | private String dbFilesLocation = "src/test/resources/dbfiles/dbInitializationTests";
55 | private File dbFilesFolder = new File(dbFilesLocation);
56 | private File instancesJson = new File(dbFilesFolder, "instances.json");
57 |
58 | @Rule
59 | public ExpectedException expectedException = ExpectedException.none();
60 |
61 | @Before
62 | public void setup() throws IOException, GeneralSecurityException {
63 | dbFilesFolder.mkdir();
64 | }
65 |
66 | @After
67 | public void tearDown() {
68 | Util.delete(dbFilesFolder);
69 | }
70 |
71 | /**
72 | * A test to see if verify if JsonDB will get initialized when emtpy directory is passed.
73 | */
74 | @Test
75 | public void testEmptyDBInitialization() {
76 | JsonDBTemplate jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model");
77 |
78 | Set collectionNames = jsonDBTemplate.getCollectionNames();
79 | assertEquals(collectionNames.size(), 0);
80 | }
81 |
82 | /**
83 | * A test to see if JsonDB will initialize when a non existing directory is passed
84 | */
85 | @Test
86 | public void testMissingDBLocationInitialization_1() {
87 | File someDbFilesFolder = new File(dbFilesLocation, "someMissingFolder");
88 | JsonDBTemplate jsonDBTemplate = new JsonDBTemplate(someDbFilesFolder.toString(), "org.jsondb.testmodel");
89 |
90 | assertTrue(someDbFilesFolder.exists());
91 | assertTrue(someDbFilesFolder.isDirectory());
92 |
93 | Set collectionNames = jsonDBTemplate.getCollectionNames();
94 | assertEquals(collectionNames.size(), 0);
95 | }
96 |
97 | /**
98 | * A test to see if JsonDB will throw exception when passing non-creatable a non existing directory is passed
99 | */
100 | @Test
101 | public void testMissingDBLocationInitialization_2() {
102 | File someDbFilesFolder = new File(dbFilesLocation, "someMissingFolder2");
103 | try {
104 | someDbFilesFolder.createNewFile();
105 | } catch (IOException e) {
106 | fail("Failed while creating temporary folder " + someDbFilesFolder.toString());
107 | }
108 |
109 | expectedException.expect(InvalidJsonDbApiUsageException.class);
110 | expectedException.expectMessage("Specified DbFiles directory is actually a file cannot use it as a directory");
111 |
112 | new JsonDBTemplate(someDbFilesFolder.toString(), "org.jsondb.tests.model");
113 | }
114 |
115 | @Test
116 | public void testDBInitializationforMissingFile() throws IOException, GeneralSecurityException {
117 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
118 | ICipher cipher = new DefaultAESCBCCipher("1r8+24pibarAWgS85/Heeg==");
119 | JsonDBTemplate jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model", cipher);
120 |
121 | assertTrue(jsonDBTemplate.collectionExists("instances"));
122 |
123 | instancesJson.delete();
124 | jsonDBTemplate.reloadCollection("instances");
125 | assertTrue(!jsonDBTemplate.collectionExists("instances"));
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/InitializeDBTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertTrue;
25 |
26 | import java.io.File;
27 | import java.io.FileWriter;
28 | import java.io.IOException;
29 | import java.security.GeneralSecurityException;
30 | import java.util.ArrayList;
31 | import java.util.List;
32 | import java.util.Set;
33 |
34 | import org.junit.After;
35 | import org.junit.Before;
36 | import org.junit.Test;
37 |
38 | import com.fasterxml.jackson.databind.ObjectMapper;
39 | import com.google.common.io.Files;
40 |
41 | import io.jsondb.JsonDBTemplate;
42 | import io.jsondb.Util;
43 | import io.jsondb.crypto.DefaultAESCBCCipher;
44 | import io.jsondb.crypto.ICipher;
45 | import io.jsondb.tests.model.Instance;
46 |
47 | /**
48 | * Unit tests that cover all aspects of DB initialization
49 | *
50 | * @author Farooq Khan
51 | * @version 1.0 31 Dec 2015
52 | */
53 | public class InitializeDBTests {
54 |
55 | private ObjectMapper objectMapper = null;
56 |
57 | private String dbFilesLocation = "src/test/resources/dbfiles/initializationTests";
58 | private File dbFilesFolder = new File(dbFilesLocation);
59 | private File instancesJson = new File(dbFilesFolder, "instances.json");
60 | private ICipher cipher;
61 |
62 | @Before
63 | public void setup() throws IOException {
64 | dbFilesFolder.mkdir();
65 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
66 | try {
67 | cipher = new DefaultAESCBCCipher("1r8+24pibarAWgS85/Heeg==");
68 | } catch (GeneralSecurityException e) {
69 | // TODO Auto-generated catch block
70 | e.printStackTrace();
71 | }
72 | objectMapper = new ObjectMapper();
73 | }
74 |
75 | @After
76 | public void tearDown() {
77 | Util.delete(dbFilesFolder);
78 | }
79 |
80 | @Test
81 | public void testInitialization() {
82 | JsonDBTemplate jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model");
83 |
84 | Set collectionNames = jsonDBTemplate.getCollectionNames();
85 | assertTrue(collectionNames.contains("instances"));
86 | assertEquals(collectionNames.size(), 1);
87 | }
88 |
89 | @Test
90 | public void testReload() {
91 | JsonDBTemplate jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model", cipher);
92 |
93 | Set collectionNames = jsonDBTemplate.getCollectionNames();
94 | assertTrue(collectionNames.contains("instances"));
95 | List instances = jsonDBTemplate.findAll(Instance.class);
96 | int size = instances.size();
97 |
98 | //Add more computers directly to the computers.json file.
99 | List instances1 = new ArrayList();
100 | for (int i = 0; i<10; i++) {
101 | Instance inst = new Instance();
102 | int id = 11 + i;
103 | inst.setId(String.format("%02d", id));
104 | inst.setHostname("ec2-54-191-" + id);
105 | //Private key is encrypted form of: b87eb02f5dd7e5232d7b0fc30a5015e4
106 | inst.setPrivateKey("Zf9vl5K6WV6BA3eL7JbnrfPMjfJxc9Rkoo0zlROQlgTslmcp9iFzos+MP93GZqop");
107 | inst.setPublicKey("d3aa045f71bf4d1dffd2c5f485a4bc1d");
108 | instances1.add(inst);
109 | }
110 | appendDirectlyToJsonFile(instances1, instancesJson);
111 |
112 | jsonDBTemplate.reLoadDB();
113 |
114 | collectionNames = jsonDBTemplate.getCollectionNames();
115 | assertTrue(collectionNames.contains("instances"));
116 | instances = jsonDBTemplate.findAll(Instance.class);
117 | assertEquals(instances.size(), size+10);
118 | }
119 |
120 | private boolean appendDirectlyToJsonFile(List collectionData, File collectionFile) {
121 |
122 | boolean retval = false;
123 | FileWriter fw = null;
124 | try {
125 | fw = new FileWriter(collectionFile, true);
126 | for (T row : collectionData) {
127 | fw.write(objectMapper.writeValueAsString(row));
128 | fw.write("\n");
129 | }
130 | retval = true;
131 | } catch (IOException e) {
132 | retval = false;
133 | e.printStackTrace();
134 | } finally {
135 | if (null != fw) {
136 | try {
137 | fw.close();
138 | } catch (IOException e) {
139 | // do nothing
140 | }
141 | }
142 | }
143 | return retval;
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/JsonDBConfigTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertFalse;
25 | import static org.junit.Assert.assertNull;
26 | import static org.junit.Assert.assertTrue;
27 |
28 | import java.io.File;
29 | import java.nio.charset.Charset;
30 |
31 | import org.junit.Test;
32 |
33 | import com.fasterxml.jackson.databind.DeserializationFeature;
34 | import com.fasterxml.jackson.databind.ObjectMapper;
35 |
36 | import io.jsondb.DefaultSchemaVersionComparator;
37 | import io.jsondb.JsonDBConfig;
38 | import io.jsondb.crypto.ICipher;
39 |
40 | /**
41 | * @version 1.0 08-Oct-2016
42 | */
43 | public class JsonDBConfigTests {
44 |
45 | private String dbFilesLocation = "src/test/resources/dbfiles/dbConfigTests";
46 |
47 | @Test
48 | public void testDbConfig() {
49 | JsonDBConfig dbConfig = new JsonDBConfig(dbFilesLocation, "io.jsondb.tests.model", null, false,
50 | new DefaultSchemaVersionComparator());
51 |
52 | assertEquals("src/test/resources/dbfiles/dbConfigTests", dbConfig.getDbFilesLocationString());
53 | assertEquals(new File("src/test/resources/dbfiles/dbConfigTests"), dbConfig.getDbFilesLocation());
54 | assertEquals(new File("src/test/resources/dbfiles/dbConfigTests").toPath(), dbConfig.getDbFilesPath());
55 | assertEquals(Charset.forName("UTF-8"), dbConfig.getCharset());
56 | assertNull(dbConfig.getCipher());
57 | assertFalse(dbConfig.isCompatibilityMode());
58 |
59 | dbConfig.setDbFilesLocationString("myfolder");
60 | assertEquals("myfolder", dbConfig.getDbFilesLocationString());
61 | assertEquals(new File("myfolder"), dbConfig.getDbFilesLocation());
62 | assertEquals(new File("myfolder").toPath(), dbConfig.getDbFilesPath());
63 |
64 | Charset newCharset = Charset.forName("UTF-16");
65 | dbConfig.setCharset(newCharset);
66 | assertEquals(newCharset, dbConfig.getCharset());
67 |
68 | ICipher mCipher = new MyCipher();
69 | dbConfig.setCipher(mCipher);
70 | assertEquals(mCipher, dbConfig.getCipher());
71 |
72 | dbConfig.setBaseScanPackage("io.newpackage");
73 | assertEquals("io.newpackage", dbConfig.getBaseScanPackage());
74 |
75 | ObjectMapper mapper = dbConfig.getObjectMapper();
76 | assertTrue(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
77 | dbConfig.setCompatibilityMode(true);
78 | assertFalse(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
79 | dbConfig.setCompatibilityMode(false);
80 | assertTrue(mapper.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
81 |
82 | ObjectMapper newMapper = new ObjectMapper();
83 | dbConfig.setObjectMapper(newMapper);
84 | assertEquals(newMapper, dbConfig.getObjectMapper());
85 | }
86 |
87 |
88 | private class MyCipher implements ICipher {
89 |
90 | /* (non-Javadoc)
91 | * @see io.jsondb.crypto.ICipher#encrypt(java.lang.String)
92 | */
93 | @Override
94 | public String encrypt(String plainText) {
95 | // TODO Auto-generated method stub
96 | return null;
97 | }
98 |
99 | /* (non-Javadoc)
100 | * @see io.jsondb.crypto.ICipher#decrypt(java.lang.String)
101 | */
102 | @Override
103 | public String decrypt(String cipherText) {
104 | // TODO Auto-generated method stub
105 | return null;
106 | }
107 |
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/JsonReaderTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertNotNull;
25 |
26 | import java.io.File;
27 | import java.io.IOException;
28 | import java.io.RandomAccessFile;
29 | import java.nio.channels.FileChannel;
30 |
31 | import org.junit.After;
32 | import org.junit.Before;
33 | import org.junit.Rule;
34 | import org.junit.Test;
35 | import org.junit.rules.ExpectedException;
36 |
37 | import com.google.common.io.Files;
38 |
39 | import io.jsondb.DefaultSchemaVersionComparator;
40 | import io.jsondb.JsonDBConfig;
41 | import io.jsondb.Util;
42 | import io.jsondb.io.JsonFileLockException;
43 | import io.jsondb.io.JsonReader;
44 |
45 | /**
46 | * Unit tests for JsonReader IO utility class
47 | * @version 1.0 11-Dec-2017
48 | */
49 | public class JsonReaderTests {
50 |
51 | private String dbFilesLocation = "src/test/resources/dbfiles/jsonReaderTests";
52 | private File dbFilesFolder = new File(dbFilesLocation);
53 | private File instancesJson = new File(dbFilesFolder, "instances.json");
54 |
55 | @Rule
56 | public ExpectedException expectedException = ExpectedException.none();
57 |
58 | /**
59 | * @throws java.lang.Exception
60 | */
61 | @Before
62 | public void setUp() throws Exception {
63 | dbFilesFolder.mkdir();
64 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
65 | }
66 |
67 | @After
68 | public void tearDown() throws Exception {
69 | Util.delete(dbFilesFolder);
70 | }
71 |
72 | @Test
73 | public void testReadLine() throws IOException {
74 | JsonDBConfig dbConfig = new JsonDBConfig(dbFilesLocation, "io.jsondb.tests.model", null, false,
75 | new DefaultSchemaVersionComparator());
76 |
77 | JsonReader jr = new JsonReader(dbConfig, instancesJson);
78 |
79 | assertNotNull(jr);
80 | assertEquals("{\"schemaVersion\":\"1.0\"}", jr.readLine());
81 | }
82 |
83 | @Test
84 | public void testLockException() throws IOException {
85 | File lockFolder = new File(dbFilesLocation, "lock");
86 | if (!lockFolder.exists()) {
87 | lockFolder.mkdirs();
88 | }
89 | File fileLockLocation = new File(lockFolder, "instances.json.lock");
90 | RandomAccessFile raf = new RandomAccessFile(fileLockLocation, "rw");
91 | raf.writeInt(0); //Will cause creation of the file
92 |
93 | FileChannel channel = raf.getChannel();
94 | try {
95 | channel.lock();
96 | } catch (IOException e) {
97 | //Ignore
98 | }
99 |
100 | expectedException.expect(JsonFileLockException.class);
101 | expectedException.expectMessage("JsonReader failed to obtain a file lock for file " + fileLockLocation);
102 |
103 | JsonDBConfig dbConfig = new JsonDBConfig(dbFilesLocation, "io.jsondb.tests.model", null, false,
104 | new DefaultSchemaVersionComparator());
105 |
106 | @SuppressWarnings("unused")
107 | JsonReader jr = new JsonReader(dbConfig, instancesJson);
108 | raf.close();
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/JsonWriterTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertNotNull;
24 |
25 | import java.io.File;
26 | import java.io.IOException;
27 |
28 | import org.junit.After;
29 | import org.junit.Before;
30 | import org.junit.Rule;
31 | import org.junit.Test;
32 | import org.junit.rules.ExpectedException;
33 |
34 | import com.google.common.io.Files;
35 |
36 | import io.jsondb.CollectionMetaData;
37 | import io.jsondb.DefaultSchemaVersionComparator;
38 | import io.jsondb.JsonDBConfig;
39 | import io.jsondb.Util;
40 | import io.jsondb.io.JsonWriter;
41 | import io.jsondb.tests.model.Instance;
42 |
43 | /**
44 | * Unit tests for JsonWriter IO utility class
45 | * @version 1.0 11-Dec-2017
46 | */
47 | public class JsonWriterTests {
48 |
49 | private String dbFilesLocation = "src/test/resources/dbfiles/jsonWriterTests";
50 | private File dbFilesFolder = new File(dbFilesLocation);
51 | private File instancesJson = new File(dbFilesFolder, "instances.json");
52 |
53 | @Rule
54 | public ExpectedException expectedException = ExpectedException.none();
55 |
56 | /**
57 | * @throws java.lang.Exception
58 | */
59 | @Before
60 | public void setUp() throws Exception {
61 | dbFilesFolder.mkdir();
62 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
63 | }
64 |
65 | @After
66 | public void tearDown() throws Exception {
67 | Util.delete(dbFilesFolder);
68 | }
69 |
70 | @Test
71 | public void test() throws IOException {
72 | JsonDBConfig dbConfig = new JsonDBConfig(dbFilesLocation, "io.jsondb.tests.model", null, false,
73 | new DefaultSchemaVersionComparator());
74 |
75 | CollectionMetaData cmd = new CollectionMetaData("instances", new Instance().getClass(), "1.0", null);
76 |
77 | JsonWriter jr = new JsonWriter(dbConfig, cmd, "instances", instancesJson);
78 |
79 | assertNotNull(jr);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/LoadInvalidJsonTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 |
25 | import java.io.File;
26 | import java.io.IOException;
27 | import java.util.Set;
28 |
29 | import org.junit.After;
30 | import org.junit.Before;
31 | import org.junit.Test;
32 |
33 | import com.google.common.io.Files;
34 |
35 | import io.jsondb.JsonDBTemplate;
36 | import io.jsondb.Util;
37 | import io.jsondb.tests.util.TestUtils;
38 |
39 | /**
40 | * @version 1.0 19-Oct-2018
41 | */
42 | public class LoadInvalidJsonTests {
43 |
44 | private String dbFilesLocation = "src/test/resources/dbfiles/loadInvalidJsonTests";
45 | private File dbFilesFolder = new File(dbFilesLocation);
46 | private File instancesJson = new File(dbFilesFolder, "instances.json");
47 |
48 | @Before
49 | public void setup() throws IOException {
50 | dbFilesFolder.mkdir();
51 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
52 | }
53 |
54 | @After
55 | public void tearDown() {
56 | Util.delete(dbFilesFolder);
57 | }
58 |
59 | /**
60 | * A test to ensure JsonDB does not delete the source files when a exception occurs during loading
61 | */
62 | @Test
63 | public void testLoadForInvalidJson() {
64 | // The invalidJson has semicolon instead of a colon between the id attribute name and value
65 | String invalidJson = "{\"id\"=\"07\",\"hostname\":\"ec2-54-191-07\",\"privateKey\":\"Zf9vl5K6WV6BA3eL7JbnrfPMjfJxc9Rkoo0zlROQlgTslmcp9iFzos+MP93GZqop\",\"publicKey\":\"\"}";
66 |
67 | TestUtils.appendDirectToFile(instancesJson, invalidJson);
68 |
69 | JsonDBTemplate jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model");
70 | Set collectionNames = jsonDBTemplate.getCollectionNames();
71 |
72 | assertEquals(collectionNames.size(), 0);
73 | assertEquals(8, TestUtils.getNoOfLinesInFile(instancesJson));
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/PojoWithEnumFieldsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertNotNull;
25 |
26 | import java.io.File;
27 | import java.util.List;
28 |
29 | import org.junit.After;
30 | import org.junit.Before;
31 | import org.junit.Test;
32 |
33 | import com.google.common.io.Files;
34 |
35 | import io.jsondb.JsonDBTemplate;
36 | import io.jsondb.Util;
37 | import io.jsondb.tests.model.PojoWithEnumFields;
38 | import io.jsondb.tests.model.PojoWithEnumFields.Status;
39 |
40 | /**
41 | * @author Farooq Khan
42 | * @version 1.0 06-Oct-2016
43 | */
44 | public class PojoWithEnumFieldsTest {
45 | private String dbFilesLocation = "src/test/resources/dbfiles/pojowithenumfieldsTests";
46 | private File dbFilesFolder = new File(dbFilesLocation);
47 | private File pojoWithEnumFieldsJson = new File(dbFilesFolder, "pojowithenumfields.json");
48 |
49 | private JsonDBTemplate jsonDBTemplate = null;
50 |
51 | @Before
52 | public void setUp() throws Exception {
53 | dbFilesFolder.mkdir();
54 | Files.copy(new File("src/test/resources/dbfiles/pojowithenumfields.json"), pojoWithEnumFieldsJson);
55 | jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model");
56 | }
57 |
58 | @After
59 | public void tearDown() throws Exception {
60 | Util.delete(dbFilesFolder);
61 | }
62 |
63 | @Test
64 | public void testFind() {
65 | PojoWithEnumFields clazz = jsonDBTemplate.findById("0001", PojoWithEnumFields.class);
66 |
67 | assertNotNull(clazz);
68 |
69 | assertEquals(clazz.getStatus(), Status.CREATED);
70 | }
71 |
72 | @Test
73 | public void testInsert() {
74 | List clazzs = jsonDBTemplate.getCollection(PojoWithEnumFields.class);
75 | int size = clazzs.size();
76 |
77 | PojoWithEnumFields clazz = new PojoWithEnumFields();
78 | clazz.setId("0010");
79 | clazz.setStatus(Status.UPDATED);
80 | jsonDBTemplate.insert(clazz);
81 |
82 | clazzs = jsonDBTemplate.getCollection(PojoWithEnumFields.class);
83 | assertNotNull(clazzs);
84 | assertEquals(clazzs.size(), size+1);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/RemoveTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertNotNull;
25 |
26 | import java.io.File;
27 | import java.util.ArrayList;
28 | import java.util.List;
29 |
30 | import org.junit.After;
31 | import org.junit.Before;
32 | import org.junit.Rule;
33 | import org.junit.Test;
34 | import org.junit.rules.ExpectedException;
35 |
36 | import com.google.common.io.Files;
37 |
38 | import io.jsondb.InvalidJsonDbApiUsageException;
39 | import io.jsondb.JsonDBTemplate;
40 | import io.jsondb.Util;
41 | import io.jsondb.crypto.DefaultAESCBCCipher;
42 | import io.jsondb.crypto.ICipher;
43 | import io.jsondb.tests.model.Instance;
44 | import io.jsondb.tests.model.Site;
45 |
46 | /**
47 | * Junit tests for the remove() apis
48 | *
49 | * @version 1.0 08-Oct-2016
50 | */
51 | public class RemoveTests {
52 |
53 | private String dbFilesLocation = "src/test/resources/dbfiles/removeTests";
54 | private File dbFilesFolder = new File(dbFilesLocation);
55 | private File instancesJson = new File(dbFilesFolder, "instances.json");
56 |
57 | private JsonDBTemplate jsonDBTemplate = null;
58 |
59 | @Rule
60 | public ExpectedException expectedException = ExpectedException.none();
61 |
62 | @Before
63 | public void setUp() throws Exception {
64 | dbFilesFolder.mkdir();
65 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
66 | ICipher cipher = new DefaultAESCBCCipher("1r8+24pibarAWgS85/Heeg==");
67 | jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model", cipher);
68 | }
69 |
70 | @After
71 | public void tearDown() throws Exception {
72 | Util.delete(dbFilesFolder);
73 | }
74 |
75 | /**
76 | * Test to remove a single non-existing object from a collection
77 | */
78 | @Test
79 | public void testRemove_NonExistingObject() {
80 | expectedException.expect(InvalidJsonDbApiUsageException.class);
81 | expectedException.expectMessage("Objects with Id 000012 not found in collection instances");
82 |
83 | Instance instance = new Instance();
84 | instance.setId("000012");
85 |
86 | jsonDBTemplate.remove(instance, Instance.class);
87 | }
88 |
89 | /**
90 | * Test to remove a null object from a collection
91 | */
92 | @Test
93 | public void testRemove_NullObject() {
94 | expectedException.expect(InvalidJsonDbApiUsageException.class);
95 | expectedException.expectMessage("Null Object cannot be removed from DB");
96 | Object nullObject = null;
97 | jsonDBTemplate.remove(nullObject, Instance.class);
98 | }
99 |
100 | /**
101 | * Test to remove a null object from a collection
102 | */
103 | @Test
104 | public void testRemove_NullObjectBatch() {
105 | expectedException.expect(InvalidJsonDbApiUsageException.class);
106 | expectedException.expectMessage("Null Object batch cannot be removed from DB");
107 |
108 | jsonDBTemplate.remove(null, Instance.class);
109 | }
110 |
111 | /**
112 | * Test to remove a object from a non-existent collection
113 | */
114 | @Test
115 | public void testRemove_FromNonExistingCollection() {
116 | expectedException.expect(InvalidJsonDbApiUsageException.class);
117 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
118 |
119 | Site s = new Site();
120 | s.setId("000012");
121 |
122 | jsonDBTemplate.remove(s, Site.class);
123 | }
124 |
125 | /**
126 | * Test to remove a object from a non-existent collection
127 | */
128 | @Test
129 | public void testRemoveBatch_FromNonExistingCollection() {
130 | expectedException.expect(InvalidJsonDbApiUsageException.class);
131 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
132 |
133 | Site s = new Site();
134 | s.setId("000012");
135 | List ss = new ArrayList();
136 | ss.add(s);
137 |
138 | jsonDBTemplate.remove(ss, "sites");
139 | }
140 |
141 | /**
142 | * Test to remove a single object from a collection
143 | */
144 | @Test
145 | public void testRemove_ValidObjectWithClass() {
146 | List instances = jsonDBTemplate.getCollection(Instance.class);
147 | int size = instances.size();
148 |
149 | Instance instance = new Instance();
150 | instance.setId("05");
151 |
152 | Instance removedObject = jsonDBTemplate.remove(instance, Instance.class);
153 |
154 | instances = jsonDBTemplate.getCollection(Instance.class);
155 | assertNotNull(instances);
156 | assertEquals(size-1, instances.size());
157 | assertNotNull(removedObject);
158 | assertEquals("05", removedObject.getId());
159 | }
160 |
161 | /**
162 | * Test to remove a single object from a collection
163 | */
164 | @Test
165 | public void testRemove_ValidObjectWithoutClass() {
166 | List instances = jsonDBTemplate.getCollection(Instance.class);
167 | int size = instances.size();
168 |
169 | Instance instance = new Instance();
170 | instance.setId("05");
171 |
172 | Instance removedObject = jsonDBTemplate.remove(instance);
173 |
174 | instances = jsonDBTemplate.getCollection(Instance.class);
175 | assertNotNull(instances);
176 | assertEquals(size-1, instances.size());
177 | assertNotNull(removedObject);
178 | assertEquals("05", removedObject.getId());
179 | }
180 |
181 | /**
182 | * Test to remove a batch of objects from collection
183 | */
184 | @Test
185 | public void testRemove_BatchOfObjects() {
186 | List instances = jsonDBTemplate.getCollection(Instance.class);
187 | int size = instances.size();
188 |
189 | List batch = new ArrayList();
190 | for (int i=1; i<3; i++) {
191 | Instance e = new Instance();
192 | e.setId(String.format("%02d", i));
193 | batch.add(e);
194 | }
195 |
196 | List removedObjects = jsonDBTemplate.remove(batch, Instance.class);
197 |
198 | instances = jsonDBTemplate.getCollection(Instance.class);
199 | assertNotNull(instances);
200 | assertEquals(size-2, instances.size());
201 | assertNotNull(removedObjects);
202 | assertEquals(2, removedObjects.size());
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/SaveTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests;
22 |
23 | import static org.junit.Assert.assertEquals;
24 |
25 | import java.io.File;
26 | import java.util.HashSet;
27 | import java.util.List;
28 |
29 | import org.junit.After;
30 | import org.junit.Before;
31 | import org.junit.Rule;
32 | import org.junit.Test;
33 | import org.junit.rules.ExpectedException;
34 |
35 | import com.google.common.io.Files;
36 |
37 | import io.jsondb.InvalidJsonDbApiUsageException;
38 | import io.jsondb.JsonDBTemplate;
39 | import io.jsondb.Util;
40 | import io.jsondb.crypto.DefaultAESCBCCipher;
41 | import io.jsondb.crypto.ICipher;
42 | import io.jsondb.tests.model.Instance;
43 | import io.jsondb.tests.model.Site;
44 |
45 | /**
46 | * Junit tests for the save() apis
47 | * @version 1.0 08-Oct-2016
48 | */
49 | public class SaveTests {
50 | private String dbFilesLocation = "src/test/resources/dbfiles/saveTests";
51 | private File dbFilesFolder = new File(dbFilesLocation);
52 | private File instancesJson = new File(dbFilesFolder, "instances.json");
53 |
54 | private JsonDBTemplate jsonDBTemplate = null;
55 |
56 | @Rule
57 | public ExpectedException expectedException = ExpectedException.none();
58 |
59 | @Before
60 | public void setUp() throws Exception {
61 | dbFilesFolder.mkdir();
62 | Files.copy(new File("src/test/resources/dbfiles/instances.json"), instancesJson);
63 | ICipher cipher = new DefaultAESCBCCipher("1r8+24pibarAWgS85/Heeg==");
64 | jsonDBTemplate = new JsonDBTemplate(dbFilesLocation, "io.jsondb.tests.model", cipher);
65 | }
66 |
67 | @After
68 | public void tearDown() throws Exception {
69 | Util.delete(dbFilesFolder);
70 | }
71 |
72 | /**
73 | * Test to save a new object into a non-existing collection.
74 | */
75 | @Test
76 | public void testSave_IntoNonExistingCollection() {
77 | expectedException.expect(InvalidJsonDbApiUsageException.class);
78 | expectedException.expectMessage("Collection by name 'sites' not found. Create collection first");
79 | jsonDBTemplate.save(new Site(), "sites");
80 | }
81 |
82 | private class SomeClass {}
83 |
84 | /**
85 | * Test to save a new object of unknown collection type.
86 | */
87 | @Test
88 | public void testSave_IntoUnknowCollection() {
89 | expectedException.expect(InvalidJsonDbApiUsageException.class);
90 | expectedException.expectMessage("Entity 'SomeClass' is not annotated with annotation @Document");
91 | jsonDBTemplate.save(new SomeClass(), SomeClass.class);
92 | }
93 |
94 | /**
95 | * Test to save a null object.
96 | */
97 | @Test
98 | public void testSave_ANullObject() {
99 | expectedException.expect(InvalidJsonDbApiUsageException.class);
100 | expectedException.expectMessage("Null Object cannot be updated into DB");
101 | jsonDBTemplate.save(null, Instance.class);
102 | }
103 |
104 | /**
105 | * Test to save a Collection object.
106 | */
107 | @Test
108 | public void testSave_ASingleCollectionObject() {
109 | expectedException.expect(InvalidJsonDbApiUsageException.class);
110 | expectedException.expectMessage("Collection object cannot be inserted, removed, updated or upserted as a single object");
111 | jsonDBTemplate.save(new HashSet(), Instance.class);
112 | }
113 |
114 | /**
115 | * Test to save a new object that does not exists in the collection
116 | */
117 | @Test
118 | public void testSave_ANewObject() {
119 | expectedException.expect(InvalidJsonDbApiUsageException.class);
120 | expectedException.expectMessage("Document with Id: '15' not found in Collection by name 'instances' not found. Insert or Upsert the object first.");
121 |
122 | Instance instance = new Instance();
123 | instance.setId("15");
124 | instance.setHostname("ec2-54-191-15");
125 | jsonDBTemplate.save(instance, Instance.class);
126 | }
127 |
128 | /**
129 | * Test to simply save/update a object
130 | */
131 | @Test
132 | public void testSave_Simple() {
133 | List instances = jsonDBTemplate.getCollection(Instance.class);
134 | int size = instances.size();
135 |
136 | Instance instance = new Instance();
137 | instance.setId("01");
138 | instance.setHostname("ec2-54-191-UPDTed");
139 | jsonDBTemplate.save(instance, Instance.class);
140 |
141 | Instance instance1 = jsonDBTemplate.findById("01", Instance.class);
142 | assertEquals("ec2-54-191-UPDTed", instance1.getHostname());
143 | assertEquals(size, instances.size());
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/model/Instance.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests.model;
22 |
23 | import io.jsondb.annotation.Document;
24 | import io.jsondb.annotation.Id;
25 | import io.jsondb.annotation.Secret;
26 |
27 | /**
28 | * A test Pojo representing a AWS Instance.
29 | * @version 1.0 28-Sep-2016
30 | */
31 | @Document(collection = "instances", schemaVersion= "1.0")
32 | public class Instance {
33 | @Id
34 | private String id;
35 | private String hostname;
36 |
37 | @Secret
38 | private String privateKey;
39 | private String publicKey;
40 |
41 | public String getId() {
42 | return id;
43 | }
44 | public void setId(String id) {
45 | this.id = id;
46 | }
47 | public String getHostname() {
48 | return hostname;
49 | }
50 | public void setHostname(String hostname) {
51 | this.hostname = hostname;
52 | }
53 | public String getPrivateKey() {
54 | return privateKey;
55 | }
56 | public void setPrivateKey(String privateKey) {
57 | this.privateKey = privateKey;
58 | }
59 | public String getPublicKey() {
60 | return publicKey;
61 | }
62 | public void setPublicKey(String publicKey) {
63 | this.publicKey = publicKey;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/model/LoadBalancer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests.model;
22 |
23 | import io.jsondb.annotation.Document;
24 | import io.jsondb.annotation.Id;
25 |
26 | /**
27 | * @version 1.0 25-Oct-2016
28 | */
29 | @Document(collection = "loadbalancer", schemaVersion= "1.0")
30 | public class LoadBalancer {
31 | @Id
32 | private String id;
33 | private String hostname;
34 | private String username;
35 |
36 | //New Field
37 | private String osName;
38 |
39 | //Just mentioned here so that is known that such a thing can happen
40 | //private int deletedField;
41 |
42 | public String getId() {
43 | return id;
44 | }
45 | public void setId(String id) {
46 | this.id = id;
47 | }
48 | public String getHostname() {
49 | return hostname;
50 | }
51 | public void setHostname(String hostname) {
52 | this.hostname = hostname;
53 | }
54 | public String getUsername() {
55 | return username;
56 | }
57 | public void setUsername(String username) {
58 | this.username = username;
59 | }
60 | public String getOsName() {
61 | return osName;
62 | }
63 | public void setOsName(String osName) {
64 | this.osName = osName;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/model/PojoForPrivateGetIdTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests.model;
22 |
23 | import io.jsondb.annotation.Document;
24 | import io.jsondb.annotation.Id;
25 |
26 | /**
27 | * @version 1.0 29-Oct-2016
28 | */
29 | @Document(collection = "pojoforprivategetidtest", schemaVersion= "1.0")
30 | public class PojoForPrivateGetIdTest {
31 | @Id
32 | private String id;
33 |
34 | public PojoForPrivateGetIdTest() {
35 | super();
36 | }
37 |
38 | public PojoForPrivateGetIdTest(String id) {
39 | super();
40 | this.id = id;
41 | }
42 |
43 | @SuppressWarnings("unused")
44 | private String getId() {
45 | return id;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/model/PojoForPrivateSetIdTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests.model;
22 |
23 | import io.jsondb.annotation.Document;
24 | import io.jsondb.annotation.Id;
25 |
26 | /**
27 | * @version 1.0 29-Oct-2016
28 | */
29 | @Document(collection = "pojoforprivatesetidtest", schemaVersion= "1.0")
30 | public class PojoForPrivateSetIdTest {
31 | @Id
32 | private String id;
33 |
34 | public String getId() {
35 | return id;
36 | }
37 |
38 | @SuppressWarnings("unused")
39 | private void setId(String id) {
40 | this.id = id;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/model/PojoWithEnumFields.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests.model;
22 |
23 | import io.jsondb.annotation.Document;
24 | import io.jsondb.annotation.Id;
25 |
26 | /**
27 | * A test POJO to represent a PojoWithEnumFields
28 | * Used to test that JsonDB can handle POJOs which have Enum fields.
29 | *
30 | * @author Farooq Khan
31 | * @version 1.0 06-Oct-2016
32 | */
33 | @Document(collection = "pojowithenumfields", schemaVersion= "1.0")
34 | public class PojoWithEnumFields {
35 | public enum Status {
36 | CREATED, COMPLETED, CONSUMED, UPDATED
37 | }
38 |
39 | @Id
40 | private String id;
41 | private Status status;
42 |
43 | public String getId() {
44 | return id;
45 | }
46 | public void setId(String id) {
47 | this.id = id;
48 | }
49 | public Status getStatus() {
50 | return status;
51 | }
52 | public void setStatus(Status status) {
53 | this.status = status;
54 | }
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/model/PojoWithList.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests.model;
22 |
23 | import java.util.List;
24 | import java.util.UUID;
25 |
26 | import io.jsondb.annotation.Document;
27 | import io.jsondb.annotation.Id;
28 |
29 | /**
30 | * @version 1.0 10-Dec-2017
31 | */
32 | @Document(collection = "pojowithlist", schemaVersion = "1.0")
33 | public class PojoWithList {
34 | @Id
35 | private String id;
36 |
37 | private List stuff;
38 |
39 | public PojoWithList() {
40 | this.id = UUID.randomUUID().toString();
41 | }
42 |
43 | public String getId() {
44 | return id;
45 | }
46 | public void setId(String id) {
47 | this.id = id;
48 | }
49 |
50 | public List getStuff() {
51 | return stuff;
52 | }
53 | public void setStuff(List stuff) {
54 | this.stuff = stuff;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/model/SecureVolume.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests.model;
22 |
23 | import io.jsondb.annotation.Document;
24 | import io.jsondb.annotation.Id;
25 | import io.jsondb.annotation.Secret;
26 |
27 | /**
28 | * A test Pojo representing a AWS EC3 Secure Volume
29 | * @version 1.0 06-Oct-2016
30 | */
31 | @Document(collection = "securevolumes", schemaVersion= "1.0")
32 | public class SecureVolume {
33 | @Id
34 | private String id;
35 | private String name;
36 | @Secret
37 | private long encryptionKey;
38 |
39 | public String getId() {
40 | return id;
41 | }
42 | public void setId(String id) {
43 | this.id = id;
44 | }
45 | public String getName() {
46 | return name;
47 | }
48 | public void setName(String name) {
49 | this.name = name;
50 | }
51 | public long getEncryptionKey() {
52 | return encryptionKey;
53 | }
54 | public void setEncryptionKey(long encryptionKey) {
55 | this.encryptionKey = encryptionKey;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/model/Site.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests.model;
22 |
23 | import io.jsondb.annotation.Document;
24 | import io.jsondb.annotation.Id;
25 |
26 | /**
27 | * A test Pojo representing a AWS Site.
28 | * Used to test JsonDB - createCollection() and dropCollection() operations
29 | * @version 1.0 06-Oct-2016
30 | */
31 | @Document(collection = "sites", schemaVersion= "1.0")
32 | public class Site {
33 | @Id
34 | private String id;
35 | private String location;
36 | public String getId() {
37 | return id;
38 | }
39 | public void setId(String id) {
40 | this.id = id;
41 | }
42 | public String getLocation() {
43 | return location;
44 | }
45 | public void setLocation(String location) {
46 | this.location = location;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/model/Volume.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests.model;
22 |
23 | import io.jsondb.annotation.Document;
24 | import io.jsondb.annotation.Id;
25 |
26 | /**
27 | * A test Pojo representing a AWS EC3 Volume
28 | * @version 1.0 06-Oct-2016
29 | */
30 | @Document(collection = "volumes", schemaVersion= "1.0")
31 | public class Volume {
32 | @Id
33 | private String id;
34 | private String name;
35 | private long size;
36 | public boolean flash;
37 |
38 | public String getId() {
39 | return id;
40 | }
41 | public void setId(String id) {
42 | this.id = id;
43 | }
44 | public String getName() {
45 | return name;
46 | }
47 | public void setName(String name) {
48 | this.name = name;
49 | }
50 | public long getSize() {
51 | return size;
52 | }
53 | public void setSize(long size) {
54 | this.size = size;
55 | }
56 | public boolean isFlash() {
57 | return flash;
58 | }
59 | public void setFlash(boolean flash) {
60 | this.flash = flash;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/test/java/io/jsondb/tests/util/TestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 - 2018 Farooq Khan
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to
6 | * deal in the Software without restriction, including without limitation the
7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 | * sell copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in
12 | * all copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 | package io.jsondb.tests.util;
22 |
23 | import java.io.BufferedReader;
24 | import java.io.File;
25 | import java.io.FileNotFoundException;
26 | import java.io.FileReader;
27 | import java.io.FileWriter;
28 | import java.io.IOException;
29 | import java.util.LinkedList;
30 | import java.util.Scanner;
31 |
32 | import org.hamcrest.MatcherAssert;
33 | import org.hamcrest.collection.IsIterableContainingInOrder;
34 |
35 | /**
36 | * @author Farooq Khan
37 | * @version 1.0 06-Oct-2016
38 | */
39 | public class TestUtils {
40 | public static void checkLastLines(File jsonFile, String[] expectedLinesAtEnd) {
41 | CircularQueue queue = new CircularQueue(expectedLinesAtEnd.length);
42 |
43 | Scanner sc = null;
44 | try {
45 | sc = new Scanner(jsonFile, "UTF-8");
46 | while (sc.hasNextLine()) {
47 | queue.add(sc.nextLine());
48 | }
49 | } catch (FileNotFoundException e) {
50 | e.printStackTrace();
51 | } finally {
52 | if (null != sc) {
53 | sc.close();
54 | }
55 | }
56 | MatcherAssert.assertThat(queue, IsIterableContainingInOrder.contains(expectedLinesAtEnd));
57 | }
58 |
59 | public static boolean appendDirectToFile(File file, String data) {
60 | boolean retval = false;
61 | FileWriter fw = null;
62 | try {
63 | fw = new FileWriter(file, true);
64 | fw.write(data);
65 | fw.write("\n");
66 | retval = true;
67 | } catch (IOException e) {
68 | retval = false;
69 | e.printStackTrace();
70 | } finally {
71 | if (null != fw) {
72 | try {
73 | fw.close();
74 | } catch (IOException e) {
75 | System.out.println(e);
76 | }
77 | }
78 | }
79 | return retval;
80 | }
81 |
82 | public static int getNoOfLinesInFile(File file) {
83 | int lines = 0;
84 | FileReader f = null;
85 | BufferedReader reader = null;
86 | try {
87 | f = new FileReader(file);
88 | reader = new BufferedReader(f);
89 | while (reader.readLine() != null) {
90 | lines++;
91 | }
92 | } catch (FileNotFoundException e) {
93 | e.printStackTrace();
94 | } catch (IOException e) {
95 | e.printStackTrace();
96 | } finally {
97 | if (null != reader) {
98 | try {
99 | reader.close();
100 | } catch (IOException e) {
101 | e.printStackTrace();
102 | }
103 | }
104 | if (null != f) {
105 | try {
106 | f.close();
107 | } catch (IOException e) {
108 | e.printStackTrace();
109 | }
110 | }
111 | }
112 | return lines;
113 | }
114 |
115 | @SuppressWarnings("serial")
116 | public static class CircularQueue extends LinkedList {
117 | private int limit;
118 |
119 | public CircularQueue(int limit) {
120 | this.limit = limit;
121 | }
122 |
123 | @Override
124 | public boolean add(E o) {
125 | super.add(o);
126 | while (size() > limit) { super.remove(); }
127 | return true;
128 | }
129 | }
130 |
131 | public static boolean isMac() {
132 | String OS = System.getProperty("os.name").toLowerCase();
133 | return (OS.indexOf("mac") >= 0);
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/test/resources/dbfiles/instances.json:
--------------------------------------------------------------------------------
1 | {"schemaVersion":"1.0"}
2 | {"id":"01","hostname":"ec2-54-191-01","privateKey":"Zf9vl5K6WV6BA3eL7JbnrfPMjfJxc9Rkoo0zlROQlgTslmcp9iFzos+MP93GZqop","publicKey":"d3aa045f71bf4d1dffd2c5f485a4bc1d"}
3 | {"id":"02","hostname":"ec2-54-191-05","privateKey":"Zf9vl5K6WV6BA3eL7JbnrfPMjfJxc9Rkoo0zlROQlgTslmcp9iFzos+MP93GZqop","publicKey":"d3aa045f71bf4d1dffd2c5f485a4bc1d"}
4 | {"id":"03","hostname":"ec2-54-191-04","privateKey":"Zf9vl5K6WV6BA3eL7JbnrfPMjfJxc9Rkoo0zlROQlgTslmcp9iFzos+MP93GZqop","publicKey":"d3aa045f71bf4d1dffd2c5f485a4bc1d"}
5 | {"id":"04","hostname":"ec2-54-191-03","privateKey":"Zf9vl5K6WV6BA3eL7JbnrfPMjfJxc9Rkoo0zlROQlgTslmcp9iFzos+MP93GZqop","publicKey":"d3aa045f71bf4d1dffd2c5f485a4bc1d"}
6 | {"id":"05","hostname":"ec2-54-191-02","privateKey":"Zf9vl5K6WV6BA3eL7JbnrfPMjfJxc9Rkoo0zlROQlgTslmcp9iFzos+MP93GZqop","publicKey":"d3aa045f71bf4d1dffd2c5f485a4bc1d"}
7 | {"id":"06","hostname":"ec2-54-191-06","privateKey":"Zf9vl5K6WV6BA3eL7JbnrfPMjfJxc9Rkoo0zlROQlgTslmcp9iFzos+MP93GZqop","publicKey":""}
8 |
--------------------------------------------------------------------------------
/src/test/resources/dbfiles/loadbalancer.json:
--------------------------------------------------------------------------------
1 | {"schemaVersion":"0.5"}
2 | {"id":"001","hostname":"eclb-54-01","username":"admin","deletedField":"yes"}
3 | {"id":"002","hostname":"eclb-54-02","username":"admin","deletedField":"yes"}
4 | {"id":"003","hostname":"eclb-54-03","username":"admin","deletedField":"yes"}
5 | {"id":"004","hostname":"eclb-54-04","username":"admin","deletedField":"yes"}
6 | {"id":"005","hostname":"eclb-54-05","username":"admin","deletedField":"yes"}
7 | {"id":"006","hostname":"eclb-54-06","username":"admin","deletedField":"yes"}
8 | {"id":"007","hostname":"eclb-54-07","username":"admin","deletedField":"yes"}
9 | {"id":"008","hostname":"eclb-54-08","username":"admin","deletedField":"yes"}
10 | {"id":"009","hostname":"eclb-54-09","username":"admin","deletedField":"yes"}
11 | {"id":"010","hostname":"eclb-54-10","username":"admin","deletedField":"yes"}
--------------------------------------------------------------------------------
/src/test/resources/dbfiles/pojowithenumfields.json:
--------------------------------------------------------------------------------
1 | {"schemaVersion":"1.0"}
2 | {"id":"0001","status":"CREATED"}
3 | {"id":"0002","status":"COMPLETED"}
4 | {"id":"0003","status":"CONSUMED"}
5 | {"id":"0004","status":"UPDATED"}
--------------------------------------------------------------------------------