>> Hey, Josh, we're back again.
I think this is the last one that you and I are doing.
After this, you get to go have fun
with other Java people on Microsoft, but not me.
I think you're going to have a lot of fun there
and people that speak your language in the market.
Today is Cosmos DB.
>> Yeah, right.
>> In particular, you're going to go,
not necessarily straight Cosmos route,
but the Mongo interface to Cosmos.
>> Yeah. It works perfectly.
That's one of the nice things about Cosmos DB is
that in addition to having been built from the ground up
to support global distribution and
a horizontal scale and to guarantee
single digit millisecond read
and write latencies at the 99th percentile, all that good stuff.
In addition to guaranteeing 99.9999
percent high availability with multi-homing anywhere in the world,
it also speaks a whole bunch of different protocols.
So if you want to consume it as a MongoDB,
you can, if you want to consume it as a Cassandra, you can,
if you want to speak to it using the Gremlin protocol,
which is a graph database, you can,
and if you want to speak to it using a SQL syntax and protocol,
again, you can, which is phenomenal.
Really, impressive piece of kit.
So we're just going to write a Spring Data MongoDB application.
There is absolutely nothing fantastic about this at all.
In fact, there's no Spring Azure starter here for this.
I'm just going to use the regular Spring Data MongoDB project
to talk about Cosmos DB, as simple as that.
Magic is not a great word,
but it's pretty appropriate in this case.
So Cosmos DB, I'm going to use that.
Then the application is going to be Spring Data,
and you can see we've got a lot of Spring Data projects here.
So Spring Data for Apache Cassandra,
I could've used that, that would have worked,
but MongoDB is by far the most prolific of
all the NoSQL data stores.
That's it, by the way I can use
Reactive MongoDB or I could use MongoDB.
So reactive APIs give us the ability
to write code that doesn't block,
it doesn't sit on a thread waiting for things to happen.
As soon as there's an opportunity,
it jumps off of the thread so that something else can use it.
I'm going to hit "Generate", and
we're going to open this up. Here we go.
Now, let's see here,
what happened here, close that.
It my Cosmos DB instance.
Good. In my portal here,
I've got my Azure Cosmos DB tile,
click on that and I've got a CosmosDB instance.
In there, I've got the actual data.
There's even a Data Explorer,
you can even see the connection string information.
I'm not going to show you that because, of course, it's private.
But once you've got that information,
you can then plug it into your MongoDB connection string.
What you're going to do is you're
going to connect to a collection.
A collection, it's like a MongoDB collection,
which has rows which are called documents.
So it actually maps very nicely.
I'm going to go to the collection here, the Data Explorer,
and I've got my data, I've got
actually the records here in my collection.
So there you go, you can see I've already got
a bunch of it already stored there.
But for my high resolution here,
there you go. I've got data there.
So all we're going to do is just write some more data, I guess,
we can actually delete the collection.
So reservations, let's delete that and delete this one as well.
Reservation, very nosy, it wants to know
why I want to delete the collection.
Now, we are going to build an application
that uses just regular spring data syntax, not a big deal here.
So public static void main, as usual,
I'm going to create an object to map
it to the domain model of our database,
in this case, it will just be an instance of type reservation.
Then I'll have a primary key or a document key of type string.
Because again, in MongoDB and in Azure Cosmos DB,
you have UUIDs, you don't have
monotonically incrementing primary keys.
So these are documents, again,
maps very naturally to the domain model there,
and we'll have a string of type name.
That's the essence of what I want to express,
that's the field plus the primary key or the data key, whatever.
I want to create some getters and setters and toString and
equals and hash code and all that good stuff.
So I'm going to go ahead and bring in Lombok.
Lombok is a compile time annotation processor,
I should've and probably would
have selected that back at the initializer, but I forgot.
So we'll have to do it the old-fashioned way by
manually adding the dependency to the build.
AllArgsConstructor, NoArgsConstructor.
Good. So there's our entity.
Now we're going to create a "Reservation Repository",
extends Mongo repository, so reservation string.
I just want to save some data into the database,
so we're going to say class CosmosDbDemo
and we're just going to create a beam.
It's going to be an object that
gets initialized when the application starts up.
I'm going to inject a reference to that repository there,
and we'll just take advantage of it.
We're going to say rr.save new reservation,
pass it null and Bootiful Azure.
Good. That's it.
Find all for each system.out print line.
Good stuff. So let's run this and see.
This will actually work. You know
why this would work? It's very deceptive.
This would work right now as I've got it
because you would connect by default to my localhost instance.
Since I have a localhost MongoDB,
I would actually be fooled into thinking it worked just fine.
I need to point it to my Cloud.
So in order to do that, I need some configuration.
This is the only place where we're going
to see that we've got to any kind
of configuration at all
that indicates that we're not talking to a local MongoDB.
So spring.data.mongodb.database equals bootiful
Cosmos db and spring.data.mongodb.URI equals,
and here I've got an environment variable,
so Azure_Cosmos_DB_Mongo_URL, that's it,
that's the entire application.
This URL could have been any valid MongoDB instance
and in this case any Azure Cosmos DB instance.
All right, let's see.
Run the application, see what we get.
It looks like it's connecting.
In the connection, we wrote out the data.
So we save the data and then we ask for
all the data to come back and you can see here,
it's a UUID that's been given to us by the database.
If we go back to here,
just hit "Refresh", data explorer, reservation, documents,
wait for it to pull down the data remotely on
my hidden server Wi-Fi.
>> So the default is,
when the collection wasn't there,
it went and it goes and creates
the collection and plops it in there.
>> Yes. So no rabbits at my sleeve.
I just did everything from the code there and you
can see the results reflected in the output in the console here.
>> So as far as your app knows,
you're looking at a Mongo database.
So I know a lot of people out there use Mongo,
and now they didn't have to go change any of their code,
but they're actually being backed by Azure Cosmos DB instead.
>> Which is a heck of a proposition.
You heard the numbers,
that truly is web-scale.
This is the first time I can actually
say that this is web-scale MongoDB,
This is crazy geo-replication,
crazy availability, crazy low latency,
just a very compelling experience.
Spring data has support for MongoDB transactions,
it's got support for all sorts of things,
I think most of which, if not all of it,
I'm pretty sure all of it, but don't quote me on that,
is supported by Cosmos DB.
It just works, which is awesome.
>> I think the cool part of this is,
you're running your Spring app and we
have a lot of Mongo customers on Azure.
So whether you're using
Mongo running on a set of IaaS VMs on Azure,
or whether you're using Mongo Enterprise from Mongo,
or you're using Mongo in Cosmos,
a lot of customers use
both for different use cases and different things.
So it's like, Spring has allowed us to just say, hey,
one API and go configure the endpoint
with the power of the Mongo interface to Cosmos.
>> Right. Works a charm.
The other thing is I didn't mention it,
but you could do reactive MongoDB here as well, so non-blocking.
>> Awesome. Well, thanks Josh,
and we'll see you again soon.
>> That's good.