├── .editorconfig
├── .gitattributes
├── .github
└── ISSUE_TEMPLATE
│ └── 01-compatible-certification-request.md
├── .gitignore
├── CONTRIBUTING.adoc
├── LICENSE
├── NOTICE
├── README.adoc
├── api
├── .gitignore
├── bnd.bnd
├── package-lock.json
├── package.json
├── pom.xml
└── src
│ ├── docs
│ └── js
│ │ ├── SourceCodePro-Regular.ttf
│ │ ├── generate-marble-diagrams.js
│ │ ├── index.html
│ │ ├── marble-diagram-hashes.json
│ │ ├── mp-rs-ops-marbles.js
│ │ ├── puppeteer.html
│ │ ├── svg-marbles.js
│ │ └── verify-marble-diagrams.js
│ └── main
│ ├── java
│ └── org
│ │ └── eclipse
│ │ └── microprofile
│ │ └── reactive
│ │ └── streams
│ │ └── operators
│ │ ├── CompletionRunner.java
│ │ ├── CompletionSubscriber.java
│ │ ├── ConnectingOperators.java
│ │ ├── ConsumingOperators.java
│ │ ├── ErrorHandlingOperators.java
│ │ ├── FilteringOperators.java
│ │ ├── PeekingOperators.java
│ │ ├── ProcessorBuilder.java
│ │ ├── ProducesResult.java
│ │ ├── PublisherBuilder.java
│ │ ├── ReactiveStreams.java
│ │ ├── ReactiveStreamsFactory.java
│ │ ├── SubscriberBuilder.java
│ │ ├── TransformingOperators.java
│ │ ├── doc-files
│ │ ├── collect.png
│ │ ├── concat.png
│ │ ├── coupled.png
│ │ ├── distinct.png
│ │ ├── dropWhile.png
│ │ ├── empty.png
│ │ ├── example.png
│ │ ├── failed.png
│ │ ├── filter.png
│ │ ├── findFirst.png
│ │ ├── flatMap.png
│ │ ├── flatMapCompletionStage.png
│ │ ├── flatMapIterable.png
│ │ ├── flatMapRsPublisher.png
│ │ ├── forEach.png
│ │ ├── fromCompletionStage.png
│ │ ├── fromCompletionStageNullable.png
│ │ ├── fromIterable.png
│ │ ├── generate.png
│ │ ├── identity.png
│ │ ├── ignore.png
│ │ ├── iterate.png
│ │ ├── limit.png
│ │ ├── map.png
│ │ ├── of-many.png
│ │ ├── of-single.png
│ │ ├── ofNullable.png
│ │ ├── onComplete.png
│ │ ├── onError.png
│ │ ├── onErrorResume.png
│ │ ├── onErrorResumeWith.png
│ │ ├── onErrorResumeWithRsPublisher.png
│ │ ├── onTerminate.png
│ │ ├── peek.png
│ │ ├── reduce-identity.png
│ │ ├── reduce.png
│ │ ├── skip.png
│ │ ├── takeWhile.png
│ │ └── toList.png
│ │ ├── package-info.java
│ │ └── spi
│ │ ├── Graph.java
│ │ ├── ReactiveStreamsEngine.java
│ │ ├── ReactiveStreamsFactoryResolver.java
│ │ ├── Stage.java
│ │ ├── SubscriberWithCompletionStage.java
│ │ ├── ToGraphable.java
│ │ ├── UnsupportedStageException.java
│ │ └── package-info.java
│ └── resources
│ └── META-INF
│ ├── LICENSE
│ └── NOTICE
├── approach.asciidoc
├── core
├── bnd.bnd
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── eclipse
│ │ └── microprofile
│ │ └── reactive
│ │ └── streams
│ │ └── operators
│ │ └── core
│ │ ├── CompletionRunnerImpl.java
│ │ ├── GraphImpl.java
│ │ ├── InternalStages.java
│ │ ├── ProcessorBuilderImpl.java
│ │ ├── PublisherBuilderImpl.java
│ │ ├── ReactiveStreamsEngineResolver.java
│ │ ├── ReactiveStreamsFactoryImpl.java
│ │ ├── ReactiveStreamsGraphBuilder.java
│ │ ├── Reductions.java
│ │ ├── Stages.java
│ │ ├── SubscriberBuilderImpl.java
│ │ └── package-info.java
│ └── resources
│ └── META-INF
│ ├── LICENSE
│ ├── NOTICE
│ └── services
│ └── org.eclipse.microprofile.reactive.streams.operators.ReactiveStreamsFactory
├── pom.xml
├── site.yaml
├── spec
├── pom.xml
└── src
│ └── main
│ ├── asciidoc
│ ├── architecture.asciidoc
│ ├── cdi.asciidoc
│ ├── design.asciidoc
│ ├── examples.asciidoc
│ ├── images
│ │ ├── change-shape.svg
│ │ ├── closed-graph-builder.svg
│ │ ├── picture-sources.odg
│ │ ├── processor-builder.svg
│ │ ├── processor-stage.svg
│ │ ├── publisher-builder.svg
│ │ ├── publisher-stage.svg
│ │ ├── subscriber-builder.svg
│ │ └── subscriber-stage.svg
│ ├── implementation.asciidoc
│ ├── java-streams.asciidoc
│ ├── license-alv2.asciidoc
│ ├── license-efsl.adoc
│ ├── microprofile-reactive-streams-operators-spec.asciidoc
│ ├── release_notes.asciidoc
│ └── spi.asciidoc
│ └── resources
│ └── META-INF
│ ├── LICENSE
│ └── NOTICE
└── tck
├── README.adoc
├── pom.xml
└── src
├── main
├── java
│ └── org
│ │ └── eclipse
│ │ └── microprofile
│ │ └── reactive
│ │ └── streams
│ │ └── operators
│ │ └── tck
│ │ ├── DefaultReactiveStreamsFactory.java
│ │ ├── ReactiveStreamsTck.java
│ │ ├── api
│ │ ├── AbstractReactiveStreamsApiVerification.java
│ │ ├── CompletionRunnerVerification.java
│ │ ├── CompletionSubscriberVerification.java
│ │ ├── Mocks.java
│ │ ├── ProcessorBuilderVerification.java
│ │ ├── PublisherBuilderVerification.java
│ │ ├── ReactiveStreamsApiVerification.java
│ │ ├── ReactiveStreamsVerification.java
│ │ └── SubscriberBuilderVerification.java
│ │ ├── arquillian
│ │ ├── ReactiveStreamsArquillianTck.java
│ │ └── ReactiveStreamsCdiTck.java
│ │ └── spi
│ │ ├── AbstractStageVerification.java
│ │ ├── CancelStageVerification.java
│ │ ├── CollectStageVerification.java
│ │ ├── ConcatStageVerification.java
│ │ ├── CoupledStageVerification.java
│ │ ├── DistinctStageVerification.java
│ │ ├── DropWhileStageVerification.java
│ │ ├── EmptyProcessorVerification.java
│ │ ├── FilterStageVerification.java
│ │ ├── FindFirstStageVerification.java
│ │ ├── FlatMapCompletionStageVerification.java
│ │ ├── FlatMapIterableStageVerification.java
│ │ ├── FlatMapStageVerification.java
│ │ ├── FromCompletionStageNullableVerification.java
│ │ ├── FromCompletionStageVerification.java
│ │ ├── LimitStageVerification.java
│ │ ├── MapStageVerification.java
│ │ ├── OfStageVerification.java
│ │ ├── OnErrorResumeStageVerification.java
│ │ ├── OnStagesVerification.java
│ │ ├── PeekStageVerification.java
│ │ ├── QuietRuntimeException.java
│ │ ├── ReactiveStreamsSpiVerification.java
│ │ ├── ScheduledPublisher.java
│ │ ├── SkipStageVerification.java
│ │ ├── SubscriberStageVerification.java
│ │ └── TakeWhileStageVerification.java
└── resources
│ └── META-INF
│ ├── LICENSE
│ ├── NOTICE
│ └── tck
└── test
├── java
└── org
│ └── eclipse
│ └── microprofile
│ └── reactive
│ └── streams
│ └── operators
│ └── tck
│ └── TckTest.java
└── resources
├── META-INF
├── LICENSE
└── NOTICE
└── README.adoc
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # http://editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 | indent_style = space
9 | indent_size = 4
10 | end_of_line = lf
11 | charset = utf-8
12 | trim_trailing_whitespace = true
13 | insert_final_newline = true
14 |
15 | [*.md]
16 | trim_trailing_whitespace = false
17 |
18 | [*.adoc]
19 | trim_trailing_whitespace = false
20 |
21 | [*.js]
22 | indent_size = 2
23 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Handle line endings automatically for files detected as text
2 | # and leave all files detected as binary untouched.
3 | * text=auto
4 |
5 | #
6 | # The above will handle all files NOT found below
7 | #
8 | # These files are text and should be normalized (Convert crlf => lf)
9 | *.adoc text
10 | *.conf text
11 | *.config text
12 | *.css text
13 | *.df text
14 | *.extension text
15 | *.groovy text
16 | *.htm text
17 | *.html text
18 | *.java text
19 | *.js text
20 | *.json text
21 | *.jsp text
22 | *.jspf text
23 | *.md text
24 | *.properties text
25 | *.sbt text
26 | *.scala text
27 | *.sh text
28 | *.sql text
29 | *.svg text
30 | *.template text
31 | *.tld text
32 | *.txt text
33 | *.vm text
34 | *.wadl text
35 | *.wsdl text
36 | *.xhtml text
37 | *.xml text
38 | *.xsd text
39 | *.yml text
40 |
41 | cipher text
42 | jaas text
43 | LICENSE text
44 | NOTICE text
45 |
46 | # These files are binary and should be left untouched
47 | # (binary is a macro for -text -diff)
48 | *.class binary
49 | *.dll binary
50 | *.ear binary
51 | *.gif binary
52 | *.ico binary
53 | *.jar binary
54 | *.jpg binary
55 | *.jpeg binary
56 | *.png binary
57 | *.ser binary
58 | *.so binary
59 | *.war binary
60 | *.zip binary
61 | *.exe binary
62 | *.gz binary
63 |
64 | #Windows
65 | *.bat text eol=crlf
66 | *.cmd text eol=crlf
67 |
68 | #Unix/Linux
69 | *.sh text eol=lf
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/01-compatible-certification-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Compatible Certification Request
3 | about: Start a request for a compatible certification
4 | title: 'MicroProfile Reactive Streams Operator [Version] Compatible Certification Request'
5 | labels: 'Certification :trophy:'
6 | assignees: ''
7 |
8 | ---
9 |
10 | - [ ] Organization Name ("Organization") and, if applicable, URL:
11 | // Add here
12 | - [ ] Product Name, Version and download URL (if applicable):
13 | // Add here
14 | - [ ] Specification Name, Version and download URL:
15 | // Add here
16 | - [ ] (Optional) TCK Version, digital SHA-256 fingerprint and download URL:
17 | // Add here
18 | - [ ] Public URL of TCK Results Summary:
19 | // Add here
20 | - [ ] Any Additional Specification Certification Requirements:
21 | // Add here
22 | - [ ] Java runtime used to run the implementation:
23 | // Add here
24 | - [ ] Summary of the information for the certification environment, operating system, cloud, ...:
25 | // Add here
26 | - [ ] By checking this box I acknowledge that the Organization I represent accepts the terms of the [EFTL](https://www.eclipse.org/legal/tck.php).
27 | - [ ] By checking this box I attest that all TCK requirements have been met, including any compatibility rules.
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | .settings/
3 | .checkstyle
4 | target/
5 | tck/bin/
6 | .project
7 | build/
8 | .classpath
9 | .factorypath
10 | test-output
11 | /*.log
12 | .idea
13 | *.iml
14 | *.iwl
15 | *.ipr
16 | # Ignore a release.conf for perform_release/* script usage
17 | release.conf
18 | /bin/
19 | .~lock.*.odg#
20 | **.DS_Store
21 | .vscode
22 |
23 |
--------------------------------------------------------------------------------
/CONTRIBUTING.adoc:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | //
4 | // See the NOTICE file(s) distributed with this work for additional
5 | // information regarding copyright ownership.
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // You may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | == How to contribute
21 |
22 | Do you want to contribute to this project? Here is what you can do:
23 |
24 | * Fork the repository, make changes, then do a pull request.
25 | ** Remember to https://help.github.com/articles/signing-commits/[sign your commits]
26 | ** Make sure you have signed the https://www.eclipse.org/legal/ECA.php[Eclipse Contributor Agreement]
27 | * https://github.com/eclipse/microprofile-reactive-streams-operators/issues[Create or fix an issue].
28 | * https://gitter.im/eclipse/microprofile-reactive[Join us on Gitter to discuss this project].
29 | * Join our https://calendar.google.com/calendar/embed?src=gbnbc373ga40n0tvbl88nkc3r4%40group.calendar.google.com[weekly meeting] on Tuesday at https://www.timeanddate.com/time/map/[10h00 GMT].
30 | ** https://docs.google.com/document/d/1UKBBNFn-CeMih3lNUGvpShcL2aTpnvmJs9LQ8qT9OI0/edit?usp=sharing[Minutes and Agenda].
31 | ** https://zoom.us/j/509807821[Meeting room].
32 | * Join the discussions on the https://groups.google.com/forum/#!forum/microprofile[MicroProfile Google Group]
33 | * https://microprofile.io/blog/[Contribute a blog post].
34 |
35 | Also see the https://wiki.eclipse.org/MicroProfile/ContributingGuidelines[MicroProfile Contributing Guidelines] on the https://wiki.eclipse.org/MicroProfile[Eclipse MicroProfile wiki page]
36 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | =========================================================================
2 | == NOTICE file corresponding to section 4(d) of the Apache License, ==
3 | == Version 3.0, MicroProfile Reactive Streams Operators ==
4 | =========================================================================
5 |
6 | This product includes software developed at
7 | The Apache Software Foundation (http://www.apache.org/).
8 |
9 |
10 | SPDXVersion: SPDX-2.1
11 | PackageName: MicroProfile
12 | PackageHomePage: http://www.eclipse.org/microprofile
13 | PackageLicenseDeclared: Apache-2.0
14 |
15 | PackageCopyrightText:
16 | James Roper james@lightbend.com
17 | Clement Escoffier clement.escoffier@redhat.com
18 | Gordon Hutchison gordon_hutchison@uk.ibm.com
19 |
--------------------------------------------------------------------------------
/api/.gitignore:
--------------------------------------------------------------------------------
1 | node/
2 | node_modules/
3 | *.log
4 |
--------------------------------------------------------------------------------
/api/bnd.bnd:
--------------------------------------------------------------------------------
1 | -exportcontents: \
2 | org.eclipse.microprofile.*
3 |
4 | Import-Package: \
5 | org.reactivestreams;version="[1.0.0,2)", \
6 | *
7 |
8 | Bundle-SymbolicName: org.eclipse.microprofile.reactive.streams.operators
9 | Bundle-Name: Eclipse MicroProfile Reactive Streams Operators API Bundle
10 | Bundle-License: Apache License, Version 2.0
11 |
--------------------------------------------------------------------------------
/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svg-marbles",
3 | "version": "1.0.0",
4 | "description": "Marble diagram generator",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/eclipse/microprofile-reactive-streams-operators.git"
8 | },
9 | "license": "Apache-2.0",
10 | "dependencies": {
11 | "svg.js": "2.6.5"
12 | },
13 | "devDependencies": {
14 | "puppeteer": "1.13.0",
15 | "shelljs": "0.8.5"
16 | },
17 | "scripts": {
18 | "generate-marble-diagrams": "node src/docs/js/generate-marble-diagrams.js",
19 | "verify-marble-diagrams": "node src/docs/js/verify-marble-diagrams.js"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 | 4.0.0
22 |
23 |
24 |
25 | org.eclipse.microprofile.reactive-streams-operators
26 | microprofile-reactive-streams-operators-parent
27 | 3.1-SNAPSHOT
28 |
29 |
30 |
31 | 1.11.0
32 | false
33 |
34 |
35 | microprofile-reactive-streams-operators-api
36 | Eclipse MicroProfile Reactive Streams Operators API
37 | Eclipse MicroProfile Reactive Streams Operators :: API
38 |
39 |
40 |
41 | org.reactivestreams
42 | reactive-streams
43 |
44 |
45 | org.osgi
46 | org.osgi.annotation.versioning
47 |
48 |
49 |
50 |
51 |
52 |
53 | com.github.eirslett
54 | frontend-maven-plugin
55 | ${frontend-maven-plugin.version}
56 |
57 | v8.11.3
58 |
59 |
60 |
61 | install-node-and-run-npm-install
62 |
63 | install-node-and-npm
64 | npm
65 |
66 |
67 | install
68 |
69 |
70 |
71 | verify-marble-diagrams
72 |
73 | npm
74 |
75 | verify
76 |
77 | run-script verify-marble-diagrams
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | marble-diagrams
88 |
89 |
90 |
91 | com.github.eirslett
92 | frontend-maven-plugin
93 | ${frontend-maven-plugin.version}
94 |
95 |
96 | generate-marble-diagrams
97 |
98 | npm
99 |
100 | prepare-package
101 |
102 | run-script generate-marble-diagrams
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/api/src/docs/js/SourceCodePro-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/docs/js/SourceCodePro-Regular.ttf
--------------------------------------------------------------------------------
/api/src/docs/js/generate-marble-diagrams.js:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | /**
21 | * Run this script in Puppeteer (ie, headless Chrome) to actually render each diagram.
22 | */
23 | const path = require("path");
24 | const projectBaseDir = path.normalize(__dirname + "/../../..");
25 | const htmlPage = "file://" + projectBaseDir + "/src/docs/js/puppeteer.html";
26 | const outputDir = projectBaseDir + "/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files";
27 |
28 | const shell = require("shelljs");
29 | shell.mkdir("-p", outputDir);
30 |
31 | const crypto = require("crypto");
32 | const fs = require("fs");
33 | const puppeteer = require("puppeteer");
34 |
35 | (async () => {
36 | const browser = await puppeteer.launch();
37 | const page = await browser.newPage();
38 | // Important to wait until networkidle0, otherwise fonts won't be loaded.
39 | await page.goto(htmlPage, {waitUntil: "networkidle0"});
40 |
41 | const keys = await page.evaluate(() => {
42 | window.marbles = createMarbles();
43 | return Object.keys(marbles.graphs);
44 | });
45 |
46 | const renderDiagrams = async (keys) => {
47 | if (keys.length > 0) {
48 | const key = keys[0];
49 | console.log("Rendering marble diagram for " + key);
50 | const dimensions = await page.evaluate((key) => {
51 | const diagram = window.document.getElementById("diagram");
52 | diagram.innerHTML = "";
53 | return window.marbles.drawSingle(diagram, window.marbles.graphs[key]);
54 | }, key);
55 | await page.screenshot({path: outputDir + "/" + key + ".png", clip: {
56 | x: 0,
57 | y: 0,
58 | width: dimensions.width,
59 | height: dimensions.height
60 | }});
61 | keys.shift();
62 | await renderDiagrams(keys);
63 | }
64 | };
65 |
66 | await renderDiagrams(keys);
67 | await browser.close();
68 |
69 | // Now update MD5 hashes of everything
70 | console.log("Generating marble-diagram-hashes.json");
71 | const files = {};
72 | function md5File(file) {
73 | const md5sum = crypto.createHash('md5');
74 | const data = fs.readFileSync(file);
75 | md5sum.update(data);
76 | files[path.relative(projectBaseDir, file)] = md5sum.digest("hex");
77 | }
78 |
79 | shell.ls(__dirname + "/*.js", __dirname + "/*.html", __dirname + "/*.ttf").forEach(md5File);
80 | shell.ls(outputDir + "/*.png").forEach(md5File);
81 |
82 | fs.writeFileSync(__dirname + "/marble-diagram-hashes.json", JSON.stringify({
83 | description1: "This file contains hashes of all the input and output files from the marble diagram generation ",
84 | description2: "process. Unfortunately due to limitations in the MicroProfile CI build and release environment, we can't ",
85 | description3: "generate diagrams as part of the build, so instead we have to check them into the build. This hash file is ",
86 | description4: "used to ensure the output files are up to date with the input files, and is verifyied by the Maven verify ",
87 | description5: "phase, so if they aren't, the build will fail.",
88 | files: files
89 | }, null, 2));
90 |
91 | })().catch(error => {
92 | console.log(error);
93 | process.exit(1);
94 | });
95 |
--------------------------------------------------------------------------------
/api/src/docs/js/index.html:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
43 |
44 |
45 |
46 |
This div exists so that the browser will load the Source Code Pro font before we render the marbles,
47 | ensuring it gets the leading and sizes right.
This div exists to force the browser to load the Source Code Pro font
45 | before we start rendering images.
46 |
47 |
48 |
--------------------------------------------------------------------------------
/api/src/docs/js/verify-marble-diagrams.js:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | const path = require("path");
21 | const projectBaseDir = path.normalize(__dirname + "/../../..");
22 | const hashesFile = projectBaseDir + "/src/docs/js/marble-diagram-hashes.json";
23 |
24 | const crypto = require("crypto");
25 | const fs = require("fs");
26 |
27 | if (!fs.existsSync(hashesFile)) {
28 | console.log(hashesFile + " not found! Cannot verify that marble diagrams are up to date.");
29 | process.exit(-1);
30 | }
31 |
32 | const files = JSON.parse(fs.readFileSync(hashesFile)).files;
33 | let conflicts = [];
34 | Object.keys(files).forEach(file => {
35 | const path = projectBaseDir + "/" + file;
36 | if (!fs.existsSync(path)) {
37 | conflicts.push(file);
38 | } else {
39 | const md5sum = crypto.createHash('md5');
40 | const data = fs.readFileSync(file);
41 | md5sum.update(data);
42 | const md5 = md5sum.digest("hex");
43 | if (files[file] !== md5) {
44 | conflicts.push(file);
45 | }
46 | }
47 | });
48 |
49 | if (conflicts.length !== 0) {
50 | console.log("Marble diagram input or output files have changed since diagrams were last generated:");
51 | conflicts.forEach(file => {
52 | console.log(" " + file);
53 | });
54 | console.log("To fix this, run:");
55 | console.log(" mvn -Pmarble-diagrams verify");
56 | console.log("If you are getting this error from a CI build, the reason is that the MicroProfile CI and release");
57 | console.log("environment does not have the necessary dependencies installed to run the diagram generation process,");
58 | console.log("hence the diagrams are checked into revision control, and this script ensures they are up to date.");
59 | console.log("After running the above maven command, add the modified diagrams and marble-diagram-hashes.json file");
60 | console.log("to git and commit.");
61 | process.exit(-1);
62 | }
63 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/CompletionRunner.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators;
21 |
22 | import java.util.concurrent.CompletionStage;
23 |
24 | import org.eclipse.microprofile.reactive.streams.operators.spi.ReactiveStreamsEngine;
25 |
26 | /**
27 | * A builder for a closed reactive streams graph.
28 | *
29 | * When built, this builder returns a {@link CompletionStage} that will be redeemed with the result produced by the
30 | * subscriber of the stream when the stream completes normally, or will be redeemed with an error if the stream
31 | * encounters an error.
32 | *
33 | * @param
34 | * The result of the stream.
35 | * @see ReactiveStreams
36 | */
37 | public interface CompletionRunner extends ProducesResult {
38 | /**
39 | * Run this stream, using the first {@code ReactiveStreamsEngine} found by the {@link java.util.ServiceLoader}.
40 | *
41 | * @return A completion stage that will be redeemed with the result of the stream, or an error if the stream fails.
42 | */
43 | CompletionStage run();
44 |
45 | /**
46 | * Run this stream, using the supplied {@code ReactiveStreamsEngine}.
47 | *
48 | * @param engine
49 | * The engine to run the stream with.
50 | * @return A completion stage that will be redeemed with the result of the stream, or an error if the stream fails.
51 | */
52 | CompletionStage run(ReactiveStreamsEngine engine);
53 | }
54 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/ConnectingOperators.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators;
21 |
22 | import org.reactivestreams.Processor;
23 | import org.reactivestreams.Publisher;
24 | import org.reactivestreams.Subscriber;
25 |
26 | /**
27 | * Operators for connecting different graphs together.
28 | *
29 | * @param
30 | * The type of the elements that the stream emits.
31 | */
32 | public interface ConnectingOperators {
33 |
34 | /**
35 | * Connect the outlet of the {@link Publisher} built by this builder to the given {@link Subscriber}. The Reactive
36 | * Streams specification states that a subscriber should cancel any new stream subscription it receives if it
37 | * already has an active subscription. The returned result of this method is a stream that creates a subscription
38 | * for the subscriber passed in, so the resulting stream should only be run once. For the same reason, the
39 | * subscriber passed in should not have any active subscriptions and should not be used in more than one call to
40 | * this method.
41 | *
42 | * @param subscriber
43 | * The subscriber to connect.
44 | * @return A completion builder that completes when the stream completes.
45 | */
46 | ProducesResult to(Subscriber super T> subscriber);
47 |
48 | /**
49 | * Connect the outlet of this stream to the given {@link SubscriberBuilder} graph. The Reactive Streams
50 | * specification states that a subscriber should cancel any new stream subscription it receives if it already has an
51 | * active subscription. For this reason, a subscriber builder, particularly any that represents a graph that
52 | * includes a user supplied {@link Subscriber} or {@link Processor} stage, should not be used in the creation of
53 | * more than one stream instance.
54 | *
55 | * @param subscriberBuilder
56 | * The subscriber builder to connect.
57 | * @return A completion builder that completes when the stream completes.
58 | */
59 | ProducesResult to(SubscriberBuilder super T, ? extends R> subscriberBuilder);
60 |
61 | /**
62 | * Connect the outlet of the {@link Publisher} built by this builder to the given {@link ProcessorBuilder}. The
63 | * Reactive Streams specification states that a subscribing processor should cancel any new stream subscription it
64 | * receives if it already has an active subscription. For this reason, a processor builder, particularly any that
65 | * represents a graph that includes a user supplied {@link Processor} stage, should not be used in the creation of
66 | * more than one stream instance.
67 | *
68 | * @param processorBuilder
69 | * The processor builder to connect.
70 | * @return A stream builder that represents the passed in processor's outlet.
71 | */
72 | ConnectingOperators via(ProcessorBuilder super T, ? extends R> processorBuilder);
73 |
74 | /**
75 | * Connect the outlet of this stream to the given {@link Processor}. The Reactive Streams specification states that
76 | * a subscribing processor should cancel any new stream subscription it receives if it already has an active
77 | * subscription. The returned result of this method is a stream that creates a subscription for the processor passed
78 | * in, so the resulting stream should only be run once. For the same reason, the processor passed in should not have
79 | * any active subscriptions and should not be used in more than one call to this method.
80 | *
81 | *
82 | * @param processor
83 | * The processor builder to connect.
84 | * @return A stream builder that represents the passed in processor builder's outlet.
85 | */
86 | ConnectingOperators via(Processor super T, ? extends R> processor);
87 | }
88 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/PeekingOperators.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators;
21 |
22 | import java.util.function.Consumer;
23 |
24 | /**
25 | * Operations for peeking at elements and signals in the stream, without impacting the stream itself.
26 | *
27 | * The documentation for each operator uses marble diagrams to visualize how the operator functions. Each element
28 | * flowing in and out of the stream is represented as a coloured marble that has a value, with the operator applying
29 | * some transformation or some side effect, termination and error signals potentially being passed, and for operators
30 | * that subscribe to the stream, an output value being redeemed at the end.
31 | *
32 | * Below is an example diagram labelling all the parts of the stream.
33 | *
34 | *
35 | *
36 | * @param
37 | * The type of the elements that the stream emits.
38 | */
39 | public interface PeekingOperators {
40 |
41 | /**
42 | * Returns a stream containing all the elements from this stream, additionally performing the provided action on
43 | * each element.
44 | *
45 | *
46 | *
47 | * @param consumer
48 | * The function called for every element.
49 | * @return A new stream builder that consumes elements of type T and emits the same elements. In
50 | * between, the given function is called for each element.
51 | */
52 | PeekingOperators peek(Consumer super T> consumer);
53 |
54 | /**
55 | * Returns a stream containing all the elements from this stream, additionally performing the provided action if
56 | * this stream conveys an error. The given consumer is called with the failure.
57 | *
58 | *
59 | *
60 | * @param errorHandler
61 | * The function called with the failure.
62 | * @return A new stream builder that consumes elements of type T and emits the same elements. If the
63 | * stream conveys a failure, the given error handler is called.
64 | */
65 | PeekingOperators onError(Consumer errorHandler);
66 |
67 | /**
68 | * Returns a stream containing all the elements from this stream, additionally performing the provided action when
69 | * this stream completes or failed. The given action does not know if the stream failed or completed. If you need to
70 | * distinguish use {@link #onError(Consumer)} and {@link #onComplete(Runnable)}. In addition, the action is called
71 | * if the stream is cancelled downstream.
72 | *
73 | *
74 | *
75 | * @param action
76 | * The function called when the stream completes or failed.
77 | * @return A new stream builder that consumes elements of type T and emits the same elements. The given
78 | * action is called when the stream completes or fails.
79 | */
80 | PeekingOperators onTerminate(Runnable action);
81 |
82 | /**
83 | * Returns a stream containing all the elements from this stream, additionally performing the provided action when
84 | * this stream completes.
85 | *
86 | *
87 | *
88 | * @param action
89 | * The function called when the stream completes.
90 | * @return A new stream builder that consumes elements of type T and emits the same elements. The given
91 | * action is called when the stream completes.
92 | */
93 | PeekingOperators onComplete(Runnable action);
94 | }
95 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/ProducesResult.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators;
21 |
22 | /**
23 | * A stream that completes with a single result.
24 | *
25 | * This will either be a {@link SubscriberBuilder}, representing a stream with an inlet that can be plumbed to a
26 | * publisher in order to run it, or a {@link CompletionRunner}, representing a closed graph that can be run as is.
27 | *
28 | * @param
29 | * The result of the stream.
30 | * @see SubscriberBuilder
31 | * @see CompletionRunner
32 | */
33 | public interface ProducesResult {
34 | }
35 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/SubscriberBuilder.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators;
21 |
22 | import org.eclipse.microprofile.reactive.streams.operators.spi.ReactiveStreamsEngine;
23 |
24 | /**
25 | * A builder for a {@link org.reactivestreams.Subscriber} and its result.
26 | *
27 | * When built, this builder returns a {@link CompletionSubscriber}, which encapsulates both a
28 | * {@link org.reactivestreams.Subscriber} and a {@link java.util.concurrent.CompletionStage} that will be redeemed with
29 | * the result produced by the subscriber when the stream completes normally, or will be redeemed with an error if the
30 | * subscriber receives an error. A {@link SubscriberBuilder} may represent a compound set of stream stages and may
31 | * complete exceptionally without receiving an error externally. Similarly, {@link SubscriberBuilder}s may encapsulate
32 | * error handling such as the onErrorResume operator and recover from an externally received errors.
33 | *
34 | * @param
35 | * The type of the elements that this subscriber consumes.
36 | * @param
37 | * The type of the result that this subscriber emits.
38 | * @see ReactiveStreams
39 | */
40 | public interface SubscriberBuilder extends ProducesResult {
41 | /**
42 | * Build this stream, using the first {@link ReactiveStreamsEngine} found by the {@link java.util.ServiceLoader}.
43 | *
44 | * @return A {@link CompletionSubscriber} that will run this stream.
45 | */
46 | CompletionSubscriber build();
47 |
48 | /**
49 | * Build this stream, using the supplied {@link ReactiveStreamsEngine}.
50 | *
51 | * @param engine
52 | * The engine to run the stream with.
53 | * @return A {@link CompletionSubscriber} that will run this stream.
54 | */
55 | CompletionSubscriber build(ReactiveStreamsEngine engine);
56 | }
57 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/collect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/collect.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/concat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/concat.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/coupled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/coupled.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/distinct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/distinct.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/dropWhile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/dropWhile.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/empty.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/example.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/failed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/failed.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/filter.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/findFirst.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/findFirst.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/flatMap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/flatMap.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/flatMapCompletionStage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/flatMapCompletionStage.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/flatMapIterable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/flatMapIterable.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/flatMapRsPublisher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/flatMapRsPublisher.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/forEach.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/forEach.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/fromCompletionStage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/fromCompletionStage.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/fromCompletionStageNullable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/fromCompletionStageNullable.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/fromIterable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/fromIterable.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/generate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/generate.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/identity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/identity.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/ignore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/ignore.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/iterate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/iterate.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/limit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/limit.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/map.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/of-many.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/of-many.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/of-single.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/of-single.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/ofNullable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/ofNullable.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onComplete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onComplete.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onError.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onError.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onErrorResume.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onErrorResume.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onErrorResumeWith.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onErrorResumeWith.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onErrorResumeWithRsPublisher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onErrorResumeWithRsPublisher.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onTerminate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/onTerminate.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/peek.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/peek.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/reduce-identity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/reduce-identity.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/reduce.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/reduce.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/skip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/skip.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/takeWhile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/takeWhile.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/toList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/doc-files/toList.png
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/spi/Graph.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.spi;
21 |
22 | import java.util.Collection;
23 |
24 | /**
25 | * A graph.
26 | *
27 | * Reactive Streams engines are required to convert the stages of this graph into a stream with interfaces according to
28 | * the shape, which is determined by which method is invoked on the {@link ReactiveStreamsEngine}.
29 | */
30 | public interface Graph {
31 | /**
32 | * Get the stages of this graph.
33 | */
34 | Collection getStages();
35 | }
36 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/spi/ReactiveStreamsEngine.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.spi;
21 |
22 | import java.util.concurrent.CompletionStage;
23 |
24 | import org.reactivestreams.Processor;
25 | import org.reactivestreams.Publisher;
26 |
27 | /**
28 | * An engine for turning reactive streams graphs into Reactive Streams publishers/subscribers.
29 | *
30 | * The zero argument {@code build} and {@code run} methods on subclasses of this will use the
31 | * {@link java.util.ServiceLoader} to load an engine for the current context classloader. It does not cache engines
32 | * between invocations. If instantiating an engine is expensive (eg, it creates threads), then it is recommended that
33 | * the implementation does its own caching by providing the engine using a static provider method.
34 | */
35 | public interface ReactiveStreamsEngine {
36 |
37 | /**
38 | * Build a {@link Publisher} from the given stages.
39 | *
40 | * The passed in graph will have an outlet and no inlet.
41 | *
42 | * @param graph
43 | * The stages to build the publisher from. Will not be empty.
44 | * @param
45 | * The type of elements that the publisher publishes.
46 | * @return A publisher that implements the passed in graph of stages.
47 | * @throws UnsupportedStageException
48 | * If a stage in the stages is not supported by this Reactive Streams engine.
49 | */
50 | Publisher buildPublisher(Graph graph) throws UnsupportedStageException;
51 |
52 | /**
53 | * Build a {@link org.reactivestreams.Subscriber} from the given stages.
54 | *
55 | * The passed in graph will have an inlet and no outlet.
56 | *
57 | * @param graph
58 | * The graph to build the subscriber from. Will not be empty.
59 | * @param
60 | * The type of elements that the subscriber subscribes to.
61 | * @param
62 | * The result of subscribing to the stages.
63 | * @return A subscriber that implements the passed in graph of stages.
64 | * @throws UnsupportedStageException
65 | * If a stage in the stages is not supported by this Reactive Streams engine.
66 | */
67 | SubscriberWithCompletionStage buildSubscriber(Graph graph) throws UnsupportedStageException;
68 |
69 | /**
70 | * Build a {@link Processor} from the given stages.
71 | *
72 | * The passed in graph will have an inlet and an outlet.
73 | *
74 | * @param graph
75 | * The graph to build the processor from. If empty, then the processor should be an identity processor.
76 | * @param
77 | * The type of elements that the processor subscribes to.
78 | * @param
79 | * The type of elements that the processor publishes.
80 | * @return A processor that implements the passed in graph of stages.
81 | * @throws UnsupportedStageException
82 | * If a stage in the stages is not supported by this Reactive Streams engine.
83 | */
84 | Processor buildProcessor(Graph graph) throws UnsupportedStageException;
85 |
86 | /**
87 | * Build a closed graph from the given stages.
88 | *
89 | * The passed in graph will have no inlet and no outlet.
90 | *
91 | * @param graph
92 | * The graph to build the closed graph from. Will not be empty.
93 | * @param
94 | * The type of the result of running the closed graph.
95 | * @return A CompletionStage of the result of running the graph.
96 | * @throws UnsupportedStageException
97 | * If a stage in the stages is not supported by this reactive streams engine.
98 | */
99 | CompletionStage buildCompletion(Graph graph) throws UnsupportedStageException;
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/spi/ReactiveStreamsFactoryResolver.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 | package org.eclipse.microprofile.reactive.streams.operators.spi;
20 |
21 | import java.security.AccessController;
22 | import java.security.PrivilegedAction;
23 | import java.security.PrivilegedActionException;
24 | import java.security.PrivilegedExceptionAction;
25 | import java.util.ServiceLoader;
26 |
27 | import org.eclipse.microprofile.reactive.streams.operators.ReactiveStreams;
28 | import org.eclipse.microprofile.reactive.streams.operators.ReactiveStreamsFactory;
29 |
30 | /**
31 | * This class is not intended to be used by end-users but for portable container integration purpose only.
32 | *
33 | * Service provider for ReactiveStreamsFactory. The implementation registers itself via the
34 | * {@link java.util.ServiceLoader} mechanism.
35 | */
36 | public class ReactiveStreamsFactoryResolver {
37 |
38 | protected ReactiveStreamsFactoryResolver() {
39 | // Avoid direct instantiation.
40 | }
41 |
42 | private static volatile ReactiveStreamsFactory instance = null;
43 |
44 | /**
45 | * Creates a ReactiveStreamsFactory object Only used internally from within {@link ReactiveStreams}
46 | *
47 | * @return ReactiveStreamsFactory an instance of ReactiveStreamsFactory
48 | */
49 | public static ReactiveStreamsFactory instance() {
50 | if (instance == null) {
51 | synchronized (ReactiveStreamsFactoryResolver.class) {
52 | if (instance != null) {
53 | return instance;
54 | }
55 |
56 | ClassLoader cl = AccessController.doPrivileged(
57 | (PrivilegedAction) () -> Thread.currentThread().getContextClassLoader());
58 | if (cl == null) {
59 | cl = ReactiveStreamsFactory.class.getClassLoader();
60 | }
61 |
62 | ReactiveStreamsFactory newInstance = loadFromSpi(cl);
63 |
64 | if (newInstance == null) {
65 | throw new IllegalStateException(
66 | "No ReactiveStreamsFactory implementation found!");
67 | }
68 |
69 | instance = newInstance;
70 | }
71 | }
72 |
73 | return instance;
74 | }
75 |
76 | private static ReactiveStreamsFactory loadFromSpi(ClassLoader cl) {
77 | if (cl == null) {
78 | return null;
79 | }
80 |
81 | if (instance == null) {
82 | try {
83 | AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
84 | ServiceLoader sl = ServiceLoader.load(
85 | ReactiveStreamsFactory.class, cl);
86 | for (ReactiveStreamsFactory spi : sl) {
87 | if (instance != null) {
88 | throw new IllegalStateException(
89 | "Multiple ReactiveStreamsFactory implementations found: "
90 | + spi.getClass().getName() + " and "
91 | + instance.getClass().getName());
92 | } else {
93 | instance = spi;
94 | }
95 | }
96 | return null;
97 | });
98 | } catch (PrivilegedActionException e) {
99 | Throwable t = e.getCause();
100 | if (t instanceof RuntimeException) {
101 | throw (RuntimeException) t;
102 | }
103 | if (t instanceof Error) {
104 | throw (Error) t;
105 | }
106 | throw new RuntimeException(t);
107 | }
108 | }
109 | return instance;
110 | }
111 |
112 | /**
113 | * Set the instance. It is used by OSGi environment while service loader pattern is not supported.
114 | *
115 | * @param factory
116 | * set the instance.
117 | */
118 | public static void setInstance(ReactiveStreamsFactory factory) {
119 | instance = factory;
120 | }
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/spi/SubscriberWithCompletionStage.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.spi;
21 |
22 | import java.util.concurrent.CompletionStage;
23 |
24 | import org.reactivestreams.Subscriber;
25 |
26 | /**
27 | * A subscriber and completion stage pair.
28 | *
29 | * @param
30 | * The type of the elements that the subscriber consumes.
31 | * @param
32 | * The type of the result that the subscriber emits.
33 | */
34 | public interface SubscriberWithCompletionStage {
35 |
36 | /**
37 | * Get the completion stage.
38 | *
39 | * This should be redeemed by the subscriber either when it cancels, or when it receives an
40 | * {@link Subscriber#onComplete} signal or an {@link Subscriber#onError(Throwable)} signal. Generally, the redeemed
41 | * value or error should be the result of consuming the stream.
42 | *
43 | * @return The completion stage.
44 | */
45 | CompletionStage getCompletion();
46 |
47 | /**
48 | * Get the subscriber.
49 | *
50 | * @return The subscriber.
51 | */
52 | Subscriber getSubscriber();
53 | }
54 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/spi/ToGraphable.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.spi;
21 |
22 | /**
23 | * All instances of {@code PublisherBuilder}, {@code ProcessorBuilder}, {@code SubscriberBuilder} and
24 | * {@code CompletionRunner} must implement this, to ensure that the builder can be turned into a graph by other
25 | * implementations of the API.
26 | */
27 | public interface ToGraphable {
28 |
29 | /**
30 | * Convert this builder to a {@link Graph}.
31 | *
32 | * @return The graph.
33 | */
34 | Graph toGraph();
35 | }
36 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/spi/UnsupportedStageException.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.spi;
21 |
22 | /**
23 | * Exception thrown when a reactive streams engine doesn't support a stage that is passed to it.
24 | *
25 | * All reactive streams engines should support all stages, but this allows for a graceful mechanism to report issues,
26 | * for example if in a future version a new stage is added that is not recognised by an existing implementation.
27 | */
28 | public class UnsupportedStageException extends RuntimeException {
29 | public UnsupportedStageException(Stage stage) {
30 | super("The " + stage.getClass().getSimpleName() + " stage is not supported by this Reactive Streams engine.");
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/api/src/main/java/org/eclipse/microprofile/reactive/streams/operators/spi/package-info.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | /**
21 | * The Reactive Streams utils SPI.
22 | *
23 | * Implementors are expected to implement the {@code ReactiveStreamsEngine} interface, and use this SPI to inspect the
24 | * graph of stages.
25 | *
26 | * A TCK is also provided that validates that an implementation is both correct according to this specification, and the
27 | * Reactive Streams specification.
28 | */
29 | @org.osgi.annotation.versioning.Version("1.0")
30 | package org.eclipse.microprofile.reactive.streams.operators.spi;
31 |
--------------------------------------------------------------------------------
/api/src/main/resources/META-INF/NOTICE:
--------------------------------------------------------------------------------
1 | =========================================================================
2 | == NOTICE file corresponding to section 4(d) of the Apache License, ==
3 | == Version 3.0, MicroProfile Reactive Streams Operators ==
4 | =========================================================================
5 |
6 | This product includes software developed at
7 | The Apache Software Foundation (http://www.apache.org/).
8 |
9 |
10 | SPDXVersion: SPDX-2.1
11 | PackageName: MicroProfile
12 | PackageHomePage: http://www.eclipse.org/microprofile
13 | PackageLicenseDeclared: Apache-2.0
14 |
15 | PackageCopyrightText:
16 | James Roper james@lightbend.com
17 | Clement Escoffier clement.escoffier@redhat.com
18 | Gordon Hutchison gordon_hutchison@uk.ibm.com
19 |
--------------------------------------------------------------------------------
/core/bnd.bnd:
--------------------------------------------------------------------------------
1 | -exportcontents: \
2 | org.eclipse.microprofile.reactive.streams.operators.core.*
3 |
4 | Import-Package: \
5 | org.reactivestreams;version="[1.0.0,2)", \
6 | *
7 |
8 | Bundle-SymbolicName: org.eclipse.microprofile.reactive.streams.operators.core
9 | Bundle-Name: Eclipse MicroProfile Reactive Streams Operators Core Bundle
10 | Bundle-License: Apache License, Version 2.0
11 |
--------------------------------------------------------------------------------
/core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 | 4.0.0
22 |
23 |
24 |
25 | org.eclipse.microprofile.reactive-streams-operators
26 | microprofile-reactive-streams-operators-parent
27 | 3.1-SNAPSHOT
28 |
29 |
30 |
31 | false
32 |
33 | microprofile-reactive-streams-operators-core
34 | MicroProfile Reactive Streams Operators Core
35 | MicroProfile Reactive Streams Operators :: Core Implementation
36 |
37 |
38 | ${project.groupId}
39 | microprofile-reactive-streams-operators-api
40 | ${project.version}
41 |
42 |
43 | org.reactivestreams
44 | reactive-streams
45 |
46 |
47 | org.osgi
48 | org.osgi.annotation.versioning
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/core/src/main/java/org/eclipse/microprofile/reactive/streams/operators/core/CompletionRunnerImpl.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.core;
21 |
22 | import java.util.Objects;
23 | import java.util.concurrent.CompletionStage;
24 |
25 | import org.eclipse.microprofile.reactive.streams.operators.CompletionRunner;
26 | import org.eclipse.microprofile.reactive.streams.operators.spi.ReactiveStreamsEngine;
27 | import org.eclipse.microprofile.reactive.streams.operators.spi.Stage;
28 |
29 | final class CompletionRunnerImpl extends ReactiveStreamsGraphBuilder implements CompletionRunner {
30 |
31 | CompletionRunnerImpl(Stage stage, ReactiveStreamsGraphBuilder previous) {
32 | super(stage, previous);
33 | }
34 |
35 | @Override
36 | public CompletionStage run() {
37 | return run(ReactiveStreamsEngineResolver.instance());
38 | }
39 |
40 | @Override
41 | public CompletionStage run(ReactiveStreamsEngine engine) {
42 | Objects.requireNonNull(engine, "Engine must not be null");
43 | return engine.buildCompletion(toGraph());
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/core/src/main/java/org/eclipse/microprofile/reactive/streams/operators/core/GraphImpl.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.core;
21 |
22 | import java.util.Collection;
23 |
24 | import org.eclipse.microprofile.reactive.streams.operators.spi.Graph;
25 | import org.eclipse.microprofile.reactive.streams.operators.spi.Stage;
26 |
27 | final class GraphImpl implements Graph {
28 | private final Collection stages;
29 |
30 | /**
31 | * Create a graph from the given stages.
32 | *
33 | * If the first stage has an inlet, then this graph has an inlet, and can therefore be represented as a
34 | * {@link org.reactivestreams.Subscriber}. If the last stage has an outlet, then this graph has an outlet, and
35 | * therefore can be represented as a {@link org.reactivestreams.Publisher}.
36 | *
37 | * @param stages
38 | * The stages.
39 | */
40 | GraphImpl(Collection stages) {
41 | this.stages = stages;
42 | }
43 |
44 | @Override
45 | public Collection getStages() {
46 | return stages;
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return "Graph{" +
52 | "stages=" + stages +
53 | '}';
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/core/src/main/java/org/eclipse/microprofile/reactive/streams/operators/core/InternalStages.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.core;
21 |
22 | import java.util.Objects;
23 |
24 | import org.eclipse.microprofile.reactive.streams.operators.spi.Graph;
25 | import org.eclipse.microprofile.reactive.streams.operators.spi.Stage;
26 | import org.eclipse.microprofile.reactive.streams.operators.spi.ToGraphable;
27 |
28 | /**
29 | * Internal stages, used to capture the graph while being built, but never passed to a
30 | * {@link org.eclipse.microprofile.reactive.streams.operators.spi.ReactiveStreamsEngine}. These exist for performance
31 | * reasons, allowing the builder to hold the graph as an immutable linked tree where multiple stages can be appended in
32 | * constant time, rather than needing to copy an array each time. However, when it comes to building the graph, it is
33 | * first flattened out to an array, removing any of the internal stages that held nested stages, etc.
34 | */
35 | class InternalStages {
36 |
37 | private InternalStages() {
38 | }
39 |
40 | interface InternalStage extends Stage {
41 | }
42 |
43 | /**
44 | * An identity stage - this stage simply passes is input to its output unchanged. It's used to represent processor
45 | * builders that have had no stages defined.
46 | *
47 | * It gets ignored by the {@link ReactiveStreamsGraphBuilder} when encountered.
48 | */
49 | static final class Identity implements InternalStage {
50 | static final Identity INSTANCE = new Identity();
51 |
52 | private Identity() {
53 | }
54 | }
55 |
56 | /**
57 | * A nested stage. This is used to avoid having to rebuild the entire graph (which is represented as an immutable
58 | * cons) whenever two graphs are joined, or a stage is prepended into the graph.
59 | *
60 | * It gets flattened out by the {@link ReactiveStreamsGraphBuilder} when building the graph.
61 | */
62 | static final class Nested implements InternalStage {
63 | private final ReactiveStreamsGraphBuilder graphBuilder;
64 |
65 | Nested(ReactiveStreamsGraphBuilder graphBuilder) {
66 | this.graphBuilder = graphBuilder;
67 | }
68 |
69 | ReactiveStreamsGraphBuilder getBuilder() {
70 | return graphBuilder;
71 | }
72 | }
73 |
74 | /**
75 | * A nested stage, holding a graph. This is used when nesting a builder that has come from another implementation.
76 | */
77 | static final class NestedGraph implements InternalStage {
78 | private final Graph graph;
79 |
80 | NestedGraph(Graph graph) {
81 | this.graph = graph;
82 | }
83 |
84 | public Graph getGraph() {
85 | return graph;
86 | }
87 | }
88 |
89 | static InternalStage nested(Object object) {
90 | Objects.requireNonNull(object);
91 | if (object instanceof ReactiveStreamsGraphBuilder) {
92 | return new Nested((ReactiveStreamsGraphBuilder) object);
93 | } else if (object instanceof ToGraphable) {
94 | return new NestedGraph(((ToGraphable) object).toGraph());
95 | } else {
96 | throw new IllegalArgumentException("The passed in builder does not implement " + ToGraphable.class +
97 | " and so can't be added to this graph");
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/core/src/main/java/org/eclipse/microprofile/reactive/streams/operators/core/ReactiveStreamsEngineResolver.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 | package org.eclipse.microprofile.reactive.streams.operators.core;
20 |
21 | import java.security.AccessController;
22 | import java.security.PrivilegedAction;
23 | import java.security.PrivilegedActionException;
24 | import java.security.PrivilegedExceptionAction;
25 | import java.util.ServiceLoader;
26 |
27 | import org.eclipse.microprofile.reactive.streams.operators.ReactiveStreams;
28 | import org.eclipse.microprofile.reactive.streams.operators.spi.ReactiveStreamsEngine;
29 |
30 | /**
31 | * This class is not intended to be used by end-users but for portable container integration purpose only.
32 | *
33 | * Service provider for ReactiveStreamsEngine. The implementation registers itself via the {@link ServiceLoader}
34 | * mechanism.
35 | */
36 | public class ReactiveStreamsEngineResolver {
37 |
38 | protected ReactiveStreamsEngineResolver() {
39 | // Avoid direct instantiation.
40 | }
41 |
42 | private static volatile ReactiveStreamsEngine instance = null;
43 |
44 | /**
45 | * Creates a ReactiveStreamsFactory object Only used internally from within {@link ReactiveStreams}
46 | *
47 | * @return ReactiveStreamsFactory an instance of ReactiveStreamsFactory
48 | */
49 | public static ReactiveStreamsEngine instance() {
50 | if (instance == null) {
51 | synchronized (ReactiveStreamsEngineResolver.class) {
52 | if (instance != null) {
53 | return instance;
54 | }
55 |
56 | ClassLoader cl = AccessController.doPrivileged(
57 | (PrivilegedAction) () -> Thread.currentThread().getContextClassLoader());
58 | if (cl == null) {
59 | cl = ReactiveStreamsEngine.class.getClassLoader();
60 | }
61 |
62 | ReactiveStreamsEngine newInstance = loadFromSpi(cl);
63 |
64 | if (newInstance == null) {
65 | throw new IllegalStateException(
66 | "No ReactiveStreamsEngine implementation found!");
67 | }
68 |
69 | instance = newInstance;
70 | }
71 | }
72 |
73 | return instance;
74 | }
75 |
76 | private static ReactiveStreamsEngine loadFromSpi(ClassLoader cl) {
77 | if (cl == null) {
78 | return null;
79 | }
80 | if (instance == null) {
81 | try {
82 | AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
83 | ServiceLoader sl = ServiceLoader.load(
84 | ReactiveStreamsEngine.class, cl);
85 | for (ReactiveStreamsEngine spi : sl) {
86 | if (instance != null) {
87 | throw new IllegalStateException(
88 | "Multiple ReactiveStreamsEngine implementations found: "
89 | + spi.getClass().getName() + " and "
90 | + instance.getClass().getName());
91 | } else {
92 | instance = spi;
93 | }
94 | }
95 | return null;
96 | });
97 | } catch (PrivilegedActionException e) {
98 | Throwable t = e.getCause();
99 | if (t instanceof RuntimeException) {
100 | throw (RuntimeException) t;
101 | }
102 | if (t instanceof Error) {
103 | throw (Error) t;
104 | }
105 | throw new RuntimeException(t);
106 | }
107 | }
108 | return instance;
109 | }
110 |
111 | /**
112 | * Set the instance. It is used by OSGi environment while service loader pattern is not supported.
113 | *
114 | * @param factory
115 | * set the instance.
116 | */
117 | public static void setInstance(ReactiveStreamsEngine factory) {
118 | instance = factory;
119 | }
120 |
121 | }
122 |
--------------------------------------------------------------------------------
/core/src/main/java/org/eclipse/microprofile/reactive/streams/operators/core/ReactiveStreamsGraphBuilder.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.core;
21 |
22 | import java.util.*;
23 |
24 | import org.eclipse.microprofile.reactive.streams.operators.spi.Graph;
25 | import org.eclipse.microprofile.reactive.streams.operators.spi.Stage;
26 | import org.eclipse.microprofile.reactive.streams.operators.spi.ToGraphable;
27 | import org.reactivestreams.Publisher;
28 |
29 | /**
30 | * Builds graphs of reactive streams.
31 | */
32 | abstract class ReactiveStreamsGraphBuilder implements ToGraphable {
33 |
34 | private final Stage stage;
35 | private final ReactiveStreamsGraphBuilder previous;
36 |
37 | ReactiveStreamsGraphBuilder(Stage stage, ReactiveStreamsGraphBuilder previous) {
38 | this.stage = stage;
39 | this.previous = previous;
40 | }
41 |
42 | @Override
43 | public Graph toGraph() {
44 | ArrayDeque deque = new ArrayDeque<>();
45 | flatten(deque);
46 | return new GraphImpl(Collections.unmodifiableCollection(deque));
47 | }
48 |
49 | private void flatten(Deque stages) {
50 | ReactiveStreamsGraphBuilder thisStage = this;
51 | while (thisStage != null) {
52 | if (thisStage.stage == InternalStages.Identity.INSTANCE) {
53 | // Ignore, no need to add an identity stage
54 | } else if (thisStage.stage instanceof InternalStages.Nested) {
55 | ((InternalStages.Nested) thisStage.stage).getBuilder().flatten(stages);
56 | } else if (thisStage.stage instanceof InternalStages.NestedGraph) {
57 | // need to prepend to front in reverse order
58 | Collection nestedStages = ((InternalStages.NestedGraph) thisStage.stage).getGraph().getStages();
59 | ListIterator iter;
60 | if (nestedStages instanceof List) {
61 | iter = ((List) nestedStages).listIterator(nestedStages.size());
62 | } else {
63 | iter = new ArrayList<>(nestedStages).listIterator(nestedStages.size());
64 | }
65 | while (iter.hasPrevious()) {
66 | stages.addFirst(iter.previous());
67 | }
68 | } else {
69 | stages.addFirst(thisStage.stage);
70 | }
71 | thisStage = thisStage.previous;
72 | }
73 | }
74 |
75 | static Graph rsBuilderToGraph(Object obj) {
76 | Objects.requireNonNull(obj);
77 | if (obj instanceof ToGraphable) {
78 | return (((ToGraphable) obj).toGraph());
79 | } else {
80 | throw new IllegalArgumentException(obj + " is not an instance of ToGraphable and so can't participate " +
81 | "in this graph");
82 | }
83 | }
84 |
85 | static Graph publisherToGraph(Publisher> publisher) {
86 | return new GraphImpl(Collections.singleton(new Stages.PublisherStage(publisher)));
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/core/src/main/java/org/eclipse/microprofile/reactive/streams/operators/core/Reductions.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.core;
21 |
22 | import java.util.Objects;
23 | import java.util.Optional;
24 | import java.util.function.BinaryOperator;
25 | import java.util.stream.Collector;
26 |
27 | /**
28 | * Reduction utilities that convert arguments supplied to reduce methods on the builders to Collectors.
29 | */
30 | final class Reductions {
31 |
32 | private Reductions() {
33 | }
34 |
35 | static Collector> reduce(BinaryOperator reducer) {
36 | Objects.requireNonNull(reducer, "Reduction function must not be null");
37 | return Collector.of(Reduction::new,
38 | (r, t) -> {
39 | if (r.value == null) {
40 | r.value = t;
41 | } else {
42 | r.value = reducer.apply(r.value, t);
43 | }
44 | },
45 | (r, s) -> {
46 | if (r.value == null) {
47 | return r.replace(s.value);
48 | } else if (s.value != null) {
49 | return r.replace(reducer.apply(r.value, s.value));
50 | } else {
51 | return r;
52 | }
53 | },
54 | r -> Optional.ofNullable(r.value));
55 | }
56 |
57 | static Collector reduce(T identity, BinaryOperator reducer) {
58 | Objects.requireNonNull(reducer, "Reduction function must not be null");
59 | return Collector.of(() -> new Reduction<>(identity),
60 | (r, t) -> r.value = reducer.apply(r.value, t),
61 | (r, s) -> r.replace(reducer.apply(r.value, s.value)),
62 | r -> r.value);
63 | }
64 |
65 | private static class Reduction {
66 | private T value;
67 |
68 | Reduction() {
69 | }
70 |
71 | Reduction(T value) {
72 | this.value = value;
73 | }
74 |
75 | Reduction replace(T newValue) {
76 | this.value = newValue;
77 | return this;
78 | }
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/core/src/main/java/org/eclipse/microprofile/reactive/streams/operators/core/SubscriberBuilderImpl.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.core;
21 |
22 | import java.util.Objects;
23 |
24 | import org.eclipse.microprofile.reactive.streams.operators.CompletionSubscriber;
25 | import org.eclipse.microprofile.reactive.streams.operators.SubscriberBuilder;
26 | import org.eclipse.microprofile.reactive.streams.operators.spi.ReactiveStreamsEngine;
27 | import org.eclipse.microprofile.reactive.streams.operators.spi.Stage;
28 | import org.eclipse.microprofile.reactive.streams.operators.spi.SubscriberWithCompletionStage;
29 |
30 | public final class SubscriberBuilderImpl extends ReactiveStreamsGraphBuilder implements SubscriberBuilder {
31 |
32 | SubscriberBuilderImpl(Stage stage, ReactiveStreamsGraphBuilder previous) {
33 | super(stage, previous);
34 | }
35 |
36 | @Override
37 | public CompletionSubscriber build() {
38 | return build(ReactiveStreamsEngineResolver.instance());
39 | }
40 |
41 | @Override
42 | public CompletionSubscriber build(ReactiveStreamsEngine engine) {
43 | Objects.requireNonNull(engine, "Engine must not be null");
44 | SubscriberWithCompletionStage subscriberWithCompletionStage = engine.buildSubscriber(toGraph());
45 | return CompletionSubscriber.of(subscriberWithCompletionStage.getSubscriber(),
46 | subscriberWithCompletionStage.getCompletion());
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/core/src/main/java/org/eclipse/microprofile/reactive/streams/operators/core/package-info.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional information regarding copyright ownership.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License"); You may not use this file except in compliance with
7 | * the License. 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, software distributed under the License is distributed on
12 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | * specific language governing permissions and limitations under the License.
14 | ******************************************************************************/
15 |
16 | @org.osgi.annotation.versioning.Version("1.0")
17 | package org.eclipse.microprofile.reactive.streams.operators.core;
18 |
--------------------------------------------------------------------------------
/core/src/main/resources/META-INF/NOTICE:
--------------------------------------------------------------------------------
1 | =========================================================================
2 | == NOTICE file corresponding to section 4(d) of the Apache License, ==
3 | == Version 3.0, MicroProfile Reactive Streams Operators ==
4 | =========================================================================
5 |
6 | This product includes software developed at
7 | The Apache Software Foundation (http://www.apache.org/).
8 |
9 |
10 | SPDXVersion: SPDX-2.1
11 | PackageName: MicroProfile
12 | PackageHomePage: http://www.eclipse.org/microprofile
13 | PackageLicenseDeclared: Apache-2.0
14 |
15 | PackageCopyrightText:
16 | James Roper james@lightbend.com
17 | Clement Escoffier clement.escoffier@redhat.com
18 | Gordon Hutchison gordon_hutchison@uk.ibm.com
19 |
--------------------------------------------------------------------------------
/core/src/main/resources/META-INF/services/org.eclipse.microprofile.reactive.streams.operators.ReactiveStreamsFactory:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | #
4 | # See the NOTICE file(s) distributed with this work for additional
5 | # information regarding copyright ownership.
6 | #
7 | # Licensed under the Apache License, Version 2.0 (the "License");
8 | # You may not use this file except in compliance with the License.
9 | # You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing, software
14 | # distributed under the License is distributed on an "AS IS" BASIS,
15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | # See the License for the specific language governing permissions and
17 | # limitations under the License.
18 | ################################################################################
19 |
20 | org.eclipse.microprofile.reactive.streams.operators.core.ReactiveStreamsFactoryImpl
21 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 | 4.0.0
22 |
23 |
24 | org.eclipse.microprofile
25 | microprofile-parent
26 | 2.11
27 |
28 |
29 | org.eclipse.microprofile.reactive-streams-operators
30 | microprofile-reactive-streams-operators-parent
31 | 3.1-SNAPSHOT
32 | pom
33 |
34 |
35 | 2018
36 | 2.11
37 |
38 |
39 | Eclipse MicroProfile Reactive Streams Operators
40 | Eclipse MicroProfile Reactive Streams Operators :: Parent POM
41 |
42 |
43 |
44 |
45 |
46 | James Roper
47 | https://jazzy.id.au
48 | Lightbend
49 | https://www.lightbend.com
50 |
51 |
52 | Clement Escoffier
53 | Red Hat
54 | https://redhat.com
55 |
56 |
57 |
58 |
59 | scm:git:https://github.com/eclipse/microprofile-reactive-streams-operators.git
60 | scm:git:git@github.com:eclipse/microprofile-reactive-streams-operators.git
61 | https://github.com/eclipse/microprofile-reactive-streams-operators
62 | HEAD
63 |
64 |
65 |
66 | api
67 | core
68 | tck
69 | spec
70 |
71 |
72 |
73 |
74 |
75 | org.reactivestreams
76 | reactive-streams
77 | 1.0.3
78 |
79 |
80 | org.reactivestreams
81 | reactive-streams-tck
82 | 1.0.3
83 |
84 |
85 | org.osgi
86 | org.osgi.annotation.versioning
87 | 1.0.0
88 | provided
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/site.yaml:
--------------------------------------------------------------------------------
1 | #######################################################################
2 | ## Copyright (c) 2018 Contributors to the Eclipse Foundation
3 | ##
4 | ## See the NOTICE file(s) distributed with this work for additional
5 | ## information regarding copyright ownership.
6 | ##
7 | ## Licensed under the Apache License, Version 2.0 (the "License");
8 | ## you may not use this file except in compliance with the License.
9 | ## You may obtain a copy of the License at
10 | ##
11 | ## http://www.apache.org/licenses/LICENSE-2.0
12 | ##
13 | ## Unless required by applicable law or agreed to in writing, software
14 | ## distributed under the License is distributed on an "AS IS" BASIS,
15 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | ## See the License for the specific language governing permissions and
17 | ## limitations under the License.
18 | #######################################################################
19 | %YAML 1.2
20 | ---
21 | documentation:
22 | - title: Reactive Streams Operators for Microprofile
23 | file: spec/src/main/asciidoc/microprofile-reactive-streams-operators-spec.asciidoc
24 |
25 | - title: Architecture
26 | file: spec/src/main/asciidoc/architecture.asciidoc
27 |
28 | - title: Usage Examples
29 | file: spec/src/main/asciidoc/examples.asciidoc
30 |
31 | - title: License
32 | file: spec/src/main/asciidoc/license-alv2.asciidoc
33 |
--------------------------------------------------------------------------------
/spec/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 | 4.0.0
22 |
23 |
24 | org.eclipse.microprofile.reactive-streams-operators
25 | microprofile-reactive-streams-operators-parent
26 | 3.1-SNAPSHOT
27 |
28 |
29 | microprofile-reactive-streams-operators-spec
30 | pom
31 | Eclipse MicroProfile Reactive Streams Operators Specification
32 | Eclipse MicroProfile Reactive Streams Operators :: Specification
33 |
34 |
35 |
--------------------------------------------------------------------------------
/spec/src/main/asciidoc/cdi.asciidoc:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018 Contributors to the Eclipse Foundation
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 | [[reactivestreamscdi]]
18 | == CDI Integration
19 |
20 | MicroProfile Reactive Streams Operators implementations may be used independently of a CDI container.
21 | Consequently, implementations are not required to provide any integration with CDI.
22 |
23 | This section of the specification is intended to provide advice for how other specifications may integrate CDI with MicroProfile Reactive Streams Operators.
24 |
25 | === Injection of engines
26 |
27 | If a MicroProfile container provides an implementation of MicroProfile Reactive Streams Operators, then it must make an application scoped `ReactiveStreamsEngine` available for injection.
28 |
29 | === Contexts
30 |
31 | This specification places no requirements on the propagation of CDI context, or what context(s) should be active when user supplied callbacks are executed during the running of a stream.
32 |
33 | Other specifications that use this specification may require that implementations make certain context's to be active when user callbacks are executed.
34 | In this case, it is expected that such specifications will have the responsibility of running the streams.
35 |
36 | For example, a hypothetical WebSocket specification may allow user code to return a `ProcessorBuilder` to handle messages:
37 |
38 | [source, java]
39 | ----
40 | @WebSocket("/echo")
41 | public ProcessorBuilder echoWebsocket() {
42 | return ReactiveStreams.builder().map(message ->
43 | new Message("Echoing " + message.getText())
44 | );
45 | }
46 | ----
47 |
48 | In this case, the implementation of that hypothetical WebSocket specification is responsible for running the `ProcessorBuilder` returned by the user, and that specification may require that the engine it uses to run it makes the request context active in callbacks, such as the `map` callback above.
49 | Since the implementation of that specification is in control of which engine is used to run the processor, this requirement can be made by that specification.
50 | It is the responsibility of that implementation (and the MicroProfile container that pulls these implementations together) to ensure that the MicroProfile Reactive Streams Operators implementation used is able to support CDI context propagation.
51 |
52 | In contrast, if a user is responsible for executing a stream, like in the following hypothetical example:
53 |
54 | [source, java]
55 | ----
56 | @WebSocket("/echo")
57 | public void echoWebsocket(PublisherBuilder incoming,
58 | SubscriberBuilder outgoing) {
59 |
60 | incoming.map(message ->
61 | new Message("Echoing " + message.getText()
62 | ).to(outgoing).run();
63 | }
64 | ----
65 |
66 | Then there is no clear way for the container to control how the engine used there, which in this case would be loaded through the Java `ServiceLoader` API, would propagate context.
67 | For this reason, any cases where users are running their own streams are not expected to require any CDI context propagation, and it is recommended that specifications favour APIs where the container runs the stream, not the user, to facilitate context propagation.
68 |
--------------------------------------------------------------------------------
/spec/src/main/asciidoc/images/picture-sources.odg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microprofile/microprofile-reactive-streams-operators/0872462adb5c6c100cb5e529cc0feead1c95740e/spec/src/main/asciidoc/images/picture-sources.odg
--------------------------------------------------------------------------------
/spec/src/main/asciidoc/implementation.asciidoc:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018 Contributors to the Eclipse Foundation
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 | [[reactivestreamsimplementation]]
18 | == Implementation
19 |
20 | The behavior of each stage is specified in the javadocs for stages in the SPI, and tested by the TCK.
21 |
22 | Generally, across all stages, the following requirements exist:
23 |
24 | === Memory visibility
25 |
26 | Within a single stage in a single stream, implementations must guarantee a _happens-before_ relationship between any invocation of all callbacks supplied to that stage.
27 |
28 | Between different stages of a single stream, it is recommended that a _happens-before_ relationship exists between callbacks of different stages, however this is not required, and end users of the API must not depend on this.
29 | Implementations are expected to implement this for performance reasons, this is also known as operator fusing.
30 | Implementations may decide, for whatever reason, not to fuse stages in certain circumstances, when this is done, it is said that there is an asynchronous boundary between the two stages.
31 |
32 | When Reactive Streams interfaces, that is, `Publisher`, `Subscriber` or `Processor`, are wrapped in a stage, implementations may place an asynchronous boundary between that stage and its neighbors if they choose.
33 | Whether implementations do or don't place an asynchronous boundary there, they must conform to the Reactive Streams specification with regards to memory visibility.
34 |
35 | === User exceptions
36 |
37 | Exceptions thrown by user supplied callbacks must be caught and propagated downstream, unless otherwise handled by an error handling stage.
38 |
39 | User exceptions must not be thrown by the `build` or `run` methods of the builders.
40 | For example, if a user supplies an `Iterable` as a source for a `PublisherBuilder`, and the `iterator()` method is invoked synchronously from the `build` method on the publisher, and it throws an exception, this exception must be caught, and propagated through the stream, not thrown from the `build` method.
41 |
42 | An exception to this is the callbacks provided in user supplied Reactive Streams, ie `Publisher`, `Subscriber` and `Processor`.
43 | Since these interfaces are specified not to throw any exceptions when the consumer is adhering to the spec, implementations may assume that these interfaces won't throw exceptions, and the behavior of an implementation should these interfaces throw exceptions is unspecified.
44 |
45 | In some cases, exceptions may be wrapped, for example, `CompletableFuture` wraps exceptions in a `CompletionException`.
46 | It is recommended that implementations do not wrap exceptions if they don't need to, but rather that they propagate them downstream as is.
47 |
48 | === Error propagation
49 |
50 | Errors may be eagerly propagated by stages if an implementation chooses to do this.
51 | Such propagation can aid with fast failure of stages, to ensure things like connection failures do not wait excessively to discover that they have failed.
52 |
53 | A consequence of this is that errors can in certain circumstances overtake elements.
54 | For example, the `flatMapCompletionStage` stage may receive an error while an element is being asynchronously processed.
55 | This error may immediately be propagated downstream, which will mean the eventual redemption of the `CompletionStage` returned by the mapper function for the stage will be ignored, and the element it is redeemed with will be dropped.
56 |
57 | When a user does not desire this behavior, and wants to guarantee that stages don't drop elements when upstream errors arrive, they may insert an error recovery stage, such as `onErrorResume`, before the stage that they don't want to drop elements from.
58 | They will then need to implement an out of band mechanism to propagate the error, such as wrapping it in an element, should they wish to handle it downstream.
59 |
60 | === Cleanup
61 |
62 | Implementations must assume that any `PublisherBuilder`, `SubscriberBuilder` or `ProcessorBuilder` supplied to them, or any stages within, potentially hold resources, and must be cleaned up when the stream shuts down.
63 | For example, a `concat` stage accepts two `PublisherBuilder`'s.
64 | If the stream is cancelled before the first is finished, the second must still be built, and then cancelled too.
65 |
66 | === null elements
67 |
68 | Reactive Streams does not allow `null` elements. Hence, any user callbacks that return `null` as an element to be emitted by a stage must cause the stage to fail with a `NullPointerException`.
69 |
--------------------------------------------------------------------------------
/spec/src/main/asciidoc/java-streams.asciidoc:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018 Contributors to the Eclipse Foundation
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 | [[reactivestreams-java-streams]]
18 | == Similarities and differences with the Java Stream API
19 |
20 | The API shares a lot of similarities with the https://docs.oracle.com/javase/9/docs/api/java/util/stream/Stream.html[Java
21 | Stream API]. This similarity has been done on purpose to ease the adoption of the API. However, there are some
22 | differences and this section highlights them.
23 |
24 | === Asynchronous processing
25 |
26 | The goal of the Reactive Stream Operators specification is to define building blocks to enable the
27 | implementation of asynchronous processing of stream of data. On the other hand, the Java Stream API provides a synchronous
28 | approach to compute a result by analyzing data conveyed in a stream. Because of this asynchronous vs. synchronous
29 | processing, the terminal stages (such as `collect`, `findFirst`...) define by this API return `CompletableStage` and
30 | not `T`. Indeed, only when the result has been computed the returned `CompletableStage` is completed. As an example,
31 | here is the two versions of the same processing:
32 |
33 | [source, java]
34 | ----
35 | List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
36 |
37 | // Java Stream version
38 | int sum = list.stream()
39 | .map(i -> i + 1)
40 | .mapToInt(i -> i)
41 | .sum();
42 | // At the point the sum is computed
43 | System.out.println("sum: " + sum);
44 |
45 | // Reactive Streams Operators version
46 | CompletionStage future = ReactiveStreams.fromIterable(list)
47 | .map(i -> i + 1)
48 | .collect(Collectors.summingInt(i -> i))
49 | .run();
50 | future.whenComplete((res, err) -> System.out.println("async sum: " + res));
51 | ----
52 |
53 | The asynchronous vs. synchronous difference also means that the error propagation works differently. In the Java Streams
54 | API, the processing can be wrapped in a `try/catch` construct. In the asynchronous case, the error is propagated into the
55 | returned future. In the example above, the function passed to the `whenComplete` stage receives the result as well as the
56 | failure (if any). If the processing throws an exception, the function can react by looking at the `err` parameter.
57 |
58 | === No parallel processing
59 |
60 | The Reactive Streams specification is intrinsically sequential. So none of the parallel processing ability from the Java
61 | Stream API are supported. As a consequence, the API does not provide a `parallel()` method. Also, operations like
62 | `findAny` are not provided as the behavior would be equivalent to the provided `findFirst` method.
63 |
64 | === Other differences
65 |
66 | * `allMatch`, `anyMatch` and `nonMatch` can be achieved by combining `filter` and `findFirst`
67 | * `collect(Collector super T,A,R> collector)` - the combiner part of the collector is not used because of the sequential
68 | nature of Reactive Streams.
69 | * `collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)` is provided as `collect
70 | (Supplier supplier, BiConsumer accumulator)`. Indeed, the combiner is not used because of the sequential
71 | nature of Reactive Streams.
72 | * `count` is not provided but can be implemented using `.collect(Collectors.counting())` instead.
73 | * `findAny` is not supported, use `findFirst` instead. Because of the sequential nature of Reactive Streams, the method
74 | has the same semantic.
75 | * `flatMapTo` and `mapTo` are not provided. These can easily be replaced using regular `flatMap` and `map` methods, or
76 | methods from `Collectors`.
77 | * `forEachOrdered` is not provided as Reactive Streams mandates ordering. So `forEach` should be used instead.
78 | * `max` and `min` can be achieved using `.collect(Collectors.maxBy(...))` and `.collect(Collectors.minBy(...))`
79 | * `sorted` is not supported
80 | * `toArray` is not supported, `toList` can be used instead
81 | * `onClose` is replaced by `onComplete`. Notice that the API also provides the `onError` and `onTerminate` methods.
82 |
83 |
--------------------------------------------------------------------------------
/spec/src/main/asciidoc/license-alv2.asciidoc:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018 Contributors to the Eclipse Foundation
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 | [subs="normal"]
18 | ....
19 |
20 | Specification: {doctitle}
21 |
22 | Version: {revnumber}
23 |
24 | Status: {revremark}
25 |
26 | Release: {revdate}
27 |
28 | Copyright (c) 2018 Contributors to the Eclipse Foundation
29 |
30 | Licensed under the Apache License, Version 2.0 (the "License");
31 | you may not use this file except in compliance with the License.
32 | You may obtain a copy of the License at
33 |
34 | http://www.apache.org/licenses/LICENSE-2.0
35 |
36 | Unless required by applicable law or agreed to in writing, software
37 | distributed under the License is distributed on an "AS IS" BASIS,
38 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39 | See the License for the specific language governing permissions and
40 | limitations under the License.
41 |
42 | ....
--------------------------------------------------------------------------------
/spec/src/main/asciidoc/license-efsl.adoc:
--------------------------------------------------------------------------------
1 | [subs="normal"]
2 | ....
3 | Specification: {doctitle}
4 |
5 | Version: {revnumber}
6 |
7 | Status: {revremark}
8 |
9 | Release: {revdate}
10 | ....
11 |
12 | == Copyright
13 |
14 | Copyright (c) {inceptionYear} , {currentYear} Eclipse Foundation.
15 |
16 | === Eclipse Foundation Specification License
17 |
18 | By using and/or copying this document, or the Eclipse Foundation
19 | document from which this statement is linked, you (the licensee) agree
20 | that you have read, understood, and will comply with the following
21 | terms and conditions:
22 |
23 | Permission to copy, and distribute the contents of this document, or
24 | the Eclipse Foundation document from which this statement is linked, in
25 | any medium for any purpose and without fee or royalty is hereby
26 | granted, provided that you include the following on ALL copies of the
27 | document, or portions thereof, that you use:
28 |
29 | * link or URL to the original Eclipse Foundation document.
30 | * All existing copyright notices, or if one does not exist, a notice
31 | (hypertext is preferred, but a textual representation is permitted)
32 | of the form: "Copyright (c) [$date-of-document]
33 | Eclipse Foundation, Inc. \<>"
34 |
35 | Inclusion of the full text of this NOTICE must be provided. We
36 | request that authorship attribution be provided in any software,
37 | documents, or other items or products that you create pursuant to the
38 | implementation of the contents of this document, or any portion
39 | thereof.
40 |
41 | No right to create modifications or derivatives of Eclipse Foundation
42 | documents is granted pursuant to this license, except anyone may
43 | prepare and distribute derivative works and portions of this document
44 | in software that implements the specification, in supporting materials
45 | accompanying such software, and in documentation of such software,
46 | PROVIDED that all such works include the notice below. HOWEVER, the
47 | publication of derivative works of this document for use as a technical
48 | specification is expressly prohibited.
49 |
50 | The notice is:
51 |
52 | "Copyright (c) [$date-of-document] Eclipse Foundation. This software or
53 | document includes material copied from or derived from [title and URI
54 | of the Eclipse Foundation specification document]."
55 |
56 | ==== Disclaimers
57 |
58 | THIS DOCUMENT IS PROVIDED "AS IS," AND THE COPYRIGHT
59 | HOLDERS AND THE ECLIPSE FOUNDATION MAKE NO REPRESENTATIONS OR
60 | WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
61 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
62 | NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE
63 | SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS
64 | WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR
65 | OTHER RIGHTS.
66 |
67 | THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION WILL NOT BE LIABLE
68 | FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT
69 | OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE
70 | CONTENTS THEREOF.
71 |
72 | The name and trademarks of the copyright holders or the Eclipse
73 | Foundation may NOT be used in advertising or publicity pertaining to
74 | this document or its contents without specific, written prior
75 | permission. Title to copyright in this document will at all times
76 | remain with copyright holders.
77 |
--------------------------------------------------------------------------------
/spec/src/main/asciidoc/microprofile-reactive-streams-operators-spec.asciidoc:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018 Contributors to the Eclipse Foundation
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 | = MicroProfile Reactive Streams Operators Specification
18 | :authors: James Roper, Clement Escoffier, Gordon Hutchison
19 | :email: james@lightbend.com, clement.escoffier@redhat.com, gordon_hutchison@uk.ibm.com
20 | :version-label!:
21 | :sectanchors:
22 | :doctype: book
23 | :license: Apache License v2.0
24 | :source-highlighter: coderay
25 | :toc: left
26 | :toclevels: 4
27 | :sectnumlevels: 4
28 | ifdef::backend-pdf[]
29 | :pagenums:
30 | endif::[]
31 |
32 |
33 | // == License
34 | :sectnums!:
35 | include::license-efsl.adoc[]
36 |
37 | == MicroProfile Reactive Streams Operators
38 |
39 | include::architecture.asciidoc[]
40 | include::design.asciidoc[]
41 | include::implementation.asciidoc[]
42 | include::cdi.asciidoc[]
43 |
44 | include::examples.asciidoc[]
45 |
46 | include::java-streams.asciidoc[]
47 |
48 | include::spi.asciidoc[]
49 |
50 | include::release_notes.asciidoc[]
51 |
--------------------------------------------------------------------------------
/spec/src/main/asciidoc/release_notes.asciidoc:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation
3 | //
4 | // See the NOTICE file(s) distributed with this work for additional
5 | // information regarding copyright ownership.
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // You may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 | [[release_notes_30]]
20 | == Release Notes for MicroProfile Reactive Streams Operator 3.0
21 | A full list of changes delivered in the 3.0 release can be found at link:https://github.com/eclipse/microprofile-reactive-streams-operators/milestone/8[MicroProfile Reactive Streams Operators 3.0 Milestone].
22 |
23 | === Other Changes
24 | - Loading ReactiveStreamsEngine and ReactiveStreamsFactory should also work running with a security manager (link:https://github.com/eclipse/microprofile-reactive-streams-operators/pull/170[#170])
25 |
26 | ==== Incompatible Changes
27 | This release aligns with Jakarta EE 9.1, so it won't work with earlier versions of Jakarta or Java EE.
28 |
29 | ==== API/SPI Changes
30 | There are no functional changes introduced in this release, except updating the dependencies from javax to jakarta.
31 |
32 | [[release_notes_20]]
33 | == Release Notes for MicroProfile Reactive Streams Operator 2.0
34 |
35 | A full list of changes delivered in the 2.0 release can be found at link:https://github.com/eclipse/microprofile-reactive-streams-operators/milestone/3?closed=1[MicroProfile Reactive Streams Operators 2.0 Milestone].
36 |
37 | === Incompatible Changes
38 |
39 | - OSGi dependencies marked as "provided" (link:https://github.com/eclipse/microprofile-reactive-streams-operators/issues/132[#132])
40 |
41 | === API/SPI Changes
42 | - ReactiveStreamsFactory.fromSubscriber parameter type change (link:https://github.com/eclipse/microprofile-reactive-streams-operators/issues/134[#134])
43 |
44 | === Other Changes
45 | - Update to Jakarta EE8 APIs for MP 4.0 (link:https://github.com/eclipse/microprofile-reactive-streams-operators/issues/128[#128])
46 | - Javadoc clarification: (link:https://github.com/eclipse/microprofile-reactive-streams-operators/issues/135[#135]) (link:https://github.com/eclipse/microprofile-reactive-streams-operators/issues/137[#137])(link:https://github.com/eclipse/microprofile-reactive-streams-operators/issues/142[#142]) (link:https://github.com/eclipse/microprofile-reactive-streams-operators/issues/129[#129])
47 | - TCK clarification: (link:https://github.com/eclipse/microprofile-reactive-streams-operators/issues/141[#141])
48 |
49 |
--------------------------------------------------------------------------------
/spec/src/main/asciidoc/spi.asciidoc:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2018 Contributors to the Eclipse Foundation
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 | == SPI
18 |
19 | The API is responsible for building graphs of stages based on the operators the user invoked.
20 | This is done using builder classes that implement the fluent API that is used to compose the
21 | graph. These builders are obtained using the `ReactiveStreamsFactory` interface, a default
22 | implementation of which exists in the core package.
23 | The static methods of the `ReactiveStreams` class delegate to a service loaded implementation of `ReactiveStreamsFactory`, enabling the core implementation to be replaced.
24 |
25 | The stages form an SPI for `ReactiveStreamsEngine` implementations to build into a running stream.
26 | Examples of stages include:
27 |
28 | * Map
29 | * Filter
30 | * Elements to publish
31 | * Collect
32 | * Instances of Reactive Streams `Publisher`, `Subscriber` and `Processor`
33 |
34 | Each stage has either an inlet, an outlet, or both.
35 | A graph is a sequence of stages, consecutive stages will have an outlet and and inlet so that they can join - a graph that has a stage with no outlet followed by a stage that has an inlet is impossible, for example.
36 | Only the stages at the ends of the graph may have no inlet or outlet, whether these end stages have an inlet or outlet determines the shape of the overall graph.
37 | The API is responsible for ensuring that as graphs are constructed, only graphs that are logically possible are passed to the `ReactiveStreamsEngine` to construct.
38 |
39 | The implementation discovery relies on the Java `ServiceLoader` mechanism.
40 | However, for environments not supporting this mechanism, the user can pass custom implementations using the following methods:
41 |
42 | * `org.eclipse.microprofile.reactive.streams.operators.core.ReactiveStreamsEngineResolver#setInstance` - to configure the `ReactiveStreamEngine`
43 | * `org.eclipse.microprofile.reactive.streams.operators.spi.ReactiveStreamsFactoryResolver#setInstance` - to configure the `ReactiveStreamsFactory`
44 |
45 | These methods must be called before the access to the API and should only be used for integration purpose.
46 |
--------------------------------------------------------------------------------
/spec/src/main/resources/META-INF/NOTICE:
--------------------------------------------------------------------------------
1 | =========================================================================
2 | == NOTICE file corresponding to section 4(d) of the Apache License, ==
3 | == Version 2.0, MicroProfile Reactive Streams Operators ==
4 | =========================================================================
5 |
6 | This product includes software developed at
7 | The Apache Software Foundation (http://www.apache.org/).
8 |
9 |
10 | SPDXVersion: SPDX-2.1
11 | PackageName: Eclipse Microprofile
12 | PackageHomePage: http://www.eclipse.org/microprofile
13 | PackageLicenseDeclared: Apache-2.0
14 |
15 | PackageCopyrightText:
16 | James Roper james@lightbend.com
17 | Clement Escoffier clement.escoffier@redhat.com
18 | Gordon Hutchison gordon_hutchison@uk.ibm.com
19 |
--------------------------------------------------------------------------------
/tck/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
35 |
36 | 4.0.0
37 |
38 |
39 | org.eclipse.microprofile.reactive-streams-operators
40 | microprofile-reactive-streams-operators-parent
41 | 3.1-SNAPSHOT
42 |
43 |
44 | microprofile-reactive-streams-operators-tck
45 | Eclipse MicroProfile Reactive Streams Operators TCK
46 | Eclipse MicroProfile Reactive Streams Operators :: TCK
47 |
48 |
49 |
50 |
51 | org.eclipse.microprofile
52 | microprofile-tck-bom
53 | ${version.microprofile.tck.bom}
54 | pom
55 | import
56 |
57 |
58 |
59 |
60 |
61 |
62 | org.eclipse.microprofile.reactive-streams-operators
63 | microprofile-reactive-streams-operators-api
64 | ${project.version}
65 | provided
66 |
67 |
68 | org.eclipse.microprofile.reactive-streams-operators
69 | microprofile-reactive-streams-operators-core
70 | ${project.version}
71 | test
72 |
73 |
74 | org.reactivestreams
75 | reactive-streams-tck
76 |
77 |
78 |
79 | org.jboss.arquillian.test
80 | arquillian-test-spi
81 |
82 |
83 | org.jboss.arquillian.testng
84 | arquillian-testng-container
85 |
86 |
87 | jakarta.enterprise
88 | jakarta.enterprise.cdi-api
89 | provided
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/tck/src/main/java/org/eclipse/microprofile/reactive/streams/operators/tck/DefaultReactiveStreamsFactory.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.tck;
21 |
22 | import java.util.concurrent.CompletionStage;
23 | import java.util.function.Supplier;
24 | import java.util.function.UnaryOperator;
25 |
26 | import org.eclipse.microprofile.reactive.streams.operators.ProcessorBuilder;
27 | import org.eclipse.microprofile.reactive.streams.operators.PublisherBuilder;
28 | import org.eclipse.microprofile.reactive.streams.operators.ReactiveStreams;
29 | import org.eclipse.microprofile.reactive.streams.operators.ReactiveStreamsFactory;
30 | import org.eclipse.microprofile.reactive.streams.operators.SubscriberBuilder;
31 | import org.reactivestreams.Processor;
32 | import org.reactivestreams.Publisher;
33 | import org.reactivestreams.Subscriber;
34 |
35 | /**
36 | * Implementation of the {@link ReactiveStreamsFactory} that delegates to {@link ReactiveStreams} static factory
37 | * methods.
38 | */
39 | public class DefaultReactiveStreamsFactory implements ReactiveStreamsFactory {
40 |
41 | @Override
42 | public PublisherBuilder fromPublisher(Publisher extends T> publisher) {
43 | return ReactiveStreams.fromPublisher(publisher);
44 | }
45 |
46 | @Override
47 | public PublisherBuilder of(T t) {
48 | return ReactiveStreams.of(t);
49 | }
50 |
51 | @Override
52 | public PublisherBuilder of(T... ts) {
53 | return ReactiveStreams.of(ts);
54 | }
55 |
56 | @Override
57 | public PublisherBuilder empty() {
58 | return ReactiveStreams.empty();
59 | }
60 |
61 | @Override
62 | public PublisherBuilder ofNullable(T t) {
63 | return ReactiveStreams.ofNullable(t);
64 | }
65 |
66 | @Override
67 | public PublisherBuilder fromIterable(Iterable extends T> ts) {
68 | return ReactiveStreams.fromIterable(ts);
69 | }
70 |
71 | @Override
72 | public PublisherBuilder failed(Throwable t) {
73 | return ReactiveStreams.failed(t);
74 | }
75 |
76 | @Override
77 | public ProcessorBuilder builder() {
78 | return ReactiveStreams.builder();
79 | }
80 |
81 | @Override
82 | public ProcessorBuilder fromProcessor(Processor super T, ? extends R> processor) {
83 | return ReactiveStreams.fromProcessor(processor);
84 | }
85 |
86 | @Override
87 | public SubscriberBuilder fromSubscriber(Subscriber super T> subscriber) {
88 | return ReactiveStreams.fromSubscriber(subscriber);
89 | }
90 |
91 | @Override
92 | public PublisherBuilder iterate(T seed, UnaryOperator f) {
93 | return ReactiveStreams.iterate(seed, f);
94 | }
95 |
96 | @Override
97 | public PublisherBuilder generate(Supplier extends T> s) {
98 | return ReactiveStreams.generate(s);
99 | }
100 |
101 | @Override
102 | public PublisherBuilder concat(PublisherBuilder extends T> a, PublisherBuilder extends T> b) {
103 | return ReactiveStreams.concat(a, b);
104 | }
105 |
106 | @Override
107 | public PublisherBuilder fromCompletionStage(CompletionStage extends T> completionStage) {
108 | return ReactiveStreams.fromCompletionStage(completionStage);
109 | }
110 |
111 | @Override
112 | public PublisherBuilder fromCompletionStageNullable(CompletionStage extends T> completionStage) {
113 | return ReactiveStreams.fromCompletionStageNullable(completionStage);
114 | }
115 |
116 | @Override
117 | public ProcessorBuilder coupled(SubscriberBuilder super T, ?> subscriber,
118 | PublisherBuilder extends R> publisher) {
119 | return ReactiveStreams.coupled(subscriber, publisher);
120 | }
121 |
122 | @Override
123 | public ProcessorBuilder coupled(Subscriber super T> subscriber, Publisher extends R> publisher) {
124 | return ReactiveStreams.coupled(subscriber, publisher);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/tck/src/main/java/org/eclipse/microprofile/reactive/streams/operators/tck/ReactiveStreamsTck.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2018, 2023 Contributors to the Eclipse Foundation
3 | *
4 | * See the NOTICE file(s) distributed with this work for additional
5 | * information regarding copyright ownership.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * You may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | ******************************************************************************/
19 |
20 | package org.eclipse.microprofile.reactive.streams.operators.tck;
21 |
22 | import java.util.ArrayList;
23 | import java.util.List;
24 | import java.util.concurrent.Executors;
25 | import java.util.concurrent.ScheduledExecutorService;
26 |
27 | import org.eclipse.microprofile.reactive.streams.operators.ReactiveStreamsFactory;
28 | import org.eclipse.microprofile.reactive.streams.operators.spi.ReactiveStreamsEngine;
29 | import org.eclipse.microprofile.reactive.streams.operators.tck.api.ReactiveStreamsApiVerification;
30 | import org.eclipse.microprofile.reactive.streams.operators.tck.spi.ReactiveStreamsSpiVerification;
31 | import org.reactivestreams.tck.TestEnvironment;
32 | import org.testng.annotations.AfterSuite;
33 | import org.testng.annotations.Factory;
34 |
35 | /**
36 | * The Reactive Streams TCK.
37 | *
38 | * A concrete class that extends this class is all that is needed to verify a {@link ReactiveStreamsEngine} against this
39 | * TCK.
40 | *
41 | * It produces a number of TestNG test classes via the TestNG {@link Factory} annotated {@link #allTests()} method.
42 | *
43 | * @param
44 | * The type of the Reactive Streams engine.
45 | */
46 | public abstract class ReactiveStreamsTck {
47 |
48 | private final TestEnvironment testEnvironment;
49 | private E engine;
50 | private ReactiveStreamsFactory rs;
51 | private ScheduledExecutorService executorService;
52 |
53 | public ReactiveStreamsTck(TestEnvironment testEnvironment) {
54 | this.testEnvironment = testEnvironment;
55 | }
56 |
57 | /**
58 | * Override to provide the reactive streams engine.
59 | */
60 | protected abstract E createEngine();
61 |
62 | /**
63 | * Create the reactive streams factory to use. By default, will use one backed by the ReactiveStreams static factory
64 | * methods, that is, using the ServiceLoader to locate one.
65 | */
66 | protected ReactiveStreamsFactory createFactory() {
67 | return new DefaultReactiveStreamsFactory();
68 | }
69 |
70 | /**
71 | * Override to implement custom shutdown logic for the Reactive Streams engine.
72 | */
73 | protected void shutdownEngine(E engine) {
74 | // By default, do nothing.
75 | }
76 |
77 | /**
78 | * Override this to disable/enable tests, useful for debugging one test at a time.
79 | */
80 | protected boolean isEnabled(Object test) {
81 | return true;
82 | }
83 |
84 | @AfterSuite(alwaysRun = true)
85 | public void shutdownEngine() {
86 | if (engine != null) {
87 | shutdownEngine(engine);
88 | }
89 | if (executorService != null) {
90 | shutdownExecutorService(executorService);
91 | }
92 | }
93 |
94 | /**
95 | * Override this to provide a different ScheduledExecutorService
96 | */
97 | protected ScheduledExecutorService createExecutorService() {
98 | return Executors.newScheduledThreadPool(4);
99 | }
100 |
101 | /**
102 | * Override this to customize the shutdown of a ScheduledExecutorService
103 | */
104 | protected void shutdownExecutorService(ScheduledExecutorService executorService) {
105 | executorService.shutdown();
106 | }
107 |
108 | @Factory
109 | public Object[] allTests() {
110 | engine = createEngine();
111 | rs = createFactory();
112 | executorService = createExecutorService();
113 |
114 | ReactiveStreamsApiVerification apiVerification = new ReactiveStreamsApiVerification(rs);
115 | ReactiveStreamsSpiVerification spiVerification =
116 | new ReactiveStreamsSpiVerification(testEnvironment, rs, engine, executorService);
117 |
118 | // Add tests that aren't dependent on the dependencies.
119 | List