├── docs ├── images │ ├── favicon.ico │ ├── siddhi-logo.png │ ├── siddhi-logo-w.png │ ├── siddhi-logo.svg │ └── siddhi-logo-w.svg ├── javascripts │ └── extra.js ├── stylesheets │ └── extra.css ├── index.md ├── license.md └── api │ └── 1.0.10.md ├── component ├── src │ ├── test │ │ ├── resources │ │ │ ├── mongodb-client.jks │ │ │ ├── testngSecureSSL.xml │ │ │ └── testngStandalone.xml │ │ └── java │ │ │ └── org │ │ │ └── wso2 │ │ │ └── extension │ │ │ └── siddhi │ │ │ └── store │ │ │ └── mongodb │ │ │ ├── MongoTableTestUtils.java │ │ │ ├── ContainsMongoTableTest.java │ │ │ ├── MongoDBConnectionSSLTest.java │ │ │ ├── DeleteFromMongoTableTest.java │ │ │ ├── UpdateOrInsertMongoTableTest.java │ │ │ ├── JoinMongoTableTest.java │ │ │ └── UpdateMongoTableTest.java │ └── main │ │ └── java │ │ └── org │ │ └── wso2 │ │ └── extension │ │ └── siddhi │ │ └── store │ │ └── mongodb │ │ ├── exception │ │ └── MongoTableException.java │ │ ├── util │ │ ├── Constant.java │ │ └── MongoTableConstants.java │ │ ├── MongoCompiledCondition.java │ │ ├── MongoIterator.java │ │ ├── MongoSetExpressionVisitor.java │ │ └── MongoExpressionVisitor.java └── pom.xml ├── .gitignore ├── issue_template.md ├── mkdocs.yml ├── pull_request_template.md ├── coverage-reports └── pom.xml ├── pom.xml ├── README.md └── LICENSE /docs/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/this/siddhi-store-mongodb/master/docs/images/favicon.ico -------------------------------------------------------------------------------- /docs/images/siddhi-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/this/siddhi-store-mongodb/master/docs/images/siddhi-logo.png -------------------------------------------------------------------------------- /docs/images/siddhi-logo-w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/this/siddhi-store-mongodb/master/docs/images/siddhi-logo-w.png -------------------------------------------------------------------------------- /component/src/test/resources/mongodb-client.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/this/siddhi-store-mongodb/master/component/src/test/resources/mongodb-client.jks -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | -------------------------------------------------------------------------------- /component/src/test/resources/testngSecureSSL.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /issue_template.md: -------------------------------------------------------------------------------- 1 | **Description:** 2 | 3 | 4 | **Suggested Labels:** 5 | 6 | 7 | **Suggested Assignees:** 8 | 9 | 10 | **Affected Product Version:** 11 | 12 | **OS, DB, other environment details and versions:** 13 | 14 | **Steps to reproduce:** 15 | 16 | 17 | **Related Issues:** 18 | -------------------------------------------------------------------------------- /docs/javascripts/extra.js: -------------------------------------------------------------------------------- 1 | /* 2 | ~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | */ 16 | 17 | var logoTitle = document.querySelector('.md-logo').title; 18 | var extentionTitle = logoTitle.slice(7); 19 | var header = document.querySelector('.md-header-nav__title'); 20 | var headerContent = document.querySelectorAll('.md-header-nav__topic')[1].textContent.trim(); 21 | 22 | header.innerHTML = '' + extentionTitle + '' + headerContent; 23 | -------------------------------------------------------------------------------- /component/src/test/resources/testngStandalone.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /component/src/main/java/org/wso2/extension/siddhi/store/mongodb/exception/MongoTableException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb.exception; 19 | 20 | import org.wso2.siddhi.core.exception.SiddhiAppCreationException; 21 | 22 | /** 23 | * Represents an unchecked exception which may be thrown during runtime, from which we may not expect the Siddhi runtime 24 | * to recover. 25 | */ 26 | public class MongoTableException extends SiddhiAppCreationException { 27 | 28 | public MongoTableException(String message) { 29 | super(message); 30 | } 31 | 32 | public MongoTableException(String message, Throwable throwable) { 33 | super(message, throwable); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /docs/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | .md-header-nav__button.md-logo img { 20 | width: 140px; 21 | height: 33px; 22 | margin-right: 0; 23 | } 24 | 25 | .md-content__icon, 26 | .md-footer-nav__button, 27 | .md-header-nav__button, 28 | .md-nav__button, 29 | .md-nav__title::before, 30 | .md-search-result__article--document::before { 31 | margin: 0.3rem; 32 | padding: 0; 33 | } 34 | 35 | .extention-title { 36 | font-weight: 700; 37 | margin-right: 50px; 38 | } 39 | 40 | .md-header-nav__title { 41 | padding-left: 5px; 42 | } 43 | 44 | @media (max-width: 1219px) { 45 | 46 | .extention-title { 47 | display: none; 48 | } 49 | 50 | html .md-nav--primary .md-nav__title--site .md-nav__button { 51 | width: 13.4rem; 52 | } 53 | } -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Siddhi Store MongoDB 2 | site_description: Siddhi Store MongoDB Extension 3 | site_author: WSO2 4 | site_url: https://wso2-extensions.github.io/siddhi-store-mongodb/ 5 | extra_css: 6 | - stylesheets/extra.css 7 | extra_javascript: 8 | - javascripts/extra.js 9 | repo_name: Siddhi-Store-MongoDB 10 | repo_url: https://github.com/wso2-extensions/siddhi-store-mongodb 11 | copyright: Copyright © 2011 - 2018 WSO2 12 | theme: 13 | name: material 14 | logo: images/siddhi-logo-w.svg 15 | favicon: images/favicon.ico 16 | palette: 17 | primary: teal 18 | accent: teal 19 | google_analytics: 20 | - UA-103065-28 21 | - auto 22 | extra: 23 | social: 24 | - type: github 25 | link: https://github.com/wso2/siddhi 26 | - type: linkedin 27 | link: https://www.linkedin.com/groups/13553064 28 | markdown_extensions: 29 | - admonition 30 | - toc(permalink=true) 31 | - codehilite(guess_lang=false) 32 | pages: 33 | - Welcome: index.md 34 | - API Docs: 35 | - 1.0.21: api/1.0.21.md 36 | - 1.0.20: api/1.0.20.md 37 | - 1.0.19: api/1.0.19.md 38 | - 1.0.18: api/1.0.18.md 39 | - 1.0.17: api/1.0.17.md 40 | - 1.0.16: api/1.0.16.md 41 | - 1.0.15: api/1.0.15.md 42 | - 1.0.14: api/1.0.14.md 43 | - 1.0.13: api/1.0.13.md 44 | - 1.0.12: api/1.0.12.md 45 | - 1.0.11: api/1.0.11.md 46 | - 1.0.10: api/1.0.10.md 47 | - 1.0.9: api/1.0.9.md 48 | - 1.0.8: api/1.0.8.md 49 | - 1.0.7: api/1.0.7.md 50 | - latest: api/latest.md 51 | - License: license.md 52 | -------------------------------------------------------------------------------- /component/src/main/java/org/wso2/extension/siddhi/store/mongodb/util/Constant.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb.util; 19 | 20 | import org.wso2.siddhi.query.api.definition.Attribute; 21 | 22 | /** 23 | * Denotes a class which is used to keep track of constants which may be specified in Siddhi query conditions. 24 | * At compile-time, the constant is evaluated and finally resolved after the condition is built. 25 | */ 26 | public class Constant { 27 | private Object value; 28 | private Attribute.Type type; 29 | 30 | public Constant(Object value, Attribute.Type type) { 31 | this.value = value; 32 | this.type = type; 33 | } 34 | 35 | public Object getValue() { 36 | return value; 37 | } 38 | 39 | public Attribute.Type getType() { 40 | return type; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /component/src/main/java/org/wso2/extension/siddhi/store/mongodb/MongoCompiledCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb; 19 | 20 | import org.wso2.siddhi.core.util.collection.operator.CompiledCondition; 21 | 22 | import java.util.Map; 23 | 24 | /** 25 | * Implementation class of {@link CompiledCondition} corresponding to the MongoDB Event Table. 26 | * Maintains the condition string returned by the ConditionVisitor as well as a map of parameters to be used at runtime. 27 | */ 28 | public class MongoCompiledCondition implements CompiledCondition { 29 | 30 | private String compiledQuery; 31 | private Map placeholders; 32 | 33 | 34 | public MongoCompiledCondition(String compiledQuery, Map parameters) { 35 | this.compiledQuery = compiledQuery; 36 | this.placeholders = parameters; 37 | } 38 | 39 | @Override 40 | public CompiledCondition cloneCompilation(String key) { 41 | return null; 42 | } 43 | 44 | public String getCompiledQuery() { 45 | return compiledQuery; 46 | } 47 | 48 | public String toString() { 49 | return getCompiledQuery(); 50 | } 51 | 52 | public Map getPlaceholders() { 53 | return placeholders; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | > Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc. 3 | 4 | ## Goals 5 | > Describe the solutions that this feature/fix will introduce to resolve the problems described above 6 | 7 | ## Approach 8 | > Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here. 9 | 10 | ## User stories 11 | > Summary of user stories addressed by this change> 12 | 13 | ## Release note 14 | > Brief description of the new feature or bug fix as it will appear in the release notes 15 | 16 | ## Documentation 17 | > Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact 18 | 19 | ## Training 20 | > Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable 21 | 22 | ## Certification 23 | > Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why. 24 | 25 | ## Marketing 26 | > Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable 27 | 28 | ## Automation tests 29 | - Unit tests 30 | > Code coverage information 31 | - Integration tests 32 | > Details about the test cases and coverage 33 | 34 | ## Security checks 35 | - Followed secure coding standards in http://wso2.com/technical-reports/wso2-secure-engineering-guidelines? yes/no 36 | - Ran FindSecurityBugs plugin and verified report? yes/no 37 | - Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets? yes/no 38 | 39 | ## Samples 40 | > Provide high-level details about the samples related to this feature 41 | 42 | ## Related PRs 43 | > List any other related PRs 44 | 45 | ## Migrations (if applicable) 46 | > Describe migration steps and platforms on which migration has been tested 47 | 48 | ## Test environment 49 | > List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested 50 | 51 | ## Learning 52 | > Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem. -------------------------------------------------------------------------------- /component/src/main/java/org/wso2/extension/siddhi/store/mongodb/MongoIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb; 19 | 20 | import com.mongodb.client.FindIterable; 21 | import com.mongodb.client.MongoCursor; 22 | import org.bson.Document; 23 | import org.wso2.siddhi.core.table.record.RecordIterator; 24 | 25 | import java.io.IOException; 26 | import java.util.ArrayList; 27 | import java.util.HashMap; 28 | import java.util.List; 29 | 30 | /** 31 | * A class representing a RecordIterator which is responsible for processing MongoDB Event Table find() operations in a 32 | * streaming fashion. 33 | */ 34 | public class MongoIterator implements RecordIterator { 35 | private MongoCursor documents; 36 | private List attributeNames; 37 | 38 | private boolean preFetched; 39 | private Object[] nextDocument; 40 | 41 | public MongoIterator(FindIterable documents, List attributeNames) { 42 | this.documents = documents.iterator(); 43 | this.attributeNames = attributeNames; 44 | } 45 | 46 | @Override 47 | public boolean hasNext() { 48 | if (!this.preFetched) { 49 | this.nextDocument = this.next(); 50 | this.preFetched = true; 51 | } 52 | return this.nextDocument.length != 0; 53 | } 54 | 55 | @Override 56 | public Object[] next() { 57 | if (this.preFetched) { 58 | this.preFetched = false; 59 | Object[] result = this.nextDocument; 60 | this.nextDocument = null; 61 | return result; 62 | } 63 | if (this.documents.hasNext()) { 64 | return this.extractRecord((Document) this.documents.next()); 65 | } else { 66 | return new Object[0]; 67 | } 68 | } 69 | 70 | /** 71 | * Method which is used for extracting record values (in the form of an Object array) from a 72 | * MongoDB {@link Document}, according to the table's field type order. 73 | * 74 | * @param document the {@link Document} from which the values should be retrieved. 75 | * @return an array of extracted values, all cast to {@link Object} type for portability. 76 | */ 77 | private Object[] extractRecord(Document document) { 78 | List result = new ArrayList<>(); 79 | for (String attributeName : this.attributeNames) { 80 | Object attributeValue = document.get(attributeName); 81 | if (attributeValue instanceof Document) { 82 | HashMap attributAsAMap = new HashMap<>(); 83 | ((Document) attributeValue).forEach(attributAsAMap::put); 84 | result.add(attributAsAMap); 85 | } else { 86 | result.add(attributeValue); 87 | } 88 | } 89 | return result.toArray(); 90 | } 91 | 92 | @Override 93 | public void close() throws IOException { 94 | 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /docs/images/siddhi-logo.svg: -------------------------------------------------------------------------------- 1 | 18 | 19 | -------------------------------------------------------------------------------- /coverage-reports/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | siddhi-store-mongodb-parent 5 | org.wso2.extension.siddhi.store.mongodb 6 | 1.0.22-SNAPSHOT 7 | ../pom.xml 8 | 9 | 4.0.0 10 | 11 | coverage-reports 12 | 13 | 14 | 15 | test-coverage-report-aggregation 16 | 17 | false 18 | 19 | 20 | 21 | 22 | org.apache.maven.plugins 23 | maven-dependency-plugin 24 | 25 | 26 | copy-jacoco-dependencies 27 | compile 28 | 29 | copy-dependencies 30 | 31 | 32 | ${project.build.directory} 33 | jar 34 | org.jacoco.ant 35 | true 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-antrun-plugin 44 | 45 | 46 | package 47 | 48 | run 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | org.jacoco 82 | org.jacoco.ant 83 | ${jacoco.ant.version} 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | ../component 93 | 94 | 95 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 4.0.0 21 | 22 | org.wso2 23 | wso2 24 | 5 25 | 26 | 27 | org.wso2.extension.siddhi.store.mongodb 28 | siddhi-store-mongodb-parent 29 | 1.0.22-SNAPSHOT 30 | pom 31 | WSO2 Siddhi Store Mongodb Extension Parent 32 | https://github.com/wso2-extensions/siddhi-store-mongodb 33 | 34 | 35 | 36 | default 37 | 38 | true 39 | 40 | 41 | component 42 | coverage-reports 43 | 44 | 45 | 46 | 47 | 48 | 4.2.17 49 | [4.1.38,5.0) 50 | 4.12 51 | 1.1.1 52 | [1.1.1,2.0) 53 | 6.11 54 | 3.4.2 55 | 0.21.0 56 | 0.7.9 57 | 0.7.9 58 | UTF-8 59 | UTF-8 60 | 61 | 62 | 63 | scm:git:https://github.com/wso2-extensions/siddhi-store-mongodb.git 64 | https://github.com/wso2-extensions/siddhi-store-mongodb.git 65 | scm:git:https://github.com/wso2-extensions/siddhi-store-mongodb.git 66 | HEAD 67 | 68 | 69 | 70 | 71 | 72 | org.wso2.siddhi 73 | siddhi-core 74 | ${siddhi.version} 75 | 76 | 77 | org.wso2.siddhi 78 | siddhi-query-api 79 | ${siddhi.version} 80 | 81 | 82 | commons-logging 83 | commons-logging 84 | ${commons.logging.version} 85 | 86 | 87 | org.mongodb 88 | mongodb-driver 89 | ${mongodb.driver.version} 90 | 91 | 92 | org.testng 93 | testng 94 | ${testng.version} 95 | test 96 | 97 | 98 | org.jacoco 99 | org.jacoco.ant 100 | ${jacoco.ant.version} 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | org.jacoco 109 | jacoco-maven-plugin 110 | ${jacoco.plugin.version} 111 | 112 | 113 | 114 | 115 | 116 | 117 | org.apache.maven.plugins 118 | maven-release-plugin 119 | 120 | clean install -Pdocumentation-deploy 121 | true 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /component/src/main/java/org/wso2/extension/siddhi/store/mongodb/util/MongoTableConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb.util; 19 | 20 | /** 21 | * Class which holds the constants required by the MongoDB Event Table implementation. 22 | */ 23 | public class MongoTableConstants { 24 | 25 | //Annotation field names 26 | public static final String ANNOTATION_ELEMENT_URI = "mongodb.uri"; 27 | public static final String ANNOTATION_ELEMENT_COLLECTION_NAME = "collection.name"; 28 | public static final String ANNOTATION_ELEMENT_KEYSTORE = "key.store"; 29 | public static final String ANNOTATION_ELEMENT_STOREPASS = "key.store.password"; 30 | public static final String ANNOTATION_ELEMENT_TRUSTSTORE = "trust.store"; 31 | public static final String ANNOTATION_ELEMENT_TRUSTSTOREPASS = "trust.store.password"; 32 | public static final String ANNOTATION_ELEMENT_SECURE_CONNECTION = "secure.connection"; 33 | 34 | //Mongo Operators 35 | public static final String MONGO_COMPARE_LESS_THAN = "$lt"; 36 | public static final String MONGO_COMPARE_GREATER_THAN = "$gt"; 37 | public static final String MONGO_COMPARE_LESS_THAN_EQUAL = "$lte"; 38 | public static final String MONGO_COMPARE_GREATER_THAN_EQUAL = "$gte"; 39 | public static final String MONGO_COMPARE_EQUAL = "$eq"; 40 | public static final String MONGO_COMPARE_NOT_EQUAL = "$ne"; 41 | public static final String MONGO_NOT = "$not"; 42 | 43 | //Regex for comparing operands 44 | public static final String REG_EXPRESSION = "\\{.*}$"; 45 | public static final String REG_SIMPLE_EXPRESSION = "^\\{(\\S*):\\{.*}}$"; 46 | public static final String REG_STREAMVAR_OR_CONST = "^strVar\\d*|^const\\d*"; 47 | public static final String REG_INDEX_BY = "^(\\S*)(\\s1|\\s-1)?(\\s\\{.*})?$"; 48 | 49 | //Mongo filters for condition builder 50 | public static final String MONGO_AND_FILTER = "{$and:[{{LEFT_OPERAND}},{{RIGHT_OPERAND}}]}"; 51 | public static final String MONGO_OR_FILTER = "{$or:[{{LEFT_OPERAND}},{{RIGHT_OPERAND}}]}"; 52 | public static final String MONGO_NOT_FILTER = "{{{FIELD_NAME}}:{{OPERAND}}}"; 53 | public static final String MONGO_COMPARE_FILTER = "{{{LEFT_OPERAND}}:{{{COMPARE_OPERATOR}}:{{RIGHT_OPERAND}}}}"; 54 | public static final String MONGO_IS_NULL_FILTER = "{{{OPERAND}}:{$eq:null}}"; 55 | 56 | //Placeholders for condition replacements 57 | public static final String PLACEHOLDER_LEFT_OPERAND = "{{LEFT_OPERAND}}"; 58 | public static final String PLACEHOLDER_RIGHT_OPERAND = "{{RIGHT_OPERAND}}"; 59 | public static final String PLACEHOLDER_OPERAND = "{{OPERAND}}"; 60 | public static final String PLACEHOLDER_FIELD_NAME = "{{FIELD_NAME}}"; 61 | public static final String PLACEHOLDER_COMPARE_OPERATOR = "{{COMPARE_OPERATOR}}"; 62 | 63 | public static final String CONNECTIONS_PER_HOST = "connectionsPerHost"; 64 | public static final String HEARTBEAT_SOCKET_TIMEOUT = "heartbeatSocketTimeout"; 65 | public static final String CONNECT_TIMEOUT = "connectTimeout"; 66 | public static final String HEARTBEAT_FREQUENCY = "heartbeatFrequency"; 67 | public static final String READ_CONCERN = "readConcern"; 68 | public static final String WRITE_CONCERN = "writeConcern"; 69 | public static final String HEARTBEAT_CONNECT_TIMEOUT = "heartbeatConnectTimeout"; 70 | public static final String LOCAL_THRESHOLD = "localThreshold"; 71 | public static final String MAX_CONNECTION_IDLE_TIME = "maxConnectionIdleTime"; 72 | public static final String MAX_CONNECTION_LIFE_TIME = "maxConnectionLifeTime"; 73 | public static final String MAX_WAIT_TIME = "maxWaitTime"; 74 | public static final String MIN_CONNECTIONS_PER_HOST = "minConnectionsPerHost"; 75 | public static final String MIN_HEARTBEAT_FREQUENCY = "minHeartbeatFrequency"; 76 | public static final String SERVER_SELECTION_TIMEOUT = "serverSelectionTimeout"; 77 | public static final String SOCKET_TIMEOUT = "socketTimeout"; 78 | public static final String THREADS_ALLOWED_TO_BLOCK = "threadsAllowedToBlockForConnectionMultiplier"; 79 | public static final String SOCKET_KEEP_ALIVE = "socketKeepAlive"; 80 | public static final String SSL_ENABLED = "sslEnabled"; 81 | public static final String CURSOR_FINALIZER_ENABLED = "cursorFinalizerEnabled"; 82 | public static final String REQUIRED_REPLICA_SET_NAME = "requiredReplicaSetName"; 83 | public static final String APPLICATION_NAME = "applicationName"; 84 | public static final String READ_PREFERENCE = "readPreference"; 85 | 86 | public static final String DEFAULT_TRUST_STORE_FILE = "${carbon.home}/resources/security/client-truststore.jks"; 87 | public static final String DEFAULT_TRUST_STORE_PASSWORD = "wso2carbon"; 88 | public static final String DEFAULT_KEY_STORE_FILE = "${carbon.home}/resources/security/client-truststore.jks"; 89 | public static final String DEFAULT_KEY_STORE_PASSWORD = "wso2carbon"; 90 | public static final String VARIABLE_CARBON_HOME = "carbon.home"; 91 | 92 | private MongoTableConstants() { 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | siddhi-store-mongodb 2 | ====================================== 3 | 4 | The **siddhi-store-mongodb extension** is an extension to Siddhi that can be used to persist events to a MongoDB instance of the users choice. 5 | Find some useful links below: 6 | 7 | * Source code 8 | * Releases 9 | * Issue tracker 10 | 11 | ## Latest API Docs 12 | 13 | Latest API Docs is 1.0.21. 14 | 15 | ## Prerequisites 16 | 17 | * A MongoDB server instance should be started. 18 | * User should have the necessary privileges and access rights to connect to the MongoDB data store of choice. 19 | 20 | ## How to use 21 | 22 | **Using the extension in WSO2 Stream Processor** 23 | 24 | * You can use this extension in the latest WSO2 Stream Processor that is a part of WSO2 Analytics offering, with editor, debugger and simulation support. 25 | 26 | * This extension is shipped by default with WSO2 Stream Processor, if you wish to use an alternative version of this extension you can replace the component jar that can be found in the `/lib` directory. 27 | 28 | **Using the extension as a java library** 29 | 30 | * This extension can be added as a maven dependency along with other Siddhi dependencies to your project. 31 | 32 | ``` 33 | 34 | org.wso2.extension.siddhi.store.mongodb 35 | siddhi-store-mongodb 36 | x.x.x 37 | 38 | ``` 39 | 40 | ## Running Integration tests in docker containers(Optional) 41 | 42 | The MongoDB functionality are tested with the docker base integration test framework. The test framework initializes the docker container according to the given profile before executing the test suite. 43 | 44 | 1. Install and run docker in daemon mode. 45 | 46 | * Installing docker on Linux,
47 | Note:
These commands retrieve content from get.docker.com web in a quiet output-document mode and install.Then we need to stop docker service as it needs to restart docker in daemon mode. After that, we need to export docker daemon host. 48 | 49 | wget -qO- https://get.docker.com/ | sh 50 | sudo service dockerd stop 51 | export DOCKER_HOST=tcp://172.17.0.1:4326 52 | docker daemon -H tcp://172.17.0.1:4326 53 | 54 | * On installing docker on Mac, see Get started with Docker for Mac 55 | 56 | * On installing docker on Windows, see Get started with Docker for Windows 57 | 58 | 2. To run the integration tests, issue the following commands. 59 | 60 | * MongoDB without SSL connection 61 | 62 | mvn verify -P mongod -Ddocker.removeVolumes=true 63 | 64 | * MongoDB with SSL connection 65 | 66 | mvn verify -P mongod-ssl -Ddocker.removeVolumes=true 67 | 68 | ## Jenkins Build Status 69 | 70 | --- 71 | 72 | | Branch | Build Status | 73 | | :------ |:------------ | 74 | | master | [![Build Status](https://wso2.org/jenkins/job/siddhi/job/siddhi-store-mongodb/badge/icon)](https://wso2.org/jenkins/job/siddhi/job/siddhi-store-mongodb/) | 75 | 76 | --- 77 | 78 | ## Features 79 | 80 | * mongodb *(Store)*

Using this extension a MongoDB Event Table can be configured to persist events in a MongoDB of user's choice.

81 | 82 | ## How to Contribute 83 | 84 | * Please report issues at GitHub Issue Tracker. 85 | 86 | * Send your contributions as pull requests to master branch. 87 | 88 | ## Contact us 89 | 90 | * Post your questions with the "Siddhi" tag in Stackoverflow. 91 | 92 | * Siddhi developers can be contacted via the mailing lists: 93 | 94 | Developers List : [dev@wso2.org](mailto:dev@wso2.org) 95 | 96 | Architecture List : [architecture@wso2.org](mailto:architecture@wso2.org) 97 | 98 | ## Support 99 | 100 | * We are committed to ensuring support for this extension in production. Our unique approach ensures that all support leverages our open development methodology and is provided by the very same engineers who build the technology. 101 | 102 | * For more details and to take advantage of this unique opportunity contact us via http://wso2.com/support/. 103 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | siddhi-store-mongodb 2 | ====================================== 3 | 4 | The **siddhi-store-mongodb extension** is an extension to Siddhi that can be used to persist events to a MongoDB instance of the users choice. 5 | Find some useful links below: 6 | 7 | * Source code 8 | * Releases 9 | * Issue tracker 10 | 11 | ## Latest API Docs 12 | 13 | Latest API Docs is 1.0.21. 14 | 15 | ## Prerequisites 16 | 17 | * A MongoDB server instance should be started. 18 | * User should have the necessary privileges and access rights to connect to the MongoDB data store of choice. 19 | 20 | ## How to use 21 | 22 | **Using the extension in WSO2 Stream Processor** 23 | 24 | * You can use this extension in the latest WSO2 Stream Processor that is a part of WSO2 Analytics offering, with editor, debugger and simulation support. 25 | 26 | * This extension is shipped by default with WSO2 Stream Processor, if you wish to use an alternative version of this extension you can replace the component jar that can be found in the `/lib` directory. 27 | 28 | **Using the extension as a java library** 29 | 30 | * This extension can be added as a maven dependency along with other Siddhi dependencies to your project. 31 | 32 | ``` 33 | 34 | org.wso2.extension.siddhi.store.mongodb 35 | siddhi-store-mongodb 36 | x.x.x 37 | 38 | ``` 39 | 40 | ## Running Integration tests in docker containers(Optional) 41 | 42 | The MongoDB functionality are tested with the docker base integration test framework. The test framework initializes the docker container according to the given profile before executing the test suite. 43 | 44 | 1. Install and run docker in daemon mode. 45 | 46 | * Installing docker on Linux,
47 | Note:
These commands retrieve content from get.docker.com web in a quiet output-document mode and install.Then we need to stop docker service as it needs to restart docker in daemon mode. After that, we need to export docker daemon host. 48 | 49 | wget -qO- https://get.docker.com/ | sh 50 | sudo service dockerd stop 51 | export DOCKER_HOST=tcp://172.17.0.1:4326 52 | docker daemon -H tcp://172.17.0.1:4326 53 | 54 | * On installing docker on Mac, see Get started with Docker for Mac 55 | 56 | * On installing docker on Windows, see Get started with Docker for Windows 57 | 58 | 2. To run the integration tests, issue the following commands. 59 | 60 | * MongoDB without SSL connection 61 | 62 | mvn verify -P mongod -Ddocker.removeVolumes=true 63 | 64 | * MongoDB with SSL connection 65 | 66 | mvn verify -P mongod-ssl -Ddocker.removeVolumes=true 67 | 68 | ## Jenkins Build Status 69 | 70 | --- 71 | 72 | | Branch | Build Status | 73 | | :------ |:------------ | 74 | | master | [![Build Status](https://wso2.org/jenkins/job/siddhi/job/siddhi-store-mongodb/badge/icon)](https://wso2.org/jenkins/job/siddhi/job/siddhi-store-mongodb/) | 75 | 76 | --- 77 | 78 | ## Features 79 | 80 | * mongodb *(Store)*

Using this extension a MongoDB Event Table can be configured to persist events in a MongoDB of user's choice.

81 | 82 | ## How to Contribute 83 | 84 | * Please report issues at GitHub Issue Tracker. 85 | 86 | * Send your contributions as pull requests to master branch. 87 | 88 | ## Contact us 89 | 90 | * Post your questions with the "Siddhi" tag in Stackoverflow. 91 | 92 | * Siddhi developers can be contacted via the mailing lists: 93 | 94 | Developers List : [dev@wso2.org](mailto:dev@wso2.org) 95 | 96 | Architecture List : [architecture@wso2.org](mailto:architecture@wso2.org) 97 | 98 | ## Support 99 | 100 | * We are committed to ensuring support for this extension in production. Our unique approach ensures that all support leverages our open development methodology and is provided by the very same engineers who build the technology. 101 | 102 | * For more details and to take advantage of this unique opportunity contact us via http://wso2.com/support/. 103 | -------------------------------------------------------------------------------- /docs/images/siddhi-logo-w.svg: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 35 | 37 | 38 | 40 | image/svg+xml 41 | 43 | 44 | 45 | 46 | 48 | 68 | 72 | 76 | 77 | 82 | 87 | 91 | 95 | 99 | 100 | 104 | 108 | 109 | 113 | 117 | 121 | 122 | 127 | 132 | 136 | 140 | 144 | 145 | 149 | 153 | 154 | 158 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /component/src/test/java/org/wso2/extension/siddhi/store/mongodb/MongoTableTestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.extension.siddhi.store.mongodb; 20 | 21 | import com.mongodb.MongoClient; 22 | import com.mongodb.MongoClientURI; 23 | import com.mongodb.MongoException; 24 | import com.mongodb.client.ListIndexesIterable; 25 | import org.apache.commons.logging.Log; 26 | import org.apache.commons.logging.LogFactory; 27 | import org.bson.Document; 28 | 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | import java.util.function.Consumer; 32 | 33 | public class MongoTableTestUtils { 34 | 35 | private static final Log log = LogFactory.getLog(MongoTableTestUtils.class); 36 | private static final String MONGO_CLIENT_URI = 37 | "mongodb://{{mongo.credentials}}{{mongo.servers}}/{{mongo.database}}"; 38 | private static String databaseName = "admin"; 39 | 40 | private MongoTableTestUtils() { 41 | } 42 | 43 | public static String resolveBaseUri(String uri) { 44 | return uri 45 | .replace("{{mongo.credentials}}", getMongoCredentials()) 46 | .replace("{{mongo.servers}}", getAddressOfContainers()) 47 | .replace("{{mongo.database}}", getMongoDatabaseName()); 48 | } 49 | 50 | public static String resolveBaseUri() { 51 | return resolveBaseUri(MONGO_CLIENT_URI); 52 | } 53 | 54 | private static String getAddressOfContainers() { 55 | String mongoServers = System.getProperty("mongo.servers"); 56 | if (!isEmpty(mongoServers)) { 57 | return mongoServers; 58 | } else { 59 | return "172.17.0.2:27017"; 60 | } 61 | } 62 | 63 | private static String getMongoCredentials() { 64 | String mongoUsername = System.getProperty("mongo.username"); 65 | String mongoPassword = System.getProperty("mongo.password"); 66 | if (!isEmpty(mongoUsername) && !isEmpty(mongoPassword)) { 67 | return mongoUsername + ":" + mongoPassword + "@"; 68 | } else { 69 | if (!isEmpty(mongoUsername)) { 70 | return mongoUsername + "@"; 71 | } 72 | return ""; 73 | } 74 | } 75 | 76 | private static String getMongoDatabaseName() { 77 | String mongoDatabaseName = System.getProperty("mongo.database.name"); 78 | if (!isEmpty(mongoDatabaseName)) { 79 | databaseName = mongoDatabaseName; 80 | } 81 | return databaseName; 82 | } 83 | 84 | private static boolean isEmpty(String field) { 85 | return (field == null || field.trim().length() == 0); 86 | } 87 | 88 | public static void dropCollection(String uri, String collectionName) { 89 | try (MongoClient mongoClient = new MongoClient(new MongoClientURI(uri))) { 90 | mongoClient.getDatabase(databaseName).getCollection(collectionName).drop(); 91 | } catch (MongoException e) { 92 | log.debug("Clearing DB collection failed due to " + e.getMessage(), e); 93 | throw e; 94 | } 95 | } 96 | 97 | public static long getDocumentsCount(String uri, String collectionName) { 98 | try (MongoClient mongoClient = new MongoClient(new MongoClientURI(uri))) { 99 | return mongoClient.getDatabase(databaseName).getCollection(collectionName).count(); 100 | } catch (MongoException e) { 101 | log.debug("Getting rows in DB table failed due to " + e.getMessage(), e); 102 | throw e; 103 | } 104 | } 105 | 106 | public static boolean doesCollectionExists(String uri, String customCollectionName) { 107 | try (MongoClient mongoClient = new MongoClient(new MongoClientURI(uri))) { 108 | for (String collectionName : mongoClient.getDatabase(databaseName).listCollectionNames()) { 109 | if (customCollectionName.equals(collectionName)) { 110 | return true; 111 | } 112 | } 113 | return false; 114 | } catch (MongoException e) { 115 | log.debug("Checking whether collection was created failed due to" + e.getMessage(), e); 116 | throw e; 117 | } 118 | } 119 | 120 | private static List getIndexList(String uri, String collectionName) { 121 | try (MongoClient mongoClient = new MongoClient(new MongoClientURI(uri))) { 122 | ListIndexesIterable existingIndexesIterable = 123 | mongoClient.getDatabase(databaseName).getCollection(collectionName).listIndexes(); 124 | List existingIndexDocuments = new ArrayList<>(); 125 | existingIndexesIterable.forEach((Consumer) existingIndex -> { 126 | existingIndex.remove("ns"); 127 | existingIndexDocuments.add(existingIndex); 128 | }); 129 | return existingIndexDocuments; 130 | } catch (MongoException e) { 131 | log.debug("Getting indexes in DB table failed due to " + e.getMessage(), e); 132 | throw e; 133 | } 134 | } 135 | 136 | public static Document getIndex(String uri, String collectionName, String indexName) { 137 | try { 138 | List existingIndexList = getIndexList(uri, collectionName); 139 | for (Document existingIndex : existingIndexList) { 140 | if (existingIndex.get("name").equals(indexName)) { 141 | return existingIndex; 142 | } 143 | } 144 | return null; 145 | } catch (MongoException e) { 146 | log.debug("Getting indexes in DB table failed due to " + e.getMessage(), e); 147 | throw e; 148 | } 149 | } 150 | 151 | public static Document getDocument(String uri, String collectionName, String findFilter) { 152 | try (MongoClient mongoClient = new MongoClient(new MongoClientURI(uri))) { 153 | Document findFilterDocument = Document.parse(findFilter); 154 | Document firstFind = mongoClient.getDatabase(databaseName).getCollection(collectionName) 155 | .find(findFilterDocument).first(); 156 | firstFind.remove("_id"); 157 | return firstFind; 158 | } catch (MongoException e) { 159 | log.debug("Getting indexes in DB table failed due to " + e.getMessage(), e); 160 | throw e; 161 | } 162 | } 163 | 164 | public static void createCollection(String uri, String collectionName) { 165 | dropCollection(uri, collectionName); 166 | try (MongoClient mongoClient = new MongoClient(new MongoClientURI(uri))) { 167 | mongoClient.getDatabase(databaseName).createCollection(collectionName); 168 | } catch (MongoException e) { 169 | log.debug("Getting indexes in DB table failed due to " + e.getMessage(), e); 170 | throw e; 171 | } 172 | } 173 | } 174 | 175 | 176 | -------------------------------------------------------------------------------- /component/src/test/java/org/wso2/extension/siddhi/store/mongodb/ContainsMongoTableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb; 19 | 20 | import org.apache.commons.logging.Log; 21 | import org.apache.commons.logging.LogFactory; 22 | import org.testng.Assert; 23 | import org.testng.annotations.AfterClass; 24 | import org.testng.annotations.BeforeClass; 25 | import org.testng.annotations.BeforeMethod; 26 | import org.testng.annotations.Test; 27 | import org.wso2.siddhi.core.SiddhiAppRuntime; 28 | import org.wso2.siddhi.core.SiddhiManager; 29 | import org.wso2.siddhi.core.event.Event; 30 | import org.wso2.siddhi.core.stream.input.InputHandler; 31 | import org.wso2.siddhi.core.stream.output.StreamCallback; 32 | import org.wso2.siddhi.core.util.SiddhiTestHelper; 33 | 34 | import java.util.concurrent.atomic.AtomicInteger; 35 | 36 | 37 | public class ContainsMongoTableTest { 38 | 39 | private static final Log log = LogFactory.getLog(ContainsMongoTableTest.class); 40 | 41 | private static String uri = MongoTableTestUtils.resolveBaseUri(); 42 | private AtomicInteger eventCount = new AtomicInteger(0); 43 | private int waitTime = 50; 44 | private int timeout = 30000; 45 | 46 | @BeforeClass 47 | public void init() { 48 | log.info("== MongoDB Collection IN tests started =="); 49 | } 50 | 51 | @AfterClass 52 | public void shutdown() { 53 | log.info("== MongoDB Collection IN tests completed =="); 54 | } 55 | 56 | @BeforeMethod 57 | public void testInit() { 58 | eventCount.set(0); 59 | } 60 | 61 | @Test 62 | public void containsMongoTableTest1() throws InterruptedException { 63 | log.info("containsMongoTableTest1 - " + 64 | "DASC5-911:Configure siddhi to check whether particular records exist in a MongoDB Collection"); 65 | 66 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 67 | 68 | SiddhiManager siddhiManager = new SiddhiManager(); 69 | String streams = "" + 70 | "define stream StockStream (symbol string, price float, volume long); " + 71 | " " + 72 | "define stream FooStream (symbol string, price float, volume long);" + 73 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 74 | "define table FooTable (symbol string, price float, volume long);"; 75 | String query = "" + 76 | "@info(name = 'query1') " + 77 | "from StockStream " + 78 | "insert into FooTable ;" + 79 | 80 | "@info(name='query2')" + 81 | "from FooStream[(FooTable.symbol == symbol) in FooTable]" + 82 | "insert into OutputStream ;"; 83 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 84 | 85 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 86 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 87 | siddhiAppRuntime.addCallback("OutputStream", new StreamCallback() { 88 | @Override 89 | public void receive(Event[] events) { 90 | if (events != null) { 91 | for (Event event : events) { 92 | eventCount.incrementAndGet(); 93 | switch (eventCount.intValue()) { 94 | case 1: 95 | Assert.assertEquals(new Object[]{"WSO2", 5.56, 200}, event.getData()); 96 | break; 97 | case 2: 98 | Assert.assertEquals(new Object[]{"IBM", 7.56, 200}, event.getData()); 99 | break; 100 | default: 101 | break; 102 | } 103 | } 104 | } 105 | } 106 | }); 107 | siddhiAppRuntime.start(); 108 | 109 | stockStream.send(new Object[]{"WSO2", 55.6F, 100L}); 110 | stockStream.send(new Object[]{"IBM", 75.6F, 100L}); 111 | stockStream.send(new Object[]{"WSO2_2", 57.6F, 100L}); 112 | fooStream.send(new Object[]{"WSO2", 5.56, 200}); 113 | fooStream.send(new Object[]{"IBM", 7.56, 200}); 114 | fooStream.send(new Object[]{"IBM_2", 70.56, 200}); 115 | SiddhiTestHelper.waitForEvents(waitTime, 2, eventCount, timeout); 116 | 117 | siddhiAppRuntime.shutdown(); 118 | 119 | Assert.assertEquals(eventCount.intValue(), 2, "Number of success events"); 120 | } 121 | 122 | @Test 123 | public void containsMongoTableTest2() throws InterruptedException { 124 | log.info("containsMongoTableTest2 - " + 125 | "DASC5-912:Configure siddhi to check whether record exist when OutputStream is already exists"); 126 | 127 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 128 | 129 | SiddhiManager siddhiManager = new SiddhiManager(); 130 | String streams = "" + 131 | "define stream StockStream (symbol string, price float, volume long); " + 132 | "@source(type='inMemory') " + 133 | "define stream FooStream (symbol string, price float, volume long);" + 134 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 135 | "define table FooTable (symbol string, price float, volume long);" + 136 | "@source(type='inMemory')" + 137 | "define stream OutputStream (symbol string, price float, volume long);"; 138 | String query = "" + 139 | "@info(name = 'query1') " + 140 | "from StockStream " + 141 | "insert into FooTable ;" + 142 | "@info(name='query2')" + 143 | "from FooStream[(FooTable.symbol == symbol) in FooTable]" + 144 | "insert into OutputStream ;"; 145 | 146 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 147 | 148 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 149 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 150 | siddhiAppRuntime.addCallback("OutputStream", new StreamCallback() { 151 | @Override 152 | public void receive(Event[] events) { 153 | if (events != null) { 154 | for (Event event : events) { 155 | eventCount.incrementAndGet(); 156 | switch (eventCount.intValue()) { 157 | case 1: 158 | Assert.assertEquals(new Object[]{"WSO2", 50.56, 200}, event.getData()); 159 | break; 160 | case 2: 161 | Assert.assertEquals(new Object[]{"IBM", 70.56, 200}, event.getData()); 162 | break; 163 | default: 164 | Assert.assertEquals(new Object[]{}, event.getData()); 165 | break; 166 | } 167 | } 168 | } 169 | } 170 | }); 171 | siddhiAppRuntime.start(); 172 | 173 | stockStream.send(new Object[]{"WSO2", 55.6F, 100L}); 174 | stockStream.send(new Object[]{"IBM", 75.6F, 100L}); 175 | stockStream.send(new Object[]{"WSO2_2", 57.6F, 100L}); 176 | fooStream.send(new Object[]{"WSO2", 50.56, 200}); 177 | fooStream.send(new Object[]{"IBM", 70.56, 200}); 178 | fooStream.send(new Object[]{"IBM_2", 70.56, 200}); 179 | SiddhiTestHelper.waitForEvents(waitTime, 2, eventCount, timeout); 180 | 181 | siddhiAppRuntime.shutdown(); 182 | 183 | Assert.assertEquals(eventCount.intValue(), 2, "Number of success events"); 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /component/src/main/java/org/wso2/extension/siddhi/store/mongodb/MongoSetExpressionVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb; 19 | 20 | import org.wso2.extension.siddhi.store.mongodb.exception.MongoTableException; 21 | import org.wso2.extension.siddhi.store.mongodb.util.Constant; 22 | import org.wso2.siddhi.core.table.record.BaseExpressionVisitor; 23 | import org.wso2.siddhi.query.api.definition.Attribute; 24 | import org.wso2.siddhi.query.api.expression.condition.Compare; 25 | 26 | import java.util.HashMap; 27 | import java.util.Map; 28 | import java.util.Stack; 29 | 30 | /** 31 | * Class which is used by the Siddhi runtime for instructions on converting the SiddhiQL condition to the condition 32 | * format understood by the MongoDB. 33 | */ 34 | public class MongoSetExpressionVisitor extends BaseExpressionVisitor { 35 | private Stack conditionOperands; 36 | private Map placeholders; 37 | 38 | private int streamVarCount; 39 | private int constantCount; 40 | 41 | public MongoSetExpressionVisitor() { 42 | this.streamVarCount = 0; 43 | this.constantCount = 0; 44 | this.conditionOperands = new Stack<>(); 45 | this.placeholders = new HashMap<>(); 46 | } 47 | 48 | public String getCompiledCondition() { 49 | String compiledCondition = this.conditionOperands.pop(); 50 | for (Map.Entry entry : this.placeholders.entrySet()) { 51 | if (entry.getValue() instanceof Constant) { 52 | Constant constant = (Constant) entry.getValue(); 53 | if (constant.getType().equals(Attribute.Type.STRING)) { 54 | compiledCondition = compiledCondition.replaceAll(entry.getKey(), 55 | "'" + constant.getValue().toString() + "'"); 56 | } else { 57 | compiledCondition = compiledCondition.replaceAll(entry.getKey(), 58 | constant.getValue().toString()); 59 | } 60 | this.placeholders.remove(entry.getKey()); 61 | } 62 | } 63 | return compiledCondition; 64 | } 65 | 66 | public Map getPlaceholders() { 67 | return placeholders; 68 | } 69 | 70 | @Override 71 | public void beginVisitAnd() { 72 | } 73 | 74 | @Override 75 | public void endVisitAnd() { 76 | throw new MongoTableException("MongoDB Event Table does not support SET function."); 77 | } 78 | 79 | @Override 80 | public void beginVisitAndLeftOperand() { 81 | } 82 | 83 | @Override 84 | public void endVisitAndLeftOperand() { 85 | } 86 | 87 | @Override 88 | public void beginVisitAndRightOperand() { 89 | } 90 | 91 | @Override 92 | public void endVisitAndRightOperand() { 93 | } 94 | 95 | @Override 96 | public void beginVisitOr() { 97 | } 98 | 99 | @Override 100 | public void endVisitOr() { 101 | throw new MongoTableException("MongoDB Event Table does not support SET function."); 102 | } 103 | 104 | @Override 105 | public void beginVisitOrLeftOperand() { 106 | } 107 | 108 | @Override 109 | public void endVisitOrLeftOperand() { 110 | } 111 | 112 | @Override 113 | public void beginVisitOrRightOperand() { 114 | } 115 | 116 | @Override 117 | public void endVisitOrRightOperand() { 118 | } 119 | 120 | @Override 121 | public void beginVisitNot() { 122 | } 123 | 124 | @Override 125 | public void endVisitNot() { 126 | throw new MongoTableException("MongoDB Event Table does not support SET function."); 127 | } 128 | 129 | @Override 130 | public void beginVisitCompare(Compare.Operator operator) { 131 | } 132 | 133 | @Override 134 | public void endVisitCompare(Compare.Operator operator) { 135 | throw new MongoTableException("MongoDB Event Table does not support SET function."); 136 | } 137 | 138 | @Override 139 | public void beginVisitCompareLeftOperand(Compare.Operator operator) { 140 | } 141 | 142 | @Override 143 | public void endVisitCompareLeftOperand(Compare.Operator operator) { 144 | } 145 | 146 | @Override 147 | public void beginVisitCompareRightOperand(Compare.Operator operator) { 148 | } 149 | 150 | @Override 151 | public void endVisitCompareRightOperand(Compare.Operator operator) { 152 | } 153 | 154 | 155 | @Override 156 | public void beginVisitIsNull(String streamId) { 157 | 158 | 159 | } 160 | 161 | @Override 162 | public void endVisitIsNull(String streamId) { 163 | throw new MongoTableException("MongoDB Event Table does not support SET function."); 164 | } 165 | 166 | @Override 167 | public void beginVisitIn(String storeId) { 168 | throw new MongoTableException("MongoDB Event Table does not support SET function."); 169 | } 170 | 171 | @Override 172 | public void endVisitIn(String storeId) { 173 | } 174 | 175 | @Override 176 | public void beginVisitMath(MathOperator mathOperator) { 177 | throw new MongoTableException("MongoDB Event Table does not support SET function."); 178 | } 179 | 180 | @Override 181 | public void endVisitMath(MathOperator mathOperator) { 182 | } 183 | 184 | @Override 185 | public void beginVisitMathLeftOperand(MathOperator mathOperator) { 186 | } 187 | 188 | @Override 189 | public void endVisitMathLeftOperand(MathOperator mathOperator) { 190 | } 191 | 192 | @Override 193 | public void beginVisitMathRightOperand(MathOperator mathOperator) { 194 | } 195 | 196 | @Override 197 | public void endVisitMathRightOperand(MathOperator mathOperator) { 198 | } 199 | 200 | @Override 201 | public void beginVisitAttributeFunction(String namespace, String functionName) { 202 | throw new MongoTableException("MongoDB Event Table does not support SET function."); 203 | } 204 | 205 | 206 | @Override 207 | public void endVisitAttributeFunction(String namespace, String functionName) { 208 | } 209 | 210 | @Override 211 | public void beginVisitParameterAttributeFunction(int index) { 212 | } 213 | 214 | @Override 215 | public void endVisitParameterAttributeFunction(int index) { 216 | } 217 | 218 | @Override 219 | public void beginVisitStreamVariable(String id, String streamId, String attributeName, Attribute.Type type) { 220 | String name = this.generateStreamVarName(); 221 | this.placeholders.put(name, new Attribute(id, type)); 222 | conditionOperands.push(name); 223 | } 224 | 225 | @Override 226 | public void endVisitStreamVariable(String id, String streamId, String attributeName, Attribute.Type type) { 227 | } 228 | 229 | @Override 230 | public void beginVisitConstant(Object value, Attribute.Type type) { 231 | String name = this.generateConstantName(); 232 | this.placeholders.put(name, new Constant(value, type)); 233 | conditionOperands.push(name); 234 | } 235 | 236 | @Override 237 | public void endVisitConstant(Object value, Attribute.Type type) { 238 | } 239 | 240 | @Override 241 | public void beginVisitStoreVariable(String storeId, String attributeName, Attribute.Type type) { 242 | this.conditionOperands.push(attributeName); 243 | } 244 | 245 | @Override 246 | public void endVisitStoreVariable(String storeId, String attributeName, Attribute.Type type) { 247 | } 248 | 249 | /** 250 | * Method for generating a temporary placeholder for stream variables. 251 | * 252 | * @return a placeholder string of known format. 253 | */ 254 | private String generateStreamVarName() { 255 | String name = "strVar" + this.streamVarCount; 256 | this.streamVarCount++; 257 | return name; 258 | } 259 | 260 | /** 261 | * Method for generating a temporary placeholder for constants. 262 | * 263 | * @return a placeholder string of known format. 264 | */ 265 | private String generateConstantName() { 266 | String name = "const" + this.constantCount; 267 | this.constantCount++; 268 | return name; 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /component/src/test/java/org/wso2/extension/siddhi/store/mongodb/MongoDBConnectionSSLTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb; 19 | 20 | import com.mongodb.MongoClient; 21 | import com.mongodb.MongoClientOptions; 22 | import com.mongodb.MongoClientURI; 23 | import com.mongodb.MongoException; 24 | import org.apache.log4j.Logger; 25 | import org.testng.Assert; 26 | import org.testng.annotations.AfterClass; 27 | import org.testng.annotations.BeforeClass; 28 | import org.testng.annotations.Test; 29 | import org.wso2.siddhi.core.SiddhiAppRuntime; 30 | import org.wso2.siddhi.core.SiddhiManager; 31 | 32 | import java.io.File; 33 | import java.io.FileInputStream; 34 | import java.io.FileNotFoundException; 35 | import java.io.IOException; 36 | import java.io.InputStream; 37 | import java.net.URL; 38 | import java.security.KeyManagementException; 39 | import java.security.KeyStore; 40 | import java.security.KeyStoreException; 41 | import java.security.NoSuchAlgorithmException; 42 | import java.security.UnrecoverableKeyException; 43 | import java.security.cert.CertificateException; 44 | import javax.net.ssl.KeyManager; 45 | import javax.net.ssl.KeyManagerFactory; 46 | import javax.net.ssl.SSLContext; 47 | import javax.net.ssl.TrustManager; 48 | import javax.net.ssl.TrustManagerFactory; 49 | 50 | public class MongoDBConnectionSSLTest { 51 | 52 | private static final Logger log = Logger.getLogger(MongoDBConnectionSSLTest.class); 53 | 54 | private static String uri = MongoTableTestUtils.resolveBaseUri(); 55 | private static MongoClientOptions.Builder mongoClientOptionsBuilder = getOptionsWithSSLEnabled(); 56 | private static String keyStorePath; 57 | 58 | @BeforeClass 59 | public void init() { 60 | log.info("== Mongo Table Secure Connection tests started =="); 61 | } 62 | 63 | @AfterClass 64 | public void shutdown() { 65 | log.info("== Mongo Table Secure Connection tests completed =="); 66 | } 67 | 68 | @Test 69 | public void mongoTableSSLConnectionTest1() throws InterruptedException { 70 | log.info("mongoTableSSLConnectionTest1 - " + 71 | " DASC5-862:Defining a MongoDB table with by defining ssl in mongodburl"); 72 | 73 | dropCollection(); 74 | 75 | SiddhiManager siddhiManager = new SiddhiManager(); 76 | String streams = "" + 77 | "@store(type = 'mongodb', " + 78 | "mongodb.uri='" + uri + "?authMechanism=MONGODB-X509&ssl=true&sslInvalidHostNameAllowed=true', " + 79 | "secure.connection='true', " + 80 | "key.store='" + keyStorePath + "', " + 81 | "key.store.password='123456', " + 82 | "trust.store='" + keyStorePath + "', " + 83 | "trust.store.password='123456')" + 84 | "@PrimaryKey('symbol')" + 85 | "define table FooTable (symbol string, price float, volume long); "; 86 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams); 87 | siddhiAppRuntime.start(); 88 | siddhiAppRuntime.shutdown(); 89 | 90 | Assert.assertEquals(doesCollectionExists(), true, "Definition failed"); 91 | } 92 | 93 | @Test 94 | public void mongoTableSSLConnectionTest2() { 95 | log.info("mongoTableSSLConnectionTest2 - " + 96 | "DASC5-863:Defining a MongoDB table with multiple options defined in mongodburl"); 97 | 98 | dropCollection(); 99 | 100 | SiddhiManager siddhiManager = new SiddhiManager(); 101 | String streams = "" + 102 | "@store(type = 'mongodb', " + 103 | "mongodb.uri='" + uri + "?authMechanism=MONGODB-X509&ssl=true&sslInvalidHostNameAllowed=true', " + 104 | "secure.connection='true', " + 105 | "key.store='" + keyStorePath + "', " + 106 | "key.store.password='123456', " + 107 | "trust.store='" + keyStorePath + "', " + 108 | "trust.store.password='123456')" + 109 | "@PrimaryKey('symbol')" + 110 | "define table FooTable (symbol string, price float, volume long); "; 111 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams); 112 | siddhiAppRuntime.start(); 113 | siddhiAppRuntime.shutdown(); 114 | 115 | Assert.assertEquals(doesCollectionExists(), true, "Definition failed"); 116 | } 117 | 118 | private void dropCollection() { 119 | try (MongoClient mongoClient = new MongoClient(new MongoClientURI(uri + "?authMechanism=MONGODB-X509", 120 | mongoClientOptionsBuilder))) { 121 | mongoClient.getDatabase("admin").getCollection("FooTable").drop(); 122 | } catch (MongoException e) { 123 | log.debug("Clearing DB collection failed due to " + e.getMessage(), e); 124 | throw e; 125 | } 126 | } 127 | 128 | private boolean doesCollectionExists() { 129 | try (MongoClient mongoClient = new MongoClient(new MongoClientURI(uri + "?authMechanism=MONGODB-X509", 130 | mongoClientOptionsBuilder))) { 131 | for (String collectionName : mongoClient.getDatabase("admin").listCollectionNames()) { 132 | if ("FooTable".equals(collectionName)) { 133 | return true; 134 | } 135 | } 136 | return false; 137 | } catch (MongoException e) { 138 | log.debug("Checking whether collection was created failed due to" + e.getMessage(), e); 139 | throw e; 140 | } 141 | } 142 | 143 | private static MongoClientOptions.Builder getOptionsWithSSLEnabled() { 144 | URL trustStoreFile = MongoDBConnectionSSLTest.class.getResource("/mongodb-client.jks"); 145 | keyStorePath = trustStoreFile.getPath(); 146 | File keystoreFile = new File(trustStoreFile.getFile()); 147 | try (InputStream trustStream = new FileInputStream(keystoreFile)) { 148 | char[] trustPassword = "123456".toCharArray(); 149 | 150 | KeyStore trustStore; 151 | trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 152 | trustStore.load(trustStream, trustPassword); 153 | 154 | TrustManagerFactory trustFactory = 155 | TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 156 | trustFactory.init(trustStore); 157 | TrustManager[] trustManagers = trustFactory.getTrustManagers(); 158 | 159 | KeyManagerFactory keyManagerFactory = 160 | KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 161 | keyManagerFactory.init(trustStore, trustPassword); 162 | KeyManager[] keyManagers = keyManagerFactory.getKeyManagers(); 163 | 164 | SSLContext sslContext = SSLContext.getInstance("SSL"); 165 | sslContext.init(keyManagers, trustManagers, null); 166 | 167 | mongoClientOptionsBuilder = MongoClientOptions.builder(); 168 | mongoClientOptionsBuilder 169 | .sslEnabled(true) 170 | .sslInvalidHostNameAllowed(true) 171 | .socketFactory(sslContext.getSocketFactory()); 172 | 173 | return mongoClientOptionsBuilder; 174 | } catch (FileNotFoundException e) { 175 | log.debug("Key store file not found for secure connections to mongodb.", e); 176 | } catch (IOException e) { 177 | log.debug("I/O Exception in creating trust store for secure connections to mongodb.", e); 178 | } catch (CertificateException e) { 179 | log.debug("Certificates in the trust store could not be loaded for secure connections " + 180 | "to mongodb.", e); 181 | } catch (NoSuchAlgorithmException e) { 182 | log.debug("The algorithm used to check the integrity of the trust store cannot be " + 183 | "found.", e); 184 | } catch (KeyStoreException e) { 185 | log.debug("Exception in creating trust store, no Provider supports aKeyStoreSpi " + 186 | "implementation for the specified type.", e); 187 | } catch (UnrecoverableKeyException e) { 188 | log.debug("Key in the keystore cannot be recovered.", e); 189 | } catch (KeyManagementException e) { 190 | log.debug("Error in validating the key in the key store/ trust store.", e); 191 | } 192 | return null; 193 | } 194 | 195 | } 196 | -------------------------------------------------------------------------------- /component/src/test/java/org/wso2/extension/siddhi/store/mongodb/DeleteFromMongoTableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb; 19 | 20 | import org.apache.commons.logging.Log; 21 | import org.apache.commons.logging.LogFactory; 22 | import org.testng.Assert; 23 | import org.testng.annotations.AfterClass; 24 | import org.testng.annotations.BeforeClass; 25 | import org.testng.annotations.Test; 26 | import org.wso2.siddhi.core.SiddhiAppRuntime; 27 | import org.wso2.siddhi.core.SiddhiManager; 28 | import org.wso2.siddhi.core.exception.SiddhiAppCreationException; 29 | import org.wso2.siddhi.core.stream.input.InputHandler; 30 | 31 | 32 | public class DeleteFromMongoTableTest { 33 | 34 | private static final Log log = LogFactory.getLog(DeleteFromMongoTableTest.class); 35 | 36 | private static String uri = MongoTableTestUtils.resolveBaseUri(); 37 | 38 | @BeforeClass 39 | public void init() { 40 | log.info("== MongoDB Collection DELETE tests started =="); 41 | } 42 | 43 | @AfterClass 44 | public void shutdown() { 45 | log.info("== MongoDB Collection DELETE tests completed =="); 46 | } 47 | 48 | @Test 49 | public void deleteFromMongoTableTest1() throws InterruptedException { 50 | log.info("deleteFromMongoTableTest1 - " + 51 | "DASC5-903:Delete an event of a MongoDB table successfully"); 52 | 53 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 54 | 55 | SiddhiManager siddhiManager = new SiddhiManager(); 56 | String streams = "" + 57 | "define stream StockStream (symbol string, price float, volume long); " + 58 | "define stream DeleteStockStream (symbol string, price float, volume long); " + 59 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 60 | "@PrimaryKey('symbol')" + 61 | "define table FooTable (symbol string, price float, volume long);"; 62 | String query = "" + 63 | "@info(name = 'query1') " + 64 | "from StockStream " + 65 | "insert into FooTable ;" + 66 | "" + 67 | "@info(name = 'query2') " + 68 | "from DeleteStockStream " + 69 | "delete FooTable " + 70 | " on (FooTable.symbol == symbol) "; 71 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 72 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 73 | InputHandler deleteStockStream = siddhiAppRuntime.getInputHandler("DeleteStockStream"); 74 | siddhiAppRuntime.start(); 75 | 76 | stockStream.send(new Object[]{"WSO2", 55.6F, 100L}); 77 | stockStream.send(new Object[]{"IBM", 75.6F, 100L}); 78 | stockStream.send(new Object[]{"WSO52", 57.6F, 100L}); 79 | deleteStockStream.send(new Object[]{"IBM", 75.6F, 100L}); 80 | deleteStockStream.send(new Object[]{"WSO2", 55.6F, 100L}); 81 | 82 | siddhiAppRuntime.shutdown(); 83 | 84 | long totalDocumentsInCollection = MongoTableTestUtils.getDocumentsCount(uri, "FooTable"); 85 | Assert.assertEquals(totalDocumentsInCollection, 1, "Deletion failed"); 86 | } 87 | 88 | 89 | @Test(expectedExceptions = SiddhiAppCreationException.class) 90 | public void deleteFromMongoTableTest2() { 91 | log.info("deleteFromMongoTableTest2 - " + 92 | "DASC5-904:Delete an event from a non existing MongoDB table"); 93 | 94 | SiddhiManager siddhiManager = new SiddhiManager(); 95 | String streams = "" + 96 | "define stream StockStream (symbol string, price float, volume long); " + 97 | "define stream DeleteStockStream (symbol string, price float, volume long); " + 98 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 99 | "define table FooTable (symbol string, price float, volume long);"; 100 | String query = "" + 101 | "@info(name = 'query1') " + 102 | "from StockStream " + 103 | "insert into FooTable ;" + 104 | "" + 105 | "@info(name = 'query2') " + 106 | "from DeleteStockStream " + 107 | "delete FooTable1234 " + 108 | "on FooTable.symbol == symbol;"; 109 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 110 | siddhiAppRuntime.start(); 111 | siddhiAppRuntime.shutdown(); 112 | } 113 | 114 | 115 | @Test(expectedExceptions = SiddhiAppCreationException.class) 116 | public void deleteFromMongoTableTest3() { 117 | log.info("deleteFromMongoTableTest3 - " + 118 | "DASC5-905:Delete an event from a MongoDB table by selecting from non existing stream"); 119 | 120 | SiddhiManager siddhiManager = new SiddhiManager(); 121 | String streams = "" + 122 | "define stream StockStream (symbol string, price float, volume long); " + 123 | "define stream DeleteStockStream (symbol string, price float, volume long); " + 124 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 125 | "define table FooTable (symbol string, price float, volume long);"; 126 | String query = "" + 127 | "@info(name = 'query1') " + 128 | "from StockStream " + 129 | "insert into FooTable ;" + 130 | "" + 131 | "@info(name = 'query2') " + 132 | "from DeleteStockStream345 " + 133 | "delete FooTable " + 134 | "on FooTable.symbol == symbol;"; 135 | 136 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 137 | siddhiAppRuntime.start(); 138 | siddhiAppRuntime.shutdown(); 139 | } 140 | 141 | @Test(expectedExceptions = SiddhiAppCreationException.class) 142 | public void deleteFromMongoTableTest4() { 143 | log.info("deleteFromMongoTableTest4 - " + 144 | "DASC5-906:Delete an event from a MongoDB table based on a non-existing attribute"); 145 | 146 | SiddhiManager siddhiManager = new SiddhiManager(); 147 | String streams = "" + 148 | "define stream StockStream (symbol string, price float, volume long); " + 149 | "define stream DeleteStockStream (symbol string, price float, volume long); " + 150 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 151 | "define table FooTable (symbol string, price float, volume long);"; 152 | String query = "" + 153 | "@info(name = 'query1') " + 154 | "from StockStream " + 155 | "insert into FooTable ;" + 156 | "" + 157 | "@info(name = 'query2') " + 158 | "from DeleteStockStream " + 159 | "delete FooTable " + 160 | " on (FooTable.length == length) "; 161 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 162 | siddhiAppRuntime.start(); 163 | siddhiAppRuntime.shutdown(); 164 | } 165 | 166 | @Test 167 | public void deleteFromMongoTableTest5() throws InterruptedException { 168 | log.info("deleteFromMongoTableTest5 - " + 169 | "DASC5-909:Delete an event from a MongoDB table based on a non-existing attribute value"); 170 | 171 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 172 | 173 | SiddhiManager siddhiManager = new SiddhiManager(); 174 | String streams = "" + 175 | "define stream StockStream (symbol string, price float, volume long); " + 176 | "define stream DeleteStockStream (symbol string, price float, volume long); " + 177 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 178 | "define table FooTable (symbol string, price float, volume long);"; 179 | String query = "" + 180 | "@info(name = 'query1') " + 181 | "from StockStream " + 182 | "insert into FooTable;" + 183 | "" + 184 | "@info(name = 'query2') " + 185 | "from DeleteStockStream " + 186 | "delete FooTable " + 187 | " on (FooTable.symbol == symbol) "; 188 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 189 | 190 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 191 | InputHandler deleteStockStream = siddhiAppRuntime.getInputHandler("DeleteStockStream"); 192 | siddhiAppRuntime.start(); 193 | 194 | stockStream.send(new Object[]{"WSO2", 55.6F, 100L}); 195 | stockStream.send(new Object[]{"IBM", 75.6F, 100L}); 196 | stockStream.send(new Object[]{"WSO2", 57.6F, 100L}); 197 | deleteStockStream.send(new Object[]{"IBM_v2", 75.6F, 100L}); 198 | deleteStockStream.send(new Object[]{"WSO2_v2", 55.6F, 100L}); 199 | 200 | siddhiAppRuntime.shutdown(); 201 | 202 | long totalDocumentsInCollection = MongoTableTestUtils.getDocumentsCount(uri, "FooTable"); 203 | Assert.assertEquals(totalDocumentsInCollection, 3, "Deletion failed"); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /docs/license.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 WSO2 Inc. () All Rights Reserved. 2 | 3 | WSO2 Inc. licenses this file to you under the Apache License, 4 | Version 2.0 (the "License"); you may not use this file except 5 | in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | 9 | 10 | Unless required by applicable law or agreed to in writing, 11 | software distributed under the License is distributed on an 12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | KIND, either express or implied. See the License for the 14 | specific language governing permissions and limitations 15 | under the License. 16 | 17 | ``` 18 | ------------------------------------------------------------------------- 19 | Apache License 20 | Version 2.0, January 2004 21 | http://www.apache.org/licenses/ 22 | 23 | 24 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 25 | 26 | 1. Definitions. 27 | 28 | "License" shall mean the terms and conditions for use, reproduction, 29 | and distribution as defined by Sections 1 through 9 of this document. 30 | 31 | "Licensor" shall mean the copyright owner or entity authorized by 32 | the copyright owner that is granting the License. 33 | 34 | "Legal Entity" shall mean the union of the acting entity and all 35 | other entities that control, are controlled by, or are under common 36 | control with that entity. For the purposes of this definition, 37 | "control" means (i) the power, direct or indirect, to cause the 38 | direction or management of such entity, whether by contract or 39 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 40 | outstanding shares, or (iii) beneficial ownership of such entity. 41 | 42 | "You" (or "Your") shall mean an individual or Legal Entity 43 | exercising permissions granted by this License. 44 | 45 | "Source" form shall mean the preferred form for making modifications, 46 | including but not limited to software source code, documentation 47 | source, and configuration files. 48 | 49 | "Object" form shall mean any form resulting from mechanical 50 | transformation or translation of a Source form, including but 51 | not limited to compiled object code, generated documentation, 52 | and conversions to other media types. 53 | 54 | "Work" shall mean the work of authorship, whether in Source or 55 | Object form, made available under the License, as indicated by a 56 | copyright notice that is included in or attached to the work 57 | (an example is provided in the Appendix below). 58 | 59 | "Derivative Works" shall mean any work, whether in Source or Object 60 | form, that is based on (or derived from) the Work and for which the 61 | editorial revisions, annotations, elaborations, or other modifications 62 | represent, as a whole, an original work of authorship. For the purposes 63 | of this License, Derivative Works shall not include works that remain 64 | separable from, or merely link (or bind by name) to the interfaces of, 65 | the Work and Derivative Works thereof. 66 | 67 | "Contribution" shall mean any work of authorship, including 68 | the original version of the Work and any modifications or additions 69 | to that Work or Derivative Works thereof, that is intentionally 70 | submitted to Licensor for inclusion in the Work by the copyright owner 71 | or by an individual or Legal Entity authorized to submit on behalf of 72 | the copyright owner. For the purposes of this definition, "submitted" 73 | means any form of electronic, verbal, or written communication sent 74 | to the Licensor or its representatives, including but not limited to 75 | communication on electronic mailing lists, source code control systems, 76 | and issue tracking systems that are managed by, or on behalf of, the 77 | Licensor for the purpose of discussing and improving the Work, but 78 | excluding communication that is conspicuously marked or otherwise 79 | designated in writing by the copyright owner as "Not a Contribution." 80 | 81 | "Contributor" shall mean Licensor and any individual or Legal Entity 82 | on behalf of whom a Contribution has been received by Licensor and 83 | subsequently incorporated within the Work. 84 | 85 | 2. Grant of Copyright License. Subject to the terms and conditions of 86 | this License, each Contributor hereby grants to You a perpetual, 87 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 88 | copyright license to reproduce, prepare Derivative Works of, 89 | publicly display, publicly perform, sublicense, and distribute the 90 | Work and such Derivative Works in Source or Object form. 91 | 92 | 3. Grant of Patent License. Subject to the terms and conditions of 93 | this License, each Contributor hereby grants to You a perpetual, 94 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 95 | (except as stated in this section) patent license to make, have made, 96 | use, offer to sell, sell, import, and otherwise transfer the Work, 97 | where such license applies only to those patent claims licensable 98 | by such Contributor that are necessarily infringed by their 99 | Contribution(s) alone or by combination of their Contribution(s) 100 | with the Work to which such Contribution(s) was submitted. If You 101 | institute patent litigation against any entity (including a 102 | cross-claim or counterclaim in a lawsuit) alleging that the Work 103 | or a Contribution incorporated within the Work constitutes direct 104 | or contributory patent infringement, then any patent licenses 105 | granted to You under this License for that Work shall terminate 106 | as of the date such litigation is filed. 107 | 108 | 4. Redistribution. You may reproduce and distribute copies of the 109 | Work or Derivative Works thereof in any medium, with or without 110 | modifications, and in Source or Object form, provided that You 111 | meet the following conditions: 112 | 113 | (a) You must give any other recipients of the Work or 114 | Derivative Works a copy of this License; and 115 | 116 | (b) You must cause any modified files to carry prominent notices 117 | stating that You changed the files; and 118 | 119 | (c) You must retain, in the Source form of any Derivative Works 120 | that You distribute, all copyright, patent, trademark, and 121 | attribution notices from the Source form of the Work, 122 | excluding those notices that do not pertain to any part of 123 | the Derivative Works; and 124 | 125 | (d) If the Work includes a "NOTICE" text file as part of its 126 | distribution, then any Derivative Works that You distribute must 127 | include a readable copy of the attribution notices contained 128 | within such NOTICE file, excluding those notices that do not 129 | pertain to any part of the Derivative Works, in at least one 130 | of the following places: within a NOTICE text file distributed 131 | as part of the Derivative Works; within the Source form or 132 | documentation, if provided along with the Derivative Works; or, 133 | within a display generated by the Derivative Works, if and 134 | wherever such third-party notices normally appear. The contents 135 | of the NOTICE file are for informational purposes only and 136 | do not modify the License. You may add Your own attribution 137 | notices within Derivative Works that You distribute, alongside 138 | or as an addendum to the NOTICE text from the Work, provided 139 | that such additional attribution notices cannot be construed 140 | as modifying the License. 141 | 142 | You may add Your own copyright statement to Your modifications and 143 | may provide additional or different license terms and conditions 144 | for use, reproduction, or distribution of Your modifications, or 145 | for any such Derivative Works as a whole, provided Your use, 146 | reproduction, and distribution of the Work otherwise complies with 147 | the conditions stated in this License. 148 | 149 | 5. Submission of Contributions. Unless You explicitly state otherwise, 150 | any Contribution intentionally submitted for inclusion in the Work 151 | by You to the Licensor shall be under the terms and conditions of 152 | this License, without any additional terms or conditions. 153 | Notwithstanding the above, nothing herein shall supersede or modify 154 | the terms of any separate license agreement you may have executed 155 | with Licensor regarding such Contributions. 156 | 157 | 6. Trademarks. This License does not grant permission to use the trade 158 | names, trademarks, service marks, or product names of the Licensor, 159 | except as required for reasonable and customary use in describing the 160 | origin of the Work and reproducing the content of the NOTICE file. 161 | 162 | 7. Disclaimer of Warranty. Unless required by applicable law or 163 | agreed to in writing, Licensor provides the Work (and each 164 | Contributor provides its Contributions) on an "AS IS" BASIS, 165 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 166 | implied, including, without limitation, any warranties or conditions 167 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 168 | PARTICULAR PURPOSE. You are solely responsible for determining the 169 | appropriateness of using or redistributing the Work and assume any 170 | risks associated with Your exercise of permissions under this License. 171 | 172 | 8. Limitation of Liability. In no event and under no legal theory, 173 | whether in tort (including negligence), contract, or otherwise, 174 | unless required by applicable law (such as deliberate and grossly 175 | negligent acts) or agreed to in writing, shall any Contributor be 176 | liable to You for damages, including any direct, indirect, special, 177 | incidental, or consequential damages of any character arising as a 178 | result of this License or out of the use or inability to use the 179 | Work (including but not limited to damages for loss of goodwill, 180 | work stoppage, computer failure or malfunction, or any and all 181 | other commercial damages or losses), even if such Contributor 182 | has been advised of the possibility of such damages. 183 | 184 | 9. Accepting Warranty or Additional Liability. While redistributing 185 | the Work or Derivative Works thereof, You may choose to offer, 186 | and charge a fee for, acceptance of support, warranty, indemnity, 187 | or other liability obligations and/or rights consistent with this 188 | License. However, in accepting such obligations, You may act only 189 | on Your own behalf and on Your sole responsibility, not on behalf 190 | of any other Contributor, and only if You agree to indemnify, 191 | defend, and hold each Contributor harmless for any liability 192 | incurred by, or claims asserted against, such Contributor by reason 193 | of your accepting any such warranty or additional liability. 194 | 195 | END OF TERMS AND CONDITIONS 196 | ``` 197 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /component/src/test/java/org/wso2/extension/siddhi/store/mongodb/UpdateOrInsertMongoTableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.extension.siddhi.store.mongodb; 20 | 21 | import org.apache.log4j.Logger; 22 | import org.bson.Document; 23 | import org.testng.Assert; 24 | import org.testng.annotations.AfterClass; 25 | import org.testng.annotations.BeforeClass; 26 | import org.testng.annotations.Test; 27 | import org.wso2.siddhi.core.SiddhiAppRuntime; 28 | import org.wso2.siddhi.core.SiddhiManager; 29 | import org.wso2.siddhi.core.exception.SiddhiAppCreationException; 30 | import org.wso2.siddhi.core.stream.input.InputHandler; 31 | 32 | public class UpdateOrInsertMongoTableTest { 33 | 34 | private static final Logger log = Logger.getLogger(UpdateOrInsertMongoTableTest.class); 35 | 36 | private static String uri = MongoTableTestUtils.resolveBaseUri(); 37 | 38 | @BeforeClass 39 | public void init() { 40 | log.info("== Mongo Table UPDATE/INSERT tests started =="); 41 | } 42 | 43 | @AfterClass 44 | public void shutdown() { 45 | log.info("== Mongo Table UPDATE/INSERT tests completed =="); 46 | } 47 | 48 | @Test 49 | public void updateOrInsertMongoTableTest1() throws InterruptedException { 50 | log.info("updateOrInsertMongoTableTest1 - DASC5-929:Configure siddhi to perform insert/update on " + 51 | "MongoDB document"); 52 | 53 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 54 | 55 | SiddhiManager siddhiManager = new SiddhiManager(); 56 | String streams = "" + 57 | "define stream StockStream (symbol string, price float, volume long); " + 58 | "define stream FooStream (symbol string, price float, volume long); " + 59 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 60 | "define table FooTable (symbol string, price float, volume long);"; 61 | String query = "" + 62 | "@info(name = 'query1') " + 63 | "from StockStream " + 64 | "insert into FooTable ;" + 65 | "" + 66 | "@info(name = 'query2') " + 67 | "from FooStream " + 68 | "update or insert into FooTable " + 69 | " on FooTable.symbol== symbol ;"; 70 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 71 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 72 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 73 | siddhiAppRuntime.start(); 74 | 75 | stockStream.send(new Object[]{"WSO2", 55.6F, 100L}); 76 | stockStream.send(new Object[]{"GOOG", 75.6F, 100L}); 77 | stockStream.send(new Object[]{"WSO2", 57.6F, 100L}); 78 | fooStream.send(new Object[]{"GOOG", 10.6, 100}); 79 | 80 | siddhiAppRuntime.shutdown(); 81 | 82 | long totalDocumentsInCollection = MongoTableTestUtils.getDocumentsCount(uri, "FooTable"); 83 | Assert.assertEquals(totalDocumentsInCollection, 3, "Update failed"); 84 | 85 | Document expectedUpdatedDocument = new Document() 86 | .append("symbol", "GOOG") 87 | .append("price", 10.6) 88 | .append("volume", 100); 89 | Document updatedDocument = MongoTableTestUtils.getDocument(uri, "FooTable", "{symbol:'GOOG'}"); 90 | Assert.assertEquals(updatedDocument, expectedUpdatedDocument, "Update Failed"); 91 | } 92 | 93 | @Test 94 | public void updateOrInsertMongoTableTest2() throws InterruptedException { 95 | log.info("updateOrInsertMongoTableTest2 - DASC5-930:Configure siddhi to perform insert/update on MongoDB " + 96 | "Document when no any matching record exist"); 97 | 98 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 99 | 100 | SiddhiManager siddhiManager = new SiddhiManager(); 101 | String streams = "" + 102 | "define stream StockStream (symbol string, price float, volume long); " + 103 | "define stream FooStream (symbol string, price float, volume long); " + 104 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 105 | "define table FooTable (symbol string, price float, volume long);"; 106 | String query = "" + 107 | "@info(name = 'query1') " + 108 | "from StockStream " + 109 | "insert into FooTable ;" + 110 | "" + 111 | "@info(name = 'query2') " + 112 | "from FooStream " + 113 | "update or insert into FooTable " + 114 | " on FooTable.symbol== symbol ;"; 115 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 116 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 117 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 118 | siddhiAppRuntime.start(); 119 | 120 | stockStream.send(new Object[]{"WSO2", 55.6F, 100L}); 121 | stockStream.send(new Object[]{"GOOG", 75.6F, 100L}); 122 | stockStream.send(new Object[]{"WSO2", 57.6F, 100L}); 123 | fooStream.send(new Object[]{"GOOG_2", 10.6, 100}); 124 | 125 | siddhiAppRuntime.shutdown(); 126 | 127 | long totalDocumentsInCollection = MongoTableTestUtils.getDocumentsCount(uri, "FooTable"); 128 | Assert.assertEquals(totalDocumentsInCollection, 4, "Update failed"); 129 | 130 | Document expectedUpdatedDocument = new Document() 131 | .append("symbol", "GOOG_2") 132 | .append("price", 10.6) 133 | .append("volume", 100); 134 | Document updatedDocument = MongoTableTestUtils.getDocument(uri, "FooTable", "{symbol:'GOOG_2'}"); 135 | Assert.assertEquals(updatedDocument, expectedUpdatedDocument, "Update Failed"); 136 | } 137 | 138 | @Test 139 | public void updateOrInsertMongoTableTest3() throws InterruptedException { 140 | log.info("updateOrInsertMongoTableTest3 - DASC5-931:Configure siddhi to perform insert/update when there " + 141 | "are some of matching records exist"); 142 | 143 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 144 | 145 | SiddhiManager siddhiManager = new SiddhiManager(); 146 | String streams = "" + 147 | "define stream StockStream (symbol string, price float, volume long); " + 148 | "define stream FooStream (symbol string, price float, volume long); " + 149 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 150 | "define table FooTable (symbol string, price float, volume long);"; 151 | String query = "" + 152 | "@info(name = 'query1') " + 153 | "from StockStream " + 154 | "insert into FooTable ;" + 155 | "" + 156 | "@info(name = 'query2') " + 157 | "from FooStream " + 158 | "update or insert into FooTable " + 159 | " on FooTable.symbol== symbol ;"; 160 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 161 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 162 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 163 | siddhiAppRuntime.start(); 164 | 165 | stockStream.send(new Object[]{"WSO2", 55.6F, 100L}); 166 | stockStream.send(new Object[]{"GOOG", 75.6F, 100L}); 167 | fooStream.send(new Object[]{"WSO2", 57.6, 100}); 168 | fooStream.send(new Object[]{"GOOG_2", 10.6, 100}); 169 | 170 | siddhiAppRuntime.shutdown(); 171 | 172 | long totalDocumentsInCollection = MongoTableTestUtils.getDocumentsCount(uri, "FooTable"); 173 | Assert.assertEquals(totalDocumentsInCollection, 3, "Update failed"); 174 | 175 | Document expectedUpdatedDocument = new Document() 176 | .append("symbol", "WSO2") 177 | .append("price", 57.6) 178 | .append("volume", 100); 179 | Document updatedDocument = MongoTableTestUtils.getDocument(uri, "FooTable", "{symbol:'WSO2'}"); 180 | Assert.assertEquals(updatedDocument, expectedUpdatedDocument, "Update Failed"); 181 | } 182 | 183 | @Test(expectedExceptions = SiddhiAppCreationException.class) 184 | public void updateOrInsertMongoTableTest4() { 185 | log.info("updateOrInsertMongoTableTest4 - DASC5-932:[N] Configure siddhi to perform insert/update with " + 186 | "a non existing stream"); 187 | 188 | SiddhiManager siddhiManager = new SiddhiManager(); 189 | String streams = "" + 190 | "define stream StockStream (symbol string, price float, volume long); " + 191 | "define stream FooStream (symbol string, price float, volume long); " + 192 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 193 | "define table FooTable (symbol string, price float, volume long);"; 194 | String query = "" + 195 | "@info(name = 'query1') " + 196 | "from StockStream " + 197 | "insert into FooTable ;" + 198 | "" + 199 | "@info(name = 'query2') " + 200 | "from FooStream123 " + 201 | "update or insert into FooTable " + 202 | " on FooTable.symbol== symbol ;"; 203 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 204 | siddhiAppRuntime.start(); 205 | siddhiAppRuntime.shutdown(); 206 | } 207 | 208 | @Test(expectedExceptions = SiddhiAppCreationException.class) 209 | public void updateOrInsertMongoTableTest5() { 210 | log.info("updateOrInsertMongoTableTest5 - DASC5-933:[N] Configure siddhi to perform insert/update with an " + 211 | "undefined MongoDB Document"); 212 | 213 | SiddhiManager siddhiManager = new SiddhiManager(); 214 | String streams = "" + 215 | "define stream StockStream (symbol string, price float, volume long); " + 216 | "define stream FooStream (symbol string, price float, volume long); " + 217 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 218 | "define table FooTable (symbol string, price float, volume long);"; 219 | String query = "" + 220 | "@info(name = 'query1') " + 221 | "from StockStream " + 222 | "insert into FooTable ;" + 223 | "" + 224 | "@info(name = 'query2') " + 225 | "from FooStream " + 226 | "update or insert into FooTable123 " + 227 | " on FooTable.symbol== symbol ;"; 228 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 229 | siddhiAppRuntime.start(); 230 | siddhiAppRuntime.shutdown(); 231 | } 232 | 233 | @Test(expectedExceptions = SiddhiAppCreationException.class) 234 | public void updateOrInsertMongoTableTest6() { 235 | log.info("updateOrInsertMongoTableTest6 - DASC5-934:[N] Configure siddhi to perform insert/update on " + 236 | "MongoDB Document with a non-existing attribute"); 237 | 238 | SiddhiManager siddhiManager = new SiddhiManager(); 239 | String streams = "" + 240 | "define stream StockStream (symbol string, price float, volume long); " + 241 | "define stream FooStream (symbol string, price float, volume long); " + 242 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 243 | "define table FooTable (symbol string, price float, volume long);"; 244 | String query = "" + 245 | "@info(name = 'query1') " + 246 | "from StockStream " + 247 | "insert into FooTable ;" + 248 | "" + 249 | "@info(name = 'query2') " + 250 | "from FooStream " + 251 | "update or insert into FooTable " + 252 | " on FooTable.symbol123 == symbol ;"; 253 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 254 | siddhiAppRuntime.start(); 255 | siddhiAppRuntime.shutdown(); 256 | } 257 | 258 | @Test(expectedExceptions = SiddhiAppCreationException.class) 259 | public void updateOrInsertMongoTableTest7() { 260 | log.info("updateOrInsertMongoTableTest7 - DASC5-935:[N] Configure siddhi to perform insert/update on " + 261 | "MongoDB Document incorrect siddhi query"); 262 | 263 | SiddhiManager siddhiManager = new SiddhiManager(); 264 | String streams = "" + 265 | "define stream StockStream (symbol string, price float, volume long); " + 266 | "define stream FooStream (symbol string, price float, volume long); " + 267 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 268 | "define table FooTable (symbol string, price float, volume long);"; 269 | String query = "" + 270 | "@info(name = 'query1') " + 271 | "from StockStream " + 272 | "insert into FooTable ;" + 273 | "" + 274 | "@info(name = 'query2') " + 275 | "from FooTable " + 276 | "update or insert into FooStream " + 277 | " on FooTable.symbol == symbol ;"; 278 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 279 | siddhiAppRuntime.start(); 280 | siddhiAppRuntime.shutdown(); 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /component/src/test/java/org/wso2/extension/siddhi/store/mongodb/JoinMongoTableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package org.wso2.extension.siddhi.store.mongodb; 20 | 21 | import org.apache.log4j.Logger; 22 | import org.testng.Assert; 23 | import org.testng.annotations.AfterClass; 24 | import org.testng.annotations.BeforeClass; 25 | import org.testng.annotations.BeforeMethod; 26 | import org.testng.annotations.Test; 27 | import org.wso2.siddhi.core.SiddhiAppRuntime; 28 | import org.wso2.siddhi.core.SiddhiManager; 29 | import org.wso2.siddhi.core.event.Event; 30 | import org.wso2.siddhi.core.query.output.callback.QueryCallback; 31 | import org.wso2.siddhi.core.stream.input.InputHandler; 32 | import org.wso2.siddhi.core.util.SiddhiTestHelper; 33 | import org.wso2.siddhi.query.compiler.exception.SiddhiParserException; 34 | 35 | import java.util.HashMap; 36 | import java.util.concurrent.atomic.AtomicInteger; 37 | 38 | public class JoinMongoTableTest { 39 | 40 | private static final Logger log = Logger.getLogger(JoinMongoTableTest.class); 41 | 42 | private static String uri = MongoTableTestUtils.resolveBaseUri(); 43 | private AtomicInteger eventCount = new AtomicInteger(0); 44 | private int waitTime = 50; 45 | private int timeout = 30000; 46 | 47 | @BeforeClass 48 | public void init() { 49 | log.info("== Mongo Table JOIN tests started =="); 50 | } 51 | 52 | @AfterClass 53 | public void shutdown() { 54 | log.info("== Mongo Table JOIN tests completed =="); 55 | } 56 | 57 | @BeforeMethod 58 | public void testInit() { 59 | eventCount.set(0); 60 | } 61 | 62 | @Test 63 | public void testMongoTableJoinQuery1() throws InterruptedException { 64 | log.info("testMongoTableJoinQuery1 -" + 65 | "DASC5-915:Read events from a MongoDB collection successfully"); 66 | 67 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 68 | 69 | SiddhiManager siddhiManager = new SiddhiManager(); 70 | String streams = "" + 71 | "define stream StockStream (symbol string, price float, volume long); " + 72 | "define stream FooStream (symbol string); " + 73 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 74 | "define table FooTable (symbol string, price float, volume long);"; 75 | String query = "" + 76 | "@info(name = 'query1') " + 77 | "from StockStream " + 78 | "insert into FooTable ;" + 79 | "" + 80 | "@info(name = 'query2') " + 81 | "from FooStream#window.length(1) join FooTable " + 82 | "select FooStream.symbol as checkSymbol, FooTable.symbol as symbol, " + 83 | "FooTable.volume as volume " + 84 | "insert into OutputStream ;"; 85 | 86 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 87 | siddhiAppRuntime.addCallback("query2", new QueryCallback() { 88 | @Override 89 | public void receive(long timeStamp, Event[] inEvents, Event[] removeEvents) { 90 | if (inEvents != null) { 91 | for (Event event : inEvents) { 92 | eventCount.incrementAndGet(); 93 | switch (eventCount.intValue()) { 94 | case 1: 95 | Assert.assertEquals(new Object[]{"WSO2_check", "WSO2", 100L}, event.getData()); 96 | break; 97 | case 2: 98 | Assert.assertEquals(new Object[]{"WSO2_check", "IBM", 10L}, event.getData()); 99 | break; 100 | default: 101 | break; 102 | } 103 | } 104 | } 105 | } 106 | 107 | }); 108 | 109 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 110 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 111 | siddhiAppRuntime.start(); 112 | 113 | stockStream.send(new Object[]{"WSO2", 5.6f, 100L}); 114 | stockStream.send(new Object[]{"IBM", 7.6f, 10L}); 115 | fooStream.send(new Object[]{"WSO2_check"}); 116 | SiddhiTestHelper.waitForEvents(waitTime, 2, eventCount, timeout); 117 | 118 | siddhiAppRuntime.shutdown(); 119 | 120 | Assert.assertEquals(eventCount.intValue(), 2, "Read events failed"); 121 | } 122 | 123 | @Test(expectedExceptions = SiddhiParserException.class) 124 | public void testMongoTableJoinQuery2() { 125 | log.info("testMongoTableJoinQuery2DASC5-916:Read events from a non existing MongoDB collection"); 126 | 127 | SiddhiManager siddhiManager = new SiddhiManager(); 128 | String streams = "" + 129 | "define stream StockStream (symbol string, price float, volume long); " + 130 | "define stream FooStream (symbol string); " + 131 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 132 | "define table FooTable (symbol string, price float, volume long);"; 133 | String query = "" + 134 | "@info(name = 'query1') " + 135 | "from StockStream " + 136 | "insert into FooTable ;" + 137 | "" + 138 | "@info(name = 'query2') " + 139 | "from FooStream#window.length(1) join FooTable123 " + 140 | "select FooStream.symbol as checkSymbol, FooTable.symbol as symbol, " + 141 | "FooTable.volume as volume " + 142 | "insert into OutputStream ;"; 143 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 144 | siddhiAppRuntime.start(); 145 | siddhiAppRuntime.shutdown(); 146 | } 147 | 148 | @Test(expectedExceptions = SiddhiParserException.class) 149 | public void testMongoTableJoinQuery3() { 150 | log.info("testMongoTableJoinQuery3 - " + 151 | "DASC5-917:Read events from a MongoDB collection by sending through non existing stream"); 152 | 153 | SiddhiManager siddhiManager = new SiddhiManager(); 154 | String streams = "" + 155 | "define stream StockStream (symbol string, price float, volume long); " + 156 | "define stream FooStream (symbol string); " + 157 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 158 | "define table FooTable (symbol string, price float, volume long);"; 159 | String query = "" + 160 | "@info(name = 'query1') " + 161 | "from StockStream " + 162 | "insert into FooTable ;" + 163 | "" + 164 | "@info(name = 'query2') " + 165 | "from FooStream123#window.length(1) join FooTable " + 166 | "select FooStream.symbol as checkSymbol, FooTable.symbol as symbol, " + 167 | "FooTable.volume as volume " + 168 | "insert into OutputStream ;"; 169 | 170 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 171 | siddhiAppRuntime.start(); 172 | siddhiAppRuntime.shutdown(); 173 | } 174 | 175 | @Test 176 | public void testMongoTableJoinQuery4() throws InterruptedException { 177 | log.info("testMongoTableJoinQuery4 - " + 178 | "DASC5-918:Read events from a MongoDB collection for less attributes than total attribute list"); 179 | 180 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 181 | 182 | SiddhiManager siddhiManager = new SiddhiManager(); 183 | String streams = "" + 184 | "define stream StockStream (symbol string, price float, volume long); " + 185 | "define stream FooStream (symbol string); " + 186 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 187 | "define table FooTable (symbol string, price float, volume long);"; 188 | String query = "" + 189 | "@info(name = 'query1') " + 190 | "from StockStream " + 191 | "insert into FooTable ;" + 192 | "" + 193 | "@info(name = 'query2') " + 194 | "from FooStream#window.length(1) join FooTable " + 195 | "select FooStream.symbol as checkSymbol, FooTable.symbol as symbol " + 196 | "insert into OutputStream ;"; 197 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 198 | siddhiAppRuntime.addCallback("query2", new QueryCallback() { 199 | @Override 200 | public void receive(long timeStamp, Event[] inEvents, Event[] removeEvents) { 201 | if (inEvents != null) { 202 | for (Event event : inEvents) { 203 | eventCount.incrementAndGet(); 204 | switch (eventCount.intValue()) { 205 | case 1: 206 | Assert.assertEquals(new Object[]{"WSO2_check", "WSO2"}, event.getData()); 207 | break; 208 | case 2: 209 | Assert.assertEquals(new Object[]{"WSO2_check", "IBM"}, event.getData()); 210 | break; 211 | default: 212 | break; 213 | } 214 | } 215 | } 216 | } 217 | 218 | }); 219 | 220 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 221 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 222 | siddhiAppRuntime.start(); 223 | 224 | stockStream.send(new Object[]{"WSO2", 5.6f, 100L}); 225 | stockStream.send(new Object[]{"IBM", 7.6f, 10L}); 226 | fooStream.send(new Object[]{"WSO2_check"}); 227 | SiddhiTestHelper.waitForEvents(waitTime, 2, eventCount, timeout); 228 | 229 | siddhiAppRuntime.shutdown(); 230 | 231 | Assert.assertEquals(eventCount.intValue(), 2, "Read events failed"); 232 | } 233 | 234 | @Test(expectedExceptions = SiddhiParserException.class) 235 | public void testMongoTableJoinQuery5() { 236 | log.info("testMongoTableJoinQuery5 - " + 237 | "DASC5-919:Read events from a MongoDB collection for non existing attributes"); 238 | 239 | SiddhiManager siddhiManager = new SiddhiManager(); 240 | String streams = "" + 241 | "define stream StockStream (symbol string, price float, volume long); " + 242 | "define stream FooStream (symbol string); " + 243 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 244 | "define table FooTable (symbol string, price float, volume long);"; 245 | String query = "" + 246 | "@info(name = 'query1') " + 247 | "from StockStream " + 248 | "insert into FooTable ;" + 249 | "" + 250 | "@info(name = 'query2') " + 251 | "from FooStream123#window.length(1) join FooTable " + 252 | "select FooStream.hello as checkHello, FooTable.symbol as symbol, " + 253 | "FooTable.volume as volume " + 254 | "insert into OutputStream ;"; 255 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 256 | siddhiAppRuntime.start(); 257 | siddhiAppRuntime.shutdown(); 258 | } 259 | 260 | @Test 261 | public void testMongoTableJoinQuery6() throws InterruptedException { 262 | log.info("testMongoTableJoinQuery6"); 263 | //Object reads 264 | 265 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 266 | 267 | SiddhiManager siddhiManager = new SiddhiManager(); 268 | String streams = "" + 269 | "define stream StockStream (symbol string, price float, input Object); " + 270 | "define stream FooStream (symbol string); " + 271 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "')" + 272 | "define table FooTable (symbol string, price float, input Object);"; 273 | String query = "" + 274 | "@info(name = 'query1') " + 275 | "from StockStream " + 276 | "insert into FooTable ;" + 277 | "" + 278 | "@info(name = 'query2') " + 279 | "from FooStream#window.length(1) join FooTable " + 280 | "select FooStream.symbol as checkSymbol, FooTable.symbol as symbol, " + 281 | "FooTable.input as input " + 282 | "insert into OutputStream ;"; 283 | 284 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 285 | siddhiAppRuntime.addCallback("query2", new QueryCallback() { 286 | @Override 287 | public void receive(long timeStamp, Event[] inEvents, Event[] removeEvents) { 288 | if (inEvents != null) { 289 | for (Event event : inEvents) { 290 | eventCount.incrementAndGet(); 291 | switch (eventCount.intValue()) { 292 | case 1: 293 | HashMap input = new HashMap<>(); 294 | input.put("symbol", "IBM"); 295 | Assert.assertEquals(new Object[]{"WSO2_check", "WSO2", input}, event.getData()); 296 | break; 297 | default: 298 | break; 299 | } 300 | } 301 | } 302 | } 303 | 304 | }); 305 | 306 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 307 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 308 | siddhiAppRuntime.start(); 309 | 310 | HashMap input = new HashMap<>(); 311 | input.put("symbol", "IBM"); 312 | stockStream.send(new Object[]{"WSO2", 5.6f, input}); 313 | fooStream.send(new Object[]{"WSO2_check"}); 314 | SiddhiTestHelper.waitForEvents(waitTime, 1, eventCount, timeout); 315 | 316 | siddhiAppRuntime.shutdown(); 317 | 318 | Assert.assertEquals(eventCount.intValue(), 1, "Read events failed"); 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /component/src/test/java/org/wso2/extension/siddhi/store/mongodb/UpdateMongoTableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb; 19 | 20 | import org.apache.log4j.Logger; 21 | import org.bson.Document; 22 | import org.testng.Assert; 23 | import org.testng.annotations.AfterClass; 24 | import org.testng.annotations.BeforeClass; 25 | import org.testng.annotations.Test; 26 | import org.wso2.siddhi.core.SiddhiAppRuntime; 27 | import org.wso2.siddhi.core.SiddhiManager; 28 | import org.wso2.siddhi.core.stream.input.InputHandler; 29 | import org.wso2.siddhi.query.api.exception.SiddhiAppValidationException; 30 | 31 | 32 | public class UpdateMongoTableTest { 33 | 34 | private static final Logger log = Logger.getLogger(UpdateMongoTableTest.class); 35 | 36 | private static String uri = MongoTableTestUtils.resolveBaseUri(); 37 | 38 | @BeforeClass 39 | public void init() { 40 | log.info("== Mongo Table UPDATE tests started =="); 41 | } 42 | 43 | @AfterClass 44 | public void shutdown() { 45 | log.info("== Mongo Table UPDATE tests completed =="); 46 | } 47 | 48 | @Test 49 | public void updateFromMongoTableTest1() throws InterruptedException { 50 | log.info("updateFromMongoTableTest1 - DASC5-893:Update events of a MongoDB table successfully"); 51 | 52 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 53 | 54 | SiddhiManager siddhiManager = new SiddhiManager(); 55 | String streams = "" + 56 | "define stream StockStream (symbol string, price float, volume long); " + 57 | "define stream FooStream (symbol string, price float, volume long); " + 58 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 59 | "@PrimaryKey('symbol','price')" + 60 | "define table FooTable (symbol string, price float, volume long);"; 61 | String query = "" + 62 | "@info(name = 'query1') " + 63 | "from StockStream " + 64 | "insert into FooTable ;" + 65 | "" + 66 | "@info(name = 'query2') " + 67 | "from FooStream " + 68 | "select symbol, price, volume " + 69 | "update FooTable " + 70 | "set FooTable.symbol = symbol, FooTable.price = price, FooTable.volume = volume " + 71 | "on FooTable.symbol == symbol;"; 72 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 73 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 74 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 75 | siddhiAppRuntime.start(); 76 | 77 | stockStream.send(new Object[]{"WSO2", 55.6f, 100L}); 78 | stockStream.send(new Object[]{"IBM", 74.6f, 100L}); 79 | stockStream.send(new Object[]{"WSO2_2", 57.6f, 100L}); 80 | fooStream.send(new Object[]{"IBM", 575.6, 500}); 81 | 82 | siddhiAppRuntime.shutdown(); 83 | 84 | long totalDocumentsInCollection = MongoTableTestUtils.getDocumentsCount(uri, "FooTable"); 85 | Assert.assertEquals(totalDocumentsInCollection, 3, "Update failed"); 86 | 87 | Document expectedUpdatedDocument = new Document() 88 | .append("symbol", "IBM") 89 | .append("price", 575.6) 90 | .append("volume", 500); 91 | Document updatedDocument = MongoTableTestUtils.getDocument(uri, "FooTable", "{symbol:'IBM'}"); 92 | Assert.assertEquals(updatedDocument, expectedUpdatedDocument, "Update Failed"); 93 | } 94 | 95 | @Test 96 | public void updateFromMongoTableTest2() throws InterruptedException { 97 | log.info("updateFromMongoTableTest2 - DASC5-894:Updates events of a MongoDB table when query has less " + 98 | "attributes to select from"); 99 | 100 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 101 | 102 | SiddhiManager siddhiManager = new SiddhiManager(); 103 | String streams = "" + 104 | "define stream StockStream (symbol string, price float, volume long); " + 105 | "define stream FooStream (symbol string, price float, volume long); " + 106 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 107 | "@PrimaryKey('symbol','price')" + 108 | "define table FooTable (symbol string, price float, volume long);"; 109 | String query = "" + 110 | "@info(name = 'query1') " + 111 | "from StockStream " + 112 | "insert into FooTable ;" + 113 | "" + 114 | "@info(name = 'query2') " + 115 | "from FooStream " + 116 | "select symbol, price " + 117 | "update FooTable " + 118 | "set FooTable.symbol = symbol, FooTable.price = price, FooTable.volume = volume " + 119 | " on FooTable.symbol == 'IBM' ;"; 120 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 121 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 122 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 123 | siddhiAppRuntime.start(); 124 | 125 | stockStream.send(new Object[]{"WSO2", 55.6f, 100L}); 126 | stockStream.send(new Object[]{"IBM", 74.6f, 100L}); 127 | stockStream.send(new Object[]{"WSO2_2", 57.6f, 100L}); 128 | fooStream.send(new Object[]{"IBM_2", 575.6f, 500L}); 129 | 130 | siddhiAppRuntime.shutdown(); 131 | 132 | long totalDocumentsInCollection = MongoTableTestUtils.getDocumentsCount(uri, "FooTable"); 133 | Assert.assertEquals(totalDocumentsInCollection, 3, "Update failed"); 134 | } 135 | 136 | @Test(expectedExceptions = SiddhiAppValidationException.class) 137 | public void updateFromMongoTableTest3() { 138 | log.info("updateFromMongoTableTest3 - DASC5-895:Update events of a MongoDB table when query has more " + 139 | "attributes to select from"); 140 | 141 | SiddhiManager siddhiManager = new SiddhiManager(); 142 | String streams = "" + 143 | "define stream StockStream (symbol string, price float, volume long); " + 144 | "define stream FooStream (symbol string, price float, volume long); " + 145 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 146 | "@PrimaryKey('symbol','price')" + 147 | "define table FooTable (symbol string, price float, volume long);"; 148 | String query = "" + 149 | "@info(name = 'query1') " + 150 | "from StockStream " + 151 | "insert into FooTable ;" + 152 | "" + 153 | "@info(name = 'query2') " + 154 | "from FooStream " + 155 | "select symbol, price, volume, length " + 156 | "update FooTable " + 157 | "set FooTable.symbol = symbol, FooTable.price = price, FooTable.volume = volume " + 158 | "on FooTable.symbol == symbol;"; 159 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 160 | siddhiAppRuntime.start(); 161 | siddhiAppRuntime.shutdown(); 162 | } 163 | 164 | @Test(expectedExceptions = SiddhiAppValidationException.class) 165 | public void updateFromMongoTableTest4() { 166 | log.info("updateFromMongoTableTest4 - DASC5-896:Updates events of a non existing MongoDB table"); 167 | 168 | SiddhiManager siddhiManager = new SiddhiManager(); 169 | String streams = "" + 170 | "define stream StockStream (symbol string, price float, volume long); " + 171 | "define stream FooStream (symbol string, price float, volume long); " + 172 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 173 | "@PrimaryKey('symbol','price')" + 174 | "define table FooTable (symbol string, price float, volume long);"; 175 | String query = "" + 176 | "@info(name = 'query1') " + 177 | "from StockStream " + 178 | "insert into FooTable ;" + 179 | "" + 180 | "@info(name = 'query2') " + 181 | "from FooStream " + 182 | "select symbol, price, volume " + 183 | "update FooTable3455 " + 184 | "set FooTable.symbol = symbol, FooTable.price = price, FooTable.volume = volume " + 185 | "on FooTable.symbol == symbol;"; 186 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 187 | siddhiAppRuntime.start(); 188 | siddhiAppRuntime.shutdown(); 189 | } 190 | 191 | @Test(expectedExceptions = SiddhiAppValidationException.class) 192 | public void updateFromMongoTableTest5() { 193 | log.info("updateFromMongoTableTest5 - DASC5-897:Updates events of a MongoDB table by selecting from non " + 194 | "existing stream"); 195 | 196 | SiddhiManager siddhiManager = new SiddhiManager(); 197 | String streams = "" + 198 | "define stream StockStream (symbol string, price float, volume long); " + 199 | "define stream FooStream (symbol string, price float, volume long); " + 200 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 201 | "@PrimaryKey('symbol','price')" + 202 | "define table FooTable (symbol string, price float, volume long);"; 203 | String query = "" + 204 | "@info(name = 'query1') " + 205 | "from StockStream " + 206 | "insert into FooTable ;" + 207 | "" + 208 | "@info(name = 'query2') " + 209 | "from FooStream123 " + 210 | "select symbol, price, volume " + 211 | "update FooTable " + 212 | "set FooTable.symbol = symbol, FooTable.price = price, FooTable.volume = volume " + 213 | "on FooTable.symbol == symbol;"; 214 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 215 | siddhiAppRuntime.start(); 216 | siddhiAppRuntime.shutdown(); 217 | } 218 | 219 | @Test(expectedExceptions = SiddhiAppValidationException.class) 220 | public void updateFromMongoTableTest6() { 221 | log.info("updateFromMongoTableTest6 - DASC5-899:Updates events of a MongoDB table based on a non-existing " + 222 | "attribute"); 223 | 224 | SiddhiManager siddhiManager = new SiddhiManager(); 225 | String streams = "" + 226 | "define stream StockStream (symbol string, price float, volume long); " + 227 | "define stream FooStream (symbol string, price float, volume long); " + 228 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 229 | "@PrimaryKey('symbol','price')" + 230 | "define table FooTable (symbol string, price float, volume long);"; 231 | String query = "" + 232 | "@info(name = 'query1') " + 233 | "from StockStream " + 234 | "insert into FooTable ;" + 235 | "" + 236 | "@info(name = 'query2') " + 237 | "from FooStream " + 238 | "select symbol, price, volume " + 239 | "update FooTable " + 240 | "set FooTable.symbol = symbol, FooTable.price = price, FooTable.volume = volume " + 241 | "on FooTable.length == length;"; 242 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 243 | siddhiAppRuntime.start(); 244 | siddhiAppRuntime.shutdown(); 245 | } 246 | 247 | @Test(expectedExceptions = SiddhiAppValidationException.class) 248 | public void updateFromMongoTableTest7() { 249 | log.info("updateFromMongoTableTest7 - DASC5-900:Updates events of a MongoDB table for non-existing attributes"); 250 | 251 | SiddhiManager siddhiManager = new SiddhiManager(); 252 | String streams = "" + 253 | "define stream StockStream (symbol string, price float, volume long); " + 254 | "define stream FooStream (symbol string, price float, volume long); " + 255 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 256 | "@PrimaryKey('symbol','price')" + 257 | "define table FooTable (symbol string, price float, volume long);"; 258 | String query = "" + 259 | "@info(name = 'query1') " + 260 | "from StockStream " + 261 | "insert into FooTable ;" + 262 | "" + 263 | "@info(name = 'query2') " + 264 | "from FooStream " + 265 | "select symbol, price, volume " + 266 | "update FooTable " + 267 | "set FooTable.length = length, FooTable.age = age, FooTable.time = time " + 268 | "on FooTable.symbol == symbol;"; 269 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 270 | siddhiAppRuntime.start(); 271 | siddhiAppRuntime.shutdown(); 272 | } 273 | 274 | @Test 275 | public void updateFromMongoTableTest8() throws InterruptedException { 276 | log.info("updateFromMongoTableTest8 - DASC5-901:Updates events of a MongoDB table for non-existing " + 277 | "attribute value"); 278 | 279 | MongoTableTestUtils.dropCollection(uri, "FooTable"); 280 | 281 | SiddhiManager siddhiManager = new SiddhiManager(); 282 | String streams = "" + 283 | "define stream StockStream (symbol string, price float, volume long); " + 284 | "define stream FooStream (symbol string, price float, volume long); " + 285 | "@store(type = 'mongodb' , mongodb.uri='" + uri + "') " + 286 | "@PrimaryKey('symbol','price')" + 287 | "define table FooTable (symbol string, price float, volume long);"; 288 | String query = "" + 289 | "@info(name = 'query1') " + 290 | "from StockStream " + 291 | "insert into FooTable ;" + 292 | "" + 293 | "@info(name = 'query2') " + 294 | "from FooStream " + 295 | "select symbol, price, volume " + 296 | "update FooTable " + 297 | "set FooTable.symbol = symbol, FooTable.price = price, FooTable.volume = volume " + 298 | "on FooTable.symbol == symbol;"; 299 | SiddhiAppRuntime siddhiAppRuntime = siddhiManager.createSiddhiAppRuntime(streams + query); 300 | InputHandler stockStream = siddhiAppRuntime.getInputHandler("StockStream"); 301 | InputHandler fooStream = siddhiAppRuntime.getInputHandler("FooStream"); 302 | siddhiAppRuntime.start(); 303 | 304 | stockStream.send(new Object[]{"WSO2", 55.6f, 100L}); 305 | stockStream.send(new Object[]{"IBM", 74.6f, 100L}); 306 | stockStream.send(new Object[]{"WSO2_2", 57.6f, 100L}); 307 | fooStream.send(new Object[]{"IBM_2", 575.6, 500}); 308 | 309 | siddhiAppRuntime.shutdown(); 310 | 311 | long totalDocumentsInCollection = MongoTableTestUtils.getDocumentsCount(uri, "FooTable"); 312 | Assert.assertEquals(totalDocumentsInCollection, 3, "Update failed"); 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /component/src/main/java/org/wso2/extension/siddhi/store/mongodb/MongoExpressionVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. 3 | * 4 | * WSO2 Inc. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | package org.wso2.extension.siddhi.store.mongodb; 19 | 20 | import org.wso2.extension.siddhi.store.mongodb.exception.MongoTableException; 21 | import org.wso2.extension.siddhi.store.mongodb.util.Constant; 22 | import org.wso2.extension.siddhi.store.mongodb.util.MongoTableConstants; 23 | import org.wso2.siddhi.core.table.record.BaseExpressionVisitor; 24 | import org.wso2.siddhi.query.api.definition.Attribute; 25 | import org.wso2.siddhi.query.api.expression.condition.Compare; 26 | 27 | import java.util.HashMap; 28 | import java.util.Map; 29 | import java.util.Stack; 30 | import java.util.regex.Matcher; 31 | import java.util.regex.Pattern; 32 | 33 | /** 34 | * Class which is used by the Siddhi runtime for instructions on converting the SiddhiQL condition to the condition 35 | * format understood by the MongoDB. 36 | */ 37 | public class MongoExpressionVisitor extends BaseExpressionVisitor { 38 | private Stack conditionOperands; 39 | private Map placeholders; 40 | 41 | private int streamVarCount; 42 | private int constantCount; 43 | 44 | public MongoExpressionVisitor() { 45 | this.streamVarCount = 0; 46 | this.constantCount = 0; 47 | this.conditionOperands = new Stack<>(); 48 | this.placeholders = new HashMap<>(); 49 | } 50 | 51 | public String getCompiledCondition() { 52 | String compiledCondition = this.conditionOperands.pop(); 53 | for (Map.Entry entry : this.placeholders.entrySet()) { 54 | if (entry.getValue() instanceof Constant) { 55 | Constant constant = (Constant) entry.getValue(); 56 | if (constant.getType().equals(Attribute.Type.STRING)) { 57 | compiledCondition = compiledCondition.replaceAll(entry.getKey(), 58 | "'" + constant.getValue().toString() + "'"); 59 | } else { 60 | compiledCondition = compiledCondition.replaceAll(entry.getKey(), 61 | constant.getValue().toString()); 62 | } 63 | this.placeholders.remove(entry.getKey()); 64 | } 65 | } 66 | return compiledCondition; 67 | } 68 | 69 | public Map getPlaceholders() { 70 | return placeholders; 71 | } 72 | 73 | @Override 74 | public void beginVisitAnd() { 75 | } 76 | 77 | @Override 78 | public void endVisitAnd() { 79 | String rightOperand = this.conditionOperands.pop(); 80 | String leftOperand = this.conditionOperands.pop(); 81 | if (rightOperand.matches(MongoTableConstants.REG_EXPRESSION) && 82 | leftOperand.matches(MongoTableConstants.REG_EXPRESSION)) { 83 | String andFilter = MongoTableConstants.MONGO_AND_FILTER 84 | .replace(MongoTableConstants.PLACEHOLDER_LEFT_OPERAND, leftOperand) 85 | .replace(MongoTableConstants.PLACEHOLDER_RIGHT_OPERAND, rightOperand); 86 | this.conditionOperands.push(andFilter); 87 | } else { 88 | throw new MongoTableException("MongoDB Event Table found operands '" + leftOperand + "' and '" + 89 | rightOperand + "' for AND operation. Mongo Event table only supports AND operation between " + 90 | "two expressions. Please check your query and try again."); 91 | } 92 | } 93 | 94 | @Override 95 | public void beginVisitAndLeftOperand() { 96 | } 97 | 98 | @Override 99 | public void endVisitAndLeftOperand() { 100 | } 101 | 102 | @Override 103 | public void beginVisitAndRightOperand() { 104 | } 105 | 106 | @Override 107 | public void endVisitAndRightOperand() { 108 | } 109 | 110 | @Override 111 | public void beginVisitOr() { 112 | } 113 | 114 | @Override 115 | public void endVisitOr() { 116 | String rightOperand = this.conditionOperands.pop(); 117 | String leftOperand = this.conditionOperands.pop(); 118 | if (rightOperand.matches(MongoTableConstants.REG_EXPRESSION) && 119 | leftOperand.matches(MongoTableConstants.REG_EXPRESSION)) { 120 | String orFilter = MongoTableConstants.MONGO_OR_FILTER 121 | .replace(MongoTableConstants.PLACEHOLDER_LEFT_OPERAND, leftOperand) 122 | .replace(MongoTableConstants.PLACEHOLDER_RIGHT_OPERAND, rightOperand); 123 | this.conditionOperands.push(orFilter); 124 | } else { 125 | throw new MongoTableException("MongoDB Event Table found operands '" + leftOperand + "' and '" + 126 | rightOperand + "' for OR operation.The Mongo Event table only supports OR operation between " + 127 | "two expressions. Please check your query and try again."); 128 | } 129 | } 130 | 131 | @Override 132 | public void beginVisitOrLeftOperand() { 133 | } 134 | 135 | @Override 136 | public void endVisitOrLeftOperand() { 137 | } 138 | 139 | @Override 140 | public void beginVisitOrRightOperand() { 141 | } 142 | 143 | @Override 144 | public void endVisitOrRightOperand() { 145 | } 146 | 147 | @Override 148 | public void beginVisitNot() { 149 | } 150 | 151 | @Override 152 | public void endVisitNot() { 153 | String operand = this.conditionOperands.pop(); 154 | Pattern pattern = Pattern.compile(MongoTableConstants.REG_SIMPLE_EXPRESSION); 155 | Matcher matcher = pattern.matcher(operand); 156 | if (matcher.find()) { 157 | String fieldName = matcher.group(1); 158 | operand = operand.replace(fieldName, MongoTableConstants.MONGO_NOT); 159 | String notFilter = MongoTableConstants.MONGO_NOT_FILTER 160 | .replace(MongoTableConstants.PLACEHOLDER_FIELD_NAME, fieldName) 161 | .replace(MongoTableConstants.PLACEHOLDER_OPERAND, operand); 162 | this.conditionOperands.push(notFilter); 163 | } else { 164 | throw new MongoTableException("MongoDB Event Table found operand '" + operand + "' for NOT operation. " + 165 | "The Mongo Event table only supports NOT operation on simple expression such as compare and null " + 166 | "check. Please check your query and try again."); 167 | } 168 | } 169 | 170 | @Override 171 | public void beginVisitCompare(Compare.Operator operator) { 172 | } 173 | 174 | @Override 175 | public void endVisitCompare(Compare.Operator operator) { 176 | String compareFilter = MongoTableConstants.MONGO_COMPARE_FILTER; 177 | switch (operator) { 178 | case EQUAL: 179 | compareFilter = compareFilter.replace( 180 | MongoTableConstants.PLACEHOLDER_COMPARE_OPERATOR, 181 | MongoTableConstants.MONGO_COMPARE_EQUAL); 182 | break; 183 | case GREATER_THAN: 184 | compareFilter = compareFilter.replace( 185 | MongoTableConstants.PLACEHOLDER_COMPARE_OPERATOR, 186 | MongoTableConstants.MONGO_COMPARE_GREATER_THAN); 187 | break; 188 | case GREATER_THAN_EQUAL: 189 | compareFilter = compareFilter.replace( 190 | MongoTableConstants.PLACEHOLDER_COMPARE_OPERATOR, 191 | MongoTableConstants.MONGO_COMPARE_GREATER_THAN_EQUAL); 192 | break; 193 | case LESS_THAN: 194 | compareFilter = compareFilter.replace( 195 | MongoTableConstants.PLACEHOLDER_COMPARE_OPERATOR, 196 | MongoTableConstants.MONGO_COMPARE_LESS_THAN); 197 | break; 198 | case LESS_THAN_EQUAL: 199 | compareFilter = compareFilter 200 | .replace(MongoTableConstants.PLACEHOLDER_COMPARE_OPERATOR, 201 | MongoTableConstants.MONGO_COMPARE_LESS_THAN_EQUAL); 202 | break; 203 | case NOT_EQUAL: 204 | compareFilter = compareFilter 205 | .replace(MongoTableConstants.PLACEHOLDER_COMPARE_OPERATOR, 206 | MongoTableConstants.MONGO_COMPARE_NOT_EQUAL); 207 | break; 208 | default: 209 | throw new MongoTableException("MongoDB Event Table found unknown operator '" + operator + "' for " + 210 | "COMPARE operation. Please check your query and try again."); 211 | } 212 | 213 | String rightOperand = this.conditionOperands.pop(); 214 | String leftOperand = this.conditionOperands.pop(); 215 | if (!rightOperand.matches(MongoTableConstants.REG_EXPRESSION) && 216 | !leftOperand.matches(MongoTableConstants.REG_EXPRESSION)) { 217 | if (leftOperand.matches(MongoTableConstants.REG_STREAMVAR_OR_CONST) != 218 | rightOperand.matches(MongoTableConstants.REG_STREAMVAR_OR_CONST)) { 219 | if (!rightOperand.matches(MongoTableConstants.REG_STREAMVAR_OR_CONST)) { 220 | compareFilter = compareFilter 221 | .replace(MongoTableConstants.PLACEHOLDER_LEFT_OPERAND, rightOperand) 222 | .replace(MongoTableConstants.PLACEHOLDER_RIGHT_OPERAND, leftOperand); 223 | } else { 224 | compareFilter = compareFilter 225 | .replace(MongoTableConstants.PLACEHOLDER_LEFT_OPERAND, leftOperand) 226 | .replace(MongoTableConstants.PLACEHOLDER_RIGHT_OPERAND, rightOperand); 227 | } 228 | this.conditionOperands.push(compareFilter); 229 | } else { 230 | throw new MongoTableException("MongoDB Event Table found operands '" + leftOperand + "' and '" + 231 | rightOperand + "' for COMPARE operation. The Mongo Event table only supports COMPARE " + 232 | "operation between table attribute and Stream variable/ Constant. Please check your query " + 233 | "and try again."); 234 | } 235 | } else { 236 | throw new MongoTableException("MongoDB Event Table found operands '" + leftOperand + "' and '" + 237 | rightOperand + "' for COMPARE operation. The Mongo Event table does not supports COMPARE " + 238 | "operation between expressions. Please check your query and try again."); 239 | } 240 | } 241 | 242 | @Override 243 | public void beginVisitCompareLeftOperand(Compare.Operator operator) { 244 | } 245 | 246 | @Override 247 | public void endVisitCompareLeftOperand(Compare.Operator operator) { 248 | } 249 | 250 | @Override 251 | public void beginVisitCompareRightOperand(Compare.Operator operator) { 252 | } 253 | 254 | @Override 255 | public void endVisitCompareRightOperand(Compare.Operator operator) { 256 | } 257 | 258 | 259 | @Override 260 | public void beginVisitIsNull(String streamId) { 261 | 262 | 263 | } 264 | 265 | @Override 266 | public void endVisitIsNull(String streamId) { 267 | String operand = this.conditionOperands.pop(); 268 | if (!operand.matches(MongoTableConstants.REG_EXPRESSION) && 269 | !operand.matches(MongoTableConstants.REG_STREAMVAR_OR_CONST)) { 270 | String isNullFilter = MongoTableConstants.MONGO_IS_NULL_FILTER 271 | .replace(MongoTableConstants.PLACEHOLDER_OPERAND, operand); 272 | this.conditionOperands.push(isNullFilter); 273 | } else { 274 | throw new MongoTableException("MongoDB Event Table found operand '" + operand + "' for is NULL operation." + 275 | " The Mongo Event table only supports is NULL operation on a table attribute. Please check your" + 276 | " query and try again."); 277 | } 278 | } 279 | 280 | @Override 281 | public void beginVisitIn(String storeId) { 282 | throw new MongoTableException("MongoDB Event Table does not support IN operations. Please check your" + 283 | " query and try again."); 284 | } 285 | 286 | @Override 287 | public void endVisitIn(String storeId) { 288 | } 289 | 290 | @Override 291 | public void beginVisitMath(MathOperator mathOperator) { 292 | throw new MongoTableException("The Mongo Event table do not support MATH operations. " + 293 | " Please check your query and try again."); 294 | } 295 | 296 | @Override 297 | public void endVisitMath(MathOperator mathOperator) { 298 | } 299 | 300 | @Override 301 | public void beginVisitMathLeftOperand(MathOperator mathOperator) { 302 | } 303 | 304 | @Override 305 | public void endVisitMathLeftOperand(MathOperator mathOperator) { 306 | } 307 | 308 | @Override 309 | public void beginVisitMathRightOperand(MathOperator mathOperator) { 310 | } 311 | 312 | @Override 313 | public void endVisitMathRightOperand(MathOperator mathOperator) { 314 | } 315 | 316 | @Override 317 | public void beginVisitAttributeFunction(String namespace, String functionName) { 318 | throw new MongoTableException("The Mongo Event table do not support Attribute functions. " + 319 | " Please check your query and try again."); 320 | } 321 | 322 | 323 | @Override 324 | public void endVisitAttributeFunction(String namespace, String functionName) { 325 | } 326 | 327 | @Override 328 | public void beginVisitParameterAttributeFunction(int index) { 329 | } 330 | 331 | @Override 332 | public void endVisitParameterAttributeFunction(int index) { 333 | } 334 | 335 | @Override 336 | public void beginVisitStreamVariable(String id, String streamId, String attributeName, Attribute.Type type) { 337 | String name = this.generateStreamVarName(); 338 | this.placeholders.put(name, new Attribute(id, type)); 339 | conditionOperands.push(name); 340 | } 341 | 342 | @Override 343 | public void endVisitStreamVariable(String id, String streamId, String attributeName, Attribute.Type type) { 344 | } 345 | 346 | @Override 347 | public void beginVisitConstant(Object value, Attribute.Type type) { 348 | String name = this.generateConstantName(); 349 | this.placeholders.put(name, new Constant(value, type)); 350 | conditionOperands.push(name); 351 | } 352 | 353 | @Override 354 | public void endVisitConstant(Object value, Attribute.Type type) { 355 | } 356 | 357 | @Override 358 | public void beginVisitStoreVariable(String storeId, String attributeName, Attribute.Type type) { 359 | this.conditionOperands.push(attributeName); 360 | } 361 | 362 | @Override 363 | public void endVisitStoreVariable(String storeId, String attributeName, Attribute.Type type) { 364 | } 365 | 366 | /** 367 | * Method for generating a temporary placeholder for stream variables. 368 | * 369 | * @return a placeholder string of known format. 370 | */ 371 | private String generateStreamVarName() { 372 | String name = "strVar" + this.streamVarCount; 373 | this.streamVarCount++; 374 | return name; 375 | } 376 | 377 | /** 378 | * Method for generating a temporary placeholder for constants. 379 | * 380 | * @return a placeholder string of known format. 381 | */ 382 | private String generateConstantName() { 383 | String name = "const" + this.constantCount; 384 | this.constantCount++; 385 | return name; 386 | } 387 | } 388 | -------------------------------------------------------------------------------- /component/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | 21 | 22 | 4.0.0 23 | 24 | 25 | org.wso2.extension.siddhi.store.mongodb 26 | siddhi-store-mongodb-parent 27 | 1.0.22-SNAPSHOT 28 | ../pom.xml 29 | 30 | bundle 31 | 32 | 33 | siddhi-store-mongodb 34 | WSO2 Siddhi Store Mongodb Extension 35 | 36 | 37 | 38 | org.wso2.siddhi 39 | siddhi-core 40 | 41 | 42 | org.wso2.siddhi 43 | siddhi-query-api 44 | 45 | 46 | commons-logging 47 | commons-logging 48 | 49 | 50 | org.testng 51 | testng 52 | test 53 | 54 | 55 | org.mongodb 56 | mongodb-driver 57 | 58 | 59 | 60 | 61 | 62 | mongod 63 | 64 | 65 | 66 | org.apache.maven.plugins 67 | maven-surefire-plugin 68 | 69 | true 70 | 71 | 72 | 73 | org.jacoco 74 | jacoco-maven-plugin 75 | 76 | 77 | jacoco-initialize 78 | 79 | prepare-agent 80 | 81 | 82 | ${basedir}/target/coverage-reports/jacoco.exec 83 | jcoverage.command 84 | 85 | 86 | 87 | 88 | 89 | io.fabric8 90 | docker-maven-plugin 91 | ${fabric8.docker.version} 92 | 93 | 94 | start-docker-for-mongo 95 | pre-integration-test 96 | 97 | start 98 | 99 | 100 | 101 | stop-docker-for-mongo 102 | post-integration-test 103 | 104 | stop 105 | remove 106 | 107 | 108 | 109 | 110 | 111 | 112 | das-mongo 113 | mongo:3.4 114 | 115 | 116 | admin 117 | admin 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | org.apache.maven.plugins 126 | maven-failsafe-plugin 127 | 128 | 129 | integration-test-for-mongo 130 | integration-test 131 | 132 | integration-test 133 | 134 | 135 | 136 | verify-for-mongo 137 | verify 138 | 139 | verify 140 | 141 | 142 | 143 | 144 | ${jcoverage.command} 145 | 146 | 147 | mongo.servers 148 | ${docker.container.das-mongo.ip}:27017 149 | 150 | 151 | mongo.username 152 | admin 153 | 154 | 155 | mongo.password 156 | admin 157 | 158 | 159 | mongo.database.name 160 | admin 161 | 162 | 163 | 164 | src/test/resources/testngStandalone.xml 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | mongod-ssl 174 | 175 | 176 | 177 | org.apache.maven.plugins 178 | maven-surefire-plugin 179 | 180 | true 181 | 182 | 183 | 184 | org.jacoco 185 | jacoco-maven-plugin 186 | 187 | 188 | jacoco-initialize 189 | 190 | prepare-agent 191 | 192 | 193 | ${basedir}/target/coverage-reports/jacoco-ssl.exec 194 | jcoverage.command 195 | 196 | 197 | 198 | 199 | 200 | io.fabric8 201 | docker-maven-plugin 202 | ${fabric8.docker.version} 203 | 204 | 205 | start-docker-for-mongo 206 | pre-integration-test 207 | 208 | start 209 | 210 | 211 | 212 | stop-docker-for-mongo 213 | post-integration-test 214 | 215 | stop 216 | remove 217 | 218 | 219 | 220 | 221 | 222 | 223 | das-mongo-ssl 224 | rzhilkibaev/mongo-x509-auth-ssl 225 | 226 | 227 | 228 | 229 | 230 | org.apache.maven.plugins 231 | maven-failsafe-plugin 232 | 233 | 234 | integration-test-for-mongo 235 | integration-test 236 | 237 | integration-test 238 | 239 | 240 | 241 | verify-for-mongo 242 | verify 243 | 244 | verify 245 | 246 | 247 | 248 | 249 | ${jcoverage.command} 250 | 251 | 252 | mongo.servers 253 | ${docker.container.das-mongo-ssl.ip}:27017 254 | 255 | 256 | mongo.username 257 | C=US,ST=CA,L=San Francisco,O=Jaspersoft,OU=JSDev,CN=admin 258 | 259 | 260 | mongo.database.name 261 | admin 262 | 263 | 264 | 265 | src/test/resources/testngSecureSSL.xml 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | documentation-deploy 275 | 276 | 277 | 278 | org.wso2.siddhi 279 | siddhi-doc-gen 280 | ${siddhi.version} 281 | 282 | 283 | compile 284 | 285 | deploy-mkdocs-github-pages 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | org.apache.maven.plugins 301 | maven-surefire-plugin 302 | 303 | true 304 | 305 | 306 | 307 | org.apache.felix 308 | maven-bundle-plugin 309 | true 310 | 311 | 312 | ${project.artifactId} 313 | ${project.artifactId} 314 | 315 | com.mongodb.*; 316 | org.bson.*; 317 | 318 | 319 | org.wso2.extension.siddhi.store.mongodb.* 320 | 321 | 322 | org.apache.commons.logging.*;version="${commons.logging.version.range}", 323 | org.wso2.siddhi.annotation.*;version="${siddhi.version.range}", 324 | org.wso2.siddhi.core.*;version="${siddhi.version.range}", 325 | org.wso2.siddhi.query.api.*;version="${siddhi.version.range}", 326 | 327 | 328 | META-INF=target/classes/META-INF 329 | 330 | 331 | 332 | 333 | 334 | org.wso2.siddhi 335 | siddhi-doc-gen 336 | ${siddhi.version} 337 | 338 | 339 | compile 340 | 341 | generate-md-docs 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | -------------------------------------------------------------------------------- /docs/api/1.0.10.md: -------------------------------------------------------------------------------- 1 | # API Docs - v1.0.10 2 | 3 | ## Store 4 | 5 | ### mongodb *(Store)* 6 | 7 |

Using this extension a MongoDB Event Table can be configured to persist events in a MongoDB of user's choice.

8 | 9 | Syntax 10 | ``` 11 | @Store(type="mongodb", mongodb.uri="", collection.name="", secure.connection="", trust.store="", trust.store.password="", key.store="", key.store.password="") 12 | @PrimaryKey("PRIMARY_KEY") 13 | @Index("INDEX") 14 | ``` 15 | 16 | QUERY PARAMETERS 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |
NameDescriptionDefault ValuePossible Data TypesOptionalDynamic
mongodb.uriThe MongoDB URI for the MongoDB data store. The uri must be of the format
mongodb://[username:password@]host1[:port1][,hostN[:portN]][/[database][?options]]
The options specified in the uri will override any connection options specified in the deployment yaml file.
STRINGNoNo
collection.nameThe name of the collection in the store this Event Table should be persisted as.Name of the siddhi event table.STRINGYesNo
secure.connectionDescribes enabling the SSL for the mongodb connectionfalseSTRINGYesNo
trust.storeFile path to the trust store.${carbon.home}/resources/security/client-truststore.jksSTRINGYesNo
trust.store.passwordPassword to access the trust storewso2carbonSTRINGYesNo
key.storeFile path to the keystore.${carbon.home}/resources/security/client-truststore.jksSTRINGYesNo
key.store.passwordPassword to access the keystorewso2carbonSTRINGYesNo
83 | 84 | System Parameters 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 |
NameDescriptionDefault ValuePossible Parameters
applicationNameSets the logical name of the application using this MongoClient. The application name may be used by the client to identify the application to the server, for use in server logs, slow query logs, and profile collection.nullthe logical name of the application using this MongoClient. The UTF-8 encoding may not exceed 128 bytes.
cursorFinalizerEnabledSets whether cursor finalizers are enabled.truetrue
false
requiredReplicaSetNameThe name of the replica setnullthe logical name of the replica set
sslEnabledSets whether to initiate connection with TSL/SSL enabled. true: Initiate the connection with TLS/SSL. false: Initiate the connection without TLS/SSL.falsetrue
false
trustStoreFile path to the trust store.${carbon.home}/resources/security/client-truststore.jksAny valid file path.
trustStorePasswordPassword to access the trust storewso2carbonAny valid password.
keyStoreFile path to the keystore.${carbon.home}/resources/security/client-truststore.jksAny valid file path.
keyStorePasswordPassword to access the keystorewso2carbonAny valid password.
connectTimeoutThe time in milliseconds to attempt a connection before timing out.10000Any positive integer
connectionsPerHostThe maximum number of connections in the connection pool.100Any positive integer
minConnectionsPerHostThe minimum number of connections in the connection pool.0Any natural number
maxConnectionIdleTimeThe maximum number of milliseconds that a connection can remain idle in the pool before being removed and closed. A zero value indicates no limit to the idle time. A pooled connection that has exceeded its idle time will be closed and replaced when necessary by a new connection.0Any positive integer
maxWaitTimeThe maximum wait time in milliseconds that a thread may wait for a connection to become available. A value of 0 means that it will not wait. A negative value means to wait indefinitely120000Any integer
threadsAllowedToBlockForConnectionMultiplierThe maximum number of connections allowed per host for this MongoClient instance. Those connections will be kept in a pool when idle. Once the pool is exhausted, any operation requiring a connection will block waiting for an available connection.100Any natural number
maxConnectionLifeTimeThe maximum life time of a pooled connection. A zero value indicates no limit to the life time. A pooled connection that has exceeded its life time will be closed and replaced when necessary by a new connection.0Any positive integer
socketKeepAliveSets whether to keep a connection alive through firewallsfalsetrue
false
socketTimeoutThe time in milliseconds to attempt a send or receive on a socket before the attempt times out. Default 0 means never to timeout.0Any natural integer
writeConcernThe write concern to use.acknowledgedacknowledged
w1
w2
w3
unacknowledged
fsynced
journaled
replica_acknowledged
normal
safe
majority
fsync_safe
journal_safe
replicas_safe
readConcernThe level of isolation for the reads from replica sets.defaultlocal
majority
linearizable
readPreferenceSpecifies the replica set read preference for the connection.primaryprimary
secondary
secondarypreferred
primarypreferred
nearest
localThresholdThe size (in milliseconds) of the latency window for selecting among multiple suitable MongoDB instances.15Any natural number
serverSelectionTimeoutSpecifies how long (in milliseconds) to block for server selection before throwing an exception. A value of 0 means that it will timeout immediately if no server is available. A negative value means to wait indefinitely.30000Any integer
heartbeatSocketTimeoutThe socket timeout for connections used for the cluster heartbeat. A value of 0 means that it will timeout immediately if no cluster member is available. A negative value means to wait indefinitely.20000Any integer
heartbeatConnectTimeoutThe connect timeout for connections used for the cluster heartbeat. A value of 0 means that it will timeout immediately if no cluster member is available. A negative value means to wait indefinitely.20000Any integer
heartbeatFrequencySpecify the interval (in milliseconds) between checks, counted from the end of the previous check until the beginning of the next one.10000Any positive integer
minHeartbeatFrequencySets the minimum heartbeat frequency. In the event that the driver has to frequently re-check a server's availability, it will wait at least this long since the previous check to avoid wasted effort.500Any positive integer
249 | 250 | Examples 251 | EXAMPLE 1 252 | ``` 253 | @Store(type="mongodb",mongodb.uri="mongodb://admin:admin@localhost/Foo") 254 | @PrimaryKey("symbol") 255 | @IndexBy("volume 1 {background:true,unique:true}") 256 | define table FooTable (symbol string, price float, volume long); 257 | ``` 258 |

This will create a collection called FooTable for the events to be saved with symbol as Primary Key(unique index at mongod level) and index for the field volume will be created in ascending order with the index option to create the index in the background.

Note:
@PrimaryKey: This specifies a list of comma-separated values to be treated as unique fields in the table. Each record in the table must have a unique combination of values for the fields specified here.

@IndexBy: This specifies the fields that must be indexed at the database level. You can specify multiple values as a come-separated list. A single value to be in the format,
?<FieldName> <SortOrder> <IndexOptions>?
<SortOrder> - ( 1) for Ascending and (-1) for Descending
<IndexOptions> - Index Options must be defined inside curly brackets. {} to be used for default options. Options must follow the standard mongodb index options format. Reference : https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/
Example : ?symbol 1 {?unique?:true}?

259 | 260 | --------------------------------------------------------------------------------