Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement MongoDBArtifactStore #4963

Merged

Conversation

jiangpengcheng
Copy link
Contributor

@jiangpengcheng jiangpengcheng commented Sep 4, 2020

This PR provides a MongoDBArtifactStore implementation to enable using MongoDB for storing subjects, whisks and activation in MongoDB, and mostly comes from old PR: #3570.

Since lots of codes are inspired by https://github.com/chetanmeh/openwhisk-mongo, so I added @chetanmeh as co-author

Description

Some users may want to use other database backends instead of CouchDB to store entities, this PR provides MongoDB as an alternative choice for these users

A simple document here: https://cwiki.apache.org/confluence/display/OPENWHISK/MongoDB+Artifact+Store

MongoDB driver

MongoDB provides official drivers for many languages, in this case, we pick the mongo-scala-driver, this driver provides an idiomatic Scala API that is built on top of the MongoDB Async Java driver.

Design Considerations

Data Model

The data scheme in MongoDB is just like CouchDB except that MongoDB doesn't have a _rev field, below is the data of whisk.system/invokerHealthTestAction0 in CouchDB and MongoDB:

CouchDB MongoDB
{
  "_id": "whisk.system/invokerHealthTestAction0",
  "_rev": "68-e72440f911c64ab11441c09e730e5ab8",
  "name": "invokerHealthTestAction0",
  "publish": false,
  "annotations": [],
  "version": "0.0.1",
  "updated": 1524476933182,
  "entityType": "action",
  "exec": {
    "kind": "nodejs:6",
    "code": "function main(params) { return params; }",
    "binary": false
  },
  "parameters": [],
  "limits": {
    "timeout": 60000,
    "memory": 256,
    "logs": 10
  },
  "namespace": "whisk.system"
}
{
  "_id" : "whisk.system/invokerHealthTestAction0",
  "name" : "invokerHealthTestAction0",
  "publish" : false,
  "annotations" : "[ ]",
  "version" : "0.0.1",
  "updated" : NumberLong("1524473794826"),
  "entityType" : "action",
  "exec" : {
    "kind" : "nodejs:6",
    "code" : "function main(params) { return params; }",
    "binary" : false
  },
  "parameters" : "[ ]",
  "limits" : {
    "timeout" : 60000,
    "memory" : 256,
    "logs" : 10
  },
  "namespace" : "whisk.system"
}
  • Since the annotations and parameters fields may using arbitrary strcut and MongoDB doesn't support $ as the first char for field name, so it will convert these two fields to string, and convert it back when get them via openwhisk, this is transparent to users
  • _rev field will not be generated automatically in MongoDB, so it is calculted and inserted in code explicitly

Attachment

MongoDB use GridFS to store and retrieve files that exceed the BSON-document size limit of 16 MB.

Attachment in MongoDB is stored in a separate collection with a independent _id, this PR use the doc._id + doc.file_name as the attachment's _id field, then we can find the relative attachment easily.

Progress

Finished Work

  • Basic Usage(create、update、query、delete)
  • Attachment Support
  • Automated deployment of MongoDB using Ansible
  • CI Integration
  • Documents

FurtherWork

  • Add MongoDB support for wskadmin
  • Support batch insert

My changes affect the following components

  • Data stores (e.g., CouchDB)
  • Tests
  • Deployment
  • CLI
  • Documentation

Types of changes

  • Enhancement or new feature (adds new functionality).

Checklist:

  • I signed an Apache CLA.
  • I reviewed the style guides and followed the recommendations (Travis CI will check :).
  • I added tests to cover my changes.
  • My changes require further changes to the documentation.
  • I updated the documentation where necessary.

@style95
Copy link
Member

style95 commented Sep 7, 2020

This is great!

@bdoyle0182
Copy link
Contributor

Will go through this sometime this week! Thanks!

import scala.util.Try
import scala.util.Failure

class AsyncStreamSource(stream: AsyncInputStream, chunkSize: Int)(implicit ec: ExecutionContext)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make the naming for the akka graph stages more specific so it's clear what they're used for? Something like ActionAttachmentByteStreamSource

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

// MongoDB doesn't support using `$` as the first char of field name, so below two fields needs to be encoded first
private val fieldsNeedEncode = Seq("annotations", "parameters")

override protected[database] def put(d: DocumentAbstraction)(implicit transid: TransactionId): Future[DocInfo] = {
Copy link

@michael-falk michael-falk Sep 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'm unsure how this variable is generally named.

Looking at called methods (e.g. failed, finished), could we rename this to transaction?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean the transid here? such name are also used in other places


val f = collection
.find(Filters.eq("_id", doc.id.id)) // method deserialize will check whether the _rev matched
.toFuture()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: any thoughts on .toSingle().toFutureOption()? Your result would be a Future[Option[A]] which looks to match your check for an empty collection or single-item collection below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, I didn't find which object have the toSingle method?

//Work done perform close
//Using async "blessed" callback does not work at this stage so
// need to invoke as normal callback
//TODO Revisit this

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need an open issue here to track? I can see this TODO get lost

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not related to current master code, so I think it is unfit to record as an issue?

* @param collName the name of the collection to operate on
* @param documentHandler helper class help to simulate the designDoc of CouchDB
* @param viewMapper helper class help to simulate the designDoc of CouchDB
*/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I don't tend to see scala docs on your other files. Are they expected like here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for mention! I will add such comment doc to other places

@jiangpengcheng jiangpengcheng changed the title Implement MongoDBActivationStore Implement MongoDBArtifactStore Oct 15, 2020
@bdoyle0182
Copy link
Contributor

I think we should go ahead with merging this to provide a total alternative to couchdb for people. Are you all using this in production?

@style95
Copy link
Member

style95 commented Apr 6, 2021

@bdoyle0182 We are not yet using this but will use it at some point as we can't keep up with CouchDB.

@bdoyle0182
Copy link
Contributor

Yea that's why I suggested. We also can't keep up with couchdb. I think we should offer it, but it does seem weird to advertise it without any production cases. We could potentially attempt to try it, but will need to either have dual write / reads or a safe way to migrate the data

Copy link
Member

@rabbah rabbah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit about the readme. I scanned this but did not go through it thoroughly. +1 to advance the PR and merge.

@@ -191,6 +191,42 @@ ansible-playbook -i environments/<environment> routemgmt.yml
- To use the API Gateway, you'll need to run `apigateway.yml` and `routemgmt.yml`.
- Use `ansible-playbook -i environments/<environment> openwhisk.yml` to avoid wiping the data store. This is useful to start OpenWhisk after restarting your Operating System.

### Deploying Using MongoDB

You can use MongoDB as the database backend, and there is an ansible task to deploy a single node MongoDB server for testing and developing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not clear reading this part of the doc if mongo is for entities, activations, or both.

@jiangpengcheng jiangpengcheng force-pushed the implement_mongodb_artifact_store branch from 97387f8 to 68120f2 Compare April 7, 2021 09:05
commonEnv:
CONFIG_whisk_mongodb_uri: "{{ db.mongodb.connect_string }}"
CONFIG_whisk_mongodb_database: "{{ db.mongodb.database }}"
CONFIG_whisk_spi_ArtifactStoreProvider: "org.apache.openwhisk.core.database.mongodb.MongoDBArtifactStoreProvider"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to follow the convention just like the others?

spi: "{{ userLogs_spi | default('org.apache.openwhisk.core.containerpool.logging.DockerToActivationLogStoreProvider') }}"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can follow elasticsearch activation store style?

- name: setup elasticsearch activation store env
set_fact:
elastic_env:
"CONFIG_whisk_activationStore_elasticsearch_protocol": "{{ db.elasticsearch.protocol}}"
"CONFIG_whisk_activationStore_elasticsearch_hosts": "{{ elasticsearch_connect_string }}"
"CONFIG_whisk_activationStore_elasticsearch_indexPattern": "{{ db.elasticsearch.index_pattern }}"
"CONFIG_whisk_activationStore_elasticsearch_username": "{{ db.elasticsearch.auth.admin.username }}"
"CONFIG_whisk_activationStore_elasticsearch_password": "{{ db.elasticsearch.auth.admin.password }}"
"CONFIG_whisk_spi_ActivationStoreProvider": "org.apache.openwhisk.core.database.elasticsearch.ElasticSearchActivationStoreProvider"
when: db.activation_store.backend == "ElasticSearch"
- name: merge elasticsearch activation store env
set_fact:
env: "{{ env | combine(elastic_env) }}"
when: db.activation_store.backend == "ElasticSearch"

module: mongodb
short_description: A module which support some simple operations on MongoDB.
description:
- Including add user/insert document/create indexes in MongoDB
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this tool does something similar to wskadmin, should we put this under tools?
https://github.com/apache/openwhisk/blob/68120f2170dc9f9b53361ab0cb51c4e9458dbe29/tools/admin/wskadmin

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is like an ansible library

state: absent
keep_volumes: False

- name: remove MongoDB data volume
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose even if a user wants to clean up his container, he may still want to keep his data.
I`d rather keep volumes or at least make it configurable to keep volumes when cleaning up the container.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sense, I will update

# This role will run a MongoDB server on the db group, this is only for test, please use
# shared cluster for production env

- name: (re)start mongodb
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW I think this can be handled in the subsequent PR, but just asking, should we include some steps to set up a MongoDB cluster rather than a standalone one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the standalone one is just for user to check the feature, we can submit a subsequent PR to setup a MongoDB cluster

import scala.reflect.ClassTag

case class MongoDBConfig(uri: String, database: String) {
assume(Set(database, uri).forall(_.nonEmpty), "At least one expected property is missing")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering if it's possible for one of these two parameters to be missing.
I suppose even if an empty string is passed, we can't check that with this.

Copy link
Contributor Author

@jiangpengcheng jiangpengcheng Apr 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, do you mean one parameter is an empty string "" or " "?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, Set(database, uri) would be always nonEmpty.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the _.nonEmpty will check against database and url in the Set instead of Set itself since there is a forall

scala> Set("", "asd").forall(_.nonEmpty)
res0: Boolean = false

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is this.

scala> Set("", "").forall(_.nonEmpty)
res0: Boolean = false

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so in this case Set("", ""), assume will raise an error, this is expected

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok now I get it.


// calculate the revision manually, to be compatible with couchdb's _rev field
private def revisionCalculate(doc: JsObject): (String, String) = {
val md: MessageDigest = MessageDigest.getInstance("MD5")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great, I will update

if (rev.startsWith("1-")) {
// for new document, we should get no matched document and insert new one
// if there is a matched document, that one with no _rev filed will be replaced
// if there is a document with the same id but has an _rev field, will return en E11000(conflict) error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible for MongoDB to include _rev field?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, I didn't get it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I got confused.
According to the description in this PR, MongoDB doesn't have this field.

The data scheme in MongoDB is just like CouchDB except that MongoDB doesn't have a _rev field, below is the data of whisk.system/invokerHealthTestAction0 in CouchDB and MongoDB:

So I thought we can't use a field name _rev for some reason, but it seems not.
While CouchDB manages _rev value, this will manually manage revision using revisionCalculator.
https://github.com/apache/openwhisk/pull/4963/files/68120f2170dc9f9b53361ab0cb51c4e9458dbe29#diff-f5da2a3c01f4ecedf28b8c10af6bb42c71ce4ad7f66424497f81523c17e33469R572

So the field _rev is also stored in MongoDB along with other fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, CouchDb will generate _rev automatically, while MongoDB should set this field manually

DocInfo(DocId(id), DocRevision(rev))
}
.recover {
case t: MongoException if t.getCode == 11000 =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great to add some comment to describe what 11000(conflict) stands for or suggesting to use a constant for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

val attachmentScheme: String = attachmentStore.map(_.scheme).getOrElse(mongodbScheme)

private val database = client.getDatabase(dbName)
private val collection = getCollectionAndCreateIndexes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit
getCollectionAndCreateIndexes -> getCollectionAndCreateIndexes() to indicate there is a side effect according to the scala convention.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

* @param documentHandler helper class help to simulate the designDoc of CouchDB
* @param viewMapper helper class help to simulate the designDoc of CouchDB
*/
class MongoDBArtifactStore[DocumentAbstraction <: DocumentSerializer](client: MongoClient,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need comprehensive documents describing the internals of this component and source/sink.
That would be helpful for those who have less background in MongoDB like me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I will try

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codecov-io
Copy link

codecov-io commented Apr 16, 2021

Codecov Report

Merging #4963 (747de8f) into master (59b67fe) will decrease coverage by 8.35%.
The diff coverage is 34.21%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #4963      +/-   ##
==========================================
- Coverage   81.46%   73.11%   -8.36%     
==========================================
  Files         209      223      +14     
  Lines       10344    11115     +771     
  Branches      450      467      +17     
==========================================
- Hits         8427     8127     -300     
- Misses       1917     2988    +1071     
Impacted Files Coverage Δ
...k/core/database/mongodb/MongoDBArtifactStore.scala 0.00% <0.00%> (ø)
...atabase/mongodb/MongoDBArtifactStoreProvider.scala 0.00% <0.00%> (ø)
...core/database/mongodb/MongoDBAsyncStreamSink.scala 93.54% <93.54%> (ø)
...re/database/mongodb/MongoDBAsyncStreamSource.scala 95.83% <95.83%> (ø)
...hisk/core/database/mongodb/MongoDBViewMapper.scala 98.88% <98.88%> (ø)
.../scala/org/apache/openwhisk/core/WhiskConfig.scala 95.51% <100.00%> (+0.02%) ⬆️
...core/database/cosmosdb/RxObservableImplicits.scala 0.00% <0.00%> (-100.00%) ⬇️
...ore/database/cosmosdb/cache/CacheInvalidator.scala 0.00% <0.00%> (-100.00%) ⬇️
...e/database/cosmosdb/cache/ChangeFeedConsumer.scala 0.00% <0.00%> (-100.00%) ⬇️
...core/database/cosmosdb/CosmosDBArtifactStore.scala 0.00% <0.00%> (-95.85%) ⬇️
... and 47 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 59b67fe...747de8f. Read the comment docs.

@codecov-commenter
Copy link

codecov-commenter commented Apr 19, 2021

Codecov Report

Attention: Patch coverage is 34.21687% with 273 lines in your changes missing coverage. Please review.

Project coverage is 70.11%. Comparing base (59b67fe) to head (d62917d).
Report is 217 commits behind head on master.

Files with missing lines Patch % Lines
...k/core/database/mongodb/MongoDBArtifactStore.scala 0.00% 251 Missing ⚠️
...atabase/mongodb/MongoDBArtifactStoreProvider.scala 0.00% 18 Missing ⚠️
...core/database/mongodb/MongoDBAsyncStreamSink.scala 93.54% 2 Missing ⚠️
...re/database/mongodb/MongoDBAsyncStreamSource.scala 95.83% 1 Missing ⚠️
...hisk/core/database/mongodb/MongoDBViewMapper.scala 98.88% 1 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (59b67fe) and HEAD (d62917d). Click for more details.

HEAD has 23 uploads less than BASE
Flag BASE (59b67fe) HEAD (d62917d)
27 4
Additional details and impacted files
@@             Coverage Diff             @@
##           master    #4963       +/-   ##
===========================================
- Coverage   81.46%   70.11%   -11.36%     
===========================================
  Files         209      231       +22     
  Lines       10344    12272     +1928     
  Branches      450      499       +49     
===========================================
+ Hits         8427     8604      +177     
- Misses       1917     3668     +1751     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@style95 style95 requested a review from KeonHee April 29, 2021 06:20
"CONFIG_whisk_mongodb_uri": "{{ db.mongodb.connect_string }}"
"CONFIG_whisk_mongodb_database": "{{ db.mongodb.database }}"
"CONFIG_whisk_spi_ArtifactStoreProvider": "org.apache.openwhisk.core.database.mongodb.MongoDBArtifactStoreProvider"
when: db.backend == "MongoDB"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if this is defined along with db.activation_store.backend == "ElasticSearch"?

I feel we need to consolidate DB related configuration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should work well with ES as activation backend while mongodb store other entities

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant we need a consolidated way to configure multiple DBs for each entity store as we have more options for them.

For example, we might consider the following option:

  1. Use the database for all entities if only db.backend is defined.
  2. Use a different database for activation if db.activation_store.backend is defined along with db.backend.
  3. Use a different database for whisk entities if db.artifact_store.backend is defined along with db.backend.
    .
    .
    .

if no specific backend store is defined, we can fall back to db.backend by default.
We can have fine granularity but I feel like having two configurations for activations and the others would be enough for now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think activation is a kind of artifact? so db.artifact_store.backend should refer to all kind of entities including activation, which is just like what db.backend do here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can name them accordingly as long as we can selectively configure activation stores and the other stores.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so use db.artifact_store.backend for all entities, and db.activation_store.backend for activations?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be a good starting point.
I believe we can add more options for subjects, whisk entities in the future if required.

cd <openwhisk_home>
./gradlew distDocker
cd ansible
ansible-playbook -i environments/<environment> initMongodb.yml -e mongodb_connect_string="mongodb://172.17.0.1:27017"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the relation with db_local.ini?

Getting this when deploying this change.

TASK [prepare db_local.ini] *********************************************************************************************************************************************************
Monday 24 May 2021  15:07:04 +0900 (0:00:00.883)       0:00:02.373 ************
fatal: [localhost -> localhost]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'db'"}

AnsibleUndefinedVariable: 'dict object' has no attribute 'db'

PLAY RECAP **************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems pymongo needs to be installed.
then it should be documented somewhere.

TASK [create necessary auth keys] ******************************************************************************************************************************************************************************************************************************************************************************************************************************************
Monday 24 May 2021  15:57:29 +0900 (0:00:01.872)       0:00:02.229 ************
failed: [ansible] (item=guest) => {"changed": false, "item": "guest", "msg": "the python pymongo module is required"}
failed: [ansible] (item=whisk.system) => {"changed": false, "item": "whisk.system", "msg": "the python pymongo module is required"}

All items completed

PLAY RECAP *****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
ansible                    : ok=1    changed=0    unreachable=0    failed=1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite sure the reason yet but I am unable to deploy this change with this line.

scheduler:
  dataManagementService:
    retryInterval: "{{ scheduler_dataManagementService_retryInterval | default(1 second) }}"
TASK [kafka : add kafka default env vars] **********************************************************************************************************************************************************************************************************************************************************************************************************************************
Monday 24 May 2021  16:07:39 +0900 (0:00:00.054)       0:00:13.372 ************
fatal: [kafka0]: FAILED! => {"msg": "An unhandled exception occurred while templating '{% set ret = [] %}{% for host in groups['zookeepers'] %}{{ ret.append( hostvars[host].ansible_host + ':' + ((zookeeper.port+loop.index-1)|string) ) }}{% endfor %}{{ ret | join(',') }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: template error while templating string: expected token ',', got 'second'. String: {{ scheduler_dataManagementService_retryInterval | default(1 second) }}"}

An unhandled exception occurred while templating '{% set ret = [] %}{% for
host in groups['zookeepers'] %}{{ ret.append( hostvars[host].ansible_host + ':'
+ ((zookeeper.port+loop.index-1)|string) ) }}{% endfor %}{{ ret | join(',') }}'.
Error was a <class 'ansible.errors.AnsibleError'>, original message: template
error while templating string: expected token ',', got 'second'. String: {{
scheduler_dataManagementService_retryInterval | default(1 second) }}

Copy link
Contributor Author

@jiangpengcheng jiangpengcheng May 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will remove db_local.ini relation
seems group_vars/all needs a db_local.ini

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, db_local.ini is being used to specify the target DB, can we apply the same for MongoDB as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for 2.5.2 we need to add ' ' around string value, like default('1 second')

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh ok, then that should be updated as we guide users to use ansible=2.5.2.
https://github.com/apache/openwhisk/tree/master/ansible

Copy link
Contributor Author

@jiangpengcheng jiangpengcheng May 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I will create a new PR to fix this
it's already fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could move to a more modern version of ansible (in separate PRs of course). We don't have to stay on 2.5.2 forever.

Copy link
Contributor

@ddragosd ddragosd Jun 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could move to a more modern version of ansible (in separate PRs of course). We don't have to stay on 2.5.2 forever.

I'm installing OW on a clean new machine and I'm updating the versions that worked.

Copy link
Member

@style95 style95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could deploy OW with the mongodb as a database.
image

cd <openwhisk_home>
./gradlew distDocker
cd ansible
ansible-playbook -i environments/<environment> initMongodb.yml -e mongodb_connect_string="mongodb://172.17.0.1:27017"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite sure the reason yet but I am unable to deploy this change with this line.

scheduler:
  dataManagementService:
    retryInterval: "{{ scheduler_dataManagementService_retryInterval | default(1 second) }}"
TASK [kafka : add kafka default env vars] **********************************************************************************************************************************************************************************************************************************************************************************************************************************
Monday 24 May 2021  16:07:39 +0900 (0:00:00.054)       0:00:13.372 ************
fatal: [kafka0]: FAILED! => {"msg": "An unhandled exception occurred while templating '{% set ret = [] %}{% for host in groups['zookeepers'] %}{{ ret.append( hostvars[host].ansible_host + ':' + ((zookeeper.port+loop.index-1)|string) ) }}{% endfor %}{{ ret | join(',') }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: template error while templating string: expected token ',', got 'second'. String: {{ scheduler_dataManagementService_retryInterval | default(1 second) }}"}

An unhandled exception occurred while templating '{% set ret = [] %}{% for
host in groups['zookeepers'] %}{{ ret.append( hostvars[host].ansible_host + ':'
+ ((zookeeper.port+loop.index-1)|string) ) }}{% endfor %}{{ ret | join(',') }}'.
Error was a <class 'ansible.errors.AnsibleError'>, original message: template
error while templating string: expected token ',', got 'second'. String: {{
scheduler_dataManagementService_retryInterval | default(1 second) }}

cd ansible
ansible-playbook -i environments/<environment> initMongodb.yml -e mongodb_connect_string="mongodb://172.17.0.1:27017"
ansible-playbook -i environments/<environment> apigateway.yml -e mongodb_connect_string="mongodb://172.17.0.1:27017"
ansible-playbook -i environments/<environment> openwhisk.yml -e mongodb_connect_string="mongodb://172.17.0.1:27017" -e db_artifact_backend="MongoDB"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope we can add some description about the relationship between db_artifact_backend and db_activation_backend.

They can coexist and if no db_activation_backend is specified, the system will use db_artifact_backend by default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Member

@style95 style95 May 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this also needs to be handled with this #4963 (comment)
as currently, users can't configure each DB interchangeably.

- name: merge mongodb artifact store env
set_fact:
env: "{{ env | combine(mongodb_env) }}"
when: db.artifact_store.backend == "MongoDB"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do this can we use MongoDB as an activation store and CouchDB as an artifact store?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, this is for artifact, which means all kind of entities

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What users can do if they want to use the CouchDB artifact store with the MongoDB activation store?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I havn't test such case yet

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I think that can be handled in a different PR.

@style95 style95 merged commit 9279626 into apache:master Jun 9, 2021
@rabbah
Copy link
Member

rabbah commented Jun 9, 2021

🎉 👏 nice to finally merge this capability! Great work.

@bdoyle0182
Copy link
Contributor

bdoyle0182 commented Feb 14, 2023

Playing around with this and got it working on a test deployment, but the one thing I haven't figured out is updating the limits for a namespace. Combing through the code and I think that may have been missed having support for since the limits doc lookup in couchdb was done through the identities view, unless I'm missing something. @style95 wondering if you have any idea or we need to take a work item for full compatibility.

edit: nvm looks like I potentially got bit by some caching, seems to be working. passing all of my validations now this is awesome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants