{"id":85154,"date":"2018-12-28T10:00:19","date_gmt":"2018-12-28T08:00:19","guid":{"rendered":"https:\/\/www.javacodegeeks.com\/?p=85154"},"modified":"2019-01-11T14:13:17","modified_gmt":"2019-01-11T12:13:17","slug":"bootiful-spring-cloud-stream","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html","title":{"rendered":"Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\/Sub"},"content":{"rendered":"<p>I\u2019ve recently read <a href=\"https:\/\/twitter.com\/starbuxman?lang=en\" target=\"_blank\" rel=\"noopener\">Josh Long<\/a>\u2018s <a href=\"https:\/\/spring.io\/search?q=%22Bootiful+GCP%22&amp;filters=Blog%2FEngineering\" target=\"_blank\" rel=\"noopener\">Bootiful GCP series<\/a> on Sprint Central\u2019s engineering blog and especially liked the <a href=\"https:\/\/spring.io\/blog\/2018\/08\/30\/bootiful-gcp-integration-with-google-cloud-pub-sub-4-8\" target=\"_blank\" rel=\"noopener\">4th part<\/a> about using Google Cloud\u2019s Pub\/Sub. I felt inspired by the series and as I\u2019m also evaluating Spring Cloud Stream for a new project of mine. I thought, I would expand on that article where Josh left off. This article describes how to use <a href=\"https:\/\/cloud.spring.io\/spring-cloud-stream\/\" target=\"_blank\" rel=\"noopener\">Spring Cloud Stream<\/a> with Google Cloud Pub\/Sub for implementing a simple producer and a consumer application.<\/p>\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n<p>You can safely skip this part if you\u2019ve read Josh\u2019s article before. If you haven\u2019t done so, no worries, I\u2019ll quickly summarize some key points here.<\/p>\n<h3 class=\"wp-block-heading\">What is Google Cloud Pub\/Sub?<\/h3>\n<p>Google defines <a href=\"https:\/\/cloud.google.com\/pubsub\/docs\/overview\" target=\"_blank\" rel=\"noopener\">Pub\/Sub<\/a> in the following way.<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Cloud Pub\/Sub brings the scalability, flexibility, and reliability of enterprise message-oriented middleware to the cloud. By providing many-to-many, asynchronous messaging that decouples senders and receivers, it allows for secure and highly available communication between independently written applications.<\/p>\n<\/blockquote>\n<figure class=\"wp-block-embed\">\n<div class=\"wp-block-embed__wrapper\">\nhttps:\/\/cloud.google.com\/pubsub\/docs\/overview\n<\/div>\n<\/figure>\n<p>Simply put, Pub\/Sub is Google\u2019s solution for supporting developers connecting application components with a message broker at Google\u2019s scale. As the name suggests this solution implements publish\/subscribe mechanism with the same concepts you would expect. Messages can be submitted to topics and all the subscribers of a certain topic receive a published message.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" width=\"631\" height=\"343\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/12\/cps-integration.jpg\" alt=\"Google Cloud Pub\/Sub\" class=\"wp-image-85172\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/12\/cps-integration.jpg 631w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/12\/cps-integration-300x163.jpg 300w\" sizes=\"(max-width: 631px) 100vw, 631px\" \/><\/figure>\n<\/div>\n<p><strong>It\u2019s important to emphasize here that Pub\/Sub offers at least once delivery for each submitted message. If you want to ensure that a message gets delivered only once, then you would have to take care of that yourself.&nbsp;<\/strong><\/p>\n<h3 class=\"wp-block-heading\">What is Spring Integration?<\/h3>\n<p><a href=\"https:\/\/spring.io\/projects\/spring-integration\" target=\"_blank\" rel=\"noopener\">Spring Integration<\/a> is a Spring project in their portfolio. An entire article or even an entire book could be written on it, as it\u2019s a vast framework in itself. In summary, Spring Integration is a framework which help you design and integrate applications by using <a href=\"https:\/\/www.enterpriseintegrationpatterns.com\/\" target=\"_blank\" rel=\"noopener\">EIP patterns<\/a>. The two most basic primitives <em>Spring Integration<\/em> is built upon are <code>Message&lt;T&gt;<\/code> and <code>MessageChannel<\/code>. In this regard, developers can decouple and isolate components from each other. You can think of this mechanism as though Spring Integration would take the idea of dependency injection even further in a way where components don\u2019t even have to know about each other, but they\u2019re exchanging messages instead.<\/p>\n<p>Channels can connect components with each other either if they live in the same JVM or even if they\u2019re distributed and separated by the network. At this point the relevant concept to understand is what channel adapters are. They\u2019re basically meant to transform a Spring Framework message as it goes through a message channel, into a piece of data that can be used by external systems.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" width=\"677\" height=\"339\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/12\/cafe-eip.png\" alt=\"Google Cloud Pub\/Sub\" class=\"wp-image-85173\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/12\/cafe-eip.png 677w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/12\/cafe-eip-300x150.png 300w\" sizes=\"(max-width: 677px) 100vw, 677px\" \/><\/figure>\n<\/div>\n<p>A myriad of adapters are provided by Spring Integration which help developers connect to databases, message brokers, and to many other external systems. In this case, adapters are being used for submitting and receiving messages to\/from Google Cloud Pub\/Sub. The <a href=\"https:\/\/cloud.spring.io\/spring-cloud-gcp\/\" target=\"_blank\" rel=\"noopener\">Spring Cloud GCP<\/a> project provides in- and outbound adapters for Pub\/Sub and that makes message exchanges transparent from the point of view of a Spring Integration message flow.<\/p>\n<p>If you read <a href=\"https:\/\/spring.io\/blog\/2018\/08\/30\/bootiful-gcp-integration-with-google-cloud-pub-sub-4-8\" target=\"_blank\" rel=\"noopener\">Josh\u2019s article<\/a> what he does is that he\u2019s introducing Spring Integration for using Pub\/Sub in a clean and consistent way. That means that direct references of <a href=\"https:\/\/docs.spring.io\/spring-cloud-gcp\/docs\/1.0.0.RELEASE\/api\/org\/springframework\/cloud\/gcp\/pubsub\/core\/PubSubTemplate.html\" target=\"_blank\" rel=\"noopener\">PubSubTemplate<\/a> are removed, as a consequence if you wanted to adapt examples in that article for example to RabbitMQ, all you would have to do is just replace the channel adapters accordingly.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<h3 class=\"wp-block-heading\">What is Spring Cloud Stream?<\/h3>\n<p>Messaging is a really great fit for the microservices world where a set of distributed components communicate with each other. As messages and channels are first class citizens in Spring Integration, it\u2019s a great fit for that. On the other hand, Spring Integration was specifically designed to implement those EIP patterns.<\/p>\n<p>However, with modern application development, we don\u2019t necessarily want to integrate with legacy systems, we\u2019d rather integrate with modern message brokers like <a href=\"https:\/\/www.rabbitmq.com\/\" target=\"_blank\" rel=\"noopener\">RabbitMQ<\/a>, <a href=\"https:\/\/kafka.apache.org\/\" target=\"_blank\" rel=\"noopener\">Apache Kafka<\/a> or with <a href=\"https:\/\/cloud.google.com\/pubsub\/docs\/overview\" target=\"_blank\" rel=\"noopener\">GCP Pub\/Sub<\/a> in this case. That said,&nbsp;we don\u2019t need the full repertoire of Spring Integration in terms of being able to integrate with a wide variety of external systems. That extra flexibility would require us to configure adapters, which we don\u2019t need. If we\u2019re just using GCP Pub\/Sub or any other modern message broker previously mentioned, it becomes tedious having to define and configure the adapters for every single component.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" width=\"373\" height=\"310\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/12\/SCSt-with-binder.png\" alt=\"Google Cloud Pub\/Sub\" class=\"wp-image-85174\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/12\/SCSt-with-binder.png 373w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2018\/12\/SCSt-with-binder-300x249.png 300w\" sizes=\"(max-width: 373px) 100vw, 373px\" \/><\/figure>\n<\/div>\n<p>We do want the flexibility of being able to work with messages and we want to take advantage of using a message broker, but we don\u2019t want to write that much code bare Spring Integration would require. <a href=\"https:\/\/cloud.spring.io\/spring-cloud-stream\/\" target=\"_blank\" rel=\"noopener\">Spring Cloud Stream<\/a> builds on Spring Integration and it leverages the same primitives like messages and channels, but it off-loads the developer from having to wire these components together; as channels are connected to external brokers through middleware-specific <em>Binder<\/em> implementations.<\/p>\n<h2 class=\"wp-block-heading\">Using Spring Cloud Stream with Google Cloud Pub\/Sub<\/h2>\n<p>I think I\u2019ve talked enough about the background of Spring Cloud Stream, Spring Integration and Google Cloud Pub\/Sub. It\u2019s time to see some code. There are two very simple Spring Boot applications, which exchange a simple string as the payload of messages. Let\u2019s start with the <a href=\"https:\/\/github.com\/springuni\/springuni-examples\/tree\/master\/spring-cloud\/spring-cloud-stream-pubsub-publisher\" target=\"_blank\" rel=\"noopener\">publisher<\/a>.<\/p>\n<h3 class=\"wp-block-heading\">Publisher<\/h3>\n<p>This is basically a simple controller which send a simple String as the message\u2019s payload. If you\u2019ve worked with Spring Integration before, there\u2019s nothing special about the sending part.<\/p>\n<pre class=\"wp-block-preformatted brush:java\">@RestController\npublic class PublisherController {\n\n  private final MessageChannel outgoing;\n\n  public PublisherController(Channels channels) {\n    outgoing = channels.outgoing();\n  }\n\n  @PostMapping(\"\/publish\/{name}\")\n  public void publish(@PathVariable String name) {\n    outgoing.send(MessageBuilder.withPayload(\"Hello \" + name + \"!\").build());\n  }\n\n}<\/pre>\n<p>What\u2019s interesting is how message channels are bound to the resources of an actual message broker. In line 6-8 a bean (<code>Channels<\/code>) is injected and that seems to hold a reference to the outgoing message channel.<\/p>\n<pre class=\"wp-block-preformatted brush:java\">import org.springframework.cloud.stream.annotation.Output;\nimport org.springframework.messaging.MessageChannel;\n\npublic interface Channels {\n\n  @Output\n  MessageChannel outgoing();\n\n}<\/pre>\n<p><code>Channels<\/code> in turn is just an interface where arbitrary number of message channels can be defined and marked with either <code>@Input<\/code> or <code>@Output<\/code>. Spring Cloud Stream takes care of instantiating a proxy object which is responsible for returning references to <code>MessageChannel<\/code> objects.<\/p>\n<pre class=\"wp-block-preformatted brush:java\">@EnableBinding(Channels.class)\n@SpringBootApplication\npublic class PubsubPublisherApplication {\n\n  public static void main(String[] args) {\n    SpringApplication.run(PubsubPublisherApplication.class, args);\n  }\n\n}<\/pre>\n<p>Spring Cloud Stream relies on both Spring Boot and Spring Integration. The <code>@EnableBinding<\/code> annotation marks <code>Channels<\/code> as a bindable interface and pairs a logical binding name (<code>outgoing<\/code>) with a destination. What destination means that varies across binders, for Pub\/Sub it means a topic for a message producer and a subscription for a message consumer. These bindings can be defined in <code>application.yml<\/code>.<\/p>\n<pre class=\"wp-block-preformatted brush:bash\">spring:\n  cloud:\n    stream:\n      bindings:\n        outgoing:\n          destination: reservations<\/pre>\n<h3 class=\"wp-block-heading\">Subscriber<\/h3>\n<p>The <a href=\"https:\/\/github.com\/springuni\/springuni-examples\/tree\/master\/spring-cloud\/spring-cloud-stream-pubsub-subscriber\" target=\"_blank\" rel=\"noopener\">subscriber<\/a> is even simpler than the publisher, it\u2019s just a single class.<\/p>\n<pre class=\"wp-block-preformatted brush:java\">import org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.cloud.stream.annotation.EnableBinding;\nimport org.springframework.cloud.stream.annotation.StreamListener;\nimport org.springframework.cloud.stream.messaging.Sink;\nimport org.springframework.messaging.Message;\n\n@Slf4j\n@EnableBinding(Sink.class)\n@SpringBootApplication\npublic class PubsubSubscriberApplication {\n\n  public static void main(String[] args) {\n    SpringApplication.run(PubsubSubscriberApplication.class, args);\n  }\n\n  @StreamListener(Sink.INPUT)\n  public void handleMessage(Message&lt;String&gt; message) {\n    log.info(\"Received: {}.\", message.getPayload());\n  }\n\n}<\/pre>\n<p>What\u2019s worth mentioning here is what Sink is?&nbsp;As we\u2019ve just seen <code>@EnableBinding<\/code> can take interfaces and then the framework hides the complexity of wiring in- and outbound message adapters to message channels and it also configures the related infrastructure.&nbsp;Most applications just send or receive messages to\/from a single channel. That\u2019s why Spring Cloud Stream provides the&nbsp;<code>Source<\/code>,&nbsp;<code>Sink<\/code>, and&nbsp;<code>Processor<\/code>&nbsp;interfaces in order to help you cut down on code. That said, we could\u2019ve also used a&nbsp;<code>Source<\/code> for the publisher instead of defining <code>Channels<\/code>, but I wanted to show what the framework is capable of.<\/p>\n<h2 class=\"wp-block-heading\">Running the demo<\/h2>\n<p>In order to be able to run the examples, you\u2019ll need the complete the following steps.<\/p>\n<ol class=\"wp-block-list\">\n<li>\n<ol>\n<li>\n<h2><a href=\"https:\/\/cloud.google.com\/resource-manager\/docs\/creating-managing-projects#creating_a_project\" target=\"_blank\" rel=\"noopener\">Create a GCP project<\/a><\/h2>\n<p>If you have one already, you can skip this step.<\/p>\n<\/li>\n<li>\n<h2><a href=\"https:\/\/cloud.google.com\/shell\/docs\/starting-cloud-shell\" target=\"_blank\" rel=\"noopener\">Start Google Cloud Shell<\/a><\/h2>\n<p>I think easier if you don\u2019t have to install anything. <a href=\"https:\/\/cloud.google.com\/shell\/\" target=\"_blank\" rel=\"noopener\">Google Cloud Shell<\/a> comes with <a href=\"https:\/\/cloud.google.com\/sdk\/\" target=\"_blank\" rel=\"noopener\">Google Cloud SDK<\/a>, Git, Maven and Java pre-installed by default.<\/p>\n<\/li>\n<li>\n<h2>Enable Pub\/Sub API<\/h2>\n<p>As Spring Cloud Stream is an opinionated framework, applications built upon it will create topics and subscriptions on their own. That said, creating a topic and subscription manually is optional here. You\u2019ll have to enable the Pub\/Sub API though.<\/p>\n<pre class=\"brush:bash\">% gcloud services enable pubsub.googleapis.com\n% gcloud pubsub topics create reservations\n% gcloud pubsub subscriptions create reservations --topic=reservations<\/pre>\n<\/li>\n<li>\n<h2>Clone the <a href=\"https:\/\/github.com\/springuni\/springuni-examples\" target=\"_blank\" rel=\"noopener\">springuni-examples<\/a> repo<\/h2>\n<pre class=\"brush:bash\">% git clone https:\/\/github.com\/springuni\/springuni-examples.git<\/pre>\n<\/li>\n<li>\n<h2>Start the publisher<\/h2>\n<pre class=\"brush:bash\">% cd ~\/springuni-examples\/spring-cloud\/spring-cloud-stream-pubsub-publisher\n% mvn spring-boot:run<\/pre>\n<\/li>\n<li>\n<h2>Start the subscriber<\/h2>\n<p>Google Cloud Shell comes with tmux support and that also means that it starts a tmux session by default. That can be disabled of course. Important point is that you don\u2019t have to open a new shell, you just have to open a new window by hitting Ctrl-B and C. Refer to <a href=\"https:\/\/wiki.archlinux.org\/index.php\/tmux#Key_bindings\" target=\"_blank\" rel=\"noopener\">Tmux Key Bindings<\/a> for further details.<\/p>\n<pre class=\"brush:bash\">% cd ~\/springuni-examples\/spring-cloud\/spring-cloud-stream-pubsub-subscriber\n% mvn spring-boot:run<\/pre>\n<\/li>\n<li>\n<h2>Send a message<\/h2>\n<p>Open a new window again as before and send a message.<\/p>\n<pre class=\"brush:bash\">% curl -XPOST http:\/\/localhost:8080\/publish\/test<\/pre>\n<p>You should see the subscriber receiving it.<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h2 class=\"wp-block-heading\">Questions<\/h2>\n<ul class=\"wp-block-list\">\n<li>What do you think what would happen if you started more subscribers?<\/li>\n<li>Would all of them receive the same message or only one of them?<\/li>\n<li>And of course why?<\/li>\n<\/ul>\n<p>Leave a comment below and let me know what do you think!<\/p>\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n<p>We\u2019ve seen what Google Cloud Pub\/Sub is, what Spring Integration is and how an why Spring Cloud Stream builds upon Spring Integration to help developers create message driven microservices faster. With the code examples above I\u2019ve taken Josh\u2019s example further and used Spring Cloud Stream replacing Spring Integration and ultimately cut down on code even more.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td>\n<p>Published on Java Code Geeks with permission by Laszlo Csontos, partner at our <a href=\"\/\/www.javacodegeeks.com\/join-us\/jcg\/\" target=\"_blank\" rel=\"noopener\">JCG program<\/a>. See the original article here: <a href=\"https:\/\/craftingjava.com\/tutorials\/bootiful-gcp-spring-cloud-stream-pub-sub\/\" target=\"_blank\" rel=\"noopener\">Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\/Sub<\/a><\/p>\n<p>Opinions expressed by Java Code Geeks contributors are their own.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>I\u2019ve recently read Josh Long\u2018s Bootiful GCP series on Sprint Central\u2019s engineering blog and especially liked the 4th part about using Google Cloud\u2019s Pub\/Sub. I felt inspired by the series and as I\u2019m also evaluating Spring Cloud Stream for a new project of mine. I thought, I would expand on that article where Josh left &hellip;<\/p>\n","protected":false},"author":67581,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[855,30,1840],"class_list":["post-85154","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-google-cloud","tag-spring","tag-spring-cloud-stream"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\/Sub - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Interested to learn about Google Cloud Pub\/Sub? Check our article explaining how to use Spring Cloud Stream with Google Cloud Pub\/Sub.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\/Sub - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Interested to learn about Google Cloud Pub\/Sub? Check our article explaining how to use Spring Cloud Stream with Google Cloud Pub\/Sub.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/craftingjava\" \/>\n<meta property=\"article:published_time\" content=\"2018-12-28T08:00:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-01-11T12:13:17+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Laszlo Csontos\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@craftingjava\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Laszlo Csontos\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html\"},\"author\":{\"name\":\"Laszlo Csontos\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/9b7371241503cd9c8efc7290d6df28ff\"},\"headline\":\"Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\\\/Sub\",\"datePublished\":\"2018-12-28T08:00:19+00:00\",\"dateModified\":\"2019-01-11T12:13:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html\"},\"wordCount\":1528,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Google Cloud\",\"Spring\",\"Spring Cloud Stream\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html\",\"name\":\"Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\\\/Sub - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2018-12-28T08:00:19+00:00\",\"dateModified\":\"2019-01-11T12:13:17+00:00\",\"description\":\"Interested to learn about Google Cloud Pub\\\/Sub? Check our article explaining how to use Spring Cloud Stream with Google Cloud Pub\\\/Sub.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2018\\\/12\\\/bootiful-spring-cloud-stream.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\\\/Sub\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/9b7371241503cd9c8efc7290d6df28ff\",\"name\":\"Laszlo Csontos\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g\",\"caption\":\"Laszlo Csontos\"},\"description\":\"Laszlo has been coding since the age of 9. Now he'S been coding for 25 years, with Java for 18 years and professionally for 13 years. During past projects he worked in various roles as a consultant, developer, mentor, team leader and architect. His focus areas have been database-oriented back-end applications, performance tuning techniques and distributed systems. In the last 3 years, he specialized in building microservices with the Spring Ecosystem.\",\"sameAs\":[\"https:\\\/\\\/craftingjava.com\\\/\",\"https:\\\/\\\/www.facebook.com\\\/craftingjava\",\" https:\\\/\\\/www.linkedin.com\\\/in\\\/lcsontos\\\/\",\"https:\\\/\\\/x.com\\\/craftingjava\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UC4v5ZYpefzOQu3iMP4NPgXw\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/laszlo-csontos\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\/Sub - Java Code Geeks","description":"Interested to learn about Google Cloud Pub\/Sub? Check our article explaining how to use Spring Cloud Stream with Google Cloud Pub\/Sub.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html","og_locale":"en_US","og_type":"article","og_title":"Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\/Sub - Java Code Geeks","og_description":"Interested to learn about Google Cloud Pub\/Sub? Check our article explaining how to use Spring Cloud Stream with Google Cloud Pub\/Sub.","og_url":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_author":"https:\/\/www.facebook.com\/craftingjava","article_published_time":"2018-12-28T08:00:19+00:00","article_modified_time":"2019-01-11T12:13:17+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Laszlo Csontos","twitter_card":"summary_large_image","twitter_creator":"@craftingjava","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Laszlo Csontos","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html"},"author":{"name":"Laszlo Csontos","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/9b7371241503cd9c8efc7290d6df28ff"},"headline":"Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\/Sub","datePublished":"2018-12-28T08:00:19+00:00","dateModified":"2019-01-11T12:13:17+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html"},"wordCount":1528,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Google Cloud","Spring","Spring Cloud Stream"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html","url":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html","name":"Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\/Sub - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2018-12-28T08:00:19+00:00","dateModified":"2019-01-11T12:13:17+00:00","description":"Interested to learn about Google Cloud Pub\/Sub? Check our article explaining how to use Spring Cloud Stream with Google Cloud Pub\/Sub.","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2018\/12\/bootiful-spring-cloud-stream.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Bootiful GCP: Spring Cloud Stream with Google Cloud Pub\/Sub"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/9b7371241503cd9c8efc7290d6df28ff","name":"Laszlo Csontos","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b35b5beb3547631b3588432ef7e7b8264987239a95964fc870997b06cb70d8c9?s=96&d=mm&r=g","caption":"Laszlo Csontos"},"description":"Laszlo has been coding since the age of 9. Now he'S been coding for 25 years, with Java for 18 years and professionally for 13 years. During past projects he worked in various roles as a consultant, developer, mentor, team leader and architect. His focus areas have been database-oriented back-end applications, performance tuning techniques and distributed systems. In the last 3 years, he specialized in building microservices with the Spring Ecosystem.","sameAs":["https:\/\/craftingjava.com\/","https:\/\/www.facebook.com\/craftingjava"," https:\/\/www.linkedin.com\/in\/lcsontos\/","https:\/\/x.com\/craftingjava","https:\/\/www.youtube.com\/channel\/UC4v5ZYpefzOQu3iMP4NPgXw"],"url":"https:\/\/www.javacodegeeks.com\/author\/laszlo-csontos"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/85154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/67581"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=85154"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/85154\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=85154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=85154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=85154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}