Repository files navigation

Joyce

Joyce Release
Documentation Release
Libraries Build

Componentdockerlatest versionBuild
Import Gatewaysourcesense/joyce-import-gatewayDocker Image Version (latest semver)Import Engine Build
Joyce Kafka Connectsourcesense/joyce-kafka-connectDocker Image Version (latest semver)Kafka Connect Build
Mongodb Sinksourcesense/joyce-mongodb-sinkDocker Image Version (latest semver)Mongodb Sink Build
Restsourcesense/joyce-apiDocker Image Version (latest semver)API Docker Release

Introduction

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Ok! Wait, what? Joyce allows you to ingest data from (almost) any source and expose the ingested data as standard APIs (REST, event notification) automatically. In order to specify to Joyce which data we want to pick from the incoming data stream and how APIs will look like you need to describe the expected behaviour with a DSL based on json-schema.

From a high level perspective Joyce performs 4 tasks:

  • acquire content produced from different sources.
  • transform the raw content with a DSL (a schema)
  • store it somewhere (to a sink)
  • serve the result of this process with an automatic REST API.

Documentation

Documentation is available here

Getting Started

cd joyce-compose
docker-compose up -d

This will startup:

  • a single node kafka instance persisted under data directory
  • a single node zookeeper instance persisted under data directory
  • a single node mongodb instance persisted under data directory
  • AKHQ to monitor kafka topics exposed at localhost:6680
  • joyce-import-gateway exposing it's API at localhost:6651
  • joyce-mongodb-sink to store processed content to mongodb
  • joyce-api exposed at localhost:6650 to consume processed content.

Save a schema

First of all we have to store a schema that tells the system how to project the content we import inside Joyce.

A schema is an enhanced json-schema with keywords that tells how to transform/project a content.

For a complete documentation on schema go here

You can write a schema in json or yaml.

Let's try to save one.

cat > import-user.yaml <<- "EOF"$schema: https://joyce.sourcesense.com/v1/schema$metadata: subtype: import namespace: default name: user description: A test schema development: true uid: code collection: userstype: objectproperties: code: type: integer $path: $.user_id name: type: string $path: $.first_name surname: type: string $path: $.last_name full_name: type: string $script:  language: python code: "'_'.join([source['first_name'].upper(), source['last_name'].upper()])" email: type: string email_checks: type: object $rest: url: "https://api.eva.pingutil.com/email?email={{email}}" method: GET headers: Content-Type: application/json vars: email: "$.email" extract: "$.data" properties: valid: type: boolean $path: $.valid_syntax disposable: type: boolean spam: type: boolean kind: type: string $fixed: "SimpleUser"EOF

Now we have to save the schema to import-gateway component:

curl -X POST -H "Content-Type: application/x-yaml" --data-binary @import-user.yaml http://localhost:6651/api/schema

Now your schema is ready to be used by the api, you can check it by going to http://localhost:6651/api/schema/import/default/user.

Configure API

If you go to http://localhost:6650/docs you'll see a swagger interface with no resources, that's why resource derives from schema and must be configured to be exposed.

create a file schemas.json with this content:

cat > schemas.json <<- "EOF"{  "schemas": { "test-users": { "source": "http://import-gateway:6651/api/schema/import/default/user" } }}EOF

Edit the docker compose to expose the file as a volume:

rest:
image: sourcesense/joyce-rest:latestports:
- "6650:6650"environment:
- MONGO_URI=mongodb://user:password@mongodb:27017/joyce+ - SCHEMAS_SOURCE=/opt/schemas.json+ volumes:
+ - ./schemas.json:/opt/schemas.jsonlinks:
- mongodb
- import-gateway

Now restart the api to load the schema:

docker-compose stop rest
docker-compose up -d rest

Check again swagger http://localhost:6650/docs and you'll see your resource.

Import documents

Now you are ready to store content to the import-gateway:

curl -0 -v "http://localhost:6651/api/import" \
-H 'Content-Type: application/json; charset=utf-8' \
-H "accept: application/json; charset=utf-8" \
-H "X-Joyce-Schema-Id: joyce://schema/import/default.user""http://localhost:6651/api/import" \
--data-binary @- <<EOF{ "user_id": 1337, "first_name": "Jon", "last_name": "Snow", "email": "jon@winterfell.cold", "state": "Westeros"}EOF

Your content should be transformed soon and can be retrieved using the api

curl http://localhost:6650/api/test-users

If anything goes wrong, notification of errors and success during processing are published on the joyce_notification topic on kafka, you can inspect easily by using akhq on localhost:6680.

About

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Topics

Resources

Stars

38 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Joyce

Joyce Release
Documentation Release
Libraries Build

Componentdockerlatest versionBuild
Import Gatewaysourcesense/joyce-import-gatewayDocker Image Version (latest semver)Import Engine Build
Joyce Kafka Connectsourcesense/joyce-kafka-connectDocker Image Version (latest semver)Kafka Connect Build
Mongodb Sinksourcesense/joyce-mongodb-sinkDocker Image Version (latest semver)Mongodb Sink Build
Restsourcesense/joyce-apiDocker Image Version (latest semver)API Docker Release

Introduction

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Ok! Wait, what? Joyce allows you to ingest data from (almost) any source and expose the ingested data as standard APIs (REST, event notification) automatically. In order to specify to Joyce which data we want to pick from the incoming data stream and how APIs will look like you need to describe the expected behaviour with a DSL based on json-schema.

From a high level perspective Joyce performs 4 tasks:

  • acquire content produced from different sources.
  • transform the raw content with a DSL (a schema)
  • store it somewhere (to a sink)
  • serve the result of this process with an automatic REST API.

Documentation

Documentation is available here

Getting Started

cd joyce-compose
docker-compose up -d

This will startup:

  • a single node kafka instance persisted under data directory
  • a single node zookeeper instance persisted under data directory
  • a single node mongodb instance persisted under data directory
  • AKHQ to monitor kafka topics exposed at localhost:6680
  • joyce-import-gateway exposing it's API at localhost:6651
  • joyce-mongodb-sink to store processed content to mongodb
  • joyce-api exposed at localhost:6650 to consume processed content.

Save a schema

First of all we have to store a schema that tells the system how to project the content we import inside Joyce.

A schema is an enhanced json-schema with keywords that tells how to transform/project a content.

For a complete documentation on schema go here

You can write a schema in json or yaml.

Let's try to save one.

cat > import-user.yaml <<- "EOF"$schema: https://joyce.sourcesense.com/v1/schema$metadata: subtype: import namespace: default name: user description: A test schema development: true uid: code collection: userstype: objectproperties: code: type: integer $path: $.user_id name: type: string $path: $.first_name surname: type: string $path: $.last_name full_name: type: string $script:  language: python code: "'_'.join([source['first_name'].upper(), source['last_name'].upper()])" email: type: string email_checks: type: object $rest: url: "https://api.eva.pingutil.com/email?email={{email}}" method: GET headers: Content-Type: application/json vars: email: "$.email" extract: "$.data" properties: valid: type: boolean $path: $.valid_syntax disposable: type: boolean spam: type: boolean kind: type: string $fixed: "SimpleUser"EOF

Now we have to save the schema to import-gateway component:

curl -X POST -H "Content-Type: application/x-yaml" --data-binary @import-user.yaml http://localhost:6651/api/schema

Now your schema is ready to be used by the api, you can check it by going to http://localhost:6651/api/schema/import/default/user.

Configure API

If you go to http://localhost:6650/docs you'll see a swagger interface with no resources, that's why resource derives from schema and must be configured to be exposed.

create a file schemas.json with this content:

cat > schemas.json <<- "EOF"{  "schemas": { "test-users": { "source": "http://import-gateway:6651/api/schema/import/default/user" } }}EOF

Edit the docker compose to expose the file as a volume:

rest:
image: sourcesense/joyce-rest:latestports:
- "6650:6650"environment:
- MONGO_URI=mongodb://user:password@mongodb:27017/joyce+ - SCHEMAS_SOURCE=/opt/schemas.json+ volumes:
+ - ./schemas.json:/opt/schemas.jsonlinks:
- mongodb
- import-gateway

Now restart the api to load the schema:

docker-compose stop rest
docker-compose up -d rest

Check again swagger http://localhost:6650/docs and you'll see your resource.

Import documents

Now you are ready to store content to the import-gateway:

curl -0 -v "http://localhost:6651/api/import" \
-H 'Content-Type: application/json; charset=utf-8' \
-H "accept: application/json; charset=utf-8" \
-H "X-Joyce-Schema-Id: joyce://schema/import/default.user""http://localhost:6651/api/import" \
--data-binary @- <<EOF{ "user_id": 1337, "first_name": "Jon", "last_name": "Snow", "email": "jon@winterfell.cold", "state": "Westeros"}EOF

Your content should be transformed soon and can be retrieved using the api

curl http://localhost:6650/api/test-users

If anything goes wrong, notification of errors and success during processing are published on the joyce_notification topic on kafka, you can inspect easily by using akhq on localhost:6680.

About

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Topics

Resources

Stars

38 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Joyce

Joyce Release
Documentation Release
Libraries Build

Componentdockerlatest versionBuild
Import Gatewaysourcesense/joyce-import-gatewayDocker Image Version (latest semver)Import Engine Build
Joyce Kafka Connectsourcesense/joyce-kafka-connectDocker Image Version (latest semver)Kafka Connect Build
Mongodb Sinksourcesense/joyce-mongodb-sinkDocker Image Version (latest semver)Mongodb Sink Build
Restsourcesense/joyce-apiDocker Image Version (latest semver)API Docker Release

Introduction

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Ok! Wait, what? Joyce allows you to ingest data from (almost) any source and expose the ingested data as standard APIs (REST, event notification) automatically. In order to specify to Joyce which data we want to pick from the incoming data stream and how APIs will look like you need to describe the expected behaviour with a DSL based on json-schema.

From a high level perspective Joyce performs 4 tasks:

  • acquire content produced from different sources.
  • transform the raw content with a DSL (a schema)
  • store it somewhere (to a sink)
  • serve the result of this process with an automatic REST API.

Documentation

Documentation is available here

Getting Started

cd joyce-compose
docker-compose up -d

This will startup:

  • a single node kafka instance persisted under data directory
  • a single node zookeeper instance persisted under data directory
  • a single node mongodb instance persisted under data directory
  • AKHQ to monitor kafka topics exposed at localhost:6680
  • joyce-import-gateway exposing it's API at localhost:6651
  • joyce-mongodb-sink to store processed content to mongodb
  • joyce-api exposed at localhost:6650 to consume processed content.

Save a schema

First of all we have to store a schema that tells the system how to project the content we import inside Joyce.

A schema is an enhanced json-schema with keywords that tells how to transform/project a content.

For a complete documentation on schema go here

You can write a schema in json or yaml.

Let's try to save one.

cat > import-user.yaml <<- "EOF"$schema: https://joyce.sourcesense.com/v1/schema$metadata: subtype: import namespace: default name: user description: A test schema development: true uid: code collection: userstype: objectproperties: code: type: integer $path: $.user_id name: type: string $path: $.first_name surname: type: string $path: $.last_name full_name: type: string $script:  language: python code: "'_'.join([source['first_name'].upper(), source['last_name'].upper()])" email: type: string email_checks: type: object $rest: url: "https://api.eva.pingutil.com/email?email={{email}}" method: GET headers: Content-Type: application/json vars: email: "$.email" extract: "$.data" properties: valid: type: boolean $path: $.valid_syntax disposable: type: boolean spam: type: boolean kind: type: string $fixed: "SimpleUser"EOF

Now we have to save the schema to import-gateway component:

curl -X POST -H "Content-Type: application/x-yaml" --data-binary @import-user.yaml http://localhost:6651/api/schema

Now your schema is ready to be used by the api, you can check it by going to http://localhost:6651/api/schema/import/default/user.

Configure API

If you go to http://localhost:6650/docs you'll see a swagger interface with no resources, that's why resource derives from schema and must be configured to be exposed.

create a file schemas.json with this content:

cat > schemas.json <<- "EOF"{  "schemas": { "test-users": { "source": "http://import-gateway:6651/api/schema/import/default/user" } }}EOF

Edit the docker compose to expose the file as a volume:

rest:
image: sourcesense/joyce-rest:latestports:
- "6650:6650"environment:
- MONGO_URI=mongodb://user:password@mongodb:27017/joyce+ - SCHEMAS_SOURCE=/opt/schemas.json+ volumes:
+ - ./schemas.json:/opt/schemas.jsonlinks:
- mongodb
- import-gateway

Now restart the api to load the schema:

docker-compose stop rest
docker-compose up -d rest

Check again swagger http://localhost:6650/docs and you'll see your resource.

Import documents

Now you are ready to store content to the import-gateway:

curl -0 -v "http://localhost:6651/api/import" \
-H 'Content-Type: application/json; charset=utf-8' \
-H "accept: application/json; charset=utf-8" \
-H "X-Joyce-Schema-Id: joyce://schema/import/default.user""http://localhost:6651/api/import" \
--data-binary @- <<EOF{ "user_id": 1337, "first_name": "Jon", "last_name": "Snow", "email": "jon@winterfell.cold", "state": "Westeros"}EOF

Your content should be transformed soon and can be retrieved using the api

curl http://localhost:6650/api/test-users

If anything goes wrong, notification of errors and success during processing are published on the joyce_notification topic on kafka, you can inspect easily by using akhq on localhost:6680.

About

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Topics

Resources

Stars

38 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Joyce

Joyce Release
Documentation Release
Libraries Build

Componentdockerlatest versionBuild
Import Gatewaysourcesense/joyce-import-gatewayDocker Image Version (latest semver)Import Engine Build
Joyce Kafka Connectsourcesense/joyce-kafka-connectDocker Image Version (latest semver)Kafka Connect Build
Mongodb Sinksourcesense/joyce-mongodb-sinkDocker Image Version (latest semver)Mongodb Sink Build
Restsourcesense/joyce-apiDocker Image Version (latest semver)API Docker Release

Introduction

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Ok! Wait, what? Joyce allows you to ingest data from (almost) any source and expose the ingested data as standard APIs (REST, event notification) automatically. In order to specify to Joyce which data we want to pick from the incoming data stream and how APIs will look like you need to describe the expected behaviour with a DSL based on json-schema.

From a high level perspective Joyce performs 4 tasks:

  • acquire content produced from different sources.
  • transform the raw content with a DSL (a schema)
  • store it somewhere (to a sink)
  • serve the result of this process with an automatic REST API.

Documentation

Documentation is available here

Getting Started

cd joyce-compose
docker-compose up -d

This will startup:

  • a single node kafka instance persisted under data directory
  • a single node zookeeper instance persisted under data directory
  • a single node mongodb instance persisted under data directory
  • AKHQ to monitor kafka topics exposed at localhost:6680
  • joyce-import-gateway exposing it's API at localhost:6651
  • joyce-mongodb-sink to store processed content to mongodb
  • joyce-api exposed at localhost:6650 to consume processed content.

Save a schema

First of all we have to store a schema that tells the system how to project the content we import inside Joyce.

A schema is an enhanced json-schema with keywords that tells how to transform/project a content.

For a complete documentation on schema go here

You can write a schema in json or yaml.

Let's try to save one.

cat > import-user.yaml <<- "EOF"$schema: https://joyce.sourcesense.com/v1/schema$metadata: subtype: import namespace: default name: user description: A test schema development: true uid: code collection: userstype: objectproperties: code: type: integer $path: $.user_id name: type: string $path: $.first_name surname: type: string $path: $.last_name full_name: type: string $script:  language: python code: "'_'.join([source['first_name'].upper(), source['last_name'].upper()])" email: type: string email_checks: type: object $rest: url: "https://api.eva.pingutil.com/email?email={{email}}" method: GET headers: Content-Type: application/json vars: email: "$.email" extract: "$.data" properties: valid: type: boolean $path: $.valid_syntax disposable: type: boolean spam: type: boolean kind: type: string $fixed: "SimpleUser"EOF

Now we have to save the schema to import-gateway component:

curl -X POST -H "Content-Type: application/x-yaml" --data-binary @import-user.yaml http://localhost:6651/api/schema

Now your schema is ready to be used by the api, you can check it by going to http://localhost:6651/api/schema/import/default/user.

Configure API

If you go to http://localhost:6650/docs you'll see a swagger interface with no resources, that's why resource derives from schema and must be configured to be exposed.

create a file schemas.json with this content:

cat > schemas.json <<- "EOF"{  "schemas": { "test-users": { "source": "http://import-gateway:6651/api/schema/import/default/user" } }}EOF

Edit the docker compose to expose the file as a volume:

rest:
image: sourcesense/joyce-rest:latestports:
- "6650:6650"environment:
- MONGO_URI=mongodb://user:password@mongodb:27017/joyce+ - SCHEMAS_SOURCE=/opt/schemas.json+ volumes:
+ - ./schemas.json:/opt/schemas.jsonlinks:
- mongodb
- import-gateway

Now restart the api to load the schema:

docker-compose stop rest
docker-compose up -d rest

Check again swagger http://localhost:6650/docs and you'll see your resource.

Import documents

Now you are ready to store content to the import-gateway:

curl -0 -v "http://localhost:6651/api/import" \
-H 'Content-Type: application/json; charset=utf-8' \
-H "accept: application/json; charset=utf-8" \
-H "X-Joyce-Schema-Id: joyce://schema/import/default.user""http://localhost:6651/api/import" \
--data-binary @- <<EOF{ "user_id": 1337, "first_name": "Jon", "last_name": "Snow", "email": "jon@winterfell.cold", "state": "Westeros"}EOF

Your content should be transformed soon and can be retrieved using the api

curl http://localhost:6650/api/test-users

If anything goes wrong, notification of errors and success during processing are published on the joyce_notification topic on kafka, you can inspect easily by using akhq on localhost:6680.

About

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Topics

Resources

Stars

38 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Joyce

Joyce Release
Documentation Release
Libraries Build

Componentdockerlatest versionBuild
Import Gatewaysourcesense/joyce-import-gatewayDocker Image Version (latest semver)Import Engine Build
Joyce Kafka Connectsourcesense/joyce-kafka-connectDocker Image Version (latest semver)Kafka Connect Build
Mongodb Sinksourcesense/joyce-mongodb-sinkDocker Image Version (latest semver)Mongodb Sink Build
Restsourcesense/joyce-apiDocker Image Version (latest semver)API Docker Release

Introduction

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Ok! Wait, what? Joyce allows you to ingest data from (almost) any source and expose the ingested data as standard APIs (REST, event notification) automatically. In order to specify to Joyce which data we want to pick from the incoming data stream and how APIs will look like you need to describe the expected behaviour with a DSL based on json-schema.

From a high level perspective Joyce performs 4 tasks:

  • acquire content produced from different sources.
  • transform the raw content with a DSL (a schema)
  • store it somewhere (to a sink)
  • serve the result of this process with an automatic REST API.

Documentation

Documentation is available here

Getting Started

cd joyce-compose
docker-compose up -d

This will startup:

  • a single node kafka instance persisted under data directory
  • a single node zookeeper instance persisted under data directory
  • a single node mongodb instance persisted under data directory
  • AKHQ to monitor kafka topics exposed at localhost:6680
  • joyce-import-gateway exposing it's API at localhost:6651
  • joyce-mongodb-sink to store processed content to mongodb
  • joyce-api exposed at localhost:6650 to consume processed content.

Save a schema

First of all we have to store a schema that tells the system how to project the content we import inside Joyce.

A schema is an enhanced json-schema with keywords that tells how to transform/project a content.

For a complete documentation on schema go here

You can write a schema in json or yaml.

Let's try to save one.

cat > import-user.yaml <<- "EOF"$schema: https://joyce.sourcesense.com/v1/schema$metadata: subtype: import namespace: default name: user description: A test schema development: true uid: code collection: userstype: objectproperties: code: type: integer $path: $.user_id name: type: string $path: $.first_name surname: type: string $path: $.last_name full_name: type: string $script:  language: python code: "'_'.join([source['first_name'].upper(), source['last_name'].upper()])" email: type: string email_checks: type: object $rest: url: "https://api.eva.pingutil.com/email?email={{email}}" method: GET headers: Content-Type: application/json vars: email: "$.email" extract: "$.data" properties: valid: type: boolean $path: $.valid_syntax disposable: type: boolean spam: type: boolean kind: type: string $fixed: "SimpleUser"EOF

Now we have to save the schema to import-gateway component:

curl -X POST -H "Content-Type: application/x-yaml" --data-binary @import-user.yaml http://localhost:6651/api/schema

Now your schema is ready to be used by the api, you can check it by going to http://localhost:6651/api/schema/import/default/user.

Configure API

If you go to http://localhost:6650/docs you'll see a swagger interface with no resources, that's why resource derives from schema and must be configured to be exposed.

create a file schemas.json with this content:

cat > schemas.json <<- "EOF"{  "schemas": { "test-users": { "source": "http://import-gateway:6651/api/schema/import/default/user" } }}EOF

Edit the docker compose to expose the file as a volume:

rest:
image: sourcesense/joyce-rest:latestports:
- "6650:6650"environment:
- MONGO_URI=mongodb://user:password@mongodb:27017/joyce+ - SCHEMAS_SOURCE=/opt/schemas.json+ volumes:
+ - ./schemas.json:/opt/schemas.jsonlinks:
- mongodb
- import-gateway

Now restart the api to load the schema:

docker-compose stop rest
docker-compose up -d rest

Check again swagger http://localhost:6650/docs and you'll see your resource.

Import documents

Now you are ready to store content to the import-gateway:

curl -0 -v "http://localhost:6651/api/import" \
-H 'Content-Type: application/json; charset=utf-8' \
-H "accept: application/json; charset=utf-8" \
-H "X-Joyce-Schema-Id: joyce://schema/import/default.user""http://localhost:6651/api/import" \
--data-binary @- <<EOF{ "user_id": 1337, "first_name": "Jon", "last_name": "Snow", "email": "jon@winterfell.cold", "state": "Westeros"}EOF

Your content should be transformed soon and can be retrieved using the api

curl http://localhost:6650/api/test-users

If anything goes wrong, notification of errors and success during processing are published on the joyce_notification topic on kafka, you can inspect easily by using akhq on localhost:6680.

About

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Topics

Resources

Stars

38 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Joyce

Joyce Release
Documentation Release
Libraries Build

Componentdockerlatest versionBuild
Import Gatewaysourcesense/joyce-import-gatewayDocker Image Version (latest semver)Import Engine Build
Joyce Kafka Connectsourcesense/joyce-kafka-connectDocker Image Version (latest semver)Kafka Connect Build
Mongodb Sinksourcesense/joyce-mongodb-sinkDocker Image Version (latest semver)Mongodb Sink Build
Restsourcesense/joyce-apiDocker Image Version (latest semver)API Docker Release

Introduction

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Ok! Wait, what? Joyce allows you to ingest data from (almost) any source and expose the ingested data as standard APIs (REST, event notification) automatically. In order to specify to Joyce which data we want to pick from the incoming data stream and how APIs will look like you need to describe the expected behaviour with a DSL based on json-schema.

From a high level perspective Joyce performs 4 tasks:

  • acquire content produced from different sources.
  • transform the raw content with a DSL (a schema)
  • store it somewhere (to a sink)
  • serve the result of this process with an automatic REST API.

Documentation

Documentation is available here

Getting Started

cd joyce-compose
docker-compose up -d

This will startup:

  • a single node kafka instance persisted under data directory
  • a single node zookeeper instance persisted under data directory
  • a single node mongodb instance persisted under data directory
  • AKHQ to monitor kafka topics exposed at localhost:6680
  • joyce-import-gateway exposing it's API at localhost:6651
  • joyce-mongodb-sink to store processed content to mongodb
  • joyce-api exposed at localhost:6650 to consume processed content.

Save a schema

First of all we have to store a schema that tells the system how to project the content we import inside Joyce.

A schema is an enhanced json-schema with keywords that tells how to transform/project a content.

For a complete documentation on schema go here

You can write a schema in json or yaml.

Let's try to save one.

cat > import-user.yaml <<- "EOF"$schema: https://joyce.sourcesense.com/v1/schema$metadata: subtype: import namespace: default name: user description: A test schema development: true uid: code collection: userstype: objectproperties: code: type: integer $path: $.user_id name: type: string $path: $.first_name surname: type: string $path: $.last_name full_name: type: string $script:  language: python code: "'_'.join([source['first_name'].upper(), source['last_name'].upper()])" email: type: string email_checks: type: object $rest: url: "https://api.eva.pingutil.com/email?email={{email}}" method: GET headers: Content-Type: application/json vars: email: "$.email" extract: "$.data" properties: valid: type: boolean $path: $.valid_syntax disposable: type: boolean spam: type: boolean kind: type: string $fixed: "SimpleUser"EOF

Now we have to save the schema to import-gateway component:

curl -X POST -H "Content-Type: application/x-yaml" --data-binary @import-user.yaml http://localhost:6651/api/schema

Now your schema is ready to be used by the api, you can check it by going to http://localhost:6651/api/schema/import/default/user.

Configure API

If you go to http://localhost:6650/docs you'll see a swagger interface with no resources, that's why resource derives from schema and must be configured to be exposed.

create a file schemas.json with this content:

cat > schemas.json <<- "EOF"{  "schemas": { "test-users": { "source": "http://import-gateway:6651/api/schema/import/default/user" } }}EOF

Edit the docker compose to expose the file as a volume:

rest:
image: sourcesense/joyce-rest:latestports:
- "6650:6650"environment:
- MONGO_URI=mongodb://user:password@mongodb:27017/joyce+ - SCHEMAS_SOURCE=/opt/schemas.json+ volumes:
+ - ./schemas.json:/opt/schemas.jsonlinks:
- mongodb
- import-gateway

Now restart the api to load the schema:

docker-compose stop rest
docker-compose up -d rest

Check again swagger http://localhost:6650/docs and you'll see your resource.

Import documents

Now you are ready to store content to the import-gateway:

curl -0 -v "http://localhost:6651/api/import" \
-H 'Content-Type: application/json; charset=utf-8' \
-H "accept: application/json; charset=utf-8" \
-H "X-Joyce-Schema-Id: joyce://schema/import/default.user""http://localhost:6651/api/import" \
--data-binary @- <<EOF{ "user_id": 1337, "first_name": "Jon", "last_name": "Snow", "email": "jon@winterfell.cold", "state": "Westeros"}EOF

Your content should be transformed soon and can be retrieved using the api

curl http://localhost:6650/api/test-users

If anything goes wrong, notification of errors and success during processing are published on the joyce_notification topic on kafka, you can inspect easily by using akhq on localhost:6680.

About

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Topics

Resources

Stars

38 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Joyce

Joyce Release
Documentation Release
Libraries Build

Componentdockerlatest versionBuild
Import Gatewaysourcesense/joyce-import-gatewayDocker Image Version (latest semver)Import Engine Build
Joyce Kafka Connectsourcesense/joyce-kafka-connectDocker Image Version (latest semver)Kafka Connect Build
Mongodb Sinksourcesense/joyce-mongodb-sinkDocker Image Version (latest semver)Mongodb Sink Build
Restsourcesense/joyce-apiDocker Image Version (latest semver)API Docker Release

Introduction

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Ok! Wait, what? Joyce allows you to ingest data from (almost) any source and expose the ingested data as standard APIs (REST, event notification) automatically. In order to specify to Joyce which data we want to pick from the incoming data stream and how APIs will look like you need to describe the expected behaviour with a DSL based on json-schema.

From a high level perspective Joyce performs 4 tasks:

  • acquire content produced from different sources.
  • transform the raw content with a DSL (a schema)
  • store it somewhere (to a sink)
  • serve the result of this process with an automatic REST API.

Documentation

Documentation is available here

Getting Started

cd joyce-compose
docker-compose up -d

This will startup:

  • a single node kafka instance persisted under data directory
  • a single node zookeeper instance persisted under data directory
  • a single node mongodb instance persisted under data directory
  • AKHQ to monitor kafka topics exposed at localhost:6680
  • joyce-import-gateway exposing it's API at localhost:6651
  • joyce-mongodb-sink to store processed content to mongodb
  • joyce-api exposed at localhost:6650 to consume processed content.

Save a schema

First of all we have to store a schema that tells the system how to project the content we import inside Joyce.

A schema is an enhanced json-schema with keywords that tells how to transform/project a content.

For a complete documentation on schema go here

You can write a schema in json or yaml.

Let's try to save one.

cat > import-user.yaml <<- "EOF"$schema: https://joyce.sourcesense.com/v1/schema$metadata: subtype: import namespace: default name: user description: A test schema development: true uid: code collection: userstype: objectproperties: code: type: integer $path: $.user_id name: type: string $path: $.first_name surname: type: string $path: $.last_name full_name: type: string $script:  language: python code: "'_'.join([source['first_name'].upper(), source['last_name'].upper()])" email: type: string email_checks: type: object $rest: url: "https://api.eva.pingutil.com/email?email={{email}}" method: GET headers: Content-Type: application/json vars: email: "$.email" extract: "$.data" properties: valid: type: boolean $path: $.valid_syntax disposable: type: boolean spam: type: boolean kind: type: string $fixed: "SimpleUser"EOF

Now we have to save the schema to import-gateway component:

curl -X POST -H "Content-Type: application/x-yaml" --data-binary @import-user.yaml http://localhost:6651/api/schema

Now your schema is ready to be used by the api, you can check it by going to http://localhost:6651/api/schema/import/default/user.

Configure API

If you go to http://localhost:6650/docs you'll see a swagger interface with no resources, that's why resource derives from schema and must be configured to be exposed.

create a file schemas.json with this content:

cat > schemas.json <<- "EOF"{  "schemas": { "test-users": { "source": "http://import-gateway:6651/api/schema/import/default/user" } }}EOF

Edit the docker compose to expose the file as a volume:

rest:
image: sourcesense/joyce-rest:latestports:
- "6650:6650"environment:
- MONGO_URI=mongodb://user:password@mongodb:27017/joyce+ - SCHEMAS_SOURCE=/opt/schemas.json+ volumes:
+ - ./schemas.json:/opt/schemas.jsonlinks:
- mongodb
- import-gateway

Now restart the api to load the schema:

docker-compose stop rest
docker-compose up -d rest

Check again swagger http://localhost:6650/docs and you'll see your resource.

Import documents

Now you are ready to store content to the import-gateway:

curl -0 -v "http://localhost:6651/api/import" \
-H 'Content-Type: application/json; charset=utf-8' \
-H "accept: application/json; charset=utf-8" \
-H "X-Joyce-Schema-Id: joyce://schema/import/default.user""http://localhost:6651/api/import" \
--data-binary @- <<EOF{ "user_id": 1337, "first_name": "Jon", "last_name": "Snow", "email": "jon@winterfell.cold", "state": "Westeros"}EOF

Your content should be transformed soon and can be retrieved using the api

curl http://localhost:6650/api/test-users

If anything goes wrong, notification of errors and success during processing are published on the joyce_notification topic on kafka, you can inspect easily by using akhq on localhost:6680.

About

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Topics

Resources

Stars

38 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Joyce

Joyce Release
Documentation Release
Libraries Build

Componentdockerlatest versionBuild
Import Gatewaysourcesense/joyce-import-gatewayDocker Image Version (latest semver)Import Engine Build
Joyce Kafka Connectsourcesense/joyce-kafka-connectDocker Image Version (latest semver)Kafka Connect Build
Mongodb Sinksourcesense/joyce-mongodb-sinkDocker Image Version (latest semver)Mongodb Sink Build
Restsourcesense/joyce-apiDocker Image Version (latest semver)API Docker Release

Introduction

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Ok! Wait, what? Joyce allows you to ingest data from (almost) any source and expose the ingested data as standard APIs (REST, event notification) automatically. In order to specify to Joyce which data we want to pick from the incoming data stream and how APIs will look like you need to describe the expected behaviour with a DSL based on json-schema.

From a high level perspective Joyce performs 4 tasks:

  • acquire content produced from different sources.
  • transform the raw content with a DSL (a schema)
  • store it somewhere (to a sink)
  • serve the result of this process with an automatic REST API.

Documentation

Documentation is available here

Getting Started

cd joyce-compose
docker-compose up -d

This will startup:

  • a single node kafka instance persisted under data directory
  • a single node zookeeper instance persisted under data directory
  • a single node mongodb instance persisted under data directory
  • AKHQ to monitor kafka topics exposed at localhost:6680
  • joyce-import-gateway exposing it's API at localhost:6651
  • joyce-mongodb-sink to store processed content to mongodb
  • joyce-api exposed at localhost:6650 to consume processed content.

Save a schema

First of all we have to store a schema that tells the system how to project the content we import inside Joyce.

A schema is an enhanced json-schema with keywords that tells how to transform/project a content.

For a complete documentation on schema go here

You can write a schema in json or yaml.

Let's try to save one.

cat > import-user.yaml <<- "EOF"$schema: https://joyce.sourcesense.com/v1/schema$metadata: subtype: import namespace: default name: user description: A test schema development: true uid: code collection: userstype: objectproperties: code: type: integer $path: $.user_id name: type: string $path: $.first_name surname: type: string $path: $.last_name full_name: type: string $script:  language: python code: "'_'.join([source['first_name'].upper(), source['last_name'].upper()])" email: type: string email_checks: type: object $rest: url: "https://api.eva.pingutil.com/email?email={{email}}" method: GET headers: Content-Type: application/json vars: email: "$.email" extract: "$.data" properties: valid: type: boolean $path: $.valid_syntax disposable: type: boolean spam: type: boolean kind: type: string $fixed: "SimpleUser"EOF

Now we have to save the schema to import-gateway component:

curl -X POST -H "Content-Type: application/x-yaml" --data-binary @import-user.yaml http://localhost:6651/api/schema

Now your schema is ready to be used by the api, you can check it by going to http://localhost:6651/api/schema/import/default/user.

Configure API

If you go to http://localhost:6650/docs you'll see a swagger interface with no resources, that's why resource derives from schema and must be configured to be exposed.

create a file schemas.json with this content:

cat > schemas.json <<- "EOF"{  "schemas": { "test-users": { "source": "http://import-gateway:6651/api/schema/import/default/user" } }}EOF

Edit the docker compose to expose the file as a volume:

rest:
image: sourcesense/joyce-rest:latestports:
- "6650:6650"environment:
- MONGO_URI=mongodb://user:password@mongodb:27017/joyce+ - SCHEMAS_SOURCE=/opt/schemas.json+ volumes:
+ - ./schemas.json:/opt/schemas.jsonlinks:
- mongodb
- import-gateway

Now restart the api to load the schema:

docker-compose stop rest
docker-compose up -d rest

Check again swagger http://localhost:6650/docs and you'll see your resource.

Import documents

Now you are ready to store content to the import-gateway:

curl -0 -v "http://localhost:6651/api/import" \
-H 'Content-Type: application/json; charset=utf-8' \
-H "accept: application/json; charset=utf-8" \
-H "X-Joyce-Schema-Id: joyce://schema/import/default.user""http://localhost:6651/api/import" \
--data-binary @- <<EOF{ "user_id": 1337, "first_name": "Jon", "last_name": "Snow", "email": "jon@winterfell.cold", "state": "Westeros"}EOF

Your content should be transformed soon and can be retrieved using the api

curl http://localhost:6650/api/test-users

If anything goes wrong, notification of errors and success during processing are published on the joyce_notification topic on kafka, you can inspect easily by using akhq on localhost:6680.

About

Joyce is a highly scalable event-driven Cloud Native Data Hub.

Topics

Resources

Stars

38 stars

Watchers

11 watching

Forks

Releases

Packages

Used by

Contributors

Languages