├── service-idl ├── src │ ├── generated │ │ └── .gitignore │ └── main │ │ └── proto │ │ └── service.proto ├── README.md └── build.gradle ├── ci ├── client1.sh └── client2.sh ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── number-generator ├── README.md ├── src │ └── main │ │ ├── java │ │ └── io │ │ │ └── netifi │ │ │ └── proteus │ │ │ └── example │ │ │ └── kafka │ │ │ └── generator │ │ │ ├── StreamNumberResponseSerializer.java │ │ │ ├── Main.java │ │ │ └── GeneratorRunner.java │ │ └── resources │ │ ├── application.properties │ │ └── logback.xml └── build.gradle ├── client ├── src │ └── main │ │ ├── java │ │ └── io │ │ │ └── netifi │ │ │ └── proteus │ │ │ └── example │ │ │ └── kafka │ │ │ └── client │ │ │ ├── Main.java │ │ │ └── ClientRunner.java │ │ └── resources │ │ ├── logback.xml │ │ └── application.properties ├── README.md └── build.gradle ├── client-js ├── src │ └── main │ │ ├── resources │ │ └── web │ │ │ └── index.html │ │ └── js │ │ ├── index.js │ │ └── proteus │ │ ├── service_rsocket_pb.js │ │ └── service_pb.js ├── webpack.config.js ├── package.json └── README.md ├── service ├── README.md ├── build.gradle └── src │ └── main │ ├── java │ └── io │ │ └── netifi │ │ └── proteus │ │ └── example │ │ └── kafka │ │ └── service │ │ ├── StreamNumbersResponseDeserializer.java │ │ ├── Main.java │ │ └── DefaultNumberService.java │ └── resources │ ├── logback.xml │ └── application.properties ├── README.md ├── gradlew.bat ├── .gitignore ├── gradlew └── LICENSE /service-idl/src/generated/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /ci/client1.sh: -------------------------------------------------------------------------------- 1 | cd .. && ./gradlew --no-daemon service:run -------------------------------------------------------------------------------- /ci/client2.sh: -------------------------------------------------------------------------------- 1 | cd .. && ./gradlew --no-daemon client:run -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netifi/proteus-spring-kafka-example/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'proteus-spring-kafka-example' 2 | include 'client' 3 | include 'number-generator' 4 | include 'service' 5 | include 'service-idl' 6 | 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Dec 03 11:13:29 PST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip 7 | -------------------------------------------------------------------------------- /number-generator/README.md: -------------------------------------------------------------------------------- 1 | # number-generator 2 | Generates random numbers and pushes them to a Kafka topic 3 | 4 | 5 | ## Running the Service 6 | From the root project, run the following command to start the service: 7 | 8 | ./gradlew :number-generator:run 9 | 10 | Note: The client and service can be started in any order. The client will not send data until it detects that the service has started. 11 | -------------------------------------------------------------------------------- /client/src/main/java/io/netifi/proteus/example/kafka/client/Main.java: -------------------------------------------------------------------------------- 1 | package io.netifi.proteus.example.kafka.client; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Main { 8 | 9 | public static void main(String... args) { 10 | SpringApplication.run(Main.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /client-js/src/main/resources/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Proteus Quickstart 6 | 7 | 8 |

All Numbers

9 | 10 |

Positive Numbers

11 | 12 |

Negative Numbers

13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /service-idl/README.md: -------------------------------------------------------------------------------- 1 | # service-idl 2 | This project holds the definition of your service's public interface (The methods your service will expose to other clients and services). 3 | 4 | ## Instructions 5 | Define the interface for your service using ProtoBuf IDL in the `src/main/proto` directory. 6 | 7 | An example service interface has been provided for you: [service.proto](https://github.com/netifi/proteus-quickstart/blob/master/service-idl/src/main/proto/io/netifi/proteus/quickstart/service/protobuf/service.proto) 8 | 9 | ## Documentation 10 | Documentation on the IDL format can be found here: [http://docs.netifi.com/protobuf_rsocket/](http://docs.netifi.com/protobuf_rsocket/) 11 | -------------------------------------------------------------------------------- /number-generator/src/main/java/io/netifi/proteus/example/kafka/generator/StreamNumberResponseSerializer.java: -------------------------------------------------------------------------------- 1 | package io.netifi.proteus.example.kafka.generator; 2 | 3 | 4 | import io.netifi.proteus.example.kafka.service.StreamNumbersResponse; 5 | import org.apache.kafka.common.serialization.Serializer; 6 | 7 | import java.util.Map; 8 | 9 | public class StreamNumberResponseSerializer implements Serializer { 10 | @Override 11 | public void configure(Map configs, boolean isKey) {} 12 | 13 | @Override 14 | public byte[] serialize(String topic, StreamNumbersResponse data) { 15 | return data.toByteArray(); 16 | } 17 | 18 | @Override 19 | public void close() {} 20 | } 21 | -------------------------------------------------------------------------------- /service/README.md: -------------------------------------------------------------------------------- 1 | # service 2 | Emits a stream of random numbers based on a type passed to it by a caller. 3 | 4 | ## Prerequisites 5 | The service requires that a Netifi Proteus Broker instance is running and configued with the following access key and token: 6 | 7 | * Access Key: `9007199254740991` 8 | * Access Token: `kTBDVtfRBO4tHOnZzSyY5ym2kfY=` 9 | 10 | Instructions for starting the Netifi Proteus Broker can be found in the main [README](../README.md). 11 | 12 | ## Running the Service 13 | From the root project, run the following command to start the service: 14 | 15 | ./gradlew :service:run 16 | 17 | Note: The client and service can be started in any order. The client will not send data until it detects that the service has started. 18 | -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | # client 2 | Receives a stream of random numbers qualified by a Type supplied when asking for the stream 3 | 4 | ## Prerequisites 5 | The client requires that a Netifi Proteus Broker instance is running and configued with the following access key and token: 6 | 7 | * Access Key: `9007199254740991` 8 | * Access Token: `kTBDVtfRBO4tHOnZzSyY5ym2kfY=` 9 | 10 | Instructions for starting the Netifi Proteus Broker can be found in the main [README](../README.md). 11 | 12 | ## Running the Client 13 | From the root project, run the following command to start the client: 14 | 15 | ./gradlew :client:run 16 | 17 | Note: The client and service can be started in any order. The client will not send data until it detects that the service has started. 18 | -------------------------------------------------------------------------------- /client-js/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | 4 | module.exports = { 5 | entry: path.resolve(__dirname, './src/main/js/index.js'), 6 | output: { 7 | path: path.resolve(__dirname, './src/main/resources/web/'), 8 | filename: 'app.js' 9 | }, 10 | plugins: [ 11 | new webpack.DefinePlugin({ 12 | '__DEV__': true, 13 | '__WS_URL__': JSON.stringify(process.env.WS_URL || 'ws://localhost:8101/') 14 | }) 15 | ], 16 | module: { 17 | loaders: [ 18 | { 19 | test: /\.js?$/, 20 | loader: 'babel-loader', 21 | exclude: /node_modules/ 22 | } 23 | ] 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /service-idl/src/main/proto/service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package io.netifi.proteus.example.kafka.service; 4 | 5 | option java_package = "io.netifi.proteus.example.kafka.service"; 6 | option java_outer_classname = "ServiceProto"; 7 | option java_multiple_files = true; 8 | 9 | service NumberService { 10 | 11 | // A Stream of Random numbers can be filtered by type; 12 | rpc streamNumbers (StreamNumbersRequest) returns (stream StreamNumbersResponse) {} 13 | } 14 | 15 | message StreamNumbersRequest { 16 | enum Type { 17 | EVEN = 0; 18 | ODD = 1; 19 | ALL = 2; 20 | NEGATIVE = 3; 21 | POSITIVE = 4; 22 | } 23 | Type type = 1; 24 | } 25 | 26 | message StreamNumbersResponse { 27 | int64 number = 1; 28 | } 29 | -------------------------------------------------------------------------------- /number-generator/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Netifi Inc. 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 | netifi.proteus.kafka.bootstrapServers=localhost:9092 18 | netifi.proteus.kafka.topic=demo-topic 19 | -------------------------------------------------------------------------------- /client/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'application' 4 | id 'io.spring.dependency-management' version '1.0.6.RELEASE' 5 | } 6 | 7 | mainClassName = 'io.netifi.proteus.example.kafka.client.Main' 8 | sourceCompatibility = 1.8 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootBomVersion}" 13 | } 14 | } 15 | 16 | dependencies { 17 | compile project(':service-idl') 18 | 19 | compile "io.netifi.proteus:proteus-spring-boot-starter:$proteusSpringVersion" 20 | } 21 | 22 | configurations.all { 23 | resolutionStrategy { 24 | dependencySubstitution { 25 | substitute module('com.google.guava:guava') with module('com.google.guava:guava:22.0') 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /service/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'application' 4 | id 'io.spring.dependency-management' version '1.0.6.RELEASE' 5 | } 6 | 7 | mainClassName = 'io.netifi.proteus.example.kafka.service.Main' 8 | sourceCompatibility = 1.8 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootBomVersion}" 13 | } 14 | } 15 | 16 | dependencies { 17 | compile project(':service-idl') 18 | implementation 'io.projectreactor.kafka:reactor-kafka:1.1.0.RELEASE' 19 | compile "io.netifi.proteus:proteus-spring-boot-starter:$proteusSpringVersion" 20 | } 21 | 22 | configurations.all { 23 | resolutionStrategy { 24 | dependencySubstitution { 25 | substitute module('com.google.guava:guava') with module('com.google.guava:guava:22.0') 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /service/src/main/java/io/netifi/proteus/example/kafka/service/StreamNumbersResponseDeserializer.java: -------------------------------------------------------------------------------- 1 | package io.netifi.proteus.example.kafka.service; 2 | 3 | import com.google.protobuf.InvalidProtocolBufferException; 4 | import org.apache.kafka.common.serialization.Deserializer; 5 | import reactor.core.Exceptions; 6 | 7 | import java.util.Map; 8 | 9 | public class StreamNumbersResponseDeserializer implements Deserializer { 10 | @Override 11 | public void configure(Map configs, boolean isKey) {} 12 | 13 | @Override 14 | public StreamNumbersResponse deserialize(String topic, byte[] data) { 15 | try { 16 | return StreamNumbersResponse.parseFrom(data); 17 | } catch (InvalidProtocolBufferException e) { 18 | throw Exceptions.propagate(e); 19 | } 20 | } 21 | 22 | @Override 23 | public void close() {} 24 | } 25 | -------------------------------------------------------------------------------- /client/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ${CONSOLE_LOG_PATTERN} 9 | utf8 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /number-generator/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'application' 4 | id 'io.spring.dependency-management' version '1.0.6.RELEASE' 5 | } 6 | 7 | mainClassName = 'io.netifi.proteus.example.kafka.generator.Main' 8 | sourceCompatibility = 1.8 9 | 10 | dependencyManagement { 11 | imports { 12 | mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootBomVersion}" 13 | } 14 | } 15 | 16 | dependencies { 17 | compile project(':service-idl') 18 | implementation 'io.projectreactor.kafka:reactor-kafka:1.1.0.RELEASE' 19 | implementation "org.springframework.boot:spring-boot-starter:${springBootBomVersion}" 20 | } 21 | 22 | configurations.all { 23 | resolutionStrategy { 24 | dependencySubstitution { 25 | substitute module('com.google.guava:guava') with module('com.google.guava:guava:22.0') 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /number-generator/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ${CONSOLE_LOG_PATTERN} 9 | utf8 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /service/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ${CONSOLE_LOG_PATTERN} 9 | utf8 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /client/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Netifi Inc. 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 | netifi.proteus.broker.hostname=localhost 18 | netifi.proteus.broker.port=8001 19 | 20 | netifi.proteus.access.key=9007199254740991 21 | netifi.proteus.access.token=kTBDVtfRBO4tHOnZzSyY5ym2kfY= 22 | 23 | netifi.proteus.group=proteus.kafkaDemo.client 24 | 25 | netifi.proteus.ssl.disabled=true -------------------------------------------------------------------------------- /service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 Netifi Inc. 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 | netifi.proteus.broker.hostname=localhost 18 | netifi.proteus.broker.port=8001 19 | 20 | netifi.proteus.access.key=9007199254740991 21 | netifi.proteus.access.token=kTBDVtfRBO4tHOnZzSyY5ym2kfY= 22 | 23 | netifi.proteus.group=proteus.kafkaDemo.numberService 24 | 25 | netifi.proteus.kafka.bootstrapServers=localhost:9092 26 | netifi.proteus.kafka.topic=demo-topic 27 | 28 | netifi.proteus.ssl.disabled=true -------------------------------------------------------------------------------- /service-idl/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.google.protobuf' version '0.8.7' 3 | id 'java' 4 | } 5 | 6 | sourceCompatibility = 1.8 7 | 8 | dependencies { 9 | compile "io.netifi.proteus:proteus-client:$proteusVersion" 10 | compile "com.google.protobuf:protobuf-java:$protobufVersion" 11 | } 12 | 13 | sourceSets { 14 | main { 15 | proto { srcDir 'src/main/proto' } 16 | } 17 | 18 | test { 19 | proto { srcDir 'src/test/proto' } 20 | } 21 | } 22 | 23 | protobuf { 24 | generatedFilesBaseDir = "${projectDir}/src/generated" 25 | 26 | protoc { 27 | artifact = "com.google.protobuf:protoc:$protobufVersion" 28 | } 29 | plugins { 30 | rsocketRpc { 31 | artifact = "io.rsocket.rpc:rsocket-rpc-protobuf:$rsocketRpcVersion" 32 | } 33 | } 34 | generateProtoTasks { 35 | ofSourceSet('main')*.plugins { 36 | rsocketRpc {} 37 | } 38 | } 39 | } 40 | 41 | idea { 42 | module { 43 | sourceDirs += file("src/main/proto") 44 | sourceDirs += file("src/generated/main/java") 45 | sourceDirs += file("src/generated/main/proteus") 46 | 47 | generatedSourceDirs += file('src/generated/main/java') 48 | generatedSourceDirs += file('src/generated/main/proteus') 49 | } 50 | } 51 | 52 | clean { 53 | delete 'src/generated/main' 54 | } 55 | -------------------------------------------------------------------------------- /client-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "proteus-browser-demo", 3 | "version": "0.0.1", 4 | "description": "A demo application of Proteus using RSocket from a Browser", 5 | "main": "index.js", 6 | "repository": "https://github.com/netifi-proteus/proteus-browser-demo", 7 | "author": "Kyle Bahr ", 8 | "license": "MIT", 9 | "private": false, 10 | "scripts": { 11 | "protoc": "protoc --proto_path=../service-idl/src/main/proto --proto_path=node_modules/rsocket-rpc-protobuf/proto --js_out=import_style=commonjs,binary:src/main/js/proteus --rsocket_rpc_out=src/main/js/proteus --plugin=protoc-gen-rsocket_rpc=node_modules/.bin/rsocket_rpc_js_protoc_plugin ../service-idl/src/main/proto/service.proto", 12 | "build": "webpack", 13 | "start": "webpack && http-server ./src/main/resources/web/ -p 3000 -c-1" 14 | }, 15 | "devDependencies": { 16 | "babel-core": "^6.26.3", 17 | "babel-loader": "^7.1.4", 18 | "babel-preset-env": "^1.7.0", 19 | "http-server": "^0.11.1", 20 | "rsocket-rpc-core": "^0.0.5-0", 21 | "rsocket-rpc-frames": "^0.0.3", 22 | "rsocket-rpc-metrics": "^0.0.1", 23 | "rsocket-rpc-protobuf": "^0.1.5", 24 | "rsocket-rpc-tracing": "^0.0.3", 25 | "webpack": "3.2.0", 26 | "copy-webpack-plugin": "^4.6.0" 27 | }, 28 | "dependencies": { 29 | "google-protobuf": "^3.6.1", 30 | "proteus-js-client": "^1.5.3", 31 | "ws": "^6.1.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /client/src/main/java/io/netifi/proteus/example/kafka/client/ClientRunner.java: -------------------------------------------------------------------------------- 1 | package io.netifi.proteus.example.kafka.client; 2 | 3 | import io.netifi.proteus.example.kafka.service.NumberServiceClient; 4 | import io.netifi.proteus.example.kafka.service.StreamNumbersRequest; 5 | import io.netifi.proteus.spring.core.annotation.Group; 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | import org.springframework.boot.CommandLineRunner; 9 | import org.springframework.stereotype.Component; 10 | 11 | import java.util.concurrent.ThreadLocalRandom; 12 | 13 | @Component 14 | public class ClientRunner implements CommandLineRunner { 15 | private static final Logger logger = LogManager.getLogger(ClientRunner.class); 16 | 17 | @Group("proteus.kafkaDemo.numberService") 18 | private NumberServiceClient client; 19 | 20 | @Override 21 | public void run(String... args) throws Exception { 22 | // Pick a type at random stream the results 23 | StreamNumbersRequest.Type type = randomType(); 24 | logger.info("Streaming numbers of type " + type.toString()); 25 | 26 | client 27 | .streamNumbers(StreamNumbersRequest.newBuilder().setType(type).build()) 28 | .doOnNext(s -> logger.info("found number {} of {}", s, type.toString())) 29 | .blockLast(); 30 | } 31 | 32 | private StreamNumbersRequest.Type randomType() { 33 | StreamNumbersRequest.Type[] values = StreamNumbersRequest.Type.values(); 34 | int i = ThreadLocalRandom.current().nextInt(0, values.length - 1); 35 | return values[i]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /number-generator/src/main/java/io/netifi/proteus/example/kafka/generator/Main.java: -------------------------------------------------------------------------------- 1 | package io.netifi.proteus.example.kafka.generator; 2 | 3 | import io.netifi.proteus.example.kafka.service.StreamNumbersResponse; 4 | import org.apache.kafka.clients.producer.ProducerConfig; 5 | import org.apache.kafka.common.serialization.IntegerSerializer; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.context.annotation.Bean; 10 | import reactor.kafka.sender.KafkaSender; 11 | import reactor.kafka.sender.SenderOptions; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | @SpringBootApplication 17 | public class Main { 18 | 19 | @Value("${netifi.proteus.kafka.bootstrapServers}") 20 | private String bootstrapServers; 21 | 22 | public static void main(String... args) { 23 | SpringApplication.run(Main.class, args); 24 | } 25 | 26 | @Bean 27 | KafkaSender kafkaSender() { 28 | Map props = new HashMap<>(); 29 | props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); 30 | props.put(ProducerConfig.CLIENT_ID_CONFIG, "sample-producer"); 31 | props.put(ProducerConfig.ACKS_CONFIG, "all"); 32 | props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class); 33 | props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StreamNumberResponseSerializer.class); 34 | 35 | SenderOptions senderOptions = SenderOptions.create(props); 36 | return KafkaSender.create(senderOptions); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /service/src/main/java/io/netifi/proteus/example/kafka/service/Main.java: -------------------------------------------------------------------------------- 1 | package io.netifi.proteus.example.kafka.service; 2 | 3 | import org.apache.kafka.clients.consumer.ConsumerConfig; 4 | import org.apache.kafka.common.serialization.IntegerDeserializer; 5 | import org.apache.kafka.common.serialization.IntegerSerializer; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.context.annotation.Bean; 10 | import reactor.kafka.receiver.KafkaReceiver; 11 | import reactor.kafka.receiver.ReceiverOptions; 12 | 13 | import java.util.Collections; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | @SpringBootApplication 18 | public class Main { 19 | 20 | @Value("${netifi.proteus.kafka.bootstrapServers}") 21 | private String bootstrapServers; 22 | 23 | @Value("${netifi.proteus.kafka.topic}") 24 | private String topic; 25 | 26 | public static void main(String... args) { 27 | SpringApplication.run(Main.class, args); 28 | } 29 | 30 | @Bean 31 | KafkaReceiver kafkaReceiver() { 32 | Map props = new HashMap<>(); 33 | props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); 34 | props.put(ConsumerConfig.CLIENT_ID_CONFIG, "sample-consumer"); 35 | props.put(ConsumerConfig.GROUP_ID_CONFIG, "sample-group"); 36 | props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, IntegerDeserializer.class); 37 | props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StreamNumbersResponseDeserializer.class); 38 | props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); 39 | 40 | ReceiverOptions receiverOptions = 41 | ReceiverOptions.create(props) 42 | .subscription(Collections.singleton(topic)); 43 | return KafkaReceiver.create(receiverOptions); 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /service/src/main/java/io/netifi/proteus/example/kafka/service/DefaultNumberService.java: -------------------------------------------------------------------------------- 1 | package io.netifi.proteus.example.kafka.service; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import org.apache.kafka.clients.consumer.ConsumerRecord; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | import reactor.core.publisher.Flux; 8 | import reactor.kafka.receiver.KafkaReceiver; 9 | 10 | import java.util.function.Function; 11 | import java.util.function.Predicate; 12 | 13 | @Component 14 | public class DefaultNumberService implements NumberService { 15 | 16 | final Flux streamNumbersResponseFlux; 17 | 18 | @Autowired 19 | public DefaultNumberService(KafkaReceiver kafkaReceiver) { 20 | // KafkaReceiver only allows on subscriber so publish a stream with refCnt to allow multiple 21 | // subscribers 22 | streamNumbersResponseFlux = 23 | kafkaReceiver 24 | .receiveAutoAck() 25 | .log() // Just log method to print whats happen... 26 | .flatMap(Function.identity()) 27 | .map(ConsumerRecord::value) 28 | .publish() 29 | .refCount(); 30 | } 31 | 32 | @Override 33 | public Flux streamNumbers(StreamNumbersRequest message, ByteBuf metadata) { 34 | // Filter message based on the type sent in 35 | return streamNumbersResponseFlux.filter(filter(message.getType())); 36 | } 37 | 38 | private Predicate filter(StreamNumbersRequest.Type type) { 39 | switch (type) { 40 | case ALL: 41 | return l -> true; 42 | case ODD: 43 | return l -> l.getNumber() % 2 == 1; 44 | case EVEN: 45 | return l -> l.getNumber() % 2 == 0; 46 | case NEGATIVE: 47 | return l -> l.getNumber() < 0; 48 | case POSITIVE: 49 | return l -> l.getNumber() > -1; 50 | default: 51 | throw new IllegalArgumentException("unknown type " + type); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # proteus-spring-kafka-example 2 | Simple project that shows how to use [reactor-kafka](https://github.com/reactor/reactor-kafka) with Proteus 3 | 4 | ## Projects 5 | This repo contains the following projects: 6 | 7 | * [client](client) - Client asks for a stream of numbers 8 | * [client-js](client-js) - Web Browser client that request streams of numbers 9 | * [service](service) - Service that reads a stream of numbers for kafka 10 | * [service-idl](service-idl) - Definition of the API served by the service 11 | * [number-generator](service-idl) - Application sends random numbers to kafka 12 | 13 | ## Prerequisites 14 | The Proteus Spring Kafka Examples requires you have the following items installed on your machine: 15 | 16 | * [Docker](https://docs.docker.com/install/) 17 | * [Kafka](https://kafka.apache.org/) 18 | 19 | ## Proteus Broker Startup 20 | docker run -p 8001:8001 -p 7001:7001 -p 9000:9000 -p 8101:8101 \ 21 | -e BROKER_SERVER_OPTS="'-Dnetifi.authentication.0.accessKey=9007199254740991' \ 22 | '-Dnetifi.broker.console.enabled=true' \ 23 | '-Dnetifi.broker.ssl.disabled=true' \ 24 | '-Dnetifi.authentication.0.accessToken=kTBDVtfRBO4tHOnZzSyY5ym2kfY=' \ 25 | '-Dnetifi.broker.admin.accessKey=9007199254740991' \ 26 | '-Dnetifi.broker.admin.accessToken=kTBDVtfRBO4tHOnZzSyY5ym2kfY='" netifi/proteus:1.5.3 27 | 28 | ## Bugs and Feedback 29 | For bugs, questions, and discussions please use the [Github Issues](https://github.com/netifi/proteus-spring-kafka-example/issues). 30 | 31 | ## License 32 | Copyright 2019 [Netifi Inc.](https://www.netifi.com) 33 | 34 | Licensed under the Apache License, Version 2.0 (the "License"); 35 | you may not use this file except in compliance with the License. 36 | You may obtain a copy of the License at 37 | 38 | http://www.apache.org/licenses/LICENSE-2.0 39 | 40 | Unless required by applicable law or agreed to in writing, software 41 | distributed under the License is distributed on an "AS IS" BASIS, 42 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 43 | See the License for the specific language governing permissions and 44 | limitations under the License. 45 | -------------------------------------------------------------------------------- /client-js/README.md: -------------------------------------------------------------------------------- 1 | # proteus-spring-kafka-example client js 2 | Demo application for [Netifi Proteus](https://www.netifi.com) and [RSocket](http://rsocket.io). 3 | 4 | ## Preparing the Demo 5 | 6 | - Ensure you have Yarn, Node, and NPM installed: 7 | - https://nodejs.org/en/download/ 8 | - https://www.npmjs.com/get-npm 9 | - https://yarnpkg.com/lang/en/docs/install/ 10 | 11 | ## Running the Demo 12 | 13 | - Fork/clone the repo and `cd` to the root directory from a terminal window 14 | - Install the JavaScript dependencies with 15 | 16 | yarn 17 | 18 | - The generated code in `src/main/resources/web/public/` should be 19 | checked in, and can be updated with: 20 | 21 | yarn run build 22 | 23 | - To view the app in action, start a web server to host the JS: 24 | 25 | yarn start 26 | 27 | - Hit http://localhost:3000 in a webbrowser 28 | 29 | - The page will have several sections 30 | 31 | ## Modifying the Demo 32 | 33 | To edit the homepage (including the JavaScript example code), do the following: 34 | 35 | - In a text editor of your choice, open and modify `src/main/js/index.js` and/or `src/main/resources/index.html` 36 | 37 | - Regenerate the website code in `src/main/resources/web/public/` with: 38 | 39 | yarn run build 40 | 41 | - Launch the new version of the website, which delivers your modified app with: 42 | 43 | yarn start 44 | 45 | - Hit http://localhost:3000 in a webbrowser 46 | 47 | ### Notes 48 | 49 | - This client consume messages from a Kafka topic via a streaming server 50 | 51 | ## Bugs and Feedback 52 | For bugs, questions, and discussions please use the [Github Issues](https://github.com/netifi-proteus/proteus-browser-demo/issues). 53 | 54 | ## License 55 | Copyright 2019 [Netifi Inc.](https://www.netifi.com) 56 | 57 | Licensed under the Apache License, Version 2.0 (the "License"); 58 | you may not use this file except in compliance with the License. 59 | You may obtain a copy of the License at 60 | 61 | http://www.apache.org/licenses/LICENSE-2.0 62 | 63 | Unless required by applicable law or agreed to in writing, software 64 | distributed under the License is distributed on an "AS IS" BASIS, 65 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 66 | See the License for the specific language governing permissions and 67 | limitations under the License. 68 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/java,linux,macos,gradle,intellij 3 | 4 | ### Intellij ### 5 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 6 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 7 | 8 | # User-specific stuff: 9 | .idea/** 10 | *.iml 11 | target/ 12 | pom.xml.tag 13 | pom.xml.releaseBackup 14 | pom.xml.versionsBackup 15 | pom.xml.next 16 | release.properties 17 | dependency-reduced-pom.xml 18 | buildNumber.properties 19 | .mvn/timing.properties 20 | .mvn/wrapper/maven-wrapper.jar 21 | # CMake 22 | cmake-build-debug/ 23 | 24 | ### Java ### 25 | # Compiled class file 26 | 27 | # Log file 28 | 29 | # BlueJ files 30 | *.ctxt 31 | 32 | # Mobile Tools for Java (J2ME) 33 | 34 | # Package Files # 35 | *.jar 36 | *.zip 37 | *.tar.gz 38 | *.rar 39 | 40 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 41 | 42 | ### Linux ### 43 | 44 | # temporary files which can be created if a process still has a handle open of a deleted file 45 | .fuse_hidden* 46 | 47 | # KDE directory preferences 48 | .directory 49 | 50 | # Linux trash folder which might appear on any partition or disk 51 | .Trash-* 52 | 53 | # .nfs files are created when an open file is removed but is still being accessed 54 | .nfs* 55 | 56 | ### macOS ### 57 | *.DS_Store 58 | .AppleDouble 59 | .LSOverride 60 | 61 | # Icon must end with two \r 62 | Icon 63 | 64 | # Thumbnails 65 | 66 | # Files that might appear in the root of a volume 67 | .DocumentRevisions-V100 68 | .fseventsd 69 | .TemporaryItems 70 | .VolumeIcon.icns 71 | .com.apple.timemachine.donotpresent 72 | 73 | # Directories potentially created on remote AFP share 74 | .AppleDB 75 | .AppleDesktop 76 | Network Trash Folder 77 | Temporary Items 78 | .apdisk 79 | 80 | ### Gradle ### 81 | /build/ 82 | **/build/ 83 | /out/** 84 | **/out/ 85 | 86 | .gradle/** 87 | 88 | # Ignore Gradle GUI config 89 | gradle-app.setting 90 | 91 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 92 | !gradle-wrapper.jar 93 | 94 | # Cache of project 95 | .gradletasknamecache 96 | 97 | .project 98 | 99 | **/.settings/* 100 | 101 | .vscode 102 | 103 | .classpath 104 | 105 | bin/ 106 | 107 | node_modules/ 108 | build/ 109 | 110 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 111 | # gradle/wrapper/gradle-wrapper.properties 112 | 113 | # End of https://www.gitignore.io/api/java,linux,macos,gradle,android,intellij,androidstudio -------------------------------------------------------------------------------- /number-generator/src/main/java/io/netifi/proteus/example/kafka/generator/GeneratorRunner.java: -------------------------------------------------------------------------------- 1 | package io.netifi.proteus.example.kafka.generator; 2 | 3 | import io.netifi.proteus.example.kafka.service.StreamNumbersResponse; 4 | import org.apache.kafka.clients.producer.ProducerRecord; 5 | import org.apache.kafka.clients.producer.RecordMetadata; 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.beans.factory.annotation.Value; 10 | import org.springframework.boot.CommandLineRunner; 11 | import org.springframework.stereotype.Component; 12 | import reactor.core.publisher.Flux; 13 | import reactor.kafka.sender.KafkaSender; 14 | import reactor.kafka.sender.SenderRecord; 15 | 16 | import java.text.SimpleDateFormat; 17 | import java.time.Duration; 18 | import java.util.Date; 19 | import java.util.concurrent.ThreadLocalRandom; 20 | 21 | @Component 22 | public class GeneratorRunner implements CommandLineRunner { 23 | private static final Logger logger = LogManager.getLogger(GeneratorRunner.class); 24 | private final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSS z dd MMM yyyy"); 25 | @Autowired KafkaSender kafkaSender; 26 | 27 | @Value("${netifi.proteus.kafka.topic}") 28 | String topic; 29 | 30 | @Override 31 | public void run(String... args) throws Exception { 32 | Flux> records = 33 | Flux.interval(Duration.ofSeconds(1)) 34 | .map( 35 | l -> { 36 | long number = ThreadLocalRandom.current().nextLong(); 37 | StreamNumbersResponse response = 38 | StreamNumbersResponse.newBuilder().setNumber(number).build(); 39 | 40 | return SenderRecord.create(new ProducerRecord<>(topic, response), number); 41 | }); 42 | kafkaSender 43 | .send(records) 44 | .doOnError(e -> logger.error("Send failed", e)) 45 | .doOnNext( 46 | r -> { 47 | RecordMetadata metadata = r.recordMetadata(); 48 | System.out.printf( 49 | "Random number %d sent successfully, topic-partition=%s-%d offset=%d timestamp=%s\n", 50 | r.correlationMetadata(), 51 | metadata.topic(), 52 | metadata.partition(), 53 | metadata.offset(), 54 | dateFormat.format(new Date(metadata.timestamp()))); 55 | }) 56 | .blockLast(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /client-js/src/main/js/index.js: -------------------------------------------------------------------------------- 1 | const {StreamNumbersRequest} = require('./proteus/service_pb'); 2 | const {StreamNumbersResponse} = require('./proteus/service_pb'); 3 | const {NumberServiceClient} = require('./proteus/service_rsocket_pb'); 4 | const {Proteus} = require('proteus-js-client'); 5 | 6 | /** Helpers **/ 7 | 8 | // For generating variable identities in order to easily tell if messages are coming from this application instance or another 9 | const alphabet = [ 10 | "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India", "Juliet", "Kilo", "Lima", "Mike", "November", 11 | "Oscar", "Papa", "Quebec", "Romeo", "Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-Ray", "Yankee", "Zulu" 12 | ]; 13 | 14 | const numbers = [ 15 | "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" 16 | ]; 17 | 18 | function getRandomInt(max) { 19 | return Math.floor(Math.random() * Math.floor(max)); 20 | } 21 | 22 | function generateName(){ 23 | return alphabet[getRandomInt(25)] + '-' + numbers[getRandomInt(9)] + '-' + numbers[getRandomInt(9)] + '-' + numbers[getRandomInt(9)]; 24 | } 25 | 26 | 27 | function addMessage(message) { 28 | var ul = document.getElementById('messages'); 29 | var li = document.createElement("li"); 30 | li.appendChild(document.createTextNode(message)); 31 | if(ul.childElementCount >= 10){ 32 | ul.removeChild(ul.childNodes[0]); 33 | } 34 | ul.appendChild(li); 35 | } 36 | 37 | function main() { 38 | const url = __WS_URL__; 39 | 40 | const sessionId = generateName(); 41 | 42 | // This Proteus object acts as our gateway to both send messages to services and to register services that we support 43 | const proteusGateway = Proteus.create({ 44 | setup: { 45 | group: 'proteus.kafkaDemo.browserClient', 46 | destination: sessionId, 47 | accessKey: 9007199254740991, 48 | accessToken: 'kTBDVtfRBO4tHOnZzSyY5ym2kfY=', 49 | }, 50 | transport: { 51 | url, 52 | }, 53 | }); 54 | 55 | // Connect to Netifi Proteus Platform 56 | const conn = proteusGateway.group("proteus.kafkaDemo.numberService"); 57 | 58 | // Create Client to Communicate with the NumberService 59 | const client = new NumberServiceClient(conn); 60 | 61 | // Create Request to NumberService 62 | const requestAllNumbers = new StreamNumbersRequest(); 63 | requestAllNumbers.setType(2) 64 | 65 | client.streamNumbers(requestAllNumbers).subscribe({ 66 | onNext: response => { 67 | console.log("Pong received: " + JSON.stringify(response)); 68 | allNumbers("Number Service responded with: " + response) 69 | _subscription.request(1); 70 | }, 71 | onError: error => { 72 | logFunction("Number Service responded with error: " + error); 73 | }, 74 | onSubscribe: subscription => { 75 | _subscription = subscription; 76 | _subscription.request(1); 77 | } 78 | }, 15000) 79 | 80 | // Create Request to NumberService 81 | const requestPositiveNumbers = new StreamNumbersRequest(); 82 | requestPositiveNumbers.setType(4) 83 | 84 | client.streamNumbers(requestPositiveNumbers).subscribe({ 85 | onNext: response => { 86 | console.log("Pong received: " + JSON.stringify(response)); 87 | positiveNumbers("Number Service responded with: " + response) 88 | _subscription1.request(4); 89 | }, 90 | onError: error => { 91 | logFunction("Number Service responded with error: " + error); 92 | }, 93 | onSubscribe: subscription => { 94 | _subscription1 = subscription; 95 | _subscription1.request(1); 96 | } 97 | }, 15000) 98 | 99 | // Create Request to NumberService 100 | const requestNegativeNumbers = new StreamNumbersRequest(); 101 | requestNegativeNumbers.setType(3) 102 | 103 | client.streamNumbers(requestNegativeNumbers).subscribe({ 104 | onNext: response => { 105 | console.log("Pong received: " + JSON.stringify(response)); 106 | negativeNumbers("Number Service responded with: " + response) 107 | _subscription2.request(1); 108 | }, 109 | onError: error => { 110 | logFunction("Number Service responded with error: " + error); 111 | }, 112 | onSubscribe: subscription => { 113 | _subscription2 = subscription; 114 | _subscription2.request(1); 115 | } 116 | }, 15000) 117 | } 118 | 119 | function allNumbers(message) { 120 | var ul = document.getElementById('allNumbers'); 121 | var li = document.createElement("li"); 122 | li.appendChild(document.createTextNode(message)); 123 | if(ul.childElementCount >= 10){ 124 | ul.removeChild(ul.childNodes[0]); 125 | } 126 | ul.appendChild(li); 127 | } 128 | 129 | function positiveNumbers(message) { 130 | var ul = document.getElementById('positiveNumbers'); 131 | var li = document.createElement("li"); 132 | li.appendChild(document.createTextNode(message)); 133 | if(ul.childElementCount >= 10){ 134 | ul.removeChild(ul.childNodes[0]); 135 | } 136 | ul.appendChild(li); 137 | } 138 | 139 | function negativeNumbers(message) { 140 | var ul = document.getElementById('negativeNumbers'); 141 | var li = document.createElement("li"); 142 | li.appendChild(document.createTextNode(message)); 143 | if(ul.childElementCount >= 10){ 144 | ul.removeChild(ul.childNodes[0]); 145 | } 146 | ul.appendChild(li); 147 | } 148 | 149 | 150 | main(); -------------------------------------------------------------------------------- /client-js/src/main/js/proteus/service_rsocket_pb.js: -------------------------------------------------------------------------------- 1 | // GENERATED CODE -- DO NOT EDIT! 2 | 3 | 'use strict'; 4 | var rsocket_rpc_frames = require('rsocket-rpc-frames'); 5 | var rsocket_rpc_core = require('rsocket-rpc-core'); 6 | var rsocket_rpc_tracing = require('rsocket-rpc-tracing'); 7 | var rsocket_rpc_metrics = require('rsocket-rpc-metrics').Metrics; 8 | var rsocket_flowable = require('rsocket-flowable'); 9 | var service_pb = require('./service_pb.js'); 10 | 11 | var NumberServiceClient = function () { 12 | function NumberServiceClient(rs, tracer, meterRegistry) { 13 | this._rs = rs; 14 | this._tracer = tracer; 15 | this.streamNumbersTrace = rsocket_rpc_tracing.trace(tracer, "NumberService", {"rsocket.rpc.service": "io.netifi.proteus.example.kafka.service.NumberService"}, {"method": "streamNumbers"}, {"rsocket.rpc.role": "client"}); 16 | this.streamNumbersMetrics = rsocket_rpc_metrics.timed(meterRegistry, "NumberService", {"service": "io.netifi.proteus.example.kafka.service.NumberService"}, {"method": "streamNumbers"}, {"role": "client"}); 17 | } 18 | // A Stream of Random numbers can be filtered by type; 19 | NumberServiceClient.prototype.streamNumbers = function streamNumbers(message, metadata) { 20 | const map = {}; 21 | return this.streamNumbersMetrics( 22 | this.streamNumbersTrace(map)(new rsocket_flowable.Flowable(subscriber => { 23 | var dataBuf = Buffer.from(message.serializeBinary()); 24 | var tracingMetadata = rsocket_rpc_tracing.mapToBuffer(map); 25 | var metadataBuf = rsocket_rpc_frames.encodeMetadata('io.netifi.proteus.example.kafka.service.NumberService', 'streamNumbers', tracingMetadata, metadata || Buffer.alloc(0)); 26 | this._rs.requestStream({ 27 | data: dataBuf, 28 | metadata: metadataBuf 29 | }).map(function (payload) { 30 | //TODO: resolve either 'https://github.com/rsocket/rsocket-js/issues/19' or 'https://github.com/google/protobuf/issues/1319' 31 | var binary = !payload.data || payload.data.constructor === Buffer || payload.data.constructor === Uint8Array ? payload.data : new Uint8Array(payload.data); 32 | return service_pb.StreamNumbersResponse.deserializeBinary(binary); 33 | }).subscribe(subscriber); 34 | }) 35 | ) 36 | ); 37 | }; 38 | return NumberServiceClient; 39 | }(); 40 | 41 | exports.NumberServiceClient = NumberServiceClient; 42 | 43 | var NumberServiceServer = function () { 44 | function NumberServiceServer(service, tracer, meterRegistry) { 45 | this._service = service; 46 | this._tracer = tracer; 47 | this.streamNumbersTrace = rsocket_rpc_tracing.traceAsChild(tracer, "NumberService", {"rsocket.rpc.service": "io.netifi.proteus.example.kafka.service.NumberService"}, {"method": "streamNumbers"}, {"rsocket.rpc.role": "server"}); 48 | this.streamNumbersMetrics = rsocket_rpc_metrics.timed(meterRegistry, "NumberService", {"service": "io.netifi.proteus.example.kafka.service.NumberService"}, {"method": "streamNumbers"}, {"role": "server"}); 49 | this._channelSwitch = (payload, restOfMessages) => { 50 | if (payload.metadata == null) { 51 | return rsocket_flowable.Flowable.error(new Error('metadata is empty')); 52 | } 53 | var method = rsocket_rpc_frames.getMethod(payload.metadata); 54 | var spanContext = rsocket_rpc_tracing.deserializeTraceData(this._tracer, payload.metadata); 55 | let deserializedMessages; 56 | switch(method){ 57 | default: 58 | return rsocket_flowable.Flowable.error(new Error('unknown method')); 59 | } 60 | }; 61 | } 62 | NumberServiceServer.prototype.fireAndForget = function fireAndForget(payload) { 63 | throw new Error('fireAndForget() is not implemented'); 64 | }; 65 | NumberServiceServer.prototype.requestResponse = function requestResponse(payload) { 66 | return rsocket_flowable.Single.error(new Error('requestResponse() is not implemented')); 67 | }; 68 | NumberServiceServer.prototype.requestStream = function requestStream(payload) { 69 | try { 70 | if (payload.metadata == null) { 71 | return rsocket_flowable.Flowable.error(new Error('metadata is empty')); 72 | } 73 | var method = rsocket_rpc_frames.getMethod(payload.metadata); 74 | var spanContext = rsocket_rpc_tracing.deserializeTraceData(this._tracer, payload.metadata); 75 | switch (method) { 76 | case 'streamNumbers': 77 | return this.streamNumbersMetrics( 78 | this.streamNumbersTrace(spanContext)(new rsocket_flowable.Flowable(subscriber => { 79 | var binary = !payload.data || payload.data.constructor === Buffer || payload.data.constructor === Uint8Array ? payload.data : new Uint8Array(payload.data); 80 | return this._service 81 | .streamNumbers(service_pb.StreamNumbersRequest.deserializeBinary(binary), payload.metadata) 82 | .map(function (message) { 83 | return { 84 | data: Buffer.from(message.serializeBinary()), 85 | metadata: Buffer.alloc(0) 86 | } 87 | }).subscribe(subscriber); 88 | } 89 | ) 90 | ) 91 | ); 92 | default: 93 | return rsocket_flowable.Flowable.error(new Error('unknown method')); 94 | } 95 | } catch (error) { 96 | return rsocket_flowable.Flowable.error(error); 97 | } 98 | }; 99 | NumberServiceServer.prototype.requestChannel = function requestChannel(payloads) { 100 | return new rsocket_flowable.Flowable(s => payloads.subscribe(s)).lift(s => 101 | new rsocket_rpc_core.SwitchTransformOperator(s, (payload, flowable) => this._channelSwitch(payload, flowable)), 102 | ); 103 | }; 104 | NumberServiceServer.prototype.metadataPush = function metadataPush(payload) { 105 | return rsocket_flowable.Single.error(new Error('metadataPush() is not implemented')); 106 | }; 107 | return NumberServiceServer; 108 | }(); 109 | 110 | exports.NumberServiceServer = NumberServiceServer; 111 | 112 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save ( ) { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /client-js/src/main/js/proteus/service_pb.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * @enhanceable 4 | * @suppress {messageConventions} JS Compiler reports an error if a variable or 5 | * field starts with 'MSG_' and isn't a translatable message. 6 | * @public 7 | */ 8 | // GENERATED CODE -- DO NOT EDIT! 9 | 10 | var jspb = require('google-protobuf'); 11 | var goog = jspb; 12 | var global = Function('return this')(); 13 | 14 | goog.exportSymbol('proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest', null, global); 15 | goog.exportSymbol('proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.Type', null, global); 16 | goog.exportSymbol('proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse', null, global); 17 | 18 | /** 19 | * Generated by JsPbCodeGenerator. 20 | * @param {Array=} opt_data Optional initial data array, typically from a 21 | * server response, or constructed directly in Javascript. The array is used 22 | * in place and becomes part of the constructed object. It is not cloned. 23 | * If no data is provided, the constructed object will be empty, but still 24 | * valid. 25 | * @extends {jspb.Message} 26 | * @constructor 27 | */ 28 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest = function(opt_data) { 29 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 30 | }; 31 | goog.inherits(proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest, jspb.Message); 32 | if (goog.DEBUG && !COMPILED) { 33 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.displayName = 'proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest'; 34 | } 35 | 36 | 37 | if (jspb.Message.GENERATE_TO_OBJECT) { 38 | /** 39 | * Creates an object representation of this proto suitable for use in Soy templates. 40 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 41 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 42 | * For the list of reserved names please see: 43 | * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. 44 | * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 45 | * for transitional soy proto support: http://goto/soy-param-migration 46 | * @return {!Object} 47 | */ 48 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.prototype.toObject = function(opt_includeInstance) { 49 | return proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.toObject(opt_includeInstance, this); 50 | }; 51 | 52 | 53 | /** 54 | * Static version of the {@see toObject} method. 55 | * @param {boolean|undefined} includeInstance Whether to include the JSPB 56 | * instance for transitional soy proto support: 57 | * http://goto/soy-param-migration 58 | * @param {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest} msg The msg instance to transform. 59 | * @return {!Object} 60 | * @suppress {unusedLocalVariables} f is only used for nested messages 61 | */ 62 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.toObject = function(includeInstance, msg) { 63 | var f, obj = { 64 | type: jspb.Message.getFieldWithDefault(msg, 1, 0) 65 | }; 66 | 67 | if (includeInstance) { 68 | obj.$jspbMessageInstance = msg; 69 | } 70 | return obj; 71 | }; 72 | } 73 | 74 | 75 | /** 76 | * Deserializes binary data (in protobuf wire format). 77 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 78 | * @return {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest} 79 | */ 80 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.deserializeBinary = function(bytes) { 81 | var reader = new jspb.BinaryReader(bytes); 82 | var msg = new proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest; 83 | return proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.deserializeBinaryFromReader(msg, reader); 84 | }; 85 | 86 | 87 | /** 88 | * Deserializes binary data (in protobuf wire format) from the 89 | * given reader into the given message object. 90 | * @param {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest} msg The message object to deserialize into. 91 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 92 | * @return {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest} 93 | */ 94 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.deserializeBinaryFromReader = function(msg, reader) { 95 | while (reader.nextField()) { 96 | if (reader.isEndGroup()) { 97 | break; 98 | } 99 | var field = reader.getFieldNumber(); 100 | switch (field) { 101 | case 1: 102 | var value = /** @type {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.Type} */ (reader.readEnum()); 103 | msg.setType(value); 104 | break; 105 | default: 106 | reader.skipField(); 107 | break; 108 | } 109 | } 110 | return msg; 111 | }; 112 | 113 | 114 | /** 115 | * Serializes the message to binary data (in protobuf wire format). 116 | * @return {!Uint8Array} 117 | */ 118 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.prototype.serializeBinary = function() { 119 | var writer = new jspb.BinaryWriter(); 120 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.serializeBinaryToWriter(this, writer); 121 | return writer.getResultBuffer(); 122 | }; 123 | 124 | 125 | /** 126 | * Serializes the given message to binary data (in protobuf wire 127 | * format), writing to the given BinaryWriter. 128 | * @param {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest} message 129 | * @param {!jspb.BinaryWriter} writer 130 | * @suppress {unusedLocalVariables} f is only used for nested messages 131 | */ 132 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.serializeBinaryToWriter = function(message, writer) { 133 | var f = undefined; 134 | f = message.getType(); 135 | if (f !== 0.0) { 136 | writer.writeEnum( 137 | 1, 138 | f 139 | ); 140 | } 141 | }; 142 | 143 | 144 | /** 145 | * @enum {number} 146 | */ 147 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.Type = { 148 | EVEN: 0, 149 | ODD: 1, 150 | ALL: 2, 151 | NEGATIVE: 3, 152 | POSITIVE: 4 153 | }; 154 | 155 | /** 156 | * optional Type type = 1; 157 | * @return {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.Type} 158 | */ 159 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.prototype.getType = function() { 160 | return /** @type {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.Type} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); 161 | }; 162 | 163 | 164 | /** @param {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.Type} value */ 165 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersRequest.prototype.setType = function(value) { 166 | jspb.Message.setProto3EnumField(this, 1, value); 167 | }; 168 | 169 | 170 | 171 | /** 172 | * Generated by JsPbCodeGenerator. 173 | * @param {Array=} opt_data Optional initial data array, typically from a 174 | * server response, or constructed directly in Javascript. The array is used 175 | * in place and becomes part of the constructed object. It is not cloned. 176 | * If no data is provided, the constructed object will be empty, but still 177 | * valid. 178 | * @extends {jspb.Message} 179 | * @constructor 180 | */ 181 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse = function(opt_data) { 182 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 183 | }; 184 | goog.inherits(proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse, jspb.Message); 185 | if (goog.DEBUG && !COMPILED) { 186 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.displayName = 'proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse'; 187 | } 188 | 189 | 190 | if (jspb.Message.GENERATE_TO_OBJECT) { 191 | /** 192 | * Creates an object representation of this proto suitable for use in Soy templates. 193 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 194 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 195 | * For the list of reserved names please see: 196 | * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS. 197 | * @param {boolean=} opt_includeInstance Whether to include the JSPB instance 198 | * for transitional soy proto support: http://goto/soy-param-migration 199 | * @return {!Object} 200 | */ 201 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.prototype.toObject = function(opt_includeInstance) { 202 | return proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.toObject(opt_includeInstance, this); 203 | }; 204 | 205 | 206 | /** 207 | * Static version of the {@see toObject} method. 208 | * @param {boolean|undefined} includeInstance Whether to include the JSPB 209 | * instance for transitional soy proto support: 210 | * http://goto/soy-param-migration 211 | * @param {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse} msg The msg instance to transform. 212 | * @return {!Object} 213 | * @suppress {unusedLocalVariables} f is only used for nested messages 214 | */ 215 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.toObject = function(includeInstance, msg) { 216 | var f, obj = { 217 | number: jspb.Message.getFieldWithDefault(msg, 1, 0) 218 | }; 219 | 220 | if (includeInstance) { 221 | obj.$jspbMessageInstance = msg; 222 | } 223 | return obj; 224 | }; 225 | } 226 | 227 | 228 | /** 229 | * Deserializes binary data (in protobuf wire format). 230 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 231 | * @return {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse} 232 | */ 233 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.deserializeBinary = function(bytes) { 234 | var reader = new jspb.BinaryReader(bytes); 235 | var msg = new proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse; 236 | return proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.deserializeBinaryFromReader(msg, reader); 237 | }; 238 | 239 | 240 | /** 241 | * Deserializes binary data (in protobuf wire format) from the 242 | * given reader into the given message object. 243 | * @param {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse} msg The message object to deserialize into. 244 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 245 | * @return {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse} 246 | */ 247 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.deserializeBinaryFromReader = function(msg, reader) { 248 | while (reader.nextField()) { 249 | if (reader.isEndGroup()) { 250 | break; 251 | } 252 | var field = reader.getFieldNumber(); 253 | switch (field) { 254 | case 1: 255 | var value = /** @type {number} */ (reader.readInt64()); 256 | msg.setNumber(value); 257 | break; 258 | default: 259 | reader.skipField(); 260 | break; 261 | } 262 | } 263 | return msg; 264 | }; 265 | 266 | 267 | /** 268 | * Serializes the message to binary data (in protobuf wire format). 269 | * @return {!Uint8Array} 270 | */ 271 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.prototype.serializeBinary = function() { 272 | var writer = new jspb.BinaryWriter(); 273 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.serializeBinaryToWriter(this, writer); 274 | return writer.getResultBuffer(); 275 | }; 276 | 277 | 278 | /** 279 | * Serializes the given message to binary data (in protobuf wire 280 | * format), writing to the given BinaryWriter. 281 | * @param {!proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse} message 282 | * @param {!jspb.BinaryWriter} writer 283 | * @suppress {unusedLocalVariables} f is only used for nested messages 284 | */ 285 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.serializeBinaryToWriter = function(message, writer) { 286 | var f = undefined; 287 | f = message.getNumber(); 288 | if (f !== 0) { 289 | writer.writeInt64( 290 | 1, 291 | f 292 | ); 293 | } 294 | }; 295 | 296 | 297 | /** 298 | * optional int64 number = 1; 299 | * @return {number} 300 | */ 301 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.prototype.getNumber = function() { 302 | return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); 303 | }; 304 | 305 | 306 | /** @param {number} value */ 307 | proto.io.netifi.proteus.example.kafka.service.StreamNumbersResponse.prototype.setNumber = function(value) { 308 | jspb.Message.setProto3IntField(this, 1, value); 309 | }; 310 | 311 | 312 | goog.object.extend(exports, proto.io.netifi.proteus.example.kafka.service); 313 | --------------------------------------------------------------------------------