>> Hey, Josh, we're back here.
We're going to do Spring with Service Bus.
>> Yeah. Azure Service Bus,
which is a great way to connect applications on the platform.
>> My background is BizTalk.
That's where I started, was BizTalk in
just running around consulting on integration stuff.
It's not everybody's bag,
but messaging and distributed systems
and messaging patterns is just fun.
>> It is fun and it's critical
as we move forward in time day-by-day,
every single day, there's new things that need to be integrated.
New things that are now considered legacy
and surface area of
which needs to be integrated with the new things.
That's awesome. I love integration. I love messaging.
I've had experience with a few other messaging systems,
Axway integrator,
TIBCO and web methods. I love messaging like you.
I haven't had the privilege of using BizTalk.
I know it's a vulnerable piece of software.
Indeed we even have,
in the Spring portfolio,
something called Spring integration,
on which I was a contributor, committer.
I was the leading source of bugs in Spring Integration.
So that's cool. Got to have something.
So I love integration,
the Spring team loves integration and that's
why I was so enthralled to see Service Bus.
>> Yeah. The people on our side,
on the Microsoft side for core architectures, Clemens Vasters.
I think it's phenomenal that we give him the freedom to really
live standards and look at pushing
what the industry does forward silo.
He's the co-chair of the Oasis Technical Committee for AMQP.
His is always just trying to push
what are we doing on our standards?
How do we make messaging scale better, faster, more resilience?
How do we just go from
crazy amounts of messages going around to even more?
>> Yeah.
>> If he was on that prior demo where we did optic storage,
I know he would love the fact
that you did cats there because I know his Instagram feed is,
is cats and bunnies and airplanes.
So I think we may have to have him come on on the subsequent show.
>> That sounds awesome. You had him
already in earlier episode, is that right?
>> Yeah. We did.
I think that's one of the things that I
just want to mention is that,
especially when one of the couple of tidbits from
his earlier episode was make sure you're choosing
the right pricing tier
and the right service when you go to production,
because especially when you're looking at Azure Service Bus,
there are very few things in the Azure platform.
If you're changing gears, or pricing,
or changing configuration around that,
it may make things happen.
For example, I can be changing class of VM in Azure,
that will require a reboot.
But Service Bus, it's one of those things where if
you need to change gears from basic up to premium,
you have to go grab your messages on our BQs,
copy them, do something like that.
That's not something that you typically want to do when you're,
"Let's go get production up on
basic," and then, "We're in production.
Now let's switch basic to premium,"
and you may run in these things.
I'll point to the other video from Clence
because he had a whole bunch of other stuff on that.
It was all around typical messaging and he's like, "Hey,
make sure you put a subscriber
on [inaudible] that are queued right off the bat."
There's a bunch of those basic messaging things
that are just good things to follow.
>> Absolutely. Yeah. The pricing here is really compelling.
If you look at the numbers here, the SLAs
that you get for very little are crazy.
I can think of very few operations that would need to
exceed some of these requirements.
Numbers here, 2,500 million operations a month.
It's one-fifth of a dollar for every million operations.
That's remarkable.
So very cool.
The standard rates.
>> Yeah. It's crazy.
While we're doing some coding here,
I'm going to ping him and find out,
because I know he tweeted out fairly recently some of
the volumes that we have going through
the platform and it's just crazy.
We're going to do Spring.
>> He's well-known, of course, because of his expertise in AMQP,
which is a messaging protocol
that you can use if you want to talk to Azure Service Bus.
You can also use it for other brokers out there.
So it's a well-known protocol and he's an expert on that.
It's just really great to see legendary names like
himself plumbing the platform,
making it great for the rest of us so we
don't have to worry about getting it to work.
>> It's nice having standards on our platform,
so that way we can go play with other platforms nicely.
>> Right. The benefit,
of course, is we want integration.
So integration gives us a way to connect one system with another.
Standards are useful there,
and there are so many use cases for messaging
that having an easy path
towards enabling it is obviously going to be a big win.
Martin Fowler did a very good presentation or a good article
a few years ago talking about the different types of messaging.
There's event notifications, which happens when a system
sends event messages to
notify other systems of a change in those domain.
There's event-carried state transfer,
which happens when you want to update clients of
a system in such a way that they don't need to
contact the source system in order to do further work.
There's event sourcing, which is
the idea that whenever we make a change to the state of a system,
we record that state change as an event,
and we can confidently rebuild the state
by reprocessing the events at anytime in the future.
Of course, there's CQRS,
Command Query Responsibility Segregation,
which is the notion of having
separate data structures for reading and writing information.
All of these hinge on having
reliable foundational messaging services available,
and Azure Service Bus certainly fits the bill.
So I cannot wait to pull it into our Spring application
here. We're going to build a new service.
I'm just going to go to start.spring.io I'm going to
choose Spring Boot 2.2x.
We going to use a Service Bus.
We're going to bring in the Azure support and that's it.
We could use the Azure API,
the Azure Service Bus Java SDK directly.
But I want to use
an abstraction here that's available in Spring Cloud.
Speaking of unified abstractions and interfaces,
and protocols, there's an abstraction in
Spring Cloud called Spring Cloud Stream.
Now Spring Cloud Stream gives you the ability to write
messaging code against interfaces whose actual binding,
whose actual connection to the messaging platform
is a matter of configuration done external to the Java code.
That's what matters or the JVM code,
I suppose is probably fair.
So let's go ahead and use the Azure Support.
We're going to create a web app, so that we have
some way of launching the request.
We're going to hit "Generate" and
then we'll open this up in the IDE.
Again, in the IDE will work just fine.
We're going to be using IntelliJ,
Visual Studio Code and Eclipse,
and all that good stuff works just fine.
Now we're going to write the code first.
The code is going to be a pretty simple.
It's going to be a REST controller. I'm going to create
a Azure Service Bus demo.
The Azure Service Bus demo is going to be
an HTTP Controller, not a REST controller.
I could just say, REST controller,
but it's just going to be an HTTP endpoint.
It's not really RESTful in this case,
and I'm going to use an HTTP endpoint called
Send to send the request.
I'm going to use that as a way of launching a request,
and I'm going to launch the request by
de-referencing an object of type Source.
I need to bring Cloud Stream.
I don't think I actually have it here.
I forgot to bring that in so we can go here, Cloud Stream.
I'm going to explore. I'm going to copy all of this.
That's just one dependency that I forgot to add.
I'll just replace the one we've already got
the build and re-import
that into my IDE, so Spring Cloud Stream.
Then I need the Azure Spring Cloud Stream binder.
That's a very important piece there.
The binder is the thing that teaches
Spring Cloud Stream how to talk
to the messaging platform in particular.
Spring Cloud Stream provides
the core SPI of which this is an implementation.
I'll add this dependency for the moment, just for the moment,
this is not included in
the Azure Spring Integration out of the box,
it's just included as part of the release train.
You have to explicitly opt in to
this particular version of the service bus binder,
but I expected that will change in the near term.
We now are going to be able to write code against an interface.
What I mean by an interface is literally just an interface that
gives us a reference to what's called a message channel.
These message channels are named conduits or
pipes through which messages can flow.
We need to tell Spring Cloud Stream to enable a
binding with an instance of one of these interfaces
that'll actually discover the message channel definitions in
that interface and then hydrate
it given configuration, which we have yet to do.
We'll do that in the second. But one such interface
that we could use as provided out of
the box if we're not inclined to write our own is source.
Source.class is just an interface that has a MessageChannel.
The channel has a label called output.
That's it. It's a channel that sent message out.
You can see that it does so because it says,
output. It's fairly obvious really.
We're going to use output and we're going
to have another one here for input.
Data is going to be sent to this channel.
Data will arrive from this one.
So the data will come from the outside world via
the Source and the data will go to the outside world via the Sink.
The Sink is just another interface here.
By the way, I could actually bridge these two interfaces together.
I could actually have my own processor interface
which extends both Source and Sink,
or I can manually re-declare
these interfaces just as they are here.
Again, there's no reason I have to
use the out-of-the-box interfaces.
It's just a convention if you've
got something that's going to do input and output.
Now, normally, you would have
one service send a message
and then you have another one that would consume it.
But the code is so trivial.
I'll leave it to you as an exercise to just go to
start.stream and do that twice in generating new applications.
Now that we've got Source and Sink defined,
I can inject a pointer reference to Source in my constructor.
I'm going to have Limbach synthesize their constructor for me.
This reference will be non-null when the application starts up.
We're going to say source.output.
There's our message channel.
I want to send a message into that channel.
By the way, a better strategy might be to actually
just define the constructor as you can see there.
You want to define the output channel
as a private variable, so private final.
Here, I'll say that this.output equals source.output.
There you go. That's the Azure Service Bus Code rewritten.
Now, I'm not constantly dereferencing output channel.
It doesn't really make a big difference.
Then here, I say output.send and then I need to send a message.
The message I can build would be,
you guessed it, MessageBuilder.
We'll say with.Payload, "Hello Azure Service Bus.build."
Send out that message,
message.send and voila, there's the entire application code.
That could of course, provide custom headers, whatever.
Platform of choice, of course,
and the headerValue of course is Azure Spring Cloud and voila,
so that's how you would send a message out.
You've paid a message and you send it out.
Now, I can create another component,
or I could do it in the same component.
I could do another thing that is just a listener.
It'll be a component like
so class, greetings, whatever, messageListener.
It's just going to be a thing that listens for the messages.
Here is just going to be a StreamListener.
I'm going to say Sink.INPUT Public void, consume.
I can actually define
the prototype in terms of the message envelope object,
which has headers and a payload,
or I can just define it in terms of
the Java object that's going to be arriving.
By the way, I could go a step further.
There's actually support in Spring Cloud Stream
for sterilization both on the input and output.
If I know, for example, that the data is application JSON,
I can actually practically convert the JSON into a Java object.
Then the signature here would be a message of t,
or just t, where t is my type.
Here's the payload and I'm going to log that out payload.
Here's the headers.
You're going to visit each one of those k,
v system out.println k,
v. There's just me logging out the payload itself and
the headers for the message as they arrive.
Let's do a little delineation here to delimited.
That's the application and that's going to work.
Assuming it's all compiling,
it seems like it should be okay.
What's the issue here?
The only thing that we're missing is the configuration.
The configuration, as I said,
is what connects this logical code to my actual broker.
Let's rebuild that and see what's not compiling.
Go to the property file in the meantime.
Here the configuration I'm going to provide,
it's just standard Spring Cloud Stream stuff.
I mean, there's only one thing that we have
to do that is specific to
the Azure Spring Cloud Stream
binder and that's this bit right here.
I'm going to use Azure Service Bus.
This is an environment variable that I have in my local machine,
this environment variable here.
It's an Azure Service Bus Connection String.
It's going to connect to this Spring
Cloud Azure Service Bus Connection.
Then here is the Spring Cloud Stream binding definition.
It says for the input channel,
the input name on the interface
corresponds to the message queue in
Azure Service Bus. That's over here.
You can see I've got
my Azure Service Bus definitions here on the platform, bootifulsb.
Then in there I've got queues and the topics.
I'm going to use a queue and queue's name is messages-queue.
I want to consume that.
The logical name, there's messages-queue,
that's the thing from which I'm expecting
messages to arrive and the thing
on too which I want to send messages is also messages-queue.
With that, I think we can start our application,
get an HTTP endpoint, hit the HTTP endpoint,
and see that message reflected in
the console when it gets sent out
from our Java code to the platform and then
back again to the code.
>> When you're running this here, it's like on
the Microsoft platform Kestrel
would be our local server that we
spin up and listened to an endpoint.
You're doing the same thing here with that endpoint black sun.
>> I hit an exception. My Build
doesn't seem to know that I've already
got this binder on the class path, so I restarted it.
Hopefully, it's better now.
It looks better, good.
It's connecting to a service bus.
It's making that network connection there.
It does slow down the builds a little bit here.
Now, local host send.
There we go. Yes, I went to the browser,
went to local host 8084/send.
You can see them reflected on the console here.
The output of the message, there's the payload, and the headers.
My platform of choice,
of course, is Azure Spring Cloud.
That's the custom header that is sent from
the producer and then it received by the consumer.
>> That's awesome. Now what typical next steps?
I mean, obviously, you probably have
two different systems producing messages, consuming messages.
Let's say if I want these functions to do some processing,
would you have support for spring with functions.
>> Spring Cloud function,
you can actually use our abstraction
Spring Cloud Function to talk to Azure function.
It's literally, you use a Java H interface.
You create a bean that looks like
this @Bean function and then
the payload in and payload out function.
That's the essence of what you have to do.
But there's a bit of configuration to do beyond that.
But that's the contract. This would be
the incoming message and then the response that you want.
Or it could be a consumer,
which is not a function,
but it's just takes a value
comes in and you can send a message out.
Your code ends up looking very natural, very functional.
>> Awesome. I really love just
having a spring plumbing
around everything in Azure and that we keep working together.
>> I love it.
>> The Spring framework itself just makes everything so easy.
I looked at how fast you can spit stuff on here.
It's not like there's a lot
of difference between the one you're writing
here and what would lay in production.
With everything thrown around config and the interfaces
in all of your different inversion
of control and things like that,
you get to production pretty quickly.
>> This URL, I could change the auto-point to
my more beefy account.
The more provision service bus instance but that's it.
That could be, like I said, it's an environment variable.
I changed the environment variable in production,
and this is it and
getting this to production would be easy as well.
Yeah, absolutely trivial to get this to production.
>> Thanks, Josh,and we'll see you again soon.
>> Thank you.